vnpy中的EventEngine和MainEngine用法介绍


01

前言

我准备写一篇vnpy的入门文章,考虑到入门文章如果讲太多内部细节,就会显得特别累赘,所以将细节和用法单独分离出来,写在这里。本文主要介绍了vnpy中的EventEngine和MainEngine的用法。

  • vnpy是基于消息驱动的,需要一个消息引擎,EventEngine便是这个消息引擎。
  • 而MainEngine,顾名思义,实例化之后其实就是代表vnpy的实例。几乎所有交易相关的操作都可以通过MainEngine完成。

2

MainEngine

MainEngine,顾名思义,vnpy的核心。每一个vnpy脚本都需要一个MainEngine的实例。实例化之后可以使用addGateway来增加某种接口(例如ctp接口)。之后可以调用connect连接到服务器。 vnpy连接时会根据提供的gatewayName参数,自动从相应的connect.json文件读取连接配置(IP,端口,用户名,密码等等)来连接(详情请看连接配置文件)。

vnpy的绝大部分操作都可以通过MainEngine完成,例如:

  • MainEngine.sendOrder : 下单
  • MainEngine.cancelOrder : 取消委托单
  • MainEngine.subscribe : 订阅行情

还有一些查询操作

  • MainEngine.getTick : 查询行情
  • MainEngine.getContract : 查询某个合约
  • MainEngine.getOrder : 查询委托
  • MainEngine.getPositionDetail : 查询持仓细节
  • MainEngine.getAllWorkingOrders : 查询所有的活跃的委托(一般就是未成交的委托)
  • MainEngine.getAllOrders : 查询所有委托
  • MainEngine.getAllTrades : 查询所有成交
  • MainEngine.getAllAccounts : 查询所有账户
  • MainEngine.getAllPositions : 查询所有持仓
  • MainEngine.getAllPositionDetails : 查询所有持仓细节

还有gateway相关的操作:

  • MainEngine.addGateway : 增加某个接口
  • MainEngine.getGateway : 获取某个接口的代理

用例:

from vnpy.trader.vtEngine import *

from vnpy.trader.gateway import ctpGateway

event_engine = EventEngine() # 实例化

EventEnginemain_engine = MainEngine(event_engine) # 实例化

MainENginemain_engine.addGateway(ctpGateway.gatewayName) # 增加ctp接口

main_engine.connect(ctpGateway.gatewayName) # 连接ctp服务器

MainEngine.addGateway(gatewayName)

增加某个接口

from vnpy.trader.gateway import ctpGateway

main_engine.addGateway(ctpGateway.gatewayName)

MainEngine.connect(gatewayName)

连接到某个接口的服务器

from vnpy.trader.gateway import ctpGateway

main_engine.addGateway(ctpGateway.gatewayName)

main_engine.connect(ctpGateway.gatewayName)

连接时会自动读取XXX_connect.json以获取连接参数。详情请看连接配置文件

MainEngine.subscribe(req: VtSubscribeReq, gatewayName)

跟服务器订阅行情

from vnpy.trader.vtEngine import VtSubscribeReqreq = VtSubscribeReq()

req.symbol = 'cu1807'

main_engine.subscribe(req, ctpGateway.gatewayName)

VtSubscribeReq详情请看vnpy/trader/vtObject.py

MainEngine.sendOrder(order: VtOrderReq, gatewayName)

下单

from vnpy.trader.vtEngine import *

order = VtOrderReq()

order.symbol = 'cu1807' # 合约代码

# order.exchange = constant.EMPTY_STRING # 交易所, ctp中不需要

# order.vtSymbol = symbol

# VT合约代码, ctp中不需要

order.price = 0 # 价格

order.volume = 1 # 数量

order.direction = constant.DIRECTION_LONG # 买/卖(多头、空头)

order.priceType = constant.PRICETYPE_MARKETPRICE # 价格类型

order.offset = constant.OFFSET_OPEN # 开平

# order.currency = currency

# 货币类型, ctp中不需要

# order.productClass = productClass

# 合约类型, ctp中不需要

order_id = main_engine.sendOrder(order, ctpGateway.gatewayName)

# 监听该订单

def on_order(event): # type: Event

data = event.dict_['data'] # type: VtOrderData print("order : {} status: {}".format(data.vtOrderID, data.status)) pass event_engine.register(EVENT_ORDER + order_id, on_order)

VtOrderReq详情请看vnpy/trader/vtObject.py

MainEngine.cancelOrder(order: VtOrderData, gatewayName)

取消某个订单。

若要取消某个sendOrder发出去的订单,请使用EventEngine的特定消息监听,以获取对应的VtOrderData。

def cancel_all_working_orders(): for order in main_engine.getAllWorkingOrders(): # type: VtOrderData main_engine.cancelOrder(order, order.gatewayName)

VtOrderData详情请看vnpy/trader/vtObject.py

MainEngine.getTick(vtSymbol)->VtTickData

