CTA模拟交易FAQ

发这个帖子就当记录自己cta模块学习了。

总览

先说说cta策略模块的逻辑顺序。

  • 点击启动CTA策略模块后,会自动初始化生成一个CtaEngine,并且自动调用self.init_engine,做的主要有如下几件事:

    • init_rqdata()#如果没配置rqdata的可忽略
    • load_strategy_class()#从几个文件夹中读取策略类,并将其保存在self.classes字典中,用类名做key,类做value。
    • load_strategy_setting()#根据策略配置文件cta_strategy_setting.json读取配置,如果不存在该文件则创建文件,内容为{}。
      • cta_strategy_setting.json保存何种数据:从逻辑上想,根据策略名将数据切分,每个策略实例都有自身对应的合约、策略类、参数字典。
    • load_strategy_data()#从策略数据文件cta_strategy_data.json中读取本地保存的数据。
    • register_event()#将Tick,Position,Order,Trade事件推送给引擎相应处理函数。
  • 点击“添加策略”按钮时,实际运行的是引擎的add_strategy方法,作用是:将策略类实例化,根据策略名保存在self.strategies映射字典中。注意,strategy_name和类名不一样,同一个策略类可以有很多策略名(参数可以不一样)。CTA策略仅仅交易一个合约,则在引擎中将策略名和vt_symbol进行一一映射。具体规则是,单个vt_symbol对应一个策略集合(不可反)。最后,将新添加的策略更新到策略配置文件中。

  • 点击“全部初始化”按钮时,实际运行的是引擎的init_all_strategies,初始化完成的功能为:

    • 调用策略类的on_init,一般用来运行strategy.load_bar(n)。关于load_bar功能后续再说。
    • 重新读取策略数据,并且赋值给策略实例,具体数据有:
    • 通过主引擎订阅合约
    • 策略初始化状态修改
  • 点击“全部启动”按钮时,实际运行的是引擎的start_all_strategy,完成的功能为:
    • 判断交易状态(如果在交易了,就不重复启动了)
    • 调用策略类的on_start方法,将交易状态设置为True

FAQ

  • tick数据是如何进入策略的?
    在注册事件监听后,接口推送的tick数据事件会不停的向CTA引擎推送。在symbol_strategy_map映射字典中寻找对应的策略类,假设本地没有保存策略,此时也没有添加新策略,则不对tick事件做任何处理。在进行“添加策略”后,映射字典添加内容了,策略类和策略实例都形成了,那么tick事件就会传入策略实例中。

  • 策略实例的交易状态和初始化状态细节

    • inited:上面没有提到的是策略实例是如何在数据库初始化数据和实盘数据无缝衔接的,现在来解释一下。在未初始化时,接口tick事件是无法进行策略内的,每次处理tick事件都会进行一次inited判断。当开始初始化,会开启一个新的线程,将数据库或者rqdata中数据传入策略层,完毕后inited=True,此时一旦有新的tick过来,就切换到实盘tick数据了。值得注意的是:从数据库导入数据时,end是当前时间节点,从end定义开始到完成数据导入有一小段时间,比如我测试了导出10天1分钟单标的数据耗时100ms左右。这个问题的解决办法是:每天盘前就初始化策略,这也算是CTA策略隐含要求吧。
    • trading:用来控制是否下单操作的,而不是用来控制是否进行逻辑判断的;因此即使停止策略,数据依然会经过策略层,只是不会下单而已。
  • 同一策略类对应多个策略实例下,pos等变量理解

    • 待续,后续更新