VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 420
声望: 174

一、现象描述

最近编写好了自己的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)
Administrator
avatar
加入于:
帖子: 4502
声望: 321

这块是专门这么设计的,一旦策略完成了初始化,就可以实时接收Tick计算K线,哪怕策略没有启动,此时策略的数据也是最新状态,从而能满足随时启动的要求

Member
avatar
加入于:
帖子: 420
声望: 174

谢谢管理员!
是的,这么设计非常合理,否则在初始化和启动之间就会出现K线数据的缺失。
明白道理就不会觉得奇怪,而且对CTA策略的运行机制理解的更加透彻!

Member
avatar
加入于:
帖子: 9
声望: 0

用Python的交易员 wrote:

这块是专门这么设计的,一旦策略完成了初始化,就可以实时接收Tick计算K线,哪怕策略没有启动,此时策略的数据也是最新状态,从而能满足随时启动的要求
如果在on_tick中有变量的变化的话,就会有问题的吧,本来应该在启动时才发生的变化,结果在策略初始化时就发生了。这种情况应该如何解决呢?

Member
avatar
加入于:
帖子: 4684
声望: 285

请问【变化】具体指的什么?如果你的策略是基于K线交易的话,初始化不会调用on_tick。而且如果怕非交易时间段数据对策论产生影响的话,过滤掉非交易时间段的数据就好了。

Member
avatar
加入于:
帖子: 31
声望: 2

xiaohe wrote:

请问【变化】具体指的什么?如果你的策略是基于K线交易的话,初始化不会调用on_tick。而且如果怕非交易时间段数据对策论产生影响的话,过滤掉非交易时间段的数据就好了。

请问如何过滤掉非交易时间段数据?有代码可以参考吗?谢谢

Member
avatar
加入于:
帖子: 9
声望: 0

xiaohe wrote:

请问【变化】具体指的什么?如果你的策略是基于K线交易的话,初始化不会调用on_tick。而且如果怕非交易时间段数据对策论产生影响的话,过滤掉非交易时间段的数据就好了。

比如我在on_tick中有以下判断代码 flag初始值为 2
if self.pos == =0 and flag == 2:
flag = 3
本来我是要在策略启动时才应该有的判断,结果在策略初始化时,这个flag就变成了 3
这个要如何解决呢

Member
avatar
加入于:
帖子: 4684
声望: 285

人海孤鸿 wrote:

xiaohe wrote:

请问【变化】具体指的什么?如果你的策略是基于K线交易的话,初始化不会调用on_tick。而且如果怕非交易时间段数据对策论产生影响的话,过滤掉非交易时间段的数据就好了。

比如我在on_tick中有以下判断代码 flag初始值为 2
if self.pos == =0 and flag == 2:
flag = 3
本来我是要在策略启动时才应该有的判断,结果在策略初始化时,这个flag就变成了 3
这个要如何解决呢
五楼已经说过了,如果你的策略是基于K线交易的话,初始化不会调用on_tick。可以自己去看engine里的process_tick_event函数,要strategy.inited(策略初始化之后)才会把tick传进策略的on_tick函数中

Member
avatar
加入于:
帖子: 4684
声望: 285

linhertz wrote:

xiaohe wrote:

请问【变化】具体指的什么?如果你的策略是基于K线交易的话,初始化不会调用on_tick。而且如果怕非交易时间段数据对策论产生影响的话,过滤掉非交易时间段的数据就好了。

请问如何过滤掉非交易时间段数据?有代码可以参考吗?谢谢
在engine下的process_tick_event函数中做判断即可

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】