vn.py量化社区
By Traders, For Traders.

置顶主题

实盘账户资金分析画图

以CTP接口为例
1.object.py修改如下:

class AccountData(BaseData):
    """
    Account data contains information about balance, frozen and
    available.
    """

    accountid: str = ""                 #账户ID

    balance: float = 0                  #总资金
    available: float = 0                #可用资金
    percent: float = 0                  #资金使用率
    frozen: float = 0                   #冻结资金
    pre_balance: float = 0          #上个交易日总资金(币圈交易所为人民币计价总资金)
    commission: float = 0           #手续费
    margin: float = 0                   #占用保证金
    close_profit: float = 0             #平仓利润
    position_profit: float = 0          #持仓利润
    date:str = ""                           #日期
    time:str = ""                           #时间
    #--------------------------------------------------------------------------------------------------
    def __post_init__(self):
        """"""
        self.vt_accountid = f"{self.gateway_name}_{self.accountid}"
        #账户当前日期
        if self.date and '.' in self.time:
            if '-' in self.date:
                self.datetime = datetime.strptime(' '.join([self.date,self.time]),'%Y-%m-%d %H:%M:%S.%f')
            else:
                self.datetime = datetime.strptime(' '.join([self.date,self.time]),'%Y%m%d %H:%M:%S.%f')
        else:
            if self.date:
                if '-' in self.date:
                    self.datetime = datetime.strptime(' '.join([self.date,self.time]),'%Y-%m-%d %H:%M:%S')
                else:
                    self.datetime = datetime.strptime(' '.join([self.date,self.time]),'%Y%m%d %H:%M:%S')

2.ctp_gateway.py修改如下

class CtpTdApi(TdApi):
    """"""

    def __init__(self, gateway):
        """Constructor"""
        super(CtpTdApi, self).__init__()
        self.account_date = None    #账户日期
    #-------------------------------------------------------------------------------------------------
    def onRspQryTradingAccount(self, data: dict, error: dict, reqid: int,
                               last: bool):
        """"""
        account = AccountData(
            accountid=data["AccountID"],
            balance=round(data["Balance"],3),
            available = round(data["Available"],3),                   #可用资金
            pre_balance = round(data['PreBalance'],3),                #上个交易日总资金
            commission = round(data['Commission'],3),                #手续费
            margin = round(data['CurrMargin'] ,3),                    #账户保证金
            close_profit = round(data['CloseProfit'],3),              #平仓盈亏
            position_profit = round(data['PositionProfit'],3),        #持仓盈亏
            frozen=data["FrozenMargin"] + data["FrozenCash"] + data["FrozenCommission"],        #冻结资金
            date = str(datetime.now().date()),
            time = str(datetime.now().time()),
            gateway_name=self.gateway_name)
        account.percent = round(account.margin / account.balance,3) * 100      #资金使用率
        self.gateway.on_account(account)
        recording = True
        #周六周日不写入数据
        if datetime.today().weekday() == 5 or datetime.today().weekday() == 6:
            recording = False
        if recording:
            #通过CTP接口查询账户资金
            account_info = account.__dict__
            ctp_account_path = "C:\\ProgramData\\Anaconda3\\Lib\\site-packages\\vnpy-2.1.0-py3.7.egg\\vnpy\\app\\cta_strategy\\account_info\\ctp_account"+".csv"
            if not os.path.exists(ctp_account_path): # 如果文件不存在,需要写header
                with open(ctp_account_path, 'w',newline="") as f1:#newline=""不自动换行
                    w1 = csv.DictWriter(f1, account_info.keys())
                    w1.writeheader()
                    w1.writerow(account_info)
            else: # 文件存在,不需要写header
                if self.account_date and self.account_date != account.datetime.date():        #一天写入一次账户信息
                    with open(ctp_account_path,'a',newline="") as f1:  #a二进制追加形式写入
                        w1 = csv.DictWriter(f1, account_info.keys())
                        w1.writerow(account_info)
                self.account_date = account.datetime.date()


阿里云ubuntu18.04安装运行vnpy教程

感谢社区老大的指导,感谢下面两篇文章的作者。终于在阿里云ubuntu18.04成功安装运行了vnpy2.1.0。
文章一:ubuntu 18.04 安装 vnpy2.0.9 总结
文章二:一步步学会搭建阿里云Ubuntu

