【vn.py】量化策略历史回测(基于本地csv数据)

写在前面

策略研发之后,为了检测我们策略的效果,不可能一上来就接入实盘,所以需要的就是通过历史数据对我们的策略进行检验,也就是历史回测。vn.py也有推出历史回测的教程,是通过内置的RQdata进行的,也就是说需要购买RQdata的服务,通过RQdata下载的数据会自动添加到.vntrader下面的SQlite数据库中。除此之外,vn.py还有一种回测方式,就是通过手动导入csv到SQlite数据库中,这种方式就需要你自己有提供数据服务的服务器或者本地用于回测的csv数据。因为在vn.py的源码中,默认是通过RQdata获取数据,如果没有成功,就从数据库中查询。
第一种方法由于需要购买数据服务,虽然需要花钱,但是这是最好的方式了,因为RQdata与vn.py正好契合,不仅可以提供历史回测的数据还可以在实盘阶段为策略进行初始化操作,所以有条件的还是购买这个比较合适。RQdata在vn.py的配置官方教程中已经推出,下面以本地csv进行历史回测进行演示和总结整理。

获取数据

数据获取按照上一篇文中以新浪财经API获取数据为例。在获取到数据之后,我们需要将得到的数据保存为csv格式数据,以代码中RB1910的1h线为例:

from urllib import request
import json
import pandas as pd


def get_data(id):
    url_60m = 'http://stock2.finance.sina.com.cn/futures/api/json.php/IndexService.getInnerFuturesMiniKLine60m?symbol='
    url = url_60m + id
    req = request.Request(url)
    rsp = request.urlopen(req)
    res = rsp.read()
    res_json = json.loads(res)


    bar_list = []

    res_json.reverse()
    for line in res_json:
        bar = {}
        bar['Datetime'] = line[0]
        bar['Open'] = float(line[1])
        bar['High'] = float(line[2])
        bar['Low'] = float(line[3])
        bar['Close'] = float(line[4])
        bar['Volume'] = int(line[5])
        bar_list.append(bar)

    df = pd.DataFrame(data=bar_list)
    print(df)
    df.to_csv('./data.csv', index=None)

if __name__ == '__main__':
    get_data('rb1910')

这里需要注意的是,在生成的csv的columns的名字必须按照上面的形式进行创建,因为vn.py在csv导入时是按照这些名称进行解析的。

csv数据导入

在得到csv数据之后,我们打开VN Station,选择csv载入模块。

根据我们的数据格式进行选择导入数据。由于我们的数据是rb1910的1h数据,所以代码就是rb1910,交易所是SHFE,周期是HOUR,然后将数据进行导入。

历史回测

输入成功导入之后,打开CTA回测模块,填入相关信息然后开始回测:

得到回测结果:

在这里插入图片描述
上面四个图的意义为别是:

  • 子图1:资金变化曲线,笔直向下说明稳定亏损
  • 子图2:最大回撤曲线,越来越大说明策略亏损越来越多
  • 子图3:每日盈亏统计,红绿分布平均,但绿色密度更大(亏损)
  • 子图4:盈亏的概率分布图,尖峰在0轴左侧(中位数日期发生亏损)
    除了基本的收益走势,每一笔的成交记录、每日盈亏以及K线图都可以进行查看。

回测的另一方面也是为了让我们找到合适的参数,所以对参数进行优化也是必要的。vn.py中也为我们提供了参数优化的模块:
在这里插入图片描述
通过多进程优化可以得到优化的结果:

通过参数优化,我们可以得到最优的参数组合,通过这个最优参数组合再进行回测可以得到更好的结果:

写在后面

不得不说,vn.py无论是数据的下载或者本地csv的load,还是回测的可视化效果,还有参数优化,作为一个专注于量化实盘的框架已经做的很不错了。如果习惯于其他的回测框架,如pybacktest、zipline,也可以选择它们作为回测框架+vn.py实盘框架,回测当然可以选择多个框架进行测试,这样也可以得到更高的鲁棒性。不过话说回来,vn.py在回测方面也做得这么贴心和周到,确实很不容易。

REF

