[bug fix]

This commit is contained in:
msincenselee 2020-03-19 13:49:27 +08:00
parent 6fb4ff3969
commit 8bec0006ac
4 changed files with 57 additions and 31 deletions

View File

@ -378,6 +378,8 @@ class BackTestingEngine(object):
def get_position_holding(self, vt_symbol: str, gateway_name: str = ''): def get_position_holding(self, vt_symbol: str, gateway_name: str = ''):
""" 查询合约在账号的持仓(包含多空)""" """ 查询合约在账号的持仓(包含多空)"""
if not gateway_name:
gateway_name = self.gateway_name
k = f'{gateway_name}.{vt_symbol}' k = f'{gateway_name}.{vt_symbol}'
holding = self.holdings.get(k, None) holding = self.holdings.get(k, None)
if not holding: if not holding:
@ -1063,8 +1065,12 @@ class BackTestingEngine(object):
strategy.on_stop_order(stop_order) strategy.on_stop_order(stop_order)
strategy.on_order(order) strategy.on_order(order)
self.append_trade(trade) self.append_trade(trade)
holding = self.get_position_holding(vt_symbol=trade.vt_symbol)
# 更新持仓缓存数据
k = '.'.join([self.gateway_name, trade.vt_symbol])
holding = self.get_position_holding(trade.vt_symbol, self.gateway_name)
holding.update_trade(trade) holding.update_trade(trade)
strategy.on_trade(trade) strategy.on_trade(trade)
def cross_limit_order(self, bar: BarData = None, tick: TickData = None): def cross_limit_order(self, bar: BarData = None, tick: TickData = None):
@ -1139,21 +1145,19 @@ class BackTestingEngine(object):
# 记录该合约来自哪个策略实例 # 记录该合约来自哪个策略实例
trade.strategy_name = strategy.strategy_name trade.strategy_name = strategy.strategy_name
# 更新持仓缓存数据
k = '.'.join([self.gateway_name, trade.vt_symbol])
holding = self.get_position_holding(trade.vt_symbol, self.gateway_name)
holding.update_trade(trade)
strategy.on_trade(trade) strategy.on_trade(trade)
self.trade_dict[trade.vt_tradeid] = trade self.trade_dict[trade.vt_tradeid] = trade
self.trades[trade.vt_tradeid] = copy.copy(trade) self.trades[trade.vt_tradeid] = copy.copy(trade)
self.write_log(u'vt_trade_id:{0}'.format(trade.vt_tradeid)) self.write_log(u'vt_trade_id:{0}'.format(trade.vt_tradeid))
# 更新持仓缓存数据
pos_buffer = self.pos_holding_dict.get(trade.vt_symbol, None)
if not pos_buffer:
pos_buffer = PositionHolding(self.get_contract(vt_symbol))
self.pos_holding_dict[trade.vt_symbol] = pos_buffer
pos_buffer.update_trade(trade)
self.write_log(u'{} : crossLimitOrder: TradeId:{}, posBuffer = {}'.format(trade.strategy_name, self.write_log(u'{} : crossLimitOrder: TradeId:{}, posBuffer = {}'.format(trade.strategy_name,
trade.tradeid, trade.tradeid,
pos_buffer.to_str())) holding.to_str()))
# 写入交易记录 # 写入交易记录
self.append_trade(trade) self.append_trade(trade)

View File

