一、现象描述
最近编写好了自己的CTA策略,上线运行,发现一个奇怪的现象:
1、设置好策略
2、初始化策略
3、运行策略
策略已经运行起来,一切都表现的正常——可以开仓、平仓。
可是当我想把策略停止下来,我发现交易停止了,可是on_bar()函数中的一些调试信息(为了观察策略的活动而增加的)仍然还在继续工作!
怪了,明明策略研究停止了的,为什么on_bar()函数仍然在执行?
二、原因分析
原来策略中涉及到的合约与CTA策略是被添加到在CtaEngine中的symbol_strategy_map字典中了,而消息EVENT_TICK和CtaEngine的process_tick_event()被注册到消息引擎中,这样子只要接口接受到tick数据就会调用CtaEngine的process_tick_event()。
class CtaEngine(BaseEngine):
...
...
def init_engine(self):
self.init_rqdata()
self.load_strategy_class()
self.load_strategy_setting()
self.load_strategy_data()
self.register_event()
self.write_log("CTA策略引擎初始化成功")
def register_event(self):
""""""
self.event_engine.register(EVENT_TICK, self.process_tick_event)
self.event_engine.register(EVENT_ORDER, self.process_order_event)
self.event_engine.register(EVENT_TRADE, self.process_trade_event)
self.event_engine.register(EVENT_POSITION, self.process_position_event)
def process_tick_event(self, event: Event):
""""""
tick = event.data
strategies = self.symbol_strategy_map[tick.vt_symbol]
if not strategies:
return
self.check_stop_order(tick)
for strategy in strategies:
if strategy.inited:
self.call_strategy_func(strategy, strategy.on_tick, tick)
而CtaEngine的process_tick_event()中使用tick的vt_symbol找到symbol_strategy_map字典中对应所有策略,然后把tick逐个推送给策略的on_tick()函数,而这里只是判断每个策略的状态是否为inited==True。
三、如果把已经运行的策略停止会怎样?
如果说策略已经初始化了,那么不管是否被主动停止(trading==False),策略的on_tick()函数都会被执行!进而策略的on_bar()也会被执行,只是所有的交易函数均不会执行而已。
这样对停止策略的处理是否有点文不对题?既然已经停止策略,就应该把它停止下来,可是实际的情况是策略处理交易动作被限制之外,其他的处理逻辑和流程仍然再执行,并没有停止下来!
下面是CtaTemplate类中的几个交易相关函数的代码,其中就有策略的trading状态的限制条件:
def send_order(
self,
direction: Direction,
offset: Offset,
price: float,
volume: float,
stop: bool = False,
lock: bool = False
):
"""
Send a new order.
"""
if self.trading:
vt_orderids = self.cta_engine.send_order(
self, direction, offset, price, volume, stop, lock
)
return vt_orderids
else:
return []
def cancel_order(self, vt_orderid: str):
"""
Cancel an existing order.
"""
if self.trading:
self.cta_engine.cancel_order(self, vt_orderid)
def cancel_all(self):
"""
Cancel all orders sent by strategy.
"""
if self.trading:
self.cta_engine.cancel_all(self)