注意点:安装成功,能够运行,只限于客户端为widnows系统,且用mobaxterm软件,链接阿里云的ubuntu18.0.4的环境。
另,mobaxterm的安装使用请参照上面的文章二(论坛中查找)。其他的ssh链接工具,启动vnpy不会成功,会出错。

一,安装2.1.0的流程
1.执行刷新
sudo apt-get update
2.下载并安装最新版Anaconda3.7 64位
bash Miniconda3-latest-Linux-x86_64.sh
安装后重启服务器
3.安装下面的库
sudo apt-get install build-essential
sudo apt-get install libpq-dev
sudo apt-get dist-upgrade
sudo apt install ubuntu-desktop mesa-utils
4.安装vnpy
sudo PATH=/root/miniconda3/bin:$PATH bash install.sh

二:运行run.sh
1.examples/vn_trader目录下,修改run.py注释掉四行
from vnpy.gateway.femas import FemasGateway
from vnpy.app.option_master import OptionMasterApp
main_engine.add_gateway(FemasGateway)
main_engine.add_app(OptionMasterApp)
2.运行run.sh
python run.py



防骗公告:vn.py项目的官网,请认准www.vnpy.com

说实话,写这么个公告我的感觉挺奇怪的。

看到过很多其他知名的公司,被别有用心的人冒名顶替,去做一些诈骗忽悠的事情,没想到有一天会发生在vn.py身上。

遇到对vn.py搞碰瓷、蹭流量,没想到现在手段更升级了, 某些现在居然(不提名字)打着vn.py即将倒闭、被他收购的说法,去忽悠金融机构(券商)来和他合作, 还扬言要拿下vnpy.cn域名。

所以在这里专门发布一个公告,vn.py项目的官方社区的网址是

www.vnpy.com

老的论坛“维恩的派”已经停止更新(将会在2019年中关闭),请认准了,谨防李鬼!

尤其需要提防的一些:vnpy.cn、vnpy.com.cn等等非常类似的域名。



看完这篇,彻底搞定期货穿透式CTP API接入

操作流程

不多废话先上结论(操作流程图):

description

下面是步骤说明,只要照着做100%可以搞定!!!

 

第一步:申请穿透式接入

电话联系你的客户经理,向期货公司申请进行穿透式接入测试。如果期货公司服务质量较好,可能已经主动联系你邀请测试了。

 

第二步:填表提交AppID

填写申请表,每家期货公司有所区别,但整体上需要提供的信息可能包括:

  • CPU序列号
  • 硬盘序列号
  • 硬盘主分区盘符和大小
  • 网卡MAC地址
  • 内网IP和外网IP
  • 交易程序的AppID

以上多条信息的获取,就需要用到cmd中的系统命令工具了。

输入以下命令获取CPU序列号:

wmic cpu get processorid

逐条输入以下命令,获取硬盘序列号、主分区盘符和大小:

diskpart
select disk 0
detail disk

输入以下命令,“以太网适配器”下的“物理地址”就是MAC地址,“IPv4地址”就是内网IP:

ipconfig /all

访问www.ip138.com获取你的外网IP,或者直接百度搜索“IP”也行。

最后的AppID,是一个由用户提供的交易程序代码,以个人身份申请时,格式为:

client_xxxx_yyyy

其中xxxx是你的软件名称,yyyy是版本号,这两个字段都是客户自己填的信息(没有固定规则),以vn.py的v2.0版本为例,AppID可能为:

client_vnpy888_2.0

其中888的部分,是自定义的一个字符串,主要为了避免你的AppID和其他人重复,你可以选择随意选择:姓名拼音缩写、某个数字、幸运词......

 

第三步:拿到AuthCode

提交申请表后,一般当天或者第二天就能拿到期货公司针对你的这个AppID提供的测试账号信息,包括:

  • 用户名、密码
  • 经纪商代码、仿真测试服务器地址(交易、行情)
  • 产品名称(你填的AppID)、授权编码(AuthCode)

 

第四步:仿真测试

