|
其他参考文章
《快速入门教程》
https://q.vnpy.cn/comm/thread-13-1-1.html
《新版策略自动生成回测文件功能代码解析》
https://q.vnpy.cn/comm/thread-22-1-1.html
《VNPY3.0以后的版本为什么不用数据库设计架构?》
https://q.vnpy.cn/comm/thread-21-1-1.html
《VNPY3.0行情数据调用的5种方式 》
https://q.vnpy.cn/comm/thread-24-1-1.html
《VNPY新手常见问题说明》
https://q.vnpy.cn/comm/thread-3-1-1.html
《VNPY3.0 架构图》
https://q.vnpy.cn/comm/thread-25-1-1.html
《A股\期货解决方案》
http://www.vnta.cn
VNPY官网
https://www.vnpy.cn
VNTA 证券和期货方案
http://www.vnta.cn
《用户福利》
https://www.vnpy.cn/kaihu/
1. marketdata 是 实时Tick数据
可参考 strategyfile/talib_MA.py
参数marketdata 行情来自CTP接口的的TICK回调数据
thostmduserapi_se.dll(CTP原生行情API) -> vnctpmd.dll (这是代理API,是CTP和PY之间的桥梁,代码项目名vnctpmd,需要和thostmduserapi_se.lib 、thostmduserapi_se.h一起编译) ->vnctpmd.py ->module_md.py
(1)CTP原生API thostmduserapi_se.dll 、 C++ 头文件 thostmduserapi_se.h 中CThostFtdcMdSpi类的
- ///深度行情通知
- virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData) {};
复制代码
CThostFtdcMdSpi类的完整代码如下
- class CThostFtdcMdSpi
- {
- public:
- ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。
- virtual void OnFrontConnected(){};
-
- ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
- ///@param nReason 错误原因
- /// 0x1001 网络读失败
- /// 0x1002 网络写失败
- /// 0x2001 接收心跳超时
- /// 0x2002 发送心跳失败
- /// 0x2003 收到错误报文
- virtual void OnFrontDisconnected(int nReason){};
-
- ///心跳超时警告。当长时间未收到报文时,该方法被调用。
- ///@param nTimeLapse 距离上次接收报文的时间
- virtual void OnHeartBeatWarning(int nTimeLapse){};
-
- ///登录请求响应
- virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///登出请求响应
- virtual void OnRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///请求查询组播合约响应
- virtual void OnRspQryMulticastInstrument(CThostFtdcMulticastInstrumentField *pMulticastInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///错误应答
- virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///订阅行情应答
- virtual void OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///取消订阅行情应答
- virtual void OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///订阅询价应答
- virtual void OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///取消订阅询价应答
- virtual void OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {};
- ///深度行情通知
- virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData) {};
- ///询价通知
- virtual void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp) {};
- };
复制代码
(2) vnctpmd.dll、 vnctpmd.py
vnctpmd.py通过ctypes方式调用vnctpmd.dll中的方法- # 行情回调
- def OnRtnDepthMarketData(self, a):
- pass
复制代码
(3) module_md.py
module_md.py的MyCTPMarket类继承自 vnctpmd.py的vnctpmd类
MyCTPMarket类中的OnRtnDepthMarketData获得回调后,不直接更新UI,是通过signal_md_tick是信号,将数据发送给UI更新。
OnRtnDepthMarketData还将驱动策略文件进行计算,策略文件保存在strategyfile目录下,比如 talib_MA.py 就是策略文件,该目录下同名 talib_MA.ini 文件为策略配置文件。
回测时,系统会自动根据 talib_MA.py 生成strategyfilebacktest目录下的同名 talib_MA.py 文件。
- # MyCTPMarket类继承自CTPMarket类
- class MyCTPMarket(vnctpmd, QtCore.QThread):
- loginstate = False
- def ReqUserLogin(self):
- pass
- def OnRtnDepthMarketData(self, tickdatacontents):
- tickdata = tickdatacontents[0]
- update_depthMarketData(tickdata)
- module_strategy.StrategyManager(tickdata)
- self.signal_md_tick.emit([tickdata.InstrumentID, tickdata.LastPrice, tickdata.Volume,
- tickdata.TradingDay, tickdata.UpdateTime,
- tickdata.UpdateMillisec])
- try:
- globalvar.thistoday = int(tickdata.TradingDay)
- except Exception as e:
- pass
复制代码
2. 这是从CTP Tick由vnctpmd.dll 在本机生成的K线,可以直接按下标方式取得,速度快
vnctptd.dll、vnctpmd.py、vnctptd.ini
该数据是由CTP实时Tick在vnctptd.dll中合成的,存储在用户计算机内存中,通过vnctpmd.py的GetKline(self, InstrumentID, ID)方法调用
如果用户网络中断的话,可能导致该数据不完整。
- def GetKline(self, InstrumentID, ID):
- try:
- # data = self.fGetKline(InstrumentID.encode("utf-8"),ID)
- data = self.fGetKline(InstrumentID, ID)
- return cast(data, POINTER(KLineDataType))
- except Exception as e:
- print("GetKline Error:" + repr(e))
复制代码
3. 这是从服务器获得当日K线取法,禁止频繁调用 vnklineservice.dll、vnklineservice.py、vnklineservice.ini
vnklineservice.py文件的vnklineservice类,通过ctypes方式调用vnklineservice.dll中的GetServerKline()方法
4. 这是当前显示K线图数据暂存,数据来自于 vnctpmd.dll 和 vnklineservice.dll,策略计算不用这个。
当系统启动和断线重连时,会先从vnklineservice.dll获取最近的M1周期K线数据,然后通过vnctpmd.dll从CTP接口TICK合成K线追加数据。
其中vnklineservice.dll 服务是可选项,如果没有该服务,那么数据的唯一来源就是CTP接口,程序启动时会从第一个线开始计算。
vnklineservice.dll 服务需要用户通过客户端主动调用,不仅用于K线显示,也可以用于策略计算。
5. 历史数据
backtestdata目录下的CSV文件
|
|