一、run.py
from vnpy.event import EventEngine
from vnpy.trader.engine import MainEngine
from vnpy.trader.ui import MainWindow, create_qapp
from vnpy.gateway.ctp import CtpGateway
from vnpy_ctastrategy import CtaStrategyApp
from vnpy_spreadtrading import SpreadTradingApp
def main():
"""Start VN Trader"""
"创建pyqt界面"
qapp = create_qapp()
"事件引擎"
event_engine = EventEngine()
"主引擎"
main_engine = MainEngine(event_engine)
"增加网关引擎, CTP"
main_engine.add_gateway(CtpGateway)
"APP模块"
main_engine.add_app(CtaStrategyApp)
main_engine.add_app(SpreadTradingApp)
"启动主窗口,并且配置事件引擎和主引擎"
main_window = MainWindow(main_engine, event_engine)
main_window.showMaximized()
qapp.exec()
if __name__ == "__main__":
main()
上面的代码整理:
创建pyqt的界面 -> 创建事件引擎 -> 创建主引擎 -> 配置各种网关引擎 -> 配置APP -> 创建主窗体 -> 启动。
二、引擎对象
vnpy最核心的部分是两个引擎对象:main_engine和event_engine,其中main_engine负责各个功能模块的组装,event_engine负责回调事件的调度。
打个比方,vnpy是一辆车子,main_engine负责对这辆车子进行组装,为他组装发动机,变速箱,底盘等一些列配置,具体说需要哪些配置,是手动波箱还是自动波箱,是主厂品牌还是副厂品牌,都由main_engine说了算。
event_engine负责设置汽车工作时各个配置的运行规则,比如一辆自动挡汽车当前档位为舒适模式,则event_engine告诉变速箱在2000转再换挡;当档位切换成运动模式,则event_engine告诉变速箱在3000转再换挡(8000转干他!)。
vnpy把各个功能模块抽象成app,需要使用哪些功能就在主引擎中进行添加即可。
回归代码,运行vnpy首先实例化一个EventEngine:
EventEngine是一个事件路由,各个功能模块app将不同类型的处理函数注册到这个引擎中,然后引擎中的任务队列接收到事件时,根据事件的类型将事件数据推送给相应注册的处理函数进行回调。
然后实例化main_engine,在main_engine中通过add_gateway方法将各种交易接口加入(具体的交易接口在vnpy/api中封装),然后通过add_app将需要的功能模块组装到主程序中(vnpy/app目录中为各个功能模块,如例子中的main_engine.add_app(DataRecorderApp)就是调用了其中的数据存储模块)
add_app函数作用是根据具体注册的app类型(继承BaseApp父类),实例化app.engine_class,
每个engine_class在构造函数中将各自的事件函数注册到main_engine的event_engine中。
最后将EventEngine和MainEngine实例化对象作为参数构造MainWindow,由MainWindow负责调用各个模块的ui组件进行可视化,实现交互。