From 1d08252d8cfd7b9e2446e1b527e6dd98ec32f779 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Mon, 9 Oct 2017 19:19:03 +0800 Subject: [PATCH] =?UTF-8?q?[Fix]=E8=A7=A3=E5=86=B3CTP=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=A4=9C=E7=9B=98=E6=97=B6=E9=97=B4=E6=88=B3=E7=9A=84=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E8=8E=B7=E5=8F=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/trader/gateway/ctpGateway/ctpGateway.py | 50 +++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/vnpy/trader/gateway/ctpGateway/ctpGateway.py b/vnpy/trader/gateway/ctpGateway/ctpGateway.py index 67240c04..3eff9846 100644 --- a/vnpy/trader/gateway/ctpGateway/ctpGateway.py +++ b/vnpy/trader/gateway/ctpGateway/ctpGateway.py @@ -11,7 +11,7 @@ vtSymbol直接使用symbol import os import json from copy import copy -from datetime import datetime +from datetime import datetime, timedelta from vnpy.api.ctp import MdApi, TdApi, defineDict from vnpy.trader.vtGateway import * @@ -74,6 +74,12 @@ statusMap[STATUS_NOTTRADED] = defineDict["THOST_FTDC_OST_NoTradeQueueing"] statusMap[STATUS_CANCELLED] = defineDict["THOST_FTDC_OST_Canceled"] statusMapReverse = {v:k for k,v in statusMap.items()} +# 全局字典, key:symbol, value:exchange +symbolExchangeDict = {} + +# 夜盘交易时间段分隔判断 +NIGHT_TRADING = datetime(1900, 1, 1, 20).time() + ######################################################################## class CtpGateway(VtGateway): @@ -214,7 +220,6 @@ class CtpGateway(VtGateway): self.qryEnabled = qryEnabled - ######################################################################## class CtpMdApi(MdApi): """CTP行情API实现""" @@ -239,6 +244,10 @@ class CtpMdApi(MdApi): self.brokerID = EMPTY_STRING # 经纪商代码 self.address = EMPTY_STRING # 服务器地址 + self.tradingDt = None # 交易日datetime对象 + self.tradingDate = EMPTY_STRING # 交易日期字符串 + self.tickTime = None # 最新行情time对象 + #---------------------------------------------------------------------- def onFrontConnected(self): """服务器连接""" @@ -286,6 +295,10 @@ class CtpMdApi(MdApi): for subscribeReq in self.subscribedSymbols: self.subscribe(subscribeReq) + # 获取交易日 + self.tradingDate = data['TradingDay'] + self.tradingDt = datetime.strptime(self.tradingDate, '%Y%m%d') + # 否则,推送错误信息 else: err = VtErrorData() @@ -332,17 +345,16 @@ class CtpMdApi(MdApi): 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.exchange = symbolExchangeDict.get(tick.symbol, EXCHANGE_UNKNOWN) + tick.vtSymbol = tick.symbol #'.'.join([tick.symbol, tick.exchange]) 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.date = datetime.now().strftime('%Y%m%d') + # 上期所和郑商所可以直接使用,大商所需要转换 + tick.date = data['ActionDay'] tick.openPrice = data['OpenPrice'] tick.highPrice = data['HighestPrice'] @@ -358,6 +370,21 @@ class CtpMdApi(MdApi): tick.askPrice1 = data['AskPrice1'] tick.askVolume1 = data['AskVolume1'] + # 大商所日期转换 + if tick.exchange is EXCHANGE_DCE: + newTime = datetime.strptime(tick.time, '%H:%M:%S.%f').time() # 最新tick时间戳 + + # 如果新tick的时间小于夜盘分隔,且上一个tick的时间大于夜盘分隔,则意味着越过了12点 + if (self.tickTime and + newTime < NIGHT_TRADING and + self.tickTime > NIGHT_TRADING): + self.tradingDt += timedelta(1) # 日期加1 + self.tradingDate = self.tradingDt.strftime('%Y%m%d') # 生成新的日期字符串 + + tick.date = self.tradingDate # 使用本地维护的日期 + + self.tickTime = newTime # 更新上一个tick时间 + self.gateway.onTick(tick) #---------------------------------------------------------------------- @@ -816,6 +843,9 @@ class CtpTdApi(TdApi): # 推送 self.gateway.onContract(contract) + + # 缓存合约代码和交易所映射 + symbolExchangeDict[contract.symbol] = contract.exchange if last: self.writeLog(text.CONTRACT_DATA_RECEIVED) @@ -1457,3 +1487,9 @@ class CtpTdApi(TdApi): log.gatewayName = self.gatewayName log.logContent = content self.gateway.onLog(log) + + + + + + \ No newline at end of file