diff --git a/vnpy/app/cta_stock/back_testing.py b/vnpy/app/cta_stock/back_testing.py index 5045297e..3bc4b34f 100644 --- a/vnpy/app/cta_stock/back_testing.py +++ b/vnpy/app/cta_stock/back_testing.py @@ -164,7 +164,7 @@ class BackTestingEngine(object): self.net_capital = self.init_capital # 实时资金净值(每日根据capital和持仓浮盈计算) self.max_capital = self.init_capital # 资金最高净值 self.max_net_capital = self.init_capital - self.avaliable = self.init_capital + self.available = self.init_capital self.max_pnl = 0 # 最高盈利 self.min_pnl = 0 # 最大亏损 @@ -261,7 +261,7 @@ class BackTestingEngine(object): if self.net_capital == 0.0: self.percent = 0.0 - return self.net_capital, self.avaliable, self.percent, self.percent_limit + return self.net_capital, self.available, self.percent, self.percent_limit def set_test_start_date(self, start_date: str = '20100416', init_days: int = 10): """设置回测的启动日期""" @@ -294,7 +294,7 @@ class BackTestingEngine(object): self.net_capital = capital # 实时资金净值(每日根据capital和持仓浮盈计算) self.max_capital = capital # 资金最高净值 self.max_net_capital = capital - self.avaliable = capital + self.available = capital self.init_capital = capital def set_margin_rate(self, vt_symbol: str, margin_rate: float): @@ -1544,7 +1544,7 @@ class BackTestingEngine(object): holding_cost = holding_cost + cur_holding_cost # 可用资金 = 当前净值 - 占用保证金 - self.avaliable = self.net_capital - holding_cost + self.available = self.net_capital - holding_cost # 当前成本占比 self.percent = round(float(holding_cost * 100 / self.net_capital), 2) # 更新最大成本占比 @@ -1595,7 +1595,7 @@ class BackTestingEngine(object): self.write_log(msg) # 重新计算一次avaliable - self.avaliable = self.net_capital - holding_cost + self.available = self.net_capital - holding_cost self.percent = round(float(holding_cost * 100 / self.net_capital), 2) def saving_daily_data(self, d, c, m, commission, benchmark=0): diff --git a/vnpy/app/cta_stock/engine.py b/vnpy/app/cta_stock/engine.py index 426b9b32..505b307c 100644 --- a/vnpy/app/cta_stock/engine.py +++ b/vnpy/app/cta_stock/engine.py @@ -349,6 +349,20 @@ class CtaEngine(BaseEngine): # Update GUI self.put_strategy_event(strategy) + if self.engine_config.get('trade_2_wx', False): + accountid = self.engine_config.get('accountid', 'XXX') + d = { + 'account': accountid, + 'strategy': strategy_name, + 'symbol': trade.symbol, + 'action': f'{trade.direction.value} {trade.offset.value}', + 'price': str(trade.price), + 'volume': trade.volume, + 'remark': f'{accountid}:{strategy_name}', + 'timestamp': trade.time + } + send_wx_msg(content=d, target=accountid, msg_type='TRADE') + def process_position_event(self, event: Event): """""" position = event.data diff --git a/vnpy/app/cta_stock/template.py b/vnpy/app/cta_stock/template.py index 8db1d2ad..82e3bfaf 100644 --- a/vnpy/app/cta_stock/template.py +++ b/vnpy/app/cta_stock/template.py @@ -546,6 +546,7 @@ class CtaStockTemplate(CtaTemplate): def get_klines_snapshot(self): """返回当前klines的切片数据""" try: + self.write_log(f'获取{self.strategy_name}的切片数据') d = { 'strategy': self.strategy_name, 'datetime': datetime.now()} @@ -878,11 +879,44 @@ class CtaStockTemplate(CtaTemplate): continue cur_price = self.cta_engine.get_price(lg.vt_symbol) - if lg.stop_price != 0 and lg.stop_price > cur_price > 0: + + # 主动止盈 + if 0 < lg.close_price <= cur_price: + cn_name = self.cta_engine.get_name(lg.vt_symbol) # 调用平仓模块 - self.write_log(u'{} {}当前价:{} 触发止损线{},开仓价:{},v:{}'. + self.write_log(u'{} {}[{}] 当前价:{} 触发止盈{},开仓价:{},v:{}'. format(self.cur_datetime, lg.vt_symbol, + cn_name, + cur_price, + lg.close_price, + lg.open_price, + lg.volume)) + + if lg.traded_volume > 0: + lg.volume -= lg.traded_volume + lg.traded_volume = 0 + if lg.volume <= 0: + remove_gids.append(lg.id) + lg.open_status = False + lg.order_status = False + lg.close_status = False + continue + + lg.order_status = True + lg.close_status = True + self.write_log(f'{lg.vt_symbol}[{cn_name}] 数量:{lg.volume},准备卖出') + continue + + # 止损 + if lg.stop_price != 0 and lg.stop_price > cur_price > 0: + cn_name = self.cta_engine.get_name(lg.vt_symbol) + + # 调用平仓模块 + self.write_log(u'{} {}[{}] 当前价:{} 触发止损线{},开仓价:{},v:{}'. + format(self.cur_datetime, + lg.vt_symbol, + cn_name, cur_price, lg.stop_price, lg.open_price, @@ -900,13 +934,13 @@ class CtaStockTemplate(CtaTemplate): lg.order_status = True lg.close_status = True - self.write_log(f'{lg.vt_symbol} 数量:{lg.volume},准备卖出') + self.write_log(f'{lg.vt_symbol}[{cn_name}] 数量:{lg.volume},准备卖出') if len(remove_gids) > 0: self.gt.remove_grids_by_ids(direction=Direction.LONG, ids=remove_gids) self.gt.save() - def tns_excute_sell_grids(self): + def tns_excute_sell_grids(self, vt_symbol=None): """ 事务执行卖出网格 1、找出所有order_status=True,open_status=Talse, close_status=True的网格。 @@ -926,6 +960,10 @@ class CtaStockTemplate(CtaTemplate): ordering_grid = None for grid in self.gt.dn_grids: + # 只扫描vt_symbol 匹配的网格 + if vt_symbol and vt_symbol != grid.vt_symbol: + continue + # 排除: 未开仓/非平仓/非委托的网格 if not grid.open_status or not grid.close_status or not grid.open_status: continue @@ -1031,7 +1069,7 @@ class CtaStockTemplate(CtaTemplate): self.gt.save() self.policy.save() - def tns_execute_buy_grids(self): + def tns_execute_buy_grids(self, vt_symbol=None): """ 事务执行买入网格 :return: @@ -1048,6 +1086,11 @@ class CtaStockTemplate(CtaTemplate): ordering_grid = None for grid in self.gt.dn_grids: + + # 只扫描vt_symbol 匹配的网格 + if vt_symbol and vt_symbol != vt_symbol: + continue + # 排除已经执行完毕(处于开仓状态)的网格, 或者处于平仓状态的网格 if grid.open_status or grid.close_status: continue