@ -140,9 +140,12 @@ class CtaEngine(BaseEngine):
def init_engine(self): def init_engine(self):
""" """
""" """
self.register_event()
self.register_funcs()
self.load_strategy_class() self.load_strategy_class()
self.load_strategy_setting() self.load_strategy_setting()
self.register_event()
self.write_log("CTA策略数字货币引擎初始化成功") self.write_log("CTA策略数字货币引擎初始化成功")
def close(self): def close(self):
@ -175,18 +178,17 @@ class CtaEngine(BaseEngine):
self.main_engine.save_strategy_snapshot = self.save_strategy_snapshot self.main_engine.save_strategy_snapshot = self.save_strategy_snapshot
# 注册到远程服务调用 # 注册到远程服务调用
rpc_service = self.main_engine.apps.get('RpcService') if self.main_engine.rpc_service:
if rpc_service: self.main_engine.rpc_service.register(self.main_engine.get_strategy_status)
rpc_service.register(self.main_engine.get_strategy_status) self.main_engine.rpc_service.register(self.main_engine.get_strategy_pos)
rpc_service.register(self.main_engine.get_strategy_pos) self.main_engine.rpc_service.register(self.main_engine.add_strategy)
rpc_service.register(self.main_engine.add_strategy) self.main_engine.rpc_service.register(self.main_engine.init_strategy)
rpc_service.register(self.main_engine.init_strategy) self.main_engine.rpc_service.register(self.main_engine.start_strategy)
rpc_service.register(self.main_engine.start_strategy) self.main_engine.rpc_service.register(self.main_engine.stop_strategy)
rpc_service.register(self.main_engine.stop_strategy) self.main_engine.rpc_service.register(self.main_engine.remove_strategy)
rpc_service.register(self.main_engine.remove_strategy) self.main_engine.rpc_service.register(self.main_engine.reload_strategy)
rpc_service.register(self.main_engine.reload_strategy) self.main_engine.rpc_service.register(self.main_engine.save_strategy_data)
rpc_service.register(self.main_engine.save_strategy_data) self.main_engine.rpc_service.register(self.main_engine.save_strategy_snapshot)
rpc_service.register(self.main_engine.save_strategy_snapshot)
def process_timer_event(self, event: Event): def process_timer_event(self, event: Event):
""" 处理定时器事件""" """ 处理定时器事件"""
@ -1317,7 +1319,7 @@ class CtaEngine(BaseEngine):
""" """
return list(self.classes.keys()) return list(self.classes.keys())
def get_strategy_status(self, strategy_name): def get_strategy_status(self):
""" """
return strategy inited/trading status return strategy inited/trading status
:param strategy_name: :param strategy_name:

View File