我们这里测试环节以最新版的VN Studio为例,如果没有的话请点击下载:VNStudio-2.0.3。同样你也可以选择使用任何其他的软件程序来操作,如果不幸掉坑后爬不出来的话再回到VN Station好了。

双击桌面的VN Station图标,启动后会弹出登录框。如果是第一次使用,请点击“微信登录”按钮,扫描二维码后注册VN Station账号(同样也是vn.py官方社区论坛www.vnpy.com的登录账号),如果已经有账号了可以直接输入后点击“登录”。

description

登录完成后会看到VN Station主界面,此时请点击底部的“VN Trader Pro”,并在弹出的目录选择对话框中直接点“选择文件夹”按钮(即在默认的Windows用户目录下启动VN Station):

description

随后会弹出配置VN Treader的对话框,注意此时请一定只勾选加载CTPTEST接口,千万不要同时勾选加载CTP接口,会因为dll冲突导致后续测试失败!!!!

description

在VN Trader主界面上,点击左上角的“系统”->“连接CTPTEST”,在弹出的登录配置对话框中输入期货公司提供的测试账号信息(产品名称就是AppID),点击连接按钮后登录CTP穿透式测试用服务器:

description

当VN Trader左下角的日志监控组件中,刷新出熟悉的日志信息,看到“合约信息获取成功”的时候,就意味着我们已经完成测试了!

 

第五步:期货公司校验

搞定上面的测试服务器连接登录后,就可以联系期货公司进行校验工作了,通常可以一次性直接通过,如果遇到不通过的情况请查看本文最后的常见问题来解决。

 

第六步:实盘接入

期货公司校验通过后,会将客户申请的AppID和AuthCode添加到实盘CTP的服务器上,此时只要把启动VN Trader Pro时,加载的接口由CTPTEST改为CTP,就可以连接上实盘交易环境,和以往一样进行量化交易了。

description

 
 

名词解释

穿透式监管

新的监管模式主要是明确了期货公司对于其客户交易行为的管理责任,因此需要对所有接入交易柜台系统的交易终端软件进行认证管理,防止坏人耍流氓后一走了之,难以追查。

穿透式API

穿透式监管的主要实现工具,支持对交易终端机器的信息采集功能(即采集之前提到的CPU序列号、MAC地址等信息),并在加密后直接上传期货市场监控中心。除了本文中用到的CTP穿透式API外,其他的柜台也都提供了对应的穿透式API版本:恒生、易盛、飞创等,操作方法基本类似。

执行日期

在6月14日当天,所有期货公司的柜台系统全部强制升级为穿透式监管版本,老的非穿透式柜台会全部下线,没有所谓的“过渡期”,现在就已经是“过渡期”了!!!还有不到两周的时间,所有通过API接入交易的用户请赶紧吧,不要到了那天没法交易才着急,而且普遍的拖拉习惯,目前在申请接入测试的客户与日俱增,也对期货公司每天繁忙的后台IT部门表示感谢。

6.3.13

CTP穿透式柜台的仿真测试版本,也是CTPTEST接口中使用的API版本,所有客户的仿真接入认证测试都必须使用该版本!主要因为该版API采集客户的信息是没有加密的,期货公司可以在后台查看来进行认证工作。

6.3.15

CTP穿透式柜台的实盘交易版本,也是CTP接口中使用的API版本,完成仿真接入测试后,必须使用该版本才能连接实盘交易的CTP柜台。该版本的采集信息是安全加密的,期货公司的IT用后台系统也看不到。

直连模式

指的是所有用交易程序直接使用CTP的API连接CTP柜台,进行行情获取和委托交易的情况,几乎所有自主开发或者使用开源框架的量化交易客户都属于这种情况,直接使用穿透式监管版本的API进行开发就行(带_se后缀的)。

中继模式

指的是:交易客户端->中继服务器->CTP柜台,采用这种连接模式主要包括商业量化交易软件(比如文华财经)以及机构量化资管系统(比如O32),只有中继模式才需要用到那个DataCollect.dll文件。

 
 

API内部工作流程

同样以CTP为例:

  1. 调用Init,开始连接
  2. 收到OnFrontConnected,确认连接成功
  3. 调用ReqAuthenticate,这一步填入AppID和AuthCode,进行认证
  4. 收到OnRspAuthenticate,确认认证成功
  5. 调用ReqUserLogin,这一步同样需要填入AppID,进行登录
  6. 收到OnRspUserLogin,确认登录成功

