上图的是RPC业务的标准流程。
对于安装了VNStudio的用户,启动VN Station后,直接点击右下角的更新按钮就能完成自动更新。
对于没有安装的用户,请下载VNStudio-2.0.5,体验一键安装的量化交易Python发行版。
脚本策略
对于一些本身学习和工作背景是IT技术方向的用户来说,初学vn.py的时候可能比较难以理解CTA策略开发中的事件驱动概念。如果你在基于异步回调的思维逻辑来开发交易策略中感到非常的痛苦(那种想来想去就是不懂数据哪里来的痛苦),不妨试试ScriptTrader策略模块。
首先,你可以在这样的Jupyter Notebook中以REPL交互式开发的模式来进行各种行情订阅、数据查询、委托交易的功能:
完全同步的程序写法,所见即所得模式:
- 想要连接交易接口?写好配置dict,调用engine.connect_gateway开始连接,所有初始化日志都会显示在单元格下方输出区域
- 想要获取最新行情?调用engine.subscribe订阅行情更新,后续随时通过engine.get_tick获取的Tick数据,都保证是最新推送的结果,本地瞬间返回(和其他数据工具每次查询服务器,然后等待服务端数据返回的阻塞模式完全不同)
- 想要交易?buy/sell/short/cover,传入vt_symbol、price、volume,直接执行委托(实盘账户请想清楚了再回车,不要乱点......)
- 想要获取K线数据?配置好RQData账号后,调用get_bars即可任意获取想要的股票/期货的K线时间序列数据(RQData试用期延长到1个月了!申请链接戳这里)
- 想要查询所有可交易合约?调用engine.get_all_contracts函数,可选参数use_df为True时将会以pandas.DataFrame数据结构返回,在Jupyter中更加便于分析
- 想要查询账户的状态?engine.get_all_accounts/get_all_positions/get_all_active_orders任意查询资金、委托、持仓情况
- 想要记录当前的运行信息?engine.write_log打印日志,engine.send_email发送邮件到指定邮箱(结合QQ邮箱就能实现微信实时通知)
OK~ 经过一段时间研究后,你已经精通了如何通过engine进行交易,尽管Jupyter用来做学习研究非常方便,但直接拿来跑实盘好像就有点安全隐患了(想象下你的篮子委托函数单元格不小心Shift-Enter......),那么你可以选择使用脚本策略执行引擎,在一个完全独立的线程中运行你的脚本:
脚本主函数的持续运行,可以通过while engine.strategy_active循环来实现时间驱动的策略同步运行模式。
后续随着你的策略升级,需要更低的响应延时,可以考虑替换使用更加进阶的CtaStrategy或者SpreadTrading等模块来实现低延时实时交易。
RPC服务
RPC,全称Remote Procedure Call(远程过程调用),主要用于实现跨进程或者跨网络的服务功能调用,具体其中的各项概念细节网上可以找到非常丰富的资料,这里就不展开了。
尽管传闻Python 3.8(或者3.9)计划将全局锁GIL由进程唯一改为解释器唯一,从而实现单Python进程能够真正利用多核CPU的全部性能,但截止目前2019年7月,Python 3.7依旧最多只能利用到CPU的单核性能。
对于量化交易这种CPU密集型的计算应用程序,如何绕过GIL限制充分利用CPU的多核性能,一直是各类社区里讨论最火热的话题。
回顾下Python中并行的三种方案(按照从轻到重):
- 协程,本质是用户态的逻辑流切换,对于IO密集型任务有用,但同样无法绕开GIL
- 多线程,由于GIL的存在,任意时间点永远只能有一个线程在运行,无法利用CPU多核
- 多进程,每个进程内有自己的GIL,得以完全利用CPU多核,但进程间的数据无法直接共享
所以现阶段唯一能用的就是多进程,核心痛点则在于如何实现跨进程通讯(RPC),以及安排每个进程中运行的程序功能。
作为互联网分布式架构的底层基础框架之一,RPC有着大量成熟的开源工具:gRPC、JSON-RPC、Thrift等等,这些工具的应用场景各有区别。对于量化交易程序中的一条腿,由客户端发起的主动函数调用,都能很方便的实现支持。但对于另一条腿,由服务端发起的被动事件推送,要么是无法实现,要么就得用双向RPC、Stream流返回等等非常复杂的办法。
针对量化交易这种需要两条腿的情况,我们也是纠结许久,最后选择基于pyzmq定制开发了一套轻量级的RPC框架(一共235行代码,真.轻量!)。
除了支持Client端调用Server端注册好的函数功能外,Server端也能广播(publish)推送事件数据到客户端。在Windows上通过常规的TCP Socket来实现通讯,在Linux上则进一步支持性能更高的Local Socket(数据不过网卡,大约是TCP性能10倍+)。
按照vn.py的设计理念,有了功能框架,自然就必须有解决实际交易需求的应用。v2.0.5版本中提供了一套包含客户端和服务端的RPC应用,包括:
- RpcServiceApp:将VN Trader进程转化为RPC服务器,对外提供交易路由、行情数据推送、持仓资金查询等功能
- RpcGateway:将RPC服务器视作类似于CTP的服务端系统,通过标准Gateway来连接并进行交易,对上层应用完全透明
具体的使用方法可以参考examples/client_server。
Server中默认加载了CtpGateway和RpcServiceApp,运行后会自动连接,如下图所示:
Client中则默认加载了RpcGateway和CtaStrategyApp,启动连接RPC接口后,使用体验和直接加载CTP接口完全一致,且上层的CTA策略模块也可以完全无缝兼容使用:
所以参考以上样例,可以非常方便的实现:
- 运行策略数量较多的用户,只需本地一条行情和交易通道,支持多个Client进程同时交易,且每个Client中独立运行交易策略互不影响;
- 中小型投资机构用户,可以在通过在服务端加载各种交易接口以及RiskManagerApp,实现一个轻量级的资管交易系统,多个交易员共享统一的交易通道,并在实现基金产品级别的风险管理。
交易接口
遵循传统,每个版本的vn.py更新都会接入更多的交易通道,v2.0.5新增:
- 华鑫奇点柜台接口,针对A股证券的量化交易通道ToraGateway
- Alpaca美股证券接口,对接IEX交易所(Flash Boys主人工创立的那个)的0佣金交易通道AlpacaGateway