[bug fix]
This commit is contained in:
parent
6fb4ff3969
commit
8bec0006ac
@ -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)
|
||||||
|
@ -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:
|
||||||
|
@ -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,
|
||||||
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user