|
《VNPY3.0 官方快速入门教程》《VNPY新手常见问题说明》
https://gitee.com/vnpypro/vnpy
从上面链接下载就是最新版,无需用户自己升级。
VNPY官方在升级过程中是如何做的呢,通过下面这个步骤可以理解CTP的升级。
VNTrader 更新上期期货CTP api 6.6.1升级步骤
VNTrader 更新上期期货CTP api 6.6.1升级步骤
最近期货公司陆续启用了CTP 6.6.1, 一般CTP API是高版本服务端兼容低版本客户端CTP API,VNTrader的CTP6.3.19 版本出现了获取不到交易日的情况,导致无法读取K线。
- <p>
- </p><div class="highlight"><pre><code class="language-text">InitKlineDataFrame Error:KeyError('hc2201')
- combineklineUpdateCharts Error:TypeError("Only valid with DatetimeIndex,
- TimedeltaIndex or PeriodIndex, but got an instance of 'Index'")
- dict_talibcondition Error:KeyError('.csv')</code></pre></div>
复制代码
处理方法就是对VNTrader目录的 vnctpmd.dll,vnctptd.dll 文件需要重新编译,VNTrader目录下的thostmduserapi_se.dll和thosttraderapise.dll更新到最新版本6.6.1_P1 。
本文对如何更新 CTP API到最新版本的具体步骤做一个步骤的梳理。
有2个地方可以下载上海期货交易所 CTP api
上期仿真账号平台 SIMNOW,该平台只有工作日白天可以访问
http://www.simnow.com.cn
可以看到有2个版本 6.3.19 和6.6.1P1 ,当前VNPY还处于6.3.19版本,我们本次将更新到6.6.1_P1版本。
先下载6.6.1_P1 版本的CTP API压缩包。
解压缩后进入Windows的64位版本 CTP api目录
其中.h是C++项目的头文件,.lib和.dll文件是CTP api的库文件,
其中.lib需要编译时使用;
.dll 文件为VNTrader项目运行时使用(即把VNTrader目录下的thostmduserapi_se.dll和thosttraderapise.dll 替换掉)。
当前 VNPY(VNTrader)目录下thostmduserapise.dll和thosttraderapise.dll 时间为2020年1月6日的版本,而CTP API 6.6.1_P1的时间为2021年4月6日的版本。
替换完毕如下图
替换 .h和.lib文件重新编译vnctpmd.dll,vnctptd.dll
编译器IDE采用Visual Studio2015\Visual Studio2017\Visual Studio2019
vnctpmd.dll,vnctptd.dl 的C++代码如下图再VNTrader的目录下
先复制当前最新版本的CTP 6.6.1_P1的头文件到vnctpmd.dll,vnctptd.dll 项目目录下
当前我们只编译64位的
替换完成如图
同样的,vnctptd.dll 替换完成如图
用Visual Studio打开vnctpmd项目
用Visual Studio打开vnctptd项目
vnctptd无法编译,发现是6.6.1_P1相比6.3.19方法里的结构体名称更改了
CThostFtdcQueryMaxOrderVolumeField 改为CThostFtdcQryMaxOrderVolumeField,我们把vnctptd C++代码里的文本CThostFtdcQueryMaxOrderVolumeField全部替换为CThostFtdcQryMaxOrderVolumeField即可。
替换完成,再次编译,还有错误
ReqQueryMaxOrderVolume全部改为ReqQryMaxOrderVolume,编译成功
进入下图目录,将编译完成的vnctpmd.dll和vnctptd.dll 复制到VNTrader目录即升级完成。
用Pycharm 重新打开VNTrader项目,又可以看到熟悉的界面了
第2处修改:
InitKlineDataFrame Error:KeyError('ag2111')
filename: D:\pyqt5\VNTrader2021.10.9开源无C++\VNTrader\data_today\ag2111.csv
Exception ignored on calling ctypes callback function: <bound method MyCTPTrade.OnRspQryTradingAccount of <module_td.MyCTPTrade object at 0x000001A7B7520160>>
Traceback (most recent call last):
File "D:\pyqt5\VNTrader2021.10.9开源无C++\VNTrader\module_td.py", line 171, in OnRspQryTradingAccount
File "D:\pyqt5\VNTrader2021.10.9开源无C++\VNTrader\module_td.py", line 80, in update_account
print(TradingDaystr)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc2 in position 2: invalid continuation byte
账户资金回调OnRspQryTradingAccount
b'\xcd\xac\xc2\xf5(\x0f\xce@'
dict_dataframe_kline_M1 is empty: KeyError('ag2201')
filename: D:\pyqt5\VNTrader2021.10.9开源无C++\VNTrader\data_today\ag2201.csv
InitKlineDataFrame Error:KeyError('ag2201')
账户资金回调OnRspQryTradingAccount
b'\xcd\xac\xc2\xf5(\x0f\xce@'
# 账户资金回调
def OnRspQryTradingAccount(self, a):
print("账户资金回调OnRspQryTradingAccount")
update_account(a)
发现
a.contents.TradingDay错误,
是因为CTP 6.6.1和CTP 6.3.19 的CThostFtdcInvestorPositionField结构体发生了变化
以下是6.3.19的结构体定义
以下是CTP 6.6.1的结构体定义
改变就是在原来
- <div>///合约代码</div><div>TThostFtdcInstrumentIDType InstrumentID; </div>
复制代码
位置改为了
- <div>///保留的无效字段</div>TThostFtdcOldInstrumentIDType reserve1;
复制代码
为了解决上述错误,需要更新vnctptdType.py文件
改为以下定义
class VNDEFInvestorPosition(Structure):
_fields_ = [
('reserve1', c_char * 31), # 保留字段
('BrokerID', c_char * 11), # 经纪公司代码
('InvestorID', c_char * 13), # 投资者代码
('PosiDirection', c_char), # 持仓多空方向
('HedgeFlag', c_char), # 投机套保标志
('PositionDate', c_char), # 持仓日期
('YdPosition', c_int32), # 上日持仓
('Position', c_int32) , # 今日持仓
('LongFrozen', c_int32), # 多头冻结
('ShortFrozen', c_int32), # 空头冻结
('LongFrozenAmount', c_double), # 开仓冻结金额
('ShortFrozenAmount', c_double), # 开仓冻结金额
('OpenVolume', c_int32), # 开仓量
('CloseVolume', c_int32), # 平仓量
('OpenAmount', c_double), # 开仓金额
('CloseAmount', c_double), # 平仓金额
('PositionCost', c_double), # 持仓成本
('PreMargin', c_double), # 上次占用的保证金
('UseMargin', c_double), # 占用的保证金
('FrozenMargin', c_double), # 冻结的保证金
('FrozenCash', c_double), # 冻结的资金
('FrozenCommission', c_double), # 冻结的手续费
('CashIn', c_double), # 资金差额
('Commission', c_double), # 手续费
('CloseProfit', c_double), # 平仓盈亏
('PositionProfit', c_double), # 持仓盈亏
('PreSettlementPrice', c_double), # 上次结算价
('SettlementPrice', c_double), # 本次结算价
('TradingDay', c_char * 9), # 本次结算价
('SettlementID',c_int32), # 结算编号
('OpenCost', c_double), # 开仓成本
('ExchangeMargin', c_double), # 交易所保证金
('CombPosition', c_int32), # 组合成交形成的持仓
('CombLongFrozen', c_int32), # 组合多头冻结
('CombShortFrozen', c_int32), # 组合空头冻结
('CloseProfitByDate', c_double), # 逐日盯市平仓盈亏
('CloseProfitByTrade', c_double), # 逐笔对冲平仓盈亏
('TodayPosition', c_int32), # 今日持仓
('MarginRateByMoney', c_double), # 保证金率
('MarginRateByVolume', c_double), # 保证金率(按手数)
('StrikeFrozen', c_int32), # 执行冻结
('StrikeFrozenAmount', c_double), # 执行冻结金额
('AbandonFrozen', c_int32), # 放弃执行冻结
('ExchangeID', c_char * 9), # 交易所代码
('YdStrikeFrozen', c_int32), # 执行冻结的昨仓
('InvestUnitID', c_char * 17), # 投资单元代码
('PositionCostOffset', c_double), # 大商所持仓成本差值,只有大商所使用
('TasPosition', c_int32), # tas持仓手数
('TasPositionCost', c_double) , # tas持仓成本
('InstrumentID', c_char * 31), # 合约代码
]
pass
第三处修改:
是因为CTP 6.6.1和CTP 6.3.19 的CThostFtdcDepthMarketDataField结构体发生了变化
以下是6.3.19的结构体定义
- <div><font size="3"><font size="2">///深度行情
- struct CThostFtdcDepthMarketDataField
- {
- ///交易日
- TThostFtdcDateType TradingDay;
- ///合约代码
- TThostFtdcInstrumentIDType InstrumentID;
- ///交易所代码
- TThostFtdcExchangeIDType ExchangeID;
- ///合约在交易所的代码
- TThostFtdcExchangeInstIDType ExchangeInstID;
- ///最新价
- TThostFtdcPriceType LastPrice;
- ///上次结算价
- TThostFtdcPriceType PreSettlementPrice;
- ///昨收盘
- TThostFtdcPriceType PreClosePrice;
- ///昨持仓量
- TThostFtdcLargeVolumeType PreOpenInterest;
- ///今开盘
- TThostFtdcPriceType OpenPrice;
- ///最高价
- TThostFtdcPriceType HighestPrice;
- ///最低价
- TThostFtdcPriceType LowestPrice;
- ///数量
- TThostFtdcVolumeType Volume;
- ///成交金额
- TThostFtdcMoneyType Turnover;
- ///持仓量
- TThostFtdcLargeVolumeType OpenInterest;
- ///今收盘
- TThostFtdcPriceType ClosePrice;
- ///本次结算价
- TThostFtdcPriceType SettlementPrice;
- ///涨停板价
- TThostFtdcPriceType UpperLimitPrice;
- ///跌停板价
- TThostFtdcPriceType LowerLimitPrice;
- ///昨虚实度
- TThostFtdcRatioType PreDelta;
- ///今虚实度
- TThostFtdcRatioType CurrDelta;
- ///最后修改时间
- TThostFtdcTimeType UpdateTime;
- ///最后修改毫秒
- TThostFtdcMillisecType UpdateMillisec;
- ///申买价一
- TThostFtdcPriceType BidPrice1;
- ///申买量一
- TThostFtdcVolumeType BidVolume1;
- ///申卖价一
- TThostFtdcPriceType AskPrice1;
- ///申卖量一
- TThostFtdcVolumeType AskVolume1;
- ///申买价二
- TThostFtdcPriceType BidPrice2;
- ///申买量二
- TThostFtdcVolumeType BidVolume2;
- ///申卖价二
- TThostFtdcPriceType AskPrice2;
- ///申卖量二
- TThostFtdcVolumeType AskVolume2;
- ///申买价三
- TThostFtdcPriceType BidPrice3;
- ///申买量三
- TThostFtdcVolumeType BidVolume3;
- ///申卖价三
- TThostFtdcPriceType AskPrice3;
- ///申卖量三
- TThostFtdcVolumeType AskVolume3;
- ///申买价四
- TThostFtdcPriceType BidPrice4;
- ///申买量四
- TThostFtdcVolumeType BidVolume4;
- ///申卖价四
- TThostFtdcPriceType AskPrice4;
- ///申卖量四
- TThostFtdcVolumeType AskVolume4;
- ///申买价五
- TThostFtdcPriceType BidPrice5;
- ///申买量五
- TThostFtdcVolumeType BidVolume5;
- ///申卖价五
- TThostFtdcPriceType AskPrice5;
- ///申卖量五
- TThostFtdcVolumeType AskVolume5;
- ///当日均价
- TThostFtdcPriceType AveragePrice;
- ///业务日期
- TThostFtdcDateType ActionDay;
- };</font>
- </font></div>
复制代码
6.6.1
- ///深度行情
- struct CThostFtdcDepthMarketDataField
- {
- ///交易日
- TThostFtdcDateType TradingDay;
- ///保留的无效字段
- TThostFtdcOldInstrumentIDType reserve1;
- ///交易所代码
- TThostFtdcExchangeIDType ExchangeID;
- ///保留的无效字段
- TThostFtdcOldExchangeInstIDType reserve2;
- ///最新价
- TThostFtdcPriceType LastPrice;
- ///上次结算价
- TThostFtdcPriceType PreSettlementPrice;
- ///昨收盘
- TThostFtdcPriceType PreClosePrice;
- ///昨持仓量
- TThostFtdcLargeVolumeType PreOpenInterest;
- ///今开盘
- TThostFtdcPriceType OpenPrice;
- ///最高价
- TThostFtdcPriceType HighestPrice;
- ///最低价
- TThostFtdcPriceType LowestPrice;
- ///数量
- TThostFtdcVolumeType Volume;
- ///成交金额
- TThostFtdcMoneyType Turnover;
- ///持仓量
- TThostFtdcLargeVolumeType OpenInterest;
- ///今收盘
- TThostFtdcPriceType ClosePrice;
- ///本次结算价
- TThostFtdcPriceType SettlementPrice;
- ///涨停板价
- TThostFtdcPriceType UpperLimitPrice;
- ///跌停板价
- TThostFtdcPriceType LowerLimitPrice;
- ///昨虚实度
- TThostFtdcRatioType PreDelta;
- ///今虚实度
- TThostFtdcRatioType CurrDelta;
- ///最后修改时间
- TThostFtdcTimeType UpdateTime;
- ///最后修改毫秒
- TThostFtdcMillisecType UpdateMillisec;
- ///申买价一
- TThostFtdcPriceType BidPrice1;
- ///申买量一
- TThostFtdcVolumeType BidVolume1;
- ///申卖价一
- TThostFtdcPriceType AskPrice1;
- ///申卖量一
- TThostFtdcVolumeType AskVolume1;
- ///申买价二
- TThostFtdcPriceType BidPrice2;
- ///申买量二
- TThostFtdcVolumeType BidVolume2;
- ///申卖价二
- TThostFtdcPriceType AskPrice2;
- ///申卖量二
- TThostFtdcVolumeType AskVolume2;
- ///申买价三
- TThostFtdcPriceType BidPrice3;
- ///申买量三
- TThostFtdcVolumeType BidVolume3;
- ///申卖价三
- TThostFtdcPriceType AskPrice3;
- ///申卖量三
- TThostFtdcVolumeType AskVolume3;
- ///申买价四
- TThostFtdcPriceType BidPrice4;
- ///申买量四
- TThostFtdcVolumeType BidVolume4;
- ///申卖价四
- TThostFtdcPriceType AskPrice4;
- ///申卖量四
- TThostFtdcVolumeType AskVolume4;
- ///申买价五
- TThostFtdcPriceType BidPrice5;
- ///申买量五
- TThostFtdcVolumeType BidVolume5;
- ///申卖价五
- TThostFtdcPriceType AskPrice5;
- ///申卖量五
- TThostFtdcVolumeType AskVolume5;
- ///当日均价
- TThostFtdcPriceType AveragePrice;
- ///业务日期
- TThostFtdcDateType ActionDay;
- ///合约代码
- TThostFtdcInstrumentIDType InstrumentID;
- ///合约在交易所的代码
- TThostFtdcExchangeInstIDType ExchangeInstID;
- ///上带价
- TThostFtdcPriceType BandingUpperPrice;
- ///下带价
- TThostFtdcPriceType BandingLowerPrice;
- };
复制代码
所以将 vnctpmdType.py 同步修改为
class VNDepMarketData(Structure):
_fields_ = [('TradingDay', c_char * 9),
('reserve1', c_char * 31),
('ExchangeID', c_char * 9),
('reserve2', c_char * 31),
('LastPrice', c_double),
('PreSettlementPrice', c_double),
('PreClosePrice', c_double),
('PreOpenInterest', c_double),
('OpenPrice', c_double),
('HighestPrice', c_double),
('LowestPrice', c_double),
('Volume', c_int),
('Turnover', c_double),
('OpenInterest', c_double),
('ClosePrice', c_double),
('SettlementPrice', c_double),
('UpperLimitPrice', c_double),
('LowerLimitPrice', c_double),
('PreDelta', c_double),
('CurrDelta', c_double),
('UpdateTime', c_char * 9),
('UpdateMillisec', c_int32),
('BidPrice1', c_double),
('BidVolume1', c_int32),
('AskPrice1', c_double),
('AskVolume1', c_int32),
('BidPrice2', c_double),
('BidVolume2', c_int32),
('AskPrice2', c_double),
('AskVolume2', c_int32),
('BidPrice3', c_double),
('BidVolume3', c_int32),
('AskPrice3', c_double),
('AskVolume3', c_int32),
('BidPrice4', c_double),
('BidVolume4', c_int32),
('AskPrice4', c_double),
('AskVolume4', c_int32),
('BidPrice5', c_double),
('BidVolume5', c_int32),
('AskPrice5', c_double),
('AskVolume5', c_int32),
('AveragePrice', c_double),
('ActionDay', c_char * 9),
('InstrumentID', c_char * 81),
('ExchangeInstID', c_char * 81),
('BandingUpperPrice', c_double),
('BandingLowerPrice', c_double)
]
pass
好嘛, CTP 6.6.1 增加了
///保留的无效字段
TThostFtdcOldInstrumentIDType reserve1;
///保留的无效字段
TThostFtdcOldInstrumentIDType reserve2;
///业务日期
TThostFtdcDateType ActionDay;
///上带价
TThostFtdcPriceType BandingUpperPrice;
///下带价
TThostFtdcPriceType BandingLowerPrice;
移动了位置
///合约代码
TThostFtdcInstrumentIDType InstrumentID;
///合约在交易所的代码
TThostFtdcExchangeInstIDType ExchangeInstID;
还将原来TThostFtdcInstrumentIDType和TThostFtdcExchangeInstIDType 长度从31改为81,难度是char[31] 不够存储合约代码了吗?
|
|