只有交易接口TD需要进行认证,MD直接登录就行。每一步出错的话都会有相应的报错输出提示,查看错误信息内容后照着修改就行。

 
 

常见问题

哪个版本的vn.py目前支持穿透式API?

最新的v2.0.3发布版本(Py3 64位),和v1.9.2-LTS版本(Py2 32位),都支持了穿透式API,推荐使用Windows进行相关测试工作(Linux上需要自己调整链接库做编译)。

更新后SimNow环境连不上了!

截止目前的2019年6月1日,SimNow上的交易测试环境(包括第一套和第二套)依旧为非穿透式的老版本,因此用穿透式版本的API都是连不上的。

SimNow的终端厂商测试环境连上后没有行情!

SimNow所提供的6.3.13测试环境,目前仅仅为了满足用户的穿透式版本测试需求(也就是能成功登录上来查询一下合约信息等),尚未提供第一套或者第二套环境中的仿真行情以及仿真交易功能,所以:就是没有行情的~

报错4097,cmd有输出Decrypt handshake data failed

这是因为你的API版本和服务器的版本不一致导致的,请按照以下流程排查:

  1. 是否同时import了CTP(CtpGateway)和CTPTEST(CtptestGateway)接口,如有请移除另一个(两个同时加载会冲突)
  2. 确保使用CtptestGateway来连接6.3.13穿透式测试环境,用CtpGateway来连接6.3.15穿透式实盘环境
  3. v2.0.3以及v1.9.2-LTS(最新Github代码)都已升级到穿透式API,因此无法用于连接SimNow的老版本环境

UserProductInfo字段是用来干嘛的?

该字段是之前非穿透式API时,用来进行客户认证的产品名称字段(配合AuthCode一起)。穿透式版本接入的方案文档并没有对该字段的强制要求,目前我们这边已经对接了的5家期货公司也均未要求使用,但听说某些公司需要:如中信建投等,如果有了解其他公司情况的请在评论中分享。

能否使用云服务器或者虚拟机进行测试认证?

虚拟机和云服务器,对于本文开头部分提到的CPU序列号、硬盘序列号等信息,有可能获取不全或者部分字段不符合规定。目前有些期货公司要求严格,必须全部能正确获取到,且和第二部申请表中填写的内容一致,才能算认证测试成功;另一些公司则是十分宽松,表也不用填,采集信息也不看,只要登录上来就算测试通过。

所以,能否使用云服务器和虚拟机,完全取决于你开户的这家期货公司了。

如果使用v1.9.2之前老版本的vn.py怎么办?

请将v1.9.2的以下内容复制到你的老版本对应的目录下:

  • vnpy/api/ctp
  • vnpy/trader/gateway/ctpGateway
  • vnpy/trader/gateway/ctptestGateway

并采用上文提到的方式去做认证。

6.3.15的穿透式实盘API,想进行下测试怎么办?

目前只发现中信期货提供了6.3.15的仿真测试环境(忍不住竖起大拇指,不愧是中信),但最近估计申请人数过多,新的申请处理非常缓慢,如果大家发现别家提供6.3.15的测试环境也欢迎在评论里告知。

为什么期货公司一定要用6.3.13和6.3.15两个版本,接下来是否会合并都使用6.3.15?

为了满足穿透式监管认证要求,期货公司认证时要看到客户机器采集的信息,就只能通过6.3.13版本的CTP API。而实盘交易的环境中,期货监控中心要求直接上报采集信息,禁止期货公司查看和修改,就必须通过6.3.15版本。

所以目前来看仿真和实盘使用两个版本的API,是监管中心比较放心得过的方案吧,也就意味着交易客户端必须要两套API都对接准备好了。



自用backtesting分享,关键词【回测盈亏统计】,【pyecharts画图】,【还有empyrical统计指标】

盈亏统计在update_postion函数里面,其他在calculate_statistics里面,还有一些改动大家自己看吧。
PS:backtesting里面的路径大家看着改

2020.03.07增加月度盈亏统计和omega_ratio指标



