最近在做VNPY前台界面的修改,不可避免就是要接触到Event事件和相关的引擎,学习了不少。这里简单介绍下Event事件和相关处理;然后关于如何维护自己定义的新事件类型。

在VNPY中,常见的合约价格,策略状态,发单状态,成交状态和账务等等,这些从相关交易或者市场接口传入后,打包成event,发送对应的接收方法,其中 前台界面显示数据更新,都是通过event传入。可以理解为一个VNPY数据传输机制。

从VNPY代码来看,涉及Evnet的定义是类 Event,定义Event,其实很简单,就是事件类型和数据两个属性,事件这个就是是字符串名字,比如原生的EVENT_TICK = "eTick." EVENT_TRADE = "eTrade." ; 而数据就是对应的TickData, TradeData这样的可以数据类型。

另一个是类EventEngine,这个引擎就是维护可以理解就是维护一个队列Queue, 像流水线一样有各个地方放入的事件,和把事件传给对应处理方法;。这个按照事件类型注册的对应方法,是在EventEngine中维护一个字典,存储事件类型和处理方法关联。这里要用到一些线程技巧;具体可以自己看看代码,事件类型是key值,对应的处理方法是按照list来存储,所以一个事件类型可以注册多个处理方法,放到list中;之前我说一个事件类型只能注册一个处理方法是错误的。

这里说说如何创建一个新的事件类型,和绑定注册的过程。

比如在CTA策略交易中,有原生的EVENT_CTA_STOPORDER = "eCtaStopOrder";来返回策略对应的停止单;但是在显示的成交信息中,并没有显示是那个策略的相关成交;这里为就为做一个新的事件类型EVENT_CTA_TRADE = 'eCtaTrade';绑定CTA策略成交信息。

首先维护一个事件类型名称,EVENT_CTA_TRADE = 'eCtaTrade';这个直接放在cta_strategy的base文件就是,就是一段字符串。

然后做在cta_strategy的cta_engine中创建一个事件抛出方法,抛出事件, 下面代码可以放在已有方法process_trade_event。

使用动态绑定实例,给已有trade添加一个新的属性strategy,变成; 这里使用了浅复制,避免后面处理时候影响源文件。

cta_trade = copy(trade)
cta_trade .strategy = strategy.strategy_name
event = Event(EVENT_CTA_TRADE, cta_trade)
self.event_engine.put(event)

然后尝试把交易信息事件类型在事件引擎进行注册,关联处理方法,当有这个事件时候,传入到一个叫process_cta_trade_event事件处理:

self.event_engine.register(EVENT_CTA_TRADE , self.process_cta_trade_event)
至于process_cta_trade_event, 这么处理就看你,只要抓取trade的数据,可以输出到log,数据库或者文本就随意了。