蜗牛博客VNPY学习记录:
VN.PY 2.0学习记录一(如何回测)
VN.PY 2.0学习记录二(策略开发)
Vn.py学习记录三(米筐教程)
VN.PY 2.0学习记录四(多线程、多进程)
Vn.py学习记录五–交易时间段及Widgets
Vn.py学习记录六(无界面模拟盘)
Vn.py学习记录七(V2.0.5版本)
Vnpy学习记录八(R-Breaker及pickle)
Vn.py学习记录九(事件驱动引擎)
VN.PY学习记录十(源码概述)
VNPY学习记录11(微信+Vscode)
VNPY学习记录12(父子进程、回调函数)
VNPY学习记录13(部署到云服务器,实现自动交易)
一、下载RQdata数据
1.获取账号
到米筐(RiceQuant)注册一个试用账号(注册地址:https://www.ricequant.com/purchase#1)。然后会得到一个make.bat的文件。用文本编辑打开,可以看到里面存了你的账号、密码,试用账号可以试用一个月。
Updated on Jan-10-2020
现在米筐对试用账号的注册也很严格了,需要上传名片,以及电话验证,所以大家注册成功之后一定要珍惜这一个月的使用权。
2.修改设置
打开F:\vnpy\vnpy-2.0.2\tests\backtesting这个文件夹,再打开里面的getdata.py,将上面获取到的账号、密码添加进去。
并设定好你要下载的vt_symbol、start_date、End_data这些。
3.下载数据
执行getdata.py,就可以下载数据了。

备注:
1.判断是否RQdata过期。
可以执行F:\vnpy\vnpy-2.0.2\tests\backtesting\getdata.py,如果过期,会报错:
getdata
rqdatac.share.errors.AuthenticationFailed: user auth failed! code: 202 message:
该 License 已过期
2.如何在VN.PY中使用?
直接修改“C:\ProgramData\VNConda\Lib\site-packages\vnpy\trader\setting.py”中的账号、密码即可。
3.2019.Jul.05 重新申请了一个号码,看看什么时候过期。
Updated on 14-Sep-2019:
今天发现license过期了,重新申请,发现发生了许多变化:
1.注册时除了提供手机号码,还需要提供邮箱。
2.邮箱中会收到.bat文件以及密码,需要执行.bat文件,然后就可以使用这里的rq.get_price('平安银行','2018-3-23','2018-4-23')代码了。
3.执行上面的F:\vnpy\vnpy-2.0.2\tests\backtesting\getdata.py文件也不会报错了。
Updated on 14-Oct-2019
再次申请了一个,已经使用了邮箱:
myso、2207、
而且发现不用再执行那个bat了,直接在vnpy中输入密码就可以直接使用了。
Oct-16-2019
执行getdata.py报错,说 License 已过期,那么它的有效期刚好是30天。
二、截取最近三根K线的值
from vnpy.app.cta_strategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
class MaDbwStrategy(CtaTemplate):
author = "蜗牛博客snailtoday.com"
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
""""""
super(MaDbwStrategy, self).__init__(
cta_engine, strategy_name, vt_symbol, setting
)
self.bg = BarGenerator(self.on_bar, 5, self.on_5min_bar)
self.am = ArrayManager()
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
self.load_bar(10)
def on_start(self):
"""
Callback when strategy is started.
"""
self.write_log("策略启动")
self.put_event()
def on_stop(self):
"""
Callback when strategy is stopped.
"""
self.write_log("策略停止")
self.put_event()
def on_tick(self, tick: TickData):
"""
Callback of new tick data update.
"""
self.bg.update_tick(tick)
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.bg.update_bar(bar)
def on_5min_bar(self, bar: BarData):
""""""
self.cancel_all()
am = self.am
am.update_bar(bar)
if not am.inited:
return
print('上一根K线的开盘价是{}:'.format(am.open_array[-1]))
print('上一根K线的最高价是{}:'.format(am.high_array[-1]))
print('上一根K线的最低价是{}:'.format(am.low_array[-1]))
print('上一根K线的收盘价是{}:'.format(am.close_array[-1]))
print('上二根K线的开盘价是{}:'.format(am.open_array[-2]))
print('上三根K线的开盘价是{}:'.format(am.open_array[-3]))
self.put_event()
def on_order(self, order: OrderData):
"""
Callback of new order data update.
"""
pass
def on_trade(self, trade: TradeData):
"""
Callback of new trade data update.
"""
self.put_event()
def on_stop_order(self, stop_order: StopOrder):
"""
Callback of stop order update.
"""
pass
然后用以下的代码进行验证:
from vnpy.app.cta_strategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
class TestBarStrategy(CtaTemplate):
author = "蜗牛博客snailtoday.com"
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
""""""
super(TestBarStrategy, self).__init__(
cta_engine, strategy_name, vt_symbol, setting
)
self.bg = BarGenerator(self.on_bar)
self.am = ArrayManager()
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
self.load_bar(10)
def on_start(self):
"""
Callback when strategy is started.
"""
self.write_log("策略启动")
self.put_event()
def on_stop(self):
"""
Callback when strategy is stopped.
"""
self.write_log("策略停止")
self.put_event()
def on_tick(self, tick: TickData):
"""
Callback of new tick data update.
"""
self.bg.update_tick(tick)
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
am = self.am
am.update_bar(bar)
if not am.inited:
return
print('上一根K线的最高价是{}:'.format(am.high_array[-1]))
self.put_event()
def on_order(self, order: OrderData):
"""
Callback of new order data update.
"""
pass
def on_trade(self, trade: TradeData):
"""
Callback of new trade data update.
"""
self.put_event()
def on_stop_order(self, stop_order: StopOrder):
"""
Callback of stop order update.
"""
pass
验证结果:
虽然我设定的日期是:
start = datetime(2018,3,29), end = datetime(2018,5,28),
从结果来看,5月28日的数据并没有加载,只加载到了5月28日的前一天5月25日的数据。

验证前三根K线
print('上一根K线的最高价是{}:'.format(am.high_array[-1]))
print('上二根K线的最高价是{}:'.format(am.high_array[-2]))
print('上三根K线的最高价是{}:'.format(am.high_array[-3]))
结果和上面的一致

四、合约代码
直接在vn.py里面查询即可。比如:rb1906.SHFE

五、事件引擎



例二:
利用内置的函数,注册事件:


github.com/msincenselee/vnpy
六、主引擎
main engine实例化所有引擎,比如策略引擎、事件引擎等。

七、OnOrder OnTrade的区别:
Onorder: 发了单,交易所收到你的单,你的单没有成交他也会发一个onorder指令给你。如果你发10手,第一次成交5手,第二次成交3手,第三次成交2手,你会收到3个onorder
OnTrade: 成交结束,你有交易的时候就会拿到。
在单一合约里面,OnOrder OnTrade是同一个。
撤单是没有onTrade的,如果你发了10次开单的请求,最后都没有成交,最后撤单了(自己或者交易所),Onorder都会发送给你,onTrade是收不到的。所以最好在onorder中写处理。
还有一个区别是套利中,买卖跨期合约,将spM1705&M1709作为一个合约发送到上层,买一手spm1705,空一手M1709,onorder会收到一条信息“spM1705&M1709”。
ontrade收到两条信息:M1705多成交了一条,M1709空成交了一条。
八、时间
bar.datetime
这个米匡注册以后, mark.bat 在哪搞到呢,弄了好几天了,都没搞明白
好久没有用米匡了,以前是发到你的邮箱的。
博主有在策略内部加载eventengine,进行回测的经验吗?