RiceQuant(米筐科技)成为vn.py项目的战略合作伙伴

RQData

 

新的合作伙伴


继华尔街见闻、上海中期、富途证券后,vn.py项目拥有了第四位战略合作伙伴——RiceQuant(米筐科技)。

和之前的三家合作伙伴相比,估计有些朋友看到vn.py和RiceQuant成为合作伙伴后会一脸懵逼:你们两家不应该是直接竞争关系么???

黑人问号脸

要讲清楚这个问题,又要回到量化交易的三大环节:数据收集(维护)、策略开发(回测)、实盘交易(执行)。

 

数据的痛点


起源于私募自主量化交易系统,vn.py的核心定位始终是以上三个环节中的“交易”:算法交易(AlgoTrading)、价差交易(SpreadTrading)、期权波动率交易(OptionMaster)、事前风控(RiskManager)等等,同时也提供了对于国内最常见的CTA类“策略”的支持:针对中高频单合约的CtaStrategy和针对中低频多合约的TurtleStrategy。

但对于第一个环节的“数据”,尽管定位于交易vn.py主要需要的只是行情相关的数据(不用考虑股票因子相关数据中的种种大坑),也早就推出了行情记录模块DataRecorder和对接各类免费数据API的行情数据服务DataService,社区还是普遍反应“不方便”、“太难用”。和金融数据方面的业内人士交流后,了解到“数据服务”和“开源软件”其实在性质上有着本质的区别:

  • 新的数据记录需要大量的硬盘存储空间
  • 每日的数据清洗需要人工检查保证质量
  • 每个新增客户都会带来额外的网络流量

以上因素,使得免费的数据服务在成本上不可持续,最终要么会出现数据质量的打折(无人工检查、各种错误),要么直接就选择停止提供服务(无法再承担成本),两者都曾在vn.py的合作方中出现。而关于相关成本,这里只能给大家一个粗糙的概念:我自己曾经工作的量化私募,所采购的万得宏汇、恒生聚源、交易所L2等数据服务,每年的成本都是在数十万元的水平。

在此必须强调的是,vn.py社区对于所有的免费数据服务始终充满了尊敬和感激,对于很多初入行的Quant、在校学生、量化爱好者等初级用户群体来说,免费数据服务就是从0到1的质变,让原本看起来非常高大上的量化研究变得可以快速上手尝试,vn.py项目也会继续加入和更新各类免费的数据服务。

但从另一个角度看,vn.py的核心用户群体“实盘交易用户”(自营、资管、基金、私募等),确实对于高质量的数据服务有着庞大的刚性需求。同时许多用过DataRecorder自行收集建设数据库的用户也都表示:与其自己招人维护,不如直接花钱买省心。

所以,从18年初开始,vn.py就一直在寻找高质量收费数据服务的战略合作伙伴。

 

Why RiceQuant?


作为国内最火的量化交易技术公司之一,RiceQuant从在线量化策略平台起家(Java->Python),随后推出了自己的开源量化策略回测框架RQAlpha(比Zipline更适合中国证券市场)。这两年集中精力在量化2B业务上,建立了非常完整的量化产品体系:RQData集成数据方案、RQBeta风险管理系统以及RQPro量化一站式解决方案,产品质量也得到了诸多大型金融机构用户的肯定。

总结描述RiceQuant的关键词:

keyword

找了个机会和 RiceQuant的@LIKE总交流后,达成了这么一个合作的想法:以尽可能低的价格提供易用且高质量的数据服务方案,让愿意付费的vn.py实盘交易用户实现开箱即用,把更多的精力放在量化策略研发和交易执行细节上,而不是重复枯燥的数据录制和每日清理。

 

产品形态


目前vn.py的最新v1.9.2的dev分支已经完成了和RQData的对接,包括:

  1. CTA策略模块的实盘交易数据加载初始化,支持直接通过RQData完成,意味着从此用户即使在每天11:00的时候才启动自己的策略交易,同样可以立即获取历史以及当天之前的全部数据,而无需再始终运行着自己的行情录制工具,节省大量的硬盘服务器成本以及运维维护精力
  2. 无人值守模式的RQData数据同步工具,每1分钟自动同步用户订阅的全部合约最新分钟线数据到本地数据库中,这样CTA策略的初始化就可以通过直接访问本地数据库中的数据来完成,效率更高的同时也方便收盘后的当日对比回测分析
  3. 基于RQData提供的商品连续指数的海龟策略完整实现,关于其中的策略难点、代码实现、数据是否可靠等问题,欢迎关注即将在12月23日举行的知乎LIVE

