diff --git a/vn.trader/qdpGateway/QDP_connect_mn.json b/vn.trader/qdpGateway/QDP_connect_mn.json new file mode 100644 index 00000000..990d6694 --- /dev/null +++ b/vn.trader/qdpGateway/QDP_connect_mn.json @@ -0,0 +1,8 @@ +{ + "name": "国富模拟", + "brokerID": "guofu", + "tdAddress": "tcp://211.147.74.221:30005", + "password": "111111", + "mdAddress": "tcp://211.147.74.221:30007", + "userID": "t040" +} diff --git a/vn.trader/qdpGateway/__init__.py b/vn.trader/qdpGateway/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/vn.trader/qdpGateway/msvcp120.dll b/vn.trader/qdpGateway/msvcp120.dll new file mode 100644 index 00000000..a237d2d7 Binary files /dev/null and b/vn.trader/qdpGateway/msvcp120.dll differ diff --git a/vn.trader/qdpGateway/msvcp90.dll b/vn.trader/qdpGateway/msvcp90.dll new file mode 100644 index 00000000..05c5545c Binary files /dev/null and b/vn.trader/qdpGateway/msvcp90.dll differ diff --git a/vn.trader/qdpGateway/msvcr120.dll b/vn.trader/qdpGateway/msvcr120.dll new file mode 100644 index 00000000..8c36149a Binary files /dev/null and b/vn.trader/qdpGateway/msvcr120.dll differ diff --git a/vn.trader/qdpGateway/msvcr90.dll b/vn.trader/qdpGateway/msvcr90.dll new file mode 100644 index 00000000..4fb9fae0 Binary files /dev/null and b/vn.trader/qdpGateway/msvcr90.dll differ diff --git a/vn.trader/qdpGateway/old/thostmduserapi.dll b/vn.trader/qdpGateway/old/thostmduserapi.dll new file mode 100644 index 00000000..c7402a35 Binary files /dev/null and b/vn.trader/qdpGateway/old/thostmduserapi.dll differ diff --git a/vn.trader/qdpGateway/old/thosttraderapi.dll b/vn.trader/qdpGateway/old/thosttraderapi.dll new file mode 100644 index 00000000..d0c6dea9 Binary files /dev/null and b/vn.trader/qdpGateway/old/thosttraderapi.dll differ diff --git a/vn.trader/qdpGateway/old/vnctpmd.pyd b/vn.trader/qdpGateway/old/vnctpmd.pyd new file mode 100644 index 00000000..4d4ec0ef Binary files /dev/null and b/vn.trader/qdpGateway/old/vnctpmd.pyd differ diff --git a/vn.trader/qdpGateway/old/vnctptd.pyd b/vn.trader/qdpGateway/old/vnctptd.pyd new file mode 100644 index 00000000..4701f30e Binary files /dev/null and b/vn.trader/qdpGateway/old/vnctptd.pyd differ diff --git a/vn.trader/qdpGateway/qdpDataType.py b/vn.trader/qdpGateway/qdpDataType.py new file mode 100644 index 00000000..64471851 --- /dev/null +++ b/vn.trader/qdpGateway/qdpDataType.py @@ -0,0 +1,820 @@ +# encoding: UTF-8 + +defineDict = {} +typedefDict = {} + +#////////////////////////////////////////////////////////////////////// +#@system QuantDo Platform +#@company QuantDo +#@file QdpFtdcUserApiDataType.h +#@brief 定义了客户端接口使用的业务数据类型 +#@history +# +#////////////////////////////////////////////////////////////////////// + + + +#////////////////////////////////////////////////////////////////////// +#定义交易通道类型类别 +#////////////////////////////////////////////////////////////////////// +defineDict["QDP_EI_CFFEX"] = "CFFEX" +defineDict["QDP_EI_SHFE"] = "SHFE" +defineDict["QDP_EI_DCE"] = "DCE" +defineDict["QDP_EI_ZCE"] = "CZCE" +defineDict["QDP_EI_SSE"] = "SSE" +defineDict["QDP_EI_SZSE"] = "SZSE" +defineDict["QDP_EI_SGE"] = "SGE" +defineDict["QDP_EI_CME"] = "CME" +defineDict["QDP_EI_LME"] = "LME" +defineDict["QDP_EI_GTJA"] = "GTJA" +defineDict["QDP_EI_INE"] = "INE" + + +#////////////////////////////////////////////////////////////////////// +#TFtdcPriceTickType是一个最小变动价位类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcPriceTickType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPriceType是一个价格类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcPriceType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRatioType是一个比率类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcRatioType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMoneyType是一个资金类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcMoneyType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcLargeVolumeType是一个大额数量类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcLargeVolumeType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFeeType是一个费用类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcFeeType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInventoryType是一个库存类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcInventoryType"] = "float" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSequenceNoType是一个序列号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcSequenceNoType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMillisecType是一个最后修改毫秒类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcMillisecType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVolumeType是一个数量类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcVolumeType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUnderlyingMultipleType是一个合约乘数类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcUnderlyingMultipleType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVolumeMultipleType是一个数量乘数类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcVolumeMultipleType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSequenceSeriesType是一个序列系列号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcSequenceSeriesType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSessionIDType是一个会话编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcSessionIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcErrorIDType是一个错误代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcErrorIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDataCenterIDType是一个数据中心代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcDataCenterIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFrontIDType是一个前置编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcFrontIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcRequestIDType是一个报单编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcRequestIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTopicIDType是一个主题代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTopicIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSettlementIDType是一个结算编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcSettlementIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTotalNumsType是一个累加次数类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTotalNumsType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDiffSndType是一个偏差时间类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcDiffSndType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTIDType是一个交易ID类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTIDType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMonthType是一个月份类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcMonthType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBoolType是一个布尔型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBoolType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcYearType是一个年类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcYearType"] = "int" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMemTableNameType是一个内存表名类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcMemTableNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderSysIDType是一个报单编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcOrderSysIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeIDType是一个成交编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTradeIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserIDType是一个用户代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcUserIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcParticipantIDType是一个会员编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcParticipantIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIPAddressType是一个IP地址类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcIPAddressType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcMacAddressType是一个Mac地址类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcMacAddressType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstrumentNameType是一个合约名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcInstrumentNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBranchIDType是一个营业部代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBranchIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstrumentIDType是一个合约编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcInstrumentIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIdentifiedCardNoType是一个证件号码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcIdentifiedCardNoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIdentifiedCardTypeType是一个证件类型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcIdentifiedCardTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExchangeIDType是一个交易(所)通道类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcExchangeIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcExchangeNameType是一个交易(所)所名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcExchangeNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDateType是一个日期类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcDateType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTimeType是一个时间类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTimeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcClientTypeType是一个客户类型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcClientTypeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcClientNameType是一个客户名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcClientNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcClientIDType是一个客户编码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcClientIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAccountIDType是一个资金帐号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcAccountIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSeatIDType是一个席位号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcSeatIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProductNameType是一个品种名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcProductNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserOrderLocalIDType是一个用户本地报单号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcUserOrderLocalIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderLocalIDType是一个本地报单编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcOrderLocalIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInvestorIDType是一个投资者编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcInvestorIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserNameType是一个用户编码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcUserNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPasswordType是一个密码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcPasswordType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAbstractType是一个消息摘要类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcAbstractType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProductInfoType是一个产品信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcProductInfoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProtocolInfoType是一个协议信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcProtocolInfoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBusinessUnitType是一个业务单元类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBusinessUnitType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradingSystemNameType是一个交易系统名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTradingSystemNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBrokerIDType是一个经纪公司代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBrokerIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCustomType是一个用户自定义域类型类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcCustomType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradingDayType是一个交易日类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTradingDayType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDepartmentType是一个营业部类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcDepartmentType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcGrantFuncSetType是一个授权功能号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcGrantFuncSetType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProductIDType是一个品种编号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcProductIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAccountSeqNoType是一个资金流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcAccountSeqNoType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSettlementGroupIDType是一个结算组代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcSettlementGroupIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankIDType是一个银行代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBankIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankBrchIDType是一个银行分中心代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBankBrchIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankAccountType是一个银行账号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBankAccountType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcNameType是一个名称类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcNameType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradeCodeType是一个业务功能码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcTradeCodeType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcSerialType是一个流水号类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcSerialType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDeviceIDType是一个渠道标志类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcDeviceIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankCodingForFutureType是一个期货公司银行编码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcBankCodingForFutureType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcErrorMsgType是一个错误信息类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcErrorMsgType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcVolumeConditionType是一个成交量类型类型 +#////////////////////////////////////////////////////////////////////// +#任何数量 +defineDict["QDP_FTDC_VC_AV"] = '1' +#最小数量 +defineDict["QDP_FTDC_VC_MV"] = '2' +#全部数量 +defineDict["QDP_FTDC_VC_CV"] = '3' + +typedefDict["TQdpFtdcVolumeConditionType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcForceCloseReasonType是一个强平原因类型 +#////////////////////////////////////////////////////////////////////// +#非强平 +defineDict["QDP_FTDC_FCR_NotForceClose"] = '0' +#资金不足 +defineDict["QDP_FTDC_FCR_LackDeposit"] = '1' +#客户超仓 +defineDict["QDP_FTDC_FCR_ClientOverPositionLimit"] = '2' +#会员超仓 +defineDict["QDP_FTDC_FCR_MemberOverPositionLimit"] = '3' +#持仓非整数倍 +defineDict["QDP_FTDC_FCR_NotMultiple"] = '4' + +typedefDict["TQdpFtdcForceCloseReasonType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcInstrumentStatusType是一个合约交易状态类型 +#////////////////////////////////////////////////////////////////////// +#开盘前 +defineDict["QDP_FTDC_IS_BeforeTrading"] = '0' +#非交易 +defineDict["QDP_FTDC_IS_NoTrading"] = '1' +#连续交易 +defineDict["QDP_FTDC_IS_Continous"] = '2' +#集合竞价报单 +defineDict["QDP_FTDC_IS_AuctionOrdering"] = '3' +#集合竞价价格平衡 +defineDict["QDP_FTDC_IS_AuctionBalance"] = '4' +#集合竞价撮合 +defineDict["QDP_FTDC_IS_AuctionMatch"] = '5' +#收盘 +defineDict["QDP_FTDC_IS_Closed"] = '6' +#金交所交割申报 +defineDict["QDP_FTDC_IS_SGE_Dery_App"] = '7' +#金交所交割申报结束 +defineDict["QDP_FTDC_IS_SGE_Dery_Match"] = '8' +#金交所中立仓申报 +defineDict["QDP_FTDC_IS_SGE_Mid_App"] = '9' +#金交所交割申报撮合 +defineDict["QDP_FTDC_IS_SGE_Mid_Match"] = 'a' +#大商所自动转换报警 +defineDict["QDP_FTDC_IS_DCE_MarketStatusAlarm"] = 'b' + +typedefDict["TQdpFtdcInstrumentStatusType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOffsetFlagType是一个开平标志类型 +#////////////////////////////////////////////////////////////////////// +#开仓 +defineDict["QDP_FTDC_OF_Open"] = '0' +#平仓 +defineDict["QDP_FTDC_OF_Close"] = '1' +#强平 +defineDict["QDP_FTDC_OF_ForceClose"] = '2' +#平今 +defineDict["QDP_FTDC_OF_CloseToday"] = '3' +#平昨 +defineDict["QDP_FTDC_OF_CloseYesterday"] = '4' + +typedefDict["TQdpFtdcOffsetFlagType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderPriceTypeType是一个报单价格条件类型 +#////////////////////////////////////////////////////////////////////// +#任意价 +defineDict["QDP_FTDC_OPT_AnyPrice"] = '1' +#限价 +defineDict["QDP_FTDC_OPT_LimitPrice"] = '2' +#最优价 +defineDict["QDP_FTDC_OPT_BestPrice"] = '3' +#五档价 +defineDict["QDP_FTDC_OPT_FiveLevelPrice"] = '4' + +typedefDict["TQdpFtdcOrderPriceTypeType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderStatusType是一个报单状态类型 +#////////////////////////////////////////////////////////////////////// +#全部成交 +defineDict["QDP_FTDC_OS_AllTraded"] = '0' +#部分成交还在队列中 +defineDict["QDP_FTDC_OS_PartTradedQueueing"] = '1' +#部分成交不在队列中 +defineDict["QDP_FTDC_OS_PartTradedNotQueueing"] = '2' +#未成交还在队列中 +defineDict["QDP_FTDC_OS_NoTradeQueueing"] = '3' +#未成交不在队列中 +defineDict["QDP_FTDC_OS_NoTradeNotQueueing"] = '4' +#撤单 +defineDict["QDP_FTDC_OS_Canceled"] = '5' +#订单已报入交易所未应答 +defineDict["QDP_FTDC_OS_AcceptedNoReply"] = '6' + +typedefDict["TQdpFtdcOrderStatusType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcUserTypeType是一个用户类型类型 +#////////////////////////////////////////////////////////////////////// +#自然人 +defineDict["QDP_FTDC_UT_Person"] = '1' +#理财产品 +defineDict["QDP_FTDC_UT_Product"] = '2' +#期货公司管理员 +defineDict["QDP_FTDC_UT_Manager"] = '3' +#席位 +defineDict["QDP_FTDC_UT_Seat"] = '4' + +typedefDict["TQdpFtdcUserTypeType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTradingRightType是一个交易权限类型 +#////////////////////////////////////////////////////////////////////// +#可以交易 +defineDict["QDP_FTDC_TR_Allow"] = '0' +#只能平仓 +defineDict["QDP_FTDC_TR_CloseOnly"] = '1' +#不能交易 +defineDict["QDP_FTDC_TR_Forbidden"] = '2' + +typedefDict["TQdpFtdcTradingRightType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTimeConditionType是一个有效期类型类型 +#////////////////////////////////////////////////////////////////////// +#立即完成,否则撤销 +defineDict["QDP_FTDC_TC_IOC"] = '1' +#本节有效 +defineDict["QDP_FTDC_TC_GFS"] = '2' +#当日有效 +defineDict["QDP_FTDC_TC_GFD"] = '3' +#指定日期前有效 +defineDict["QDP_FTDC_TC_GTD"] = '4' +#撤销前有效 +defineDict["QDP_FTDC_TC_GTC"] = '5' +#集合竞价有效 +defineDict["QDP_FTDC_TC_GFA"] = '6' + +typedefDict["TQdpFtdcTimeConditionType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOrderSourceType是一个报单来源类型 +#////////////////////////////////////////////////////////////////////// +#来自参与者 +defineDict["QDP_FTDC_OS_Participant"] = '0' +#来自管理员 +defineDict["QDP_FTDC_OS_Administrator"] = '1' + +typedefDict["TQdpFtdcOrderSourceType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcDirectionType是一个买卖方向类型 +#////////////////////////////////////////////////////////////////////// +#买 +defineDict["QDP_FTDC_D_Buy"] = '0' +#卖 +defineDict["QDP_FTDC_D_Sell"] = '1' + +typedefDict["TQdpFtdcDirectionType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCurrencyType是一个币种类型 +#////////////////////////////////////////////////////////////////////// +#人民币 +defineDict["QDP_FTDC_C_RMB"] = '1' +#美元 +defineDict["QDP_FTDC_C_UDOLLAR"] = '2' + +typedefDict["TQdpFtdcCurrencyType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAccountDirectionType是一个出入金方向类型 +#////////////////////////////////////////////////////////////////////// +#入金 +defineDict["QDP_FTDC_AD_In"] = '1' +#出金 +defineDict["QDP_FTDC_AD_Out"] = '2' + +typedefDict["TQdpFtdcAccountDirectionType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcClientHedgeFlagType是一个客户投机套保标志类型 +#////////////////////////////////////////////////////////////////////// +#投机 +defineDict["QDP_FTDC_CHF_Speculation"] = '1' +#套利 +defineDict["QDP_FTDC_CHF_Arbitrage"] = '2' +#套保 +defineDict["QDP_FTDC_CHF_Hedge"] = '3' +#做市商 +defineDict["QDP_FTDC_CHF_MarketMaker"] = '4' + +typedefDict["TQdpFtdcClientHedgeFlagType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcHedgeFlagType是一个投机套保标志类型 +#////////////////////////////////////////////////////////////////////// +#投机 +defineDict["QDP_FTDC_CHF_Speculation"] = '1' +#套利 +defineDict["QDP_FTDC_CHF_Arbitrage"] = '2' +#套保 +defineDict["QDP_FTDC_CHF_Hedge"] = '3' +#做市商 +defineDict["QDP_FTDC_CHF_MarketMaker"] = '4' + +typedefDict["TQdpFtdcHedgeFlagType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcActionFlagType是一个操作标志类型 +#////////////////////////////////////////////////////////////////////// +#删除 +defineDict["QDP_FTDC_AF_Delete"] = '0' +#挂起 +defineDict["QDP_FTDC_AF_Suspend"] = '1' +#激活 +defineDict["QDP_FTDC_AF_Active"] = '2' +#修改 +defineDict["QDP_FTDC_AF_Modify"] = '3' + +typedefDict["TQdpFtdcActionFlagType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPositionTypeType是一个持仓类型类型 +#////////////////////////////////////////////////////////////////////// +#净持仓 +defineDict["QDP_FTDC_PT_Net"] = '1' +#综合持仓 +defineDict["QDP_FTDC_PT_Gross"] = '2' + +typedefDict["TQdpFtdcPositionTypeType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcOptionsTypeType是一个期权类型类型 +#////////////////////////////////////////////////////////////////////// +#非期权 +defineDict["QDP_FTDC_OT_NotOptions"] = '0' +#看涨 +defineDict["QDP_FTDC_OT_CallOptions"] = '1' +#看跌 +defineDict["QDP_FTDC_OT_PutOptions"] = '2' + +typedefDict["TQdpFtdcOptionsTypeType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcIsActiveType是一个是否活跃类型 +#////////////////////////////////////////////////////////////////////// +#不活跃 +defineDict["QDP_FTDC_UIA_NoActive"] = '0' +#活跃 +defineDict["QDP_FTDC_UIA_Active"] = '1' + +typedefDict["TQdpFtdcIsActiveType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcProductClassType是一个产品类型类型 +#////////////////////////////////////////////////////////////////////// +#期货 +defineDict["QDP_FTDC_PC_Futures"] = '1' +#期权 +defineDict["QDP_FTDC_PC_Options"] = '2' +#组合 +defineDict["QDP_FTDC_PC_Combination"] = '3' +#即期 +defineDict["QDP_FTDC_PC_Spot"] = '4' +#期转现 +defineDict["QDP_FTDC_PC_EFP"] = '5' +#未知类型 +defineDict["QDP_FTDC_PC_Unknown"] = '6' +#证券 +defineDict["QDP_FTDC_PC_Stocks"] = '7' +#股票期权 +defineDict["QDP_FTDC_PC_StockOptions"] = '8' +#金交所现货 +defineDict["QDP_FTDC_PC_SGE_SPOT"] = '9' +#金交所递延 +defineDict["QDP_FTDC_PC_SGE_DEFER"] = 'a' +#金交所远期 +defineDict["QDP_FTDC_PC_SGE_FOWARD"] = 'b' + +typedefDict["TQdpFtdcProductClassType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcCurrencyIDType是一个币种代码类型 +#////////////////////////////////////////////////////////////////////// +typedefDict["TQdpFtdcCurrencyIDType"] = "string" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBusinessTypeType是一个业务类别类型 +#////////////////////////////////////////////////////////////////////// +#普通 +defineDict["QDP_FTDC_BT_Normal"] = '1' +#撤单 +defineDict["QDP_FTDC_BT_Cancel"] = '2' +#ETF申赎 +defineDict["QDP_FTDC_BT_AppliedForRedeemed"] = '3' +#最优五档即时成交剩余撤销 +defineDict["QDP_FTDC_BT_FiveLevelIOC"] = '4' +#最优五档即时成交剩余转限价 +defineDict["QDP_FTDC_BT_FiveLevelGFD"] = '5' +#即时成交剩余撤销 +defineDict["QDP_FTDC_BT_BestPriceIOC"] = '6' +#全额成交或撤销 +defineDict["QDP_FTDC_BT_FOK"] = '7' +#本方最优价格 +defineDict["QDP_FTDC_BT_SelfGFD"] = '8' +#对方最优价格 +defineDict["QDP_FTDC_BT_CpGFD"] = '9' +#金交所中立仓申报 +defineDict["QDP_FTDC_BT_SGEMidApp"] = 'a' +#套利组合单 +defineDict["QDP_FTDC_BT_Combination"] = 'b' +#套利非组合单 +defineDict["QDP_FTDC_BT_Grab"] = 'c' +#金交所递延交割申报 +defineDict["QDP_FTDC_BT_SGEDeferDeliApp"] = 'd' + +typedefDict["TQdpFtdcBusinessTypeType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcTransferStatusType是一个转账交易状态类型 +#////////////////////////////////////////////////////////////////////// +#正常 +defineDict["QDP_FTDC_TS_TRFS_Normal"] = '0' +#被冲正 +defineDict["QDP_FTDC_TS_TRFS_Repealed"] = '1' + +typedefDict["TQdpFtdcTransferStatusType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcFeePayFlagType是一个费用支付标志类型 +#////////////////////////////////////////////////////////////////////// +#由受益方支付费用 +defineDict["QDP_FTDC_FPF_FPF_BEN"] = '0' +#由发送方支付费用 +defineDict["QDP_FTDC_FPF_FPF_OUR"] = '1' +#由发送方支付发起的费用,受益方支付接受的费用 +defineDict["QDP_FTDC_FPF_FPF_SHA"] = '2' + +typedefDict["TQdpFtdcFeePayFlagType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPwdFlagType是一个密码标志类型 +#////////////////////////////////////////////////////////////////////// +#不核对 +defineDict["QDP_FTDC_PF_BPWDF_NoCheck"] = '0' +#明文核对 +defineDict["QDP_FTDC_PF_BPWDF_BlankCheck"] = '1' +#密文核对 +defineDict["QDP_FTDC_PF_BPWDF_EncryptCheck"] = '2' + +typedefDict["TQdpFtdcPwdFlagType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcBankAccTypeType是一个银行账号类型类型 +#////////////////////////////////////////////////////////////////////// +#存折 +defineDict["QDP_FTDC_BAT_VBAT_BankBook"] = '1' +#储蓄卡 +defineDict["QDP_FTDC_BAT_VBAT_BankCard"] = '2' +#信用卡 +defineDict["QDP_FTDC_BAT_VBAT_CreditCard"] = '3' + +typedefDict["TQdpFtdcBankAccTypeType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcYesNoIndicatorType是一个是否标志类型 +#////////////////////////////////////////////////////////////////////// +#是 +defineDict["QDP_FTDC_YNI_YNI_Yes"] = '0' +#否 +defineDict["QDP_FTDC_YNI_YNI_No"] = '1' + +typedefDict["TQdpFtdcYesNoIndicatorType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcAvailabilityFlagType是一个有效标志类型 +#////////////////////////////////////////////////////////////////////// +#未确认 +defineDict["QDP_FTDC_ALF_AVAF_Invalid"] = '0' +#有效 +defineDict["QDP_FTDC_ALF_AVAF_Valid"] = '1' +#冲正 +defineDict["QDP_FTDC_ALF_AVAF_Repeal"] = '2' +#失败 +defineDict["QDP_FTDC_ALF_AVAF_FAIL"] = '3' + +typedefDict["TQdpFtdcAvailabilityFlagType"] = "char" + +#////////////////////////////////////////////////////////////////////// +#TFtdcPayDirectionType是一个金交所递延支付方向类型 +#////////////////////////////////////////////////////////////////////// +#多付空 +defineDict["QDP_FTDC_PD_Buy"] = '0' +#空付多 +defineDict["QDP_FTDC_PD_Sell"] = '1' +#支付方向未定 +defineDict["QDP_FTDC_PD_Unknown"] = '2' + +typedefDict["TQdpFtdcPayDirectionType"] = "char" + diff --git a/vn.trader/qdpGateway/qdpGateway.py b/vn.trader/qdpGateway/qdpGateway.py new file mode 100644 index 00000000..c5b22ab3 --- /dev/null +++ b/vn.trader/qdpGateway/qdpGateway.py @@ -0,0 +1,1146 @@ +# encoding: UTF-8 + +''' +vn.qdp的gateway接入 + +考虑到现阶段大部分QDP中的ExchangeID字段返回的都是空值 +vtSymbol直接使用symbol +''' + + +import os +import json +import datetime +from copy import copy + +from vnqdpmd import MdApi +from vnqdptd import TdApi +from qdpDataType import * +from vtGateway import * + + +# 以下为一些VT类型和QDP类型的映射字典 +# 价格类型映射 +priceTypeMap = {} +priceTypeMap[PRICETYPE_LIMITPRICE] = defineDict["QDP_FTDC_OPT_LimitPrice"] +priceTypeMap[PRICETYPE_MARKETPRICE] = defineDict["QDP_FTDC_OPT_AnyPrice"] +priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()} + +# 方向类型映射 +directionMap = {} +directionMap[DIRECTION_LONG] = defineDict['QDP_FTDC_D_Buy'] +directionMap[DIRECTION_SHORT] = defineDict['QDP_FTDC_D_Sell'] +directionMapReverse = {v: k for k, v in directionMap.items()} + +# 开平类型映射 +offsetMap = {} +offsetMap[OFFSET_OPEN] = defineDict['QDP_FTDC_OF_Open'] +offsetMap[OFFSET_CLOSE] = defineDict['QDP_FTDC_OF_Close'] +offsetMap[OFFSET_CLOSETODAY] = defineDict['QDP_FTDC_OF_CloseToday'] +offsetMap[OFFSET_CLOSEYESTERDAY] = defineDict['QDP_FTDC_OF_CloseYesterday'] +offsetMapReverse = {v:k for k,v in offsetMap.items()} + +# 交易所类型映射 +exchangeMap = {} +#exchangeMap[EXCHANGE_CFFEX] = defineDict['QDP_FTDC_EIDT_CFFEX'] +#exchangeMap[EXCHANGE_SHFE] = defineDict['QDP_FTDC_EIDT_SHFE'] +#exchangeMap[EXCHANGE_CZCE] = defineDict['QDP_FTDC_EIDT_CZCE'] +#exchangeMap[EXCHANGE_DCE] = defineDict['QDP_FTDC_EIDT_DCE'] +exchangeMap[EXCHANGE_CFFEX] = 'CFFEX' +exchangeMap[EXCHANGE_SHFE] = 'SHFE' +exchangeMap[EXCHANGE_CZCE] = 'CZCE' +exchangeMap[EXCHANGE_DCE] = 'DCE' +exchangeMap[EXCHANGE_SGE] = 'SGE' +exchangeMap[EXCHANGE_UNKNOWN] = '' +exchangeMapReverse = {v:k for k,v in exchangeMap.items()} + +# 持仓类型映射 +posiDirectionMap = {} +posiDirectionMap[DIRECTION_NET] = defineDict["QDP_FTDC_PT_Net"] +posiDirectionMap[DIRECTION_LONG] = defineDict["QDP_FTDC_PT_Gross"] +#posiDirectionMap[DIRECTION_SHORT] = defineDict["QDP_FTDC_PD_Short"] +posiDirectionMapReverse = {v:k for k,v in posiDirectionMap.items()} + + +######################################################################## +class QdpGateway(VtGateway): + """QDP接口""" + + #---------------------------------------------------------------------- + def __init__(self, eventEngine, gatewayName='QDP'): + """Constructor""" + super(QdpGateway, self).__init__(eventEngine, gatewayName) + + self.mdApi = QdpMdApi(self) # 行情API + self.tdApi = QdpTdApi(self) # 交易API + + self.mdConnected = False # 行情API连接状态,登录完成后为True + self.tdConnected = False # 交易API连接状态 + + self.qryEnabled = False # 是否要启动循环查询 + + self.date = None # 结算确认日期 + + #---------------------------------------------------------------------- + def connect(self, fileName=""): + """连接""" + # 载入json文件 + if fileName == "": + fileName = self.gatewayName + '_connect.json' + fileName = os.getcwd() + '/qdpGateway/' + fileName + + try: + f = file(fileName) + except IOError: + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'读取连接配置出错,请检查' + self.onLog(log) + return + + # 解析json文件 + setting = json.load(f) + try: + userID = str(setting['userID']) + password = str(setting['password']) + brokerID = str(setting['brokerID']) + tdAddress = str(setting['tdAddress']) + mdAddress = str(setting['mdAddress']) + except KeyError: + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'连接配置缺少字段,请检查' + self.onLog(log) + return + + # 创建行情和交易接口对象 + self.mdApi.connect(userID, password, brokerID, mdAddress) + self.tdApi.connect(userID, password, brokerID, tdAddress) + # 初始化并启动查询 + self.initQuery() + + self.date=datetime.datetime.now().date() + if datetime.datetime.now().hour <= 20: + self.date = self.date - datetime.timedelta(days=1) + + #---------------------------------------------------------------------- + def subscribe(self, subscribeReq): + """订阅行情""" + self.mdApi.subscribe(subscribeReq) + + #---------------------------------------------------------------------- + def sendOrder(self, orderReq): + """发单""" + return self.tdApi.sendOrder(orderReq) + + #---------------------------------------------------------------------- + def confSettle(self): + """确认结算单""" + pass + + #---------------------------------------------------------------------- + def cancelOrder(self, cancelOrderReq): + """撤单""" + self.tdApi.cancelOrder(cancelOrderReq) + + #---------------------------------------------------------------------- + def qryAccount(self): + """查询账户资金""" + self.tdApi.qryAccount() + + #---------------------------------------------------------------------- + def qryPosition(self): + """查询持仓""" + self.tdApi.qryPosition() + + #---------------------------------------------------------------------- + def qryMarginRate(self,vtSymbol): + """查询保证金率""" + pass + + #---------------------------------------------------------------------- + def qryCommissionRate(self,vtSymbol): + """查询手续费率""" + pass + + #---------------------------------------------------------------------- + def close(self): + """关闭""" + if self.mdConnected: + self.mdApi.close() + if self.tdConnected: + self.tdApi.close() + + #---------------------------------------------------------------------- + def initQuery(self): + """初始化连续查询""" + if self.qryEnabled: + # 需要循环的查询函数列表 + self.qryFunctionList = [self.qryAccount, self.qryPosition] + + self.qryCount = 0 # 查询触发倒计时 + self.qryTrigger = 2 # 查询触发点 + self.qryNextFunction = 0 # 上次运行的查询函数索引 + + self.startQuery() + + #---------------------------------------------------------------------- + def query(self, event): + """注册到事件处理引擎上的查询函数""" + self.qryCount += 1 + + if self.qryCount > self.qryTrigger: + # 清空倒计时 + self.qryCount = 0 + + # 执行查询函数 + function = self.qryFunctionList[self.qryNextFunction] + function() + + # 计算下次查询函数的索引,如果超过了列表长度,则重新设为0 + self.qryNextFunction += 1 + if self.qryNextFunction == len(self.qryFunctionList): + self.qryNextFunction = 0 + + #---------------------------------------------------------------------- + def startQuery(self): + """启动连续查询""" + self.eventEngine.register(EVENT_TIMER, self.query) + + #---------------------------------------------------------------------- + def setQryEnabled(self, qryEnabled): + """设置是否要启动循环查询""" + self.qryEnabled = qryEnabled + + + +######################################################################## +class QdpMdApi(MdApi): + """QDP行情API实现""" + + #---------------------------------------------------------------------- + def __init__(self, gateway): + """Constructor""" + super(QdpMdApi, self).__init__() + + self.gateway = gateway # gateway对象 + self.gatewayName = gateway.gatewayName # gateway对象名称 + + self.reqID = EMPTY_INT # 操作请求编号 + + self.connectionStatus = False # 连接状态 + self.loginStatus = False # 登录状态 + + self.subscribedSymbols = set() # 已订阅合约代码 + + self.userID = EMPTY_STRING # 账号 + self.password = EMPTY_STRING # 密码 + self.brokerID = EMPTY_STRING # 经纪商代码 + self.address = EMPTY_STRING # 服务器地址 + + #---------------------------------------------------------------------- + def onFrontConnected(self): + """服务器连接""" + self.connectionStatus = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器连接成功' + self.gateway.onLog(log) + self.login() + + #---------------------------------------------------------------------- + def onFrontDisconnected(self, n): + """服务器断开""" + self.connectionStatus = False + self.loginStatus = False + self.gateway.mdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器连接断开' + self.gateway.onLog(log) + + #---------------------------------------------------------------------- + def onHeartBeatWarning(self, n): + """心跳报警""" + # 因为API的心跳报警比较常被触发,且与API工作关系不大,因此选择忽略 + pass + + #---------------------------------------------------------------------- + def onRspError(self, error, n, last): + """错误回报""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 错误回报' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogin(self, data, error, n, last): + """登陆回报""" + # 如果登录成功,推送日志信息 + if error['ErrorID'] == 0: + self.loginStatus = True + self.gateway.mdConnected = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器登录完成' + self.gateway.onLog(log) + + # 重新订阅之前订阅的合约 + for subscribeReq in self.subscribedSymbols: + self.subscribe(subscribeReq) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 行情登录错误' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogout(self, data, error, n, last): + """登出回报""" + # 如果登出成功,推送日志信息 + if error['ErrorID'] == 0: + self.loginStatus = False + self.gateway.mdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'行情服务器登出完成' + self.gateway.onLog(log) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 行情登出错误' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspSubMarketData(self, data, error, n, last): + """订阅合约回报""" + # 通常不在乎订阅错误,选择忽略 + pass + + #---------------------------------------------------------------------- + def onRspUnSubMarketData(self, data, error, n, last): + """退订合约回报""" + # 同上 + pass + + #---------------------------------------------------------------------- + def onRtnDepthMarketData(self, data): + """行情推送""" + tick = VtTickData() + tick.gatewayName = self.gatewayName + + tick.symbol = data['InstrumentID'] + tick.exchange = exchangeMapReverse.get(data['ExchangeID'], u'未知') + tick.vtSymbol = tick.symbol #'.'.join([tick.symbol, EXCHANGE_UNKNOWN]) + + tick.lastPrice = data['LastPrice'] + tick.volume = data['Volume'] + tick.openInterest = data['OpenInterest'] + tick.time = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)]) + tick.date = data['TradingDay'] + + tick.openPrice = data['OpenPrice'] + tick.highPrice = data['HighestPrice'] + tick.lowPrice = data['LowestPrice'] + tick.preClosePrice = data['PreClosePrice'] + + tick.upperLimit = data['UpperLimitPrice'] + tick.lowerLimit = data['LowerLimitPrice'] + + # QDP只有一档行情 + tick.bidPrice1 = data['BidPrice1'] + tick.bidVolume1 = data['BidVolume1'] + tick.askPrice1 = data['AskPrice1'] + tick.askVolume1 = data['AskVolume1'] + + self.gateway.onTick(tick) + + #---------------------------------------------------------------------- + def connect(self, userID, password, brokerID, address): + """初始化连接""" + self.userID = userID # 账号 + self.password = password # 密码 + self.brokerID = brokerID # 经纪商代码 + self.address = address # 服务器地址 + + # 如果尚未建立服务器连接,则进行连接 + if not self.connectionStatus: + # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 + path = os.getcwd() + '/temp/' + self.gatewayName + '/md/' + if not os.path.exists(path): + os.makedirs(path) + self.createFtdcMdApi(path) + + # 注册服务器地址 + self.registerFront(self.address) + + # 初始化连接,成功会调用onFrontConnected + self.init() + + # 若已经连接但尚未登录,则进行登录 + else: + if not self.loginStatus: + self.login() + + #---------------------------------------------------------------------- + def subscribe(self, subscribeReq): + """订阅合约""" + # 这里的设计是,如果尚未登录就调用了订阅方法 + # 则先保存订阅请求,登录完成后会自动订阅 + if self.loginStatus: + self.subscribeMarketData(str(subscribeReq.symbol)) + self.subscribedSymbols.add(subscribeReq) + + #---------------------------------------------------------------------- + def login(self): + """登录""" + # 如果填入了用户名密码等,则登录 + if self.userID and self.password and self.brokerID: + req = {} + req['UserID'] = self.userID + req['Password'] = self.password + req['BrokerID'] = self.brokerID + self.reqID += 1 + self.reqUserLogin(req, self.reqID) + + #---------------------------------------------------------------------- + def logout(self): + """登录""" + # 如果填入了用户名密码等,则登录 + if self.userID and self.brokerID: + req = {} + req['UserID'] = self.userID + req['BrokerID'] = self.brokerID + self.reqID += 1 + self.reqUserLogout(req, self.reqID) + + #---------------------------------------------------------------------- + def close(self): + """关闭""" + self.logout() + self.exit() + + +######################################################################## +class QdpTdApi(TdApi): + """QDP交易API实现""" + + #---------------------------------------------------------------------- + def __init__(self, gateway): + """API对象的初始化函数""" + super(QdpTdApi, self).__init__() + + self.gateway = gateway # gateway对象 + self.gatewayName = gateway.gatewayName # gateway对象名称 + + self.reqID = EMPTY_INT # 操作请求编号 + self.orderRef = 930000 # 订单编号 + + self.connectionStatus = False # 连接状态 + self.loginStatus = False # 登录状态 + + self.userID = EMPTY_STRING # 账号 + self.investorID = EMPTY_STRING # 投资账号 + self.password = EMPTY_STRING # 密码 + self.brokerID = EMPTY_STRING # 经纪商代码 + self.address = EMPTY_STRING # 服务器地址 + + self.frontID = EMPTY_INT # 前置机编号 + self.sessionID = EMPTY_INT # 会话编号 + + self.posBufferDict = {} # 缓存持仓数据的字典 + + #---------------------------------------------------------------------- + def onFrontConnected(self): + """服务器连接""" + self.connectionStatus = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器连接成功' + self.gateway.onLog(log) + + self.login() + + #---------------------------------------------------------------------- + def onFrontDisconnected(self, n): + """服务器断开""" + self.connectionStatus = False + self.loginStatus = False + self.gateway.tdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器连接断开' + self.gateway.onLog(log) + + #---------------------------------------------------------------------- + def onHeartBeatWarning(self, n): + """""" + pass + + #---------------------------------------------------------------------- + def confSettle(self): + """""" + pass + + #---------------------------------------------------------------------- + def onRspUserLogin(self, data, error, n, last): + """登陆回报""" + # 如果登录成功,推送日志信息 + if error['ErrorID'] == 0: + self.frontID = str(data['FrontID']) + self.sessionID = str(data['SessionID']) + self.loginStatus = True + self.gateway.tdConnected = True + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器登录完成' + self.gateway.onLog(log) + + # 获取investorID + self.reqID += 1 + req = {} + req['UserID'] = self.userID + req['Password'] = self.password + req['BrokerID'] = self.brokerID + self.reqQryUserInvestor(req,self.reqID) + + + # 查询合约代码 + self.reqID += 1 + self.reqQryInstrument({}, self.reqID) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 交易登录错误' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserLogout(self, data, error, n, last): + """登出回报""" + # 如果登出成功,推送日志信息 + if error['ErrorID'] == 0: + self.loginStatus = False + self.gateway.tdConnected = False + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易服务器登出完成' + self.gateway.onLog(log) + + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 交易登出错误' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspQryUserInvestor(self, data, error, n, last): + """查询投资账户回报""" + # 如果查询成功,推送日志信息 + if error['ErrorID'] == 0: + self.investorID = data['InvestorID'] + + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'投资者查询完成' + self.gateway.onLog(log) + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 投资者查询错误' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspUserPasswordUpdate(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspOrderInsert(self, data, error, n, last): + """发单回报(柜台)""" + if error['ErrorID'] == 0: + return + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 发单错误(柜台)' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspOrderAction(self, data, error, n, last): + """撤单回报(柜台)""" + if error['ErrorID'] == 0: + return + # 否则,推送错误信息 + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 撤单错误(柜台)' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRspQryOrder(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryTrade(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryInvestorPosition(self, data, error, n, last): + """持仓查询回报""" + # 获取缓存字典中的持仓缓存,若无则创建并初始化 + positionName = '.'.join([data['InstrumentID'], data['Direction']]) + + if positionName in self.posBufferDict: + posBuffer = self.posBufferDict[positionName] + else: + posBuffer = PositionBuffer(data, self.gatewayName) + self.posBufferDict[positionName] = posBuffer + + # 更新持仓缓存,并获取VT系统中持仓对象的返回值 + pos = posBuffer.updateBuffer(data) + self.gateway.onPosition(pos) + + #---------------------------------------------------------------------- + def onRspQryInvestorAccount(self, data, error, n, last): + """资金账户查询回报""" + account = VtAccountData() + account.gatewayName = self.gatewayName + + # 账户代码 + account.accountID = data['AccountID'] + account.vtAccountID = '.'.join([self.gatewayName, account.accountID]) + + # 数值相关 + account.preBalance = data['PreBalance'] + account.available = data['Available'] + account.commission = data['Commission'] + account.margin = data['CurrMargin'] + account.closeProfit = data['CloseProfit'] + account.positionProfit = data['PositionProfit'] + + # 这里的balance和快期中的账户不确定是否一样,需要测试 + account.balance = (data['PreBalance'] - data['PreCredit'] - data['PreMortgage'] + + data['Mortgage'] - data['Withdraw'] + data['Deposit'] + + data['CloseProfit'] + data['PositionProfit'] + data['CashIn'] - + data['Commission']) + + # 推送 + self.gateway.onAccount(account) + + #---------------------------------------------------------------------- + def onRspQryInvestor(self, data, error, n, last): + """投资者查询回报""" + pass + + #---------------------------------------------------------------------- + def onRspQryExchange(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryInstrument(self, data, error, n, last): + """合约查询回报""" + contract = VtContractData() + contract.gatewayName = self.gatewayName + + contract.symbol = data['InstrumentID'] + contract.exchange = exchangeMapReverse[data['ExchangeID']] + contract.vtSymbol = contract.symbol #'.'.join([contract.symbol, contract.exchange]) + contract.name = data['InstrumentName'].decode('GBK') + + # 合约数值 + contract.size = data['VolumeMultiple'] + contract.priceTick = data['PriceTick'] + contract.strikePrice = data['StrikePrice'] + contract.underlyingSymbol = data['UnderlyingInstrID'] + + # 合约类型 + contract.productClass = PRODUCT_FUTURES + #if data['ProductClass'] == '1': + # contract.productClass = PRODUCT_FUTURES + #elif data['ProductClass'] == '2': + # contract.productClass = PRODUCT_OPTION + #elif data['ProductClass'] == '3': + # contract.productClass = PRODUCT_COMBINATION + #else: + # contract.productClass = PRODUCT_UNKNOWN + + # 期权类型 + if data['OptionsType'] == '1': + contract.optionType = OPTION_CALL + elif data['OptionsType'] == '2': + contract.optionType = OPTION_PUT + + # 推送 + self.gateway.onContract(contract) + + if last: + log = VtLogData() + log.gatewayName = self.gatewayName + log.logContent = u'交易合约信息获取完成' + self.gateway.onLog(log) + + #---------------------------------------------------------------------- + def onRspQryMarketData(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryTransferBank(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspError(self, error, n, last): + """错误回报""" + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u'错误回报(交易)' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRtnOrder(self, data): + """报单回报""" + # 更新最大报单编号 + newref = data['UserOrderLocalID'] + if not newref == '': + self.orderRef = max(self.orderRef, int(newref)) + + # 创建报单数据对象 + order = VtOrderData() + order.gatewayName = self.gatewayName + + # 保存代码和报单号 + order.symbol = data['InstrumentID'] + order.exchange = exchangeMapReverse[data['ExchangeID']] + order.vtSymbol = order.symbol #'.'.join([order.symbol, order.exchange]) + + order.orderID = data['UserOrderLocalID'] + + # 方向 + if data['Direction'] == '0': + order.direction = DIRECTION_LONG + elif data['Direction'] == '1': + order.direction = DIRECTION_SHORT + else: + order.direction = DIRECTION_UNKNOWN + + # 开平 + if data['OffsetFlag'] == '0': + order.offset = OFFSET_OPEN + elif data['OffsetFlag'] == '1': + order.offset = OFFSET_CLOSE + elif data['OffsetFlag'] == '3': + order.offset = OFFSET_CLOSETODAY + else: + order.offset = OFFSET_UNKNOWN + + # 状态 + if data['OrderStatus'] == '0': + order.status = STATUS_ALLTRADED + elif data['OrderStatus'] == '1': + order.status = STATUS_PARTTRADED + elif data['OrderStatus'] == '2': + order.status = STATUS_PARTTRADED_PARTCANCELED + elif data['OrderStatus'] == '3': + order.status = STATUS_NOTTRADED + elif data['OrderStatus'] == '5': + order.status = STATUS_CANCELLED + else: + order.status = STATUS_UNKNOWN + + # 价格、报单量等数值 + order.price = data['LimitPrice'] + order.totalVolume = data['Volume'] + order.tradedVolume = data['VolumeTraded'] + order.orderTime = data['InsertTime'] + order.cancelTime = data['CancelTime'] + order.frontID = data['FrontID'] + order.sessionID = data['SessionID'] + + # QDP的报单号一致性维护需要基于frontID, sessionID, orderID三个字段 + # 但在本接口设计中,已经考虑了QDP的OrderRef的自增性,避免重复 + # 唯一可能出现OrderRef重复的情况是多处登录并在非常接近的时间内(几乎同时发单) + # 考虑到VtTrader的应用场景,认为以上情况不会构成问题 + order.vtOrderID = '.'.join([self.gatewayName, order.orderID]) + + # 推送 + self.gateway.onOrder(order) + + #---------------------------------------------------------------------- + def onRtnTrade(self, data): + """成交回报""" + # 创建报单数据对象 + trade = VtTradeData() + trade.gatewayName = self.gatewayName + + # 保存代码和报单号 + trade.symbol = data['InstrumentID'] + trade.exchange = exchangeMapReverse[data['ExchangeID']] + trade.vtSymbol = trade.symbol #'.'.join([trade.symbol, trade.exchange]) + + trade.tradeID = data['TradeID'] + trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID]) + + trade.orderID = data['UserOrderLocalID'] + trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID]) + + # 方向 + trade.direction = directionMapReverse.get(data['Direction'], '') + + # 开平 + trade.offset = offsetMapReverse.get(data['OffsetFlag'], '') + + # 价格、报单量等数值 + trade.price = data['TradePrice'] + trade.volume = data['TradeVolume'] + trade.tradeTime = data['TradeTime'] + + # 推送 + self.gateway.onTrade(trade) + + #---------------------------------------------------------------------- + def onErrRtnOrderInsert(self, data, error): + """发单错误回报(交易所)""" + if error['ErrorID'] == 0: + return + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 发单错误(交易所)' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onErrRtnOrderAction(self, data, error): + """撤单错误回报(交易所)""" + if error['ErrorID'] == 0: + return + else: + err = VtErrorData() + err.gatewayName = self.gatewayName + err.errorID = error['ErrorID'] + err.errorMsg = error['ErrorMsg'].decode('gbk') + err.additionalInfo = str(datetime.datetime.now()) + u' 撤单错误(交易所)' # 补充信息 + self.gateway.onError(err) + + #---------------------------------------------------------------------- + def onRtnInstrumentStatus(self, data): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQryContractBank(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRtnFromBankToFutureByBank(self, data): + """""" + pass + + #---------------------------------------------------------------------- + def onRtnFromFutureToBankByBank(self, data): + """""" + pass + + #---------------------------------------------------------------------- + def onRtnFromBankToFutureByFuture(self, data): + """""" + pass + + #---------------------------------------------------------------------- + def onRtnFromFutureToBankByFuture(self, data): + """""" + pass + + #---------------------------------------------------------------------- + def onRtnQueryBankBalanceByFuture(self, data): + """""" + pass + + #---------------------------------------------------------------------- + def onErrRtnBankToFutureByFuture(self, data, error): + """""" + pass + + #---------------------------------------------------------------------- + def onErrRtnFutureToBankByFuture(self, data, error): + """""" + pass + + #---------------------------------------------------------------------- + def onErrRtnQueryBankBalanceByFuture(self, data, error): + """""" + pass + + #---------------------------------------------------------------------- + def onRspFromBankToFutureByFuture(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspFromFutureToBankByFuture(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def onRspQueryBankAccountMoneyByFuture(self, data, error, n, last): + """""" + pass + + #---------------------------------------------------------------------- + def connect(self, userID, password, brokerID, address): + """初始化连接""" + self.userID = userID # 账号 + self.password = password # 密码 + self.brokerID = brokerID # 经纪商代码 + self.address = address # 服务器地址 + + # 如果尚未建立服务器连接,则进行连接 + if not self.connectionStatus: + # 创建C++环境中的API对象,这里传入的参数是需要用来保存.con文件的文件夹路径 + path = os.getcwd() + '/temp/' + self.gatewayName + '/td/' + if not os.path.exists(path): + os.makedirs(path) + self.createFtdcTraderApi(path) + + self.subscribePrivateTopic(0) + self.subscribePublicTopic(2) + + # 注册服务器地址 + self.registerFront(self.address) + + # 初始化连接,成功会调用onFrontConnected + self.init() + + # 若已经连接但尚未登录,则进行登录 + else: + if not self.loginStatus: + self.login() + + #---------------------------------------------------------------------- + def login(self): + """连接服务器""" + # 如果填入了用户名密码等,则登录 + if self.userID and self.password and self.brokerID: + req = {} + req['UserID'] = self.userID + req['Password'] = self.password + req['BrokerID'] = self.brokerID + self.reqID += 1 + self.reqUserLogin(req, self.reqID) + + #---------------------------------------------------------------------- + def logout(self): + """连接服务器""" + # 如果填入了用户名密码等,则登录 + if self.userID and self.brokerID: + req = {} + req['UserID'] = self.userID + req['BrokerID'] = self.brokerID + self.reqID += 1 + self.reqUserLogout(req, self.reqID) + + #---------------------------------------------------------------------- + def qryAccount(self): + """查询账户""" + self.reqID += 1 + self.reqQryInvestorAccount({}, self.reqID) + + #---------------------------------------------------------------------- + def qryPosition(self): + """查询持仓""" + self.reqID += 1 + req = {} + req['BrokerID'] = self.brokerID + req['InvestorID'] = self.investorID + self.reqQryInvestorPosition(req, self.reqID) + + #---------------------------------------------------------------------- + def sendOrder(self, orderReq): + """发单""" + self.reqID += 1 + self.orderRef += 1 + + req = {} + + req['InstrumentID'] = orderReq.symbol + req['LimitPrice'] = orderReq.price + req['Volume'] = orderReq.volume + req['ExchangeID'] = str(orderReq.exchange) + + # 下面如果由于传入的类型本接口不支持,则会返回空字符串 + req['OrderPriceType'] = priceTypeMap.get(orderReq.priceType, '') + req['Direction'] = directionMap.get(orderReq.direction, '') + req['OffsetFlag'] = offsetMap.get(orderReq.offset, '') + + req['UserOrderLocalID'] = str(self.orderRef) + req['InvestorID'] = self.investorID + req['UserID'] = self.userID + req['InvestorID'] = self.investorID + req['BrokerID'] = self.brokerID + req['HedgeFlag'] = defineDict['QDP_FTDC_CHF_Speculation'] # 投机单 + req['ForceCloseReason'] = defineDict['QDP_FTDC_FCR_NotForceClose'] # 非强平 + req['IsAutoSuspend'] = 0 # 非自动挂起 + req['TimeCondition'] = defineDict['QDP_FTDC_TC_GFD'] # 今日有效 + req['VolumeCondition'] = defineDict['QDP_FTDC_VC_AV'] # 任意成交量 + req['MinVolume'] = 1 # 最小成交量为1 + + # 判断FAK和FOK + if orderReq.priceType == PRICETYPE_FAK: + req['OrderPriceType'] = defineDict["QDP_FTDC_OPT_LimitPrice"] + req['TimeCondition'] = defineDict['QDP_FTDC_TC_IOC'] + req['VolumeCondition'] = defineDict['QDP_FTDC_VC_AV'] + if orderReq.priceType == PRICETYPE_FOK: + req['OrderPriceType'] = defineDict["QDP_FTDC_OPT_LimitPrice"] + req['TimeCondition'] = defineDict['QDP_FTDC_TC_IOC'] + req['VolumeCondition'] = defineDict['QDP_FTDC_VC_CV'] + + self.reqOrderInsert(req, self.reqID) + + # 返回订单号(字符串),便于某些算法进行动态管理 + vtOrderID = '.'.join([self.gatewayName, str(self.orderRef)]) + return vtOrderID + + #---------------------------------------------------------------------- + def cancelOrder(self, cancelOrderReq): + """撤单""" + self.reqID += 1 + self.orderRef += 1 + + req = {} + + req['InstrumentID'] = cancelOrderReq.symbol + req['ExchangeID'] = cancelOrderReq.exchange + req['UserOrderLocalID'] = cancelOrderReq.orderID + req['UserOrderActionLocalID'] = str(self.orderRef) + req['FrontID'] = cancelOrderReq.frontID + req['SessionID'] = cancelOrderReq.sessionID + + req['ActionFlag'] = defineDict['QDP_FTDC_AF_Delete'] + req['BrokerID'] = self.brokerID + req['InvestorID'] = self.investorID + req['UserID'] = self.userID + + self.reqOrderAction(req, self.reqID) + + #---------------------------------------------------------------------- + def close(self): + """关闭""" + self.logout() + self.exit() + + +######################################################################## +class PositionBuffer(object): + """用来缓存持仓的数据,处理上期所的数据返回分今昨的问题""" + + #---------------------------------------------------------------------- + def __init__(self, data, gatewayName): + """Constructor""" + self.symbol = data['InstrumentID'] + self.direction = posiDirectionMapReverse.get(data['Direction'], '') + + self.todayPosition = EMPTY_INT + self.ydPosition = EMPTY_INT + self.todayPositionCost = EMPTY_FLOAT + self.ydPositionCost = EMPTY_FLOAT + + # 通过提前创建持仓数据对象并重复使用的方式来降低开销 + pos = VtPositionData() + pos.symbol = self.symbol + pos.vtSymbol = self.symbol + pos.gatewayName = gatewayName + pos.direction = self.direction + pos.vtPositionName = '.'.join([pos.vtSymbol, pos.direction]) + self.pos = pos + + #---------------------------------------------------------------------- + def updateBuffer(self, data): + """更新缓存,返回更新后的持仓数据""" + # 昨仓和今仓的数据更新是分在两条记录里的,因此需要判断检查该条记录对应仓位 + if data['Position']: + self.todayPosition = data['Position'] - data['YdPosition'] + self.todayPositionCost = data['PositionCost'] + elif data['YdPosition']: + self.ydPosition = data['YdPosition'] + self.ydPositionCost = data['YdPositionCost'] + + # 持仓的昨仓和今仓相加后为总持仓 + self.pos.position = self.todayPosition + self.ydPosition + self.pos.ydPosition = self.ydPosition + + # 如果手头还有持仓,则通过加权平均方式计算持仓均价 + if self.todayPosition or self.ydPosition: + self.pos.price = ((self.todayPositionCost + self.ydPositionCost)/ + (self.todayPosition + self.ydPosition)) + # 否则价格为0 + else: + self.pos.price = 0 + + return copy(self.pos) + +#---------------------------------------------------------------------- +def test(): + """测试""" + from PyQt4 import QtCore + import sys + + def print_log(event): + log = event.dict_['data'] + print ':'.join([log.logTime, log.logContent]) + + app = QtCore.QCoreApplication(sys.argv) + + eventEngine = EventEngine() + eventEngine.register(EVENT_LOG, print_log) + eventEngine.start() + + gateway = QdpGateway(eventEngine) + gateway.connect() + + sys.exit(app.exec_()) + + +if __name__ == '__main__': + test() diff --git a/vn.trader/qdpGateway/qdpmdapi.dll b/vn.trader/qdpGateway/qdpmdapi.dll new file mode 100644 index 00000000..1ff67357 Binary files /dev/null and b/vn.trader/qdpGateway/qdpmdapi.dll differ diff --git a/vn.trader/qdpGateway/qdptraderapi.dll b/vn.trader/qdpGateway/qdptraderapi.dll new file mode 100644 index 00000000..71358c56 Binary files /dev/null and b/vn.trader/qdpGateway/qdptraderapi.dll differ diff --git a/vn.trader/qdpGateway/vnqdpmd.pyd b/vn.trader/qdpGateway/vnqdpmd.pyd new file mode 100644 index 00000000..5327d5aa Binary files /dev/null and b/vn.trader/qdpGateway/vnqdpmd.pyd differ diff --git a/vn.trader/qdpGateway/vnqdptd.pyd b/vn.trader/qdpGateway/vnqdptd.pyd new file mode 100644 index 00000000..b68d8ea0 Binary files /dev/null and b/vn.trader/qdpGateway/vnqdptd.pyd differ