vn.py官方教程

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
vn.py】CTP首次登陆修改密码 之 接口调用法 c++量化 阅读约 7 分钟 编辑 背景 最近一直在玩vn.py,上一篇文章vn.py开发环境搭建(windows)介绍了如何搭建二次开发环境,解决了一些搭建环境过程中遇到的坑。那么接下来这篇文章将解决运行期间的第一个问题。 开始vn.py 1.环境部署完成之后,启动examples/vn_trader/run.py,弹出启动页面。具体搭建过程参考vn.py开发环境搭建(windows)。 image.png 2。连接CTP,点击系统->连接CTP,弹出连接界面。 image.png 3.介绍一下个字段 用户名:在simnow注册的用户名6位数字 密码:登录simnow使用的密码 经纪商代码:9999 交易服务器地址:180.168.146.187:10101 行情服务器地址:180.168.146.187:10111 产品名称:simnow_client_test 授权码:0000000000000000 16个0 4.获取你的用户名和密码 登录http://www.simnow.com.cn/,从右上角的注册账号开始操作,这里就不讲了,大家自己鼓捣吧。 问题来了 所有准备工作做好后,点击连接,这时左下角会显示日志。 image.png 如果你是第一次登陆,那么会提示CTP首次登陆需要修改密码,这也就是我们今天要解决的问题 试图解决 刚看到这个问题觉得没什么,修改一下密码就可以了,但是。。。。。 首先没有再vn.py上找到可以修改密码的地方,后来想了想,也正常人家只是策略平台,也不仅仅是给CTP用, 所以去注册的地方simnow官网找找吧,但是。。。。 很遗憾仍然没有找到,这里不得不吐槽一下simnow了。是不是应该给个改密码的地方? 据说可以使用市场上的交易应用修改密码,大家可以去试试。或者大家有更好的方法也可以复留言。 开始撸它 好吧,那么我们用程序员的方式来解决这个问题吧。 1.在vnpy/api/ctp目录下可以看到完整ctp开发的api,包括库和头文件。哈哈,是不是会让你产生非分之想? 2.我们在ThostFtdcTraderApi.h中发现了我们想要的东西 ///用户口令更新请求 virtual int ReqUserPasswordUpdate(CThostFtdcUserPasswordUpdateField *pUserPasswordUpdate, int nRequestID) = 0; 3.找到ctp api文档在simnow官网上可以找到,我这里用的事《综合交易平台TraderAPI接口说明.pdf》 4.开始撸代码吧,我显示在linux开始撸,后来发现我的操作系统编译器版本太低,当然升级版本应该可以解决,但升级gcc,glibc还是相当耗时的。所以后来移植到了windows,但工程还是linux风格,使用cmake构建,好在现在vs对cmake支持的不错。 5.继续撸,先贴一段吧 #include "ctp_trade_handler.h" #include "INIReader.h" #include int main(int argc, char* argv[]) { string a; INIReader reader("../conf/ctp.ini"); if (reader.ParseError() != 0) { std::cout << "Can't load 'test.ini'\n"; return 1; } std::cout << reader.GetInteger("user","BrokerID",9999) << endl; ctp_trade_handle ctp; ctp.CreateFtdcTraderApi(); ctp.RegisterFront("tcp://180.168.146.187:10100"); ctp.init(); //CThostFtdcReqAuthenticateField reqAuthenticate = { 0 }; //strcpy(reqAuthenticate.AppID, "simnow_client_test"); //strcpy(reqAuthenticate.UserID, "158477"); //strcpy(reqAuthenticate.AuthCode, "0000000000000000"); //strcpy(reqAuthenticate.BrokerID, "9999"); //ctp.ReqAuthenticate(&reqAuthenticate, 1); CThostFtdcReqUserLoginField reqUserLogin = { 0 }; strcpy(reqUserLogin.BrokerID,"9999"); strcpy(reqUserLogin.UserID,"158477"); strcpy(reqUserLogin.Password,"qwe123"); ctp.ReqUserLogin(&reqUserLogin, 1); std::cout <> a; CThostFtdcUserPasswordUpdateField reqUserPasswordUpdate = { 0 }; strcpy(reqUserPasswordUpdate.BrokerID, "9999"); strcpy(reqUserPasswordUpdate.UserID, "158477"); strcpy(reqUserPasswordUpdate.OldPassword, "qwe123"); strcpy(reqUserPasswordUpdate.NewPassword, a.c_str()); ctp.ReqUserPasswordUpdate(&reqUserPasswordUpdate, 3); std::cin >> a; ctp.exit(); return 0; } 代码很简单,这里就不多说了。目前只是为了解决我修改密码的需求,后续还会不断完善。 如有需要可以自己取来撸,代码托管地址:https://github.com/FrankXMX/c... 欢迎watch和star 5.使用上就是填写好你的相关信息,编译运行,输入新密码。得到屏幕输出。 6.vn.py使用新密码重新连接ctp。 大功告成!!!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码的quant

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值