最后,对RQData数据服务感兴趣的用户,可以通过这篇文章来了解:

RQData2.0上线 | 天下武功,唯快不破

**同时RiceQuant官网也已经开通了RQData的申请试用:RiceQuant米筐量化交易平台,相信服务质量不会让你失望!!!!



使用CSV文件进行回测

很多时候,需要用CSV文件直接回测

先看用法:

from vnpy.app.cta_strategy.csv_backtesting import CsvBacktestingEngine, OptimizationSetting
from vnpy.app.cta_strategy.base import BacktestingMode
from vnpy.app.cta_strategy.strategies.atr_rsi_strategy import ( 
    AtrRsiStrategy,
)
from datetime import datetime

engine = CsvBacktestingEngine()
engine.set_parameters(
    vt_symbol="IF88.CFFEX",
    interval="1m",
    start=datetime(2016, 1, 1),
    end=datetime(2019, 4, 30),
    rate=0.3/10000,
    slippage=0.2,
    size=300,
    pricetick=0.2,
    capital=1_000_000,
)
engine.add_strategy(AtrRsiStrategy, {})

engine.load_data("data.csv", names = [
    "datetime",
    "open_price",
    "high_price",
    "low_price",
    "close_price",
    "volume",
    "open_interest",
])

engine.run_backtesting()
df = engine.calculate_result()
engine.calculate_statistics()
engine.show_chart()

将下列代码命名为csv_backtesting.py保存到 cta_strategy 目录下并且与backtesting.py 同一目录

import pandas as pd
from vnpy.app.cta_strategy.backtesting import *


def generate_bar_from_row(row, symbol, exchange):
    """
    Generate bar from row.
    """
    return BarData(
        symbol=symbol,
        exchange=Exchange(exchange),
        interval=Interval.MINUTE,
        open_price=row["open"],
        high_price=row["high"],
        low_price=row["low"],
        close_price=row["close"],
        open_interest=row["open_interest"] or 0,
        volume=row["volume"],
        datetime=row.name.to_pydatetime(),
        gateway_name="DB",
    )


def generate_tick_from_row(row, symbol, exchange):
    """
    Generate tick from row.
    """
    return TickData(
        symbol=symbol,
        exchange=Exchange(exchange),
        datetime=row["datetime"],
        name=row["name"],
        volume=row["volume"],
        open_interest=row["open_interest"],
        last_price=row["last_price"],
        last_volume=row["last_volume"],
        limit_up=row["limit_up"],
        limit_down=row["limit_down"],
        open_price=row["open_price"],
        high_price=row["high_price"],
        low_price=row["low_price"],
        pre_close=row["pre_close"],
        bid_price_1=row["bid_price_1"],
        bid_price_2=row["bid_price_2"],
        bid_price_3=row["bid_price_3"],
        bid_price_4=row["bid_price_4"],
        bid_price_5=row["bid_price_5"],
        ask_price_1=row["ask_price_1"],
        ask_price_2=row["ask_price_2"],
        ask_price_3=row["ask_price_3"],
        ask_price_4=row["ask_price_4"],
        ask_price_5=row["ask_price_5"],
        bid_volume_1=row["bid_volume_1"],
        bid_volume_2=row["bid_volume_2"],
        bid_volume_3=row["bid_volume_3"],
        bid_volume_4=row["bid_volume_4"],
        bid_volume_5=row["bid_volume_5"],
        ask_volume_1=row["ask_volume_1"],
        ask_volume_2=row["ask_volume_2"],
        ask_volume_3=row["ask_volume_3"],
        ask_volume_4=row["ask_volume_4"],
        ask_volume_5=row["ask_volume_5"],
        gateway_name="DB",
    )