获取行情。 在获取行情之前,必须从服务器订阅行情。使用MainEngine.subscribe从服务器订阅行情。

from vnpy.trader.vtEngine import VtTickData

tick = main_engine.getTick('cu1807') # type: VtTickData

if(tick): last_price = tick.lastPrice

MainEngine.getAllPositions()-> List[VtPositionData]

获取所有合约的仓位

VtPositionData详情请看vnpy/trader/vtObject.py

3

EventEngine

vnpy是基于事件驱动的,所以需要一个消息处理引擎。EventEngine类便是用于消息处理的。 每个vnpy脚本都需要一个EventEngine。直接构造即可。如果需要监听某个消息,使用EventEngine.register即可。因为MainEngine也会用到EventEngine,所以大部分消息只需要监听就可以收到消息。但是行情消息(EVENT_TICK)必须在服务器订阅之后才会收到消息,使用MainEngine.subscribe来跟服务器订阅行情。

一般情况下都不需要自己手动调用EventEngine的其他函数。因为EventEngine会被MainEngine启动。

注册消息时可以注册很多特定消息,一般用法是监听消息类型+ID的消息(详情请看用例或者vnpy/trader/vtGateway.py)。

用例:

from vnpy.trader.vtEngine import *

# 1HZ计时器

def on_timer(event): # type: Event

pass

# 行情消息

def on_tick(event): # type: Event tick = event.dict_['data'] # type: VtTickData symbol = tick.symbol price = tick.lastPrice pass

# 仓位变化消息

def on_position(event): # type: Event

data = event.dict_['data'] # type: VtPositionData symbol = data.symbol pos = data.position pass

# 特定合约的行情

def on_cu1807_tick(event): # type: Event tick = event.dict_['data'] # type: VtTickData current_cu1807_price = tick.lastPrice pass

# 特定合约的仓位

def on_cu1807_position(event): # type: data = event.dict_['data'] # type: VtPositionData pos = data.position pass

event_engine = EventEngine() # 实例化

EventEngineevent_engine.register(EVENT_TIMER, on_timer) # 监听1Hz的计时器

event_engine.register(EVENT_TICK, on_tick) # 监听行情消息(需要从服务器订阅)

# 特定消息

event_engine.register(EVENT_TICK + 'cu1807', on_cu1807_tick) # 监听cu1807的行情(需要从服务器订阅)

event_engine.register(EVENT_POSITION + 'cu1807', on_cu1807_position) # 监听cu1807的仓位变化

VtTickData详情请看vnpy/trader/vtObject.py。 vnpy.EventEngine的完全运行还依赖Qt环境,详情请看下文EventEngine和EventEngine2的区别。

EventEngine.register(type:str, handler:Callable[Event])

监听某个消息,当消息发生时,调用handler。

  • type是一个消息类型
  • handler是一个函数,会收到一个类型为Event的参数。

type的基本的一些值可以看vnpy/trader/vtEvent.py

EventEngine.start(timer:bool)

启动消息引擎,若timer为真,则顺便启动一个频率为1s的计时器 MainEngine使用的消息引擎不需要调用此方法。

EventEngine.stop()

停止消息引擎

EventEngine.put(event:Event)

在消息队列中增加一条消息。

  • event应该为一个Event类。 用例:

from vnpy.trader.vtEngine import Event

EVENT_CUSTOM_1 = 'cusotm_event_1'

event = Event(EVENT_CUSTOM_1)

event.dict_['val1'] = 'value one'

event_engine.put(event)

EventEngine和EventEngine2的区别

vnpy有两个消息处理引擎,分别是EventEngine和EventEngine2,分别用于Qt环境和非Qt环境。 EventEngine内部用到了QTimer,所以正常运行需要Qt环境。 EventEngine2除了不依赖Qt之外,和EventEngine完全一样。

要完全运行EventEngine,需要构建Qt运行环境:

from vnpy.event import EventEngine

from vnpy.trader.uiQt import createQApp

def main(): app = createQApp()

event_engine = EventEngine() app.exec_() # 至此,Qt环境才算完全初始化完成

连接配置文件

vnpy连接到服务器时时会自动读取XXX_connect.json以获取连接参数。其中XXX是接口名称,例如ctp接口对应的就是CTP_connect.json。examples/VnTrader/目录下有各种connect.json的样本。推荐将该json文件放于当前工作目录下。

基于python的开源交易平台开发框架。截止目前,vn.py项目在Github上的Star已经达到5787,量化交易类开源项目第1,量化类项目第3(1、2依旧分别是Zipline和TuShare)。

项目官网:http://www.vnpy.org

论坛地址:www.vnpie.com

知乎专栏:https://zhuanlan.zhihu.com/vn-py

Developed by Traders,

for Traders

优质内容筛选与推荐>>
1、iOS中的数据的存储方式
2、Thread.Sleep(1000)
3、启动HDFS
4、Django 进阶 之 Restful框架
5、软件工程概论第十二周学习进度


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号