vnpy源码阅读学习(5):关于MainEngine的代码阅读
关于MainEngine的代码阅读
在入口文件中,我们看到了除了窗体界面的产生,还有关于MainEngine
和EventEngin
部分。今天来学习下MainEngine
的代码。
首先在run代码中,我们看到以下的代码
main_engine.add_gateway(DeribitGateway)
main_engine.add_app(OptionMasterApp)
从上述代码可以基本猜测所有的网管,设置,甚至策略引擎行情,都跟MainEngine有关系,MainEngine应该是一个主线,把所有的组件穿插起来了。想必MainEngine一定是一条重要的大鱼。下面我们进入MainEngin开始学习 位置:\vnpy\trader\engine.py
MainEngine的大概脉络
class MainEngine:
#初始化
def __init__(self, event_engine: EventEngine = None):
pass
#添加引擎
def add_engine(self, engine_class: Any):
pass
#添加网管
def add_gateway(self, gateway_class: Type[BaseGateway]):
pass
#添加app
def add_app(self, app_class: Type[BaseApp]):
pass
#初始化引擎
def init_engines(self):
pass
#写入日志
def write_log(self, msg: str, source: str = ""):
pass
#获得引擎
def get_engine(self, engine_name: str):
pass
#获得默认设置
def get_default_setting(self, gateway_name: str):
pass
#获得所有引擎的名字
def get_all_gateway_names(self):
pass
#获得所有的APP
def get_all_apps(self):
pass
#获得所有的交易所
def get_all_exchanges(self):
pass
#连接到行情
def connect(self, setting: dict, gateway_name: str):
pass
#合约订阅
def subscribe(self, req: SubscribeRequest, gateway_name: str):
pass
#下单
def send_order(self, req: OrderRequest, gateway_name: str):
pass
#取消订单
def cancel_order(self, req: CancelRequest, gateway_name: str):
pass
#批量下单
def send_orders(self, reqs: Sequence[OrderRequest], gateway_name: str):
pass
#批量取消订单
def cancel_orders(self, reqs: Sequence[CancelRequest], gateway_name: str):
pass
#历史查询
def query_history(self, req: HistoryRequest, gateway_name: str):
pass
#关闭
def close(self):
pass
我把所有的方法体都去掉,仅仅保留方法名称和参数,从上面的结构基本上能看出来MainEngine
几乎是一个把各个组件(GateWay, App, Engin)都连接在一起,同时提供了跟交易相关的连接、订阅、下单、撤单、历史记录等都相关的柔和在一起的大杂烩。接下来我们就一个一个方法的阅读学习。
__init__
def __init__(self, event_engine: EventEngine = None):
""""""
if event_engine:
self.event_engine = event_engine
else:
self.event_engine = EventEngine()
self.event_engine.start()
self.gateways = {}
self.engines = {}
self.apps = {}
self.exchanges = []
os.chdir(TRADER_DIR) # Change working directory
self.init_engines() # Initialize function engines
初始化的代码基本上就是实例化事件引擎(EventEngin),然后启动,同时为getways
,engines
,apps
,exchange
建立一个字典,同时调用init_engines()的方法。
各种add方法,AddEngine, AddGateWay, AddApp
def add_engine(self, engine_class: Any):
"""
Add function engine.
"""
engine = engine_class(self, self.event_engine)
self.engines[engine.engine_name] = engine
return engine
def add_gateway(self, gateway_class: Type[BaseGateway]):
"""
Add gateway.
"""
gateway = gateway_class(self.event_engine)
self.gateways[gateway.gateway_name] = gateway
# Add gateway supported exchanges into engine
for exchange in gateway.exchanges:
if exchange not in self.exchanges:
self.exchanges.append(exchange)
return gateway
def add_app(self, app_class: Type[BaseApp]):
"""
Add app.
"""
app = app_class()
self.apps[app.app_name] = app
engine = self.add_engine(app.engine_class)
return engine
上述3个Add方法比较简单,基本上都是把添加各种APP、Engine、Gateway的话,都把它们的实例化和name形成键值对放入map中去。唯一我们可以得到的线索是gateway 和Exchanges之间应该是有对应关系的话,话一句话说,gateway就是交易场所的API对接网管。所以每次添加一个gateway,就添加了一个交易所名称。
get方法
def get_gateway(self, gateway_name: str):
"""
Return gateway object by name.
"""
gateway = self.gateways.get(gateway_name, None)
if not gateway:
self.write_log(f"找不到底层接口:{gateway_name}")
return gateway
def get_engine(self, engine_name: str):
"""
Return engine object by name.
"""
engine = self.engines.get(engine_name, None)
if not engine:
self.write_log(f"找不到引擎:{engine_name}")
return engine
def get_default_setting(self, gateway_name: str):
"""
Get default setting dict of a specific gateway.
"""
gateway = self.get_gateway(gateway_name)
if gateway:
return gateway.get_default_setting()
return None
基本上是从map中根据指定的名字获得对象的方法。一目了然。get_default_setting
方法应该属于get_gateway的一个下属方法,获得gateway的setting.
get_all方法
def get_all_apps(self):
"""
Get all app objects.
"""
return list(self.apps.values())
def get_all_exchanges(self):
"""
Get all exchanges.
"""
return self.exchanges
也是对add进入的对象进行全局获取的方法。
connect
def connect(self, setting: dict, gateway_name: str):
"""
Start connection of a specific gateway.
"""
gateway = self.get_gateway(gateway_name)
if gateway:
gateway.connect(setting)
基本上可以理解connect是对gateway的一种装饰方法。通过add可以插入gateway,然后调用connect方法的话,可以通过gateway_name获得接口,然后再调用gateway的connect方法。不出意料下面的订阅行情、下单、撤单、批量撤单都是类似的作用。
gateway的其他类似方法
def subscribe(self, req: SubscribeRequest, gateway_name: str):
"""
Subscribe tick data update of a specific gateway.
"""
gateway = self.get_gateway(gateway_name)
if gateway:
gateway.subscribe(req)
def send_order(self, req: OrderRequest, gateway_name: str):
"""
Send new order request to a specific gateway.
"""
gateway = self.get_gateway(gateway_name)
if gateway:
return gateway.send_order(req)
else:
return ""
def cancel_order(self, req: CancelRequest, gateway_name: str):
"""
Send cancel order request to a specific gateway.
"""
gateway = self.get_gateway(gateway_name)
if gateway:
gateway.cancel_order(req)
def send_orders(self, reqs: Sequence[OrderRequest], gateway_name: str):
"""
"""
gateway = self.get_gateway(gateway_name)
if gateway:
return gateway.send_orders(reqs)
else:
return ["" for req in reqs]
def cancel_orders(self, reqs: Sequence[CancelRequest], gateway_name: str):
"""
"""
gateway = self.get_gateway(gateway_name)
if gateway:
gateway.cancel_orders(reqs)
def query_history(self, req: HistoryRequest, gateway_name: str):
"""
Send cancel order request to a specific gateway.
"""
gateway = self.get_gateway(gateway_name)
if gateway:
return gateway.query_history(req)
else:
return None
init_engine
def init_engines(self):
"""
Init all engines.
"""
self.add_engine(LogEngine)
self.add_engine(OmsEngine)
self.add_engine(EmailEngine)
把日志, OMSEngin, EmialEngin装配进来
close 方法
def close(self):
"""
Make sure every gateway and app is closed properly before
programme exit.
"""
# Stop event engine first to prevent new timer event.
self.event_engine.stop()
for engine in self.engines.values():
engine.close()
for gateway in self.gateways.values():
gateway.close()
基本上是程序退出以后的善后工作罢了。
总结
通过对MainEngin代码的梳理,我们看到其实MainEngine本身没有什么深奥之处。就是一个适配器的模式,把所有的操作抽象成了APP,Gateway, Engine。并且提供了一个统一的操作入口,这样可以方便实现扩展。
vnpy源码阅读学习(5):关于MainEngine的代码阅读的更多相关文章
- 【NopCommerce源码架构学习-二】单例模式实现代码分析
单例模式是是常用经典十几种设计模式中最简单的..NET中单例模式的实现也有很多种方式.下面我来介绍一下NopCommerce中单例模式实现. 我之前的文章就分析了一下nop中EngineContext ...
- vnpy源码阅读学习(1):准备工作
vnpy源码阅读学习 目标 通过阅读vnpy,学习量化交易系统的一些设计思路和理念. 通过阅读vnpy学习python项目开发的一些技巧和范式 通过vnpy的设计,可以用python复现一个小型简单的 ...
- java 并发编程——Thread 源码重新学习
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- Java小白集合源码的学习系列:LinkedList
目录 LinkedList 源码学习 LinkedList继承体系 LinkedList核心源码 Deque相关操作 总结 LinkedList 源码学习 前文传送门:Java小白集合源码的学习系列: ...
- Java小白集合源码的学习系列:Vector
目录 Vector源码学习 Vector继承体系 Vector核心源码 基本属性 构造器 扩容机制 Enumeration 概述 源码描述 具体操作 Vector总结 Vector源码学习 前文传送门 ...
- 嵌入式 十个最值得阅读学习的C开源项目代码
开源世界有许多优秀的开源项目,我选取其中十个最优秀的.最轻量级的C语言的项目,希望可以为C语言开发人员提供参考. 十个最值得阅读学习的C开源项目代码 1. Webbench 2. Tinyhttpd ...
- vnpy源码阅读学习(4):自己写一个类似vnpy的UI框架
自己写一个类似vnpy的界面框架 概述 通过之前3次对vnpy的界面代码的研究,我们去模仿做一个vn.py的大框架.巩固一下PyQt5的学习. 这部分的代码相对来说没有难度和深度,基本上就是把PyQt ...
- vnpy源码阅读学习(9)回到OptionMaster
回到OptionMaster 根据我们对APP调用的代码阅读,我们基本上知道了一个APP是如何被调用,那么我们回到OptionMaster学习下这个APP的实现. 看看结构 class OptionM ...
- vnpy源码阅读学习(3):学习vnpy的界面的实现
学习vnpy的界面的实现 通过简单的学习了PyQt5的一些代码以后,我们基本上可以理解PyQt的一些用法,下面让我们来先研究下vnpy的UI部分的代码. 首先回到上一节看到的run.py(/vnpy/ ...
随机推荐
- 线程锁Lock ,Rlock
锁的引入: 我们查看官方文档:https://docs.python.org/3/library/threading.html#lock-objects 原语锁:threading.Lock 实现原始 ...
- Sublime Text(代码编辑软件)
特点 Sublime Text 3是一个轻量.简洁.高效.跨平台的编辑器,方便的配色以及兼容vim快捷键等各种优点: 它体积小巧,无需安装,绿色便携:它可跨平台支持Windows/Mac/Linux: ...
- TP-网页静态化
首先放上一张某手册中的一段代码: 我们要想在TP框架中执行网页静态化,在这段代码的基础上稍加添加就可以了: 在TP5框架中,为了方便寻找模板文件与生成的静态文件,我们将模板文件以及生成的静态文件放在p ...
- CSS的字体样式
CSS的字体样式 1. span标签(约定俗成:重要的东西用它括起来) 首选介绍一个约定俗成的东西:span标签.一般将想要突出的东西,比较重要的东西,用span标签括起来. 比如,”学习Java“这 ...
- Netcat工具
一般Netcat有两个版本,一个版本是不提供反向连接的版本,一个是全功能版本.这两者的区别就是是否带-e参数,只有带-e参数的版本才支持反向连接. 参数说明 -c shell commands she ...
- C#设置一个控件可以鼠标拖动
C#设置一个控件可以鼠标拖动: 新建一个C#项目, 创建一个label控件, 设置label的鼠标按下和抬起事件分别为:label1_MouseDown和label1_MouseUp. 对代码进行如下 ...
- IntelliJ IDEA 2017.3尚硅谷-----版本控制(Version Control)
不管是个人开发还是团队开发,版本控制都会被使用.而 IDEA 也很好的集成了 版本控制的相关结构. Git 的 msysGit 官网下载:https://git-scm.com/ Git 客户端 To ...
- 第三十八篇 入门机器学习——Numpy.array的基本操作——查看向量或矩阵
No.1. 初始化状态 No.2. 通过ndim来查看数组维数,向量是一维数组,矩阵是二维数组 No.3. 通过shape来查看向量中元素的个数或矩阵中的行列数 No.4. 通过size来查看数组中的 ...
- sofa
来源:http://fangpeng123456789.iteye.com/blog/2172745 sofa app: biz:业务实现层(业务类型) common: ...
- python修改文件后缀名
修改文件后缀名 # -*- coding: utf-8 -*- import os # # 列出当前目录下所有的文件 # filedir = 'C:\\Users\\WT\\Desktop\\test ...