class CsvBacktestingEngine(BacktestingEngine):
    def __init__(self):
        super().__init__()

    def load_data(
        self,
        filename: str,
        names: list = [
            "datetime",
            "open_price",
            "high_price",
            "low_price",
            "close_price",
            "volume",
            "open_interest",
        ],
        compression: any = None,
        parse_dates: bool = True,
        skiprows: int = 1,
    ):
        """
        Load Bar Names: [
            "datetime",
            "open_price",
            "high_price",
            "low_price",
            "close_price",
            "volume",
            "open_interest",
        ]

        Load Tick Names: [
            "datetime",
            "name",
            "volume",
            "open_interest",
            "last_price",
            "last_volume",
            "limit_up",
            "limit_down",
            "open_price",
            "high_price",
            "low_price",
            "pre_close",
            "bid_price_1",
            "bid_price_2",
            "bid_price_3",
            "bid_price_4",
            "bid_price_5",
            "ask_price_1",
            "ask_price_2",
            "ask_price_3",
            "ask_price_4",
            "ask_price_5",
            "bid_volume_1",
            "bid_volume_2",
            "bid_volume_3",
            "bid_volume_4",
            "bid_volume_5",
            "ask_volume_1",
            "ask_volume_2",
            "ask_volume_3",
            "ask_volume_4",
            "ask_volume_5",
        ]
        """
        self.output("开始加载历史数据")

        if not self.end:
            self.end = datetime.now()

        if self.start >= self.end:
            self.output("起始日期必须小于结束日期")
            return

        self.history_data.clear()  # Clear previously loaded history data

        # Load 30 days of data each time and allow for progress update
        progress_delta = timedelta(days=30)
        total_delta = self.end - self.start
        interval_delta = INTERVAL_DELTA_MAP[self.interval]

        start = self.start
        end = self.start + progress_delta
        progress = 0

        while start < self.end:
            end = min(end, self.end)  # Make sure end time stays within set range

            df = pd.read_csv(filename, compression, parse_dates, skiprows, names,)
            # Generate
            symbol, exchange = self.vt_symbol.split(".")
            data = []
            if df is not None and not df.empty:
                for ix, row in df.iterrows():
                    if row["datetime"] > self.start and row["datetime"] < self.end:
                        if self.mode == BacktestingMode.BAR:
                            data.append(generate_bar_from_row(row, symbol, exchange))
                        else:
                            data.append(generate_tick_from_row(row, symbol, exchange))
            else:
                self.output("Csv file has no Data!")
                return

            self.history_data.extend(data)

            progress += progress_delta / total_delta
            progress = min(progress, 1)
            progress_bar = "#" * int(progress * 10)
            self.output(f"加载进度:{progress_bar} [{progress:.0%}]")

            start = end + interval_delta
            end += progress_delta + interval_delta

        self.output(f"历史数据加载完成,数据量:{len(self.history_data)}")


《vn.py 2.0.7源代码深入分析》

继续分享vn.py的学习文档。这个文档上个月叫《vn.py 2.0.7代码分析入门》,只包含本文档的第一部分。当时正在全面调研各类量化交易平台,对vn.py只做初步了解。现在准备进一步学习vn.py,也就有了本文档的第二部分。说到调研,我没资格评价哪个好哪个稍差,此处只是汇报我个人的一个情况:在调研了一圈之后,现在又回过头来研究vn.py了。
文档没有完成。本想完成后再发出来,但不想继续写了,就把现在已经写的部分发出来吧。不完整,各位老师勿怪。

文档链接:https://pan.baidu.com/s/1KUxTcMD8hY6eIqEBoNk3Tg



实现了一个在本地可以仿真交易期权的工具

期权没有类似simnow的服务器可以仿真调试,又不能像大佬那样直接实盘调试,
就自己做了一个工具,可以在本地播放tick数据,这样就能实现在本机仿真调试了,
现在的效果是:

description

这里好像不能放附件,我放到网盘去了:
https://pan.baidu.com/s/1sgQtCgk5ivarp8OQFlKvfg
提取码:3pe6