@ -714,7 +714,6 @@ class CtaFutureTemplate(CtaTemplate):
# 未执行的订单中,存在是异常,删除 # 未执行的订单中,存在是异常,删除
self.write_log(u'{}报单更新,{}'.format(self.cur_datetime, order.__dict__)) self.write_log(u'{}报单更新,{}'.format(self.cur_datetime, order.__dict__))
if order.vt_orderid in self.active_orders: if order.vt_orderid in self.active_orders:
if order.volume == order.traded and order.status in [Status.ALLTRADED]: if order.volume == order.traded and order.status in [Status.ALLTRADED]:
@ -787,6 +786,7 @@ class CtaFutureTemplate(CtaTemplate):
else: else:
old_traded_volume = grid.traded_volume old_traded_volume = grid.traded_volume
grid.traded_volume += order.volume grid.traded_volume += order.volume
grid.traded_volume = round(grid.traded_volume, 7)
self.write_log(f'{grid.direction.value}单部分{order.offset}仓,' self.write_log(f'{grid.direction.value}单部分{order.offset}仓,'
+ f'网格volume:{grid.volume}, traded_volume:{old_traded_volume}=>{grid.traded_volume}') + f'网格volume:{grid.volume}, traded_volume:{old_traded_volume}=>{grid.traded_volume}')
@ -820,7 +820,7 @@ class CtaFutureTemplate(CtaTemplate):
self.write_log(u'{} 委托信息:{}'.format(order.vt_orderid, old_order)) self.write_log(u'{} 委托信息:{}'.format(order.vt_orderid, old_order))
old_order['traded'] = order.traded old_order['traded'] = order.traded
order_vt_symbol = copy(old_order['vt_symbol']) order_vt_symbol = copy(old_order['vt_symbol'])
order_volume = old_order['volume'] - old_order['traded'] order_volume = round(old_order['volume'] - old_order['traded'], 7)
if order_volume <= 0: if order_volume <= 0:
msg = u'{} {}{}需重新开仓数量为{},不再开仓' \ msg = u'{} {}{}需重新开仓数量为{},不再开仓' \
.format(self.strategy_name, .format(self.strategy_name,
@ -1044,6 +1044,8 @@ class CtaFutureTemplate(CtaTemplate):
""" """
self.write_log(u'执行事务平多仓位:{}'.format(grid.to_json())) self.write_log(u'执行事务平多仓位:{}'.format(grid.to_json()))
self.account_pos = self.cta_engine.get_position_holding(self.vt_symbol)
if self.account_pos is None: if self.account_pos is None:
self.write_error(u'无法获取{}得持仓信息'.format(self.vt_symbol)) self.write_error(u'无法获取{}得持仓信息'.format(self.vt_symbol))
return False return False
@ -1057,14 +1059,17 @@ class CtaFutureTemplate(CtaTemplate):
# 发出平多委托 # 发出平多委托
if grid.traded_volume > 0: if grid.traded_volume > 0:
grid.volume -= grid.traded_volume grid.volume -= grid.traded_volume
grid.volume = round(grid.volume, 7)
grid.traded_volume = 0 grid.traded_volume = 0
if self.account_pos.long_pos < grid.volume: if 0 < self.account_pos.long_pos < grid.volume:
self.write_error(u'当前{}的多单持仓:{},不满足平仓目标:{}' self.write_error(u'当前{}的多单持仓:{},不满足平仓目标:{},强制降低'
.format(self.vt_symbol, .format(self.vt_symbol,
self.account_pos.long_pos, self.account_pos.long_pos,
grid.volume)) grid.volume))
grid.volume = self.account_pos.long_pos
vt_orderids = self.sell( vt_orderids = self.sell(
vt_symbol=self.vt_symbol, vt_symbol=self.vt_symbol,
price=sell_price, price=sell_price,
@ -1091,6 +1096,7 @@ class CtaFutureTemplate(CtaTemplate):
""" """
self.write_log(u'执行事务平空仓位:{}'.format(grid.to_json())) self.write_log(u'执行事务平空仓位:{}'.format(grid.to_json()))
self.account_pos = self.cta_engine.get_position_holding(self.vt_symbol)
if self.account_pos is None: if self.account_pos is None:
self.write_error(u'无法获取{}得持仓信息'.format(self.vt_symbol)) self.write_error(u'无法获取{}得持仓信息'.format(self.vt_symbol))
return False return False
@ -1104,8 +1110,17 @@ class CtaFutureTemplate(CtaTemplate):
# 发出cover委托 # 发出cover委托
if grid.traded_volume > 0: if grid.traded_volume > 0:
grid.volume -= grid.traded_volume grid.volume -= grid.traded_volume
grid.volume = round(grid.volume, 7)
grid.traded_volume = 0 grid.traded_volume = 0
if 0 < abs(self.account_pos.short_pos) < grid.volume:
self.write_error(u'当前{}的空单持仓:{},不满足平仓目标:{}, 强制降低'
.format(self.vt_symbol,
self.account_pos.short_pos,
grid.volume))
grid.volume = abs(self.account_pos.short_pos)
vt_orderids = self.cover( vt_orderids = self.cover(
price=cover_price, price=cover_price,
vt_symbol=self.vt_symbol, vt_symbol=self.vt_symbol,

View File

@ -55,12 +55,14 @@ class CtaPosition(CtaComponent):
if self.short_pos + volume > 0: if self.short_pos + volume > 0:
self.write_error(u'平仓异常,超出仓位。净:{0},空:{1},平仓:{2}'.format(self.pos, self.short_pos, volume)) self.write_error(u'平仓异常,超出仓位。净:{0},空:{1},平仓:{2}'.format(self.pos, self.short_pos, volume))
self.write_log(f'空仓:{self.short_pos}->{self.short_pos + volume}') pre_short_pos = self.short_pos
self.write_log(f'净:{self.pos}->{self.pos + volume}') pre_pos = self.pos
self.short_pos += volume self.short_pos += volume
self.pos += volume self.pos += volume
self.short_pos = round(self.short_pos, 7) self.short_pos = round(self.short_pos, 7)
self.pos = round(self.pos, 7) self.pos = round(self.pos, 7)
self.write_log(f'空仓:{pre_short_pos}->{self.short_pos}')
self.write_log(f'净:{pre_pos}->{self.pos}')
# 更新上层策略的pos。该方法不推荐使用 # 更新上层策略的pos。该方法不推荐使用
self.strategy.pos = self.pos self.strategy.pos = self.pos
@ -68,15 +70,18 @@ class CtaPosition(CtaComponent):
if direction == Direction.SHORT: # 平多仓 if direction == Direction.SHORT: # 平多仓
if self.long_pos - volume < 0: if self.long_pos - volume < 0:
self.write_error(u'平仓异常,超出仓位。净:{0},多:{1},平仓:{2}'.format(self.pos, self.long_pos, volume)) self.write_error(u'平仓异常,超出仓位。净:{0},多:{1},平仓:{2}'.format(self.pos, self.long_pos, volume))
pre_long_pos = self.long_pos
self.write_log(f'多仓:{self.long_pos}->{self.long_pos - volume}') pre_pos = self.pos
self.write_log(f'净:{self.pos}->{self.pos - volume}')
self.long_pos -= volume self.long_pos -= volume
self.pos -= volume self.pos -= volume
self.long_pos = round(self.long_pos, 7) self.long_pos = round(self.long_pos, 7)
self.pos = round(self.pos, 7) self.pos = round(self.pos, 7)
self.write_log(f'多仓:{pre_long_pos}->{self.long_pos}')
self.write_log(f'净:{pre_pos}->{self.pos}')
return True return True
def clear(self): def clear(self):