使用方法:
1:把file_gateway放到vnpy的gateway目录下面
2:进入server目录,cmd启动server ,server目录下有我测试用的tick数据和合约配置文件,启动有可以用了
3:进入client目录,cmd启动client
4:在ui界面下链接RPC,再启动OptionMaster
5:设置期权的参数,这里注意一下,配置完,按确定后,UI上可能会有一些卡顿,因为我一次把所有tick数据都加载了,数据量比较大,我测试3月10号一天的数据,就有90M
可以留意看一下server的cmd,可以看到加载数据的详细情况
6:在主界面,“交易”选项下面,代码里输入:Start, 再敲回车, 就开始自动播放tick数据了,这时行情和T型报价应该都有对应的合约在跳动了

这个版本仅仅实现了数据流的播放,发单,撮合等等功能还在弄,有兴趣的朋友可以找我交流

大概原理:
写了一个gateway,调试的时候直接使用这个file_gateway。这里面会加载对应的tick数据,并启动一个线程以流的形式播放出来。
播放的关键是同步tick时间戳,活跃的合约可能全天的时间戳都有数据,但是不活跃的有些时间点就没有数据,需要跳过这些时间,
我实现的方法是用数据最全的合约做baseline,同步播放其他合约
我现在调试的是IO2003,对应的标的是IF2003。
标的合约一般都是最活跃的,所以用IF2003做baseline,其他合约都以他的时间戳来同步播放数据流
具体实现比较简单,有兴趣的可以看看file_gateway里面TickStreamThread的实现,数据播放快慢可以在循环里修改sleep时间

现在功能还比较简单,只能播放数据,有兴趣的朋友可以自己添加,有问题可以来群里找我:老麦



Mac 下安装运行 vnpy 2.0

官网上对 Mac 下运行 vnpy 介绍的比较少, 自己尝试安装了下, 把过程简单记录下来, 希望能帮到大家.

我并不准备在 Mac 进行实盘交易, 因为刚准备开始量化, 所以就打算先熟悉下框架用用回测然后对 A股 进行模拟交易, 所以无所谓 CTP 接口是否可用.

下面以跑通 okex 来说明.

安装步骤:

  • 安装 Anaconda, 这个到官网下载 Python 3.7 的版本即可: https://www.anaconda.com/distribution/
  • git clone vnpy 代码到本地
  • 切换到 vnpy 代码目录
  • 运行 conda create --name test-vnpy python=3.7, 创建 conda 环境, 名字随便取的就叫 test-vnpy 了
  • 运行 conda activate test-vnpy, 激活环境
  • 安装 python.app (Mac 下运行 Matplotlib 需要使用到): conda install python.app
  • 安装 ta-lib, 这个直接通过 brew install ta-lib 安装
  • pip 安装依赖的时候发现报 pg_config executable not found 错误, 安装 PostgreSQL 解决, 运行 brew install postgresql 安装即可
  • 安装 rqdatac: pip install --pre --extra-index-url https://rquser:ricequant99@py.ricequant.com/simple/ rqdatac
  • 安装 ibapi: pip install https://vnpy-pip.oss-cn-shanghai.aliyuncs.com/colletion/ibapi-9.75.1-py3-none-any.whl
  • 安装 requirements 中依赖: pip install -r requirements.txt
  • 安装 vnpy: pip install .
  • 创建 run.py, 内容如下:

    from vnpy.event import EventEngine
    from vnpy.trader.engine import MainEngine
    from vnpy.trader.ui import MainWindow, create_qapp
    from vnpy.gateway.okex import OkexGateway
    from vnpy.app.cta_strategy import CtaStrategyApp
    
    def main():
        """Start VN Trader"""
        qapp = create_qapp()
    
        event_engine = EventEngine()
        main_engine = MainEngine(event_engine)
    
        main_engine.add_gateway(OkexGateway)
        main_engine.add_app(CtaStrategyApp)
    
        main_window = MainWindow(main_engine, event_engine)
        main_window.showMaximized()
    
        qapp.exec()
    
    if __name__ == "__main__":
        main()
  • 使用 pythonw run.py 运行

这样就成功启动界面了, 点击菜单连接 API 即可!

还不是很清楚 VN Trader 的用法, 不过看样子功能都正常了, 今天就先到这里了, 明天再来研究研究.


新消息

统计

主题
2686
帖子
9677
已注册用户
10678
最新用户
在线用户
199
在线来宾用户
214
© 2015-2019 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3