[Fix]解决CTP接口夜盘时间戳的日期获取问题

This commit is contained in:
vn.py 2017-10-09 19:19:03 +08:00
parent 01e0934107
commit 1d08252d8c

View File

@ -11,7 +11,7 @@ vtSymbol直接使用symbol
import os import os
import json import json
from copy import copy from copy import copy
from datetime import datetime from datetime import datetime, timedelta
from vnpy.api.ctp import MdApi, TdApi, defineDict from vnpy.api.ctp import MdApi, TdApi, defineDict
from vnpy.trader.vtGateway import * 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"] statusMap[STATUS_CANCELLED] = defineDict["THOST_FTDC_OST_Canceled"]
statusMapReverse = {v:k for k,v in statusMap.items()} 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): class CtpGateway(VtGateway):
@ -214,7 +220,6 @@ class CtpGateway(VtGateway):
self.qryEnabled = qryEnabled self.qryEnabled = qryEnabled
######################################################################## ########################################################################
class CtpMdApi(MdApi): class CtpMdApi(MdApi):
"""CTP行情API实现""" """CTP行情API实现"""
@ -239,6 +244,10 @@ class CtpMdApi(MdApi):
self.brokerID = EMPTY_STRING # 经纪商代码 self.brokerID = EMPTY_STRING # 经纪商代码
self.address = EMPTY_STRING # 服务器地址 self.address = EMPTY_STRING # 服务器地址
self.tradingDt = None # 交易日datetime对象
self.tradingDate = EMPTY_STRING # 交易日期字符串
self.tickTime = None # 最新行情time对象
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onFrontConnected(self): def onFrontConnected(self):
"""服务器连接""" """服务器连接"""
@ -286,6 +295,10 @@ class CtpMdApi(MdApi):
for subscribeReq in self.subscribedSymbols: for subscribeReq in self.subscribedSymbols:
self.subscribe(subscribeReq) self.subscribe(subscribeReq)
# 获取交易日
self.tradingDate = data['TradingDay']
self.tradingDt = datetime.strptime(self.tradingDate, '%Y%m%d')
# 否则,推送错误信息 # 否则,推送错误信息
else: else:
err = VtErrorData() err = VtErrorData()
@ -332,17 +345,16 @@ class CtpMdApi(MdApi):
tick.gatewayName = self.gatewayName tick.gatewayName = self.gatewayName
tick.symbol = data['InstrumentID'] tick.symbol = data['InstrumentID']
tick.exchange = exchangeMapReverse.get(data['ExchangeID'], u'未知') tick.exchange = symbolExchangeDict.get(tick.symbol, EXCHANGE_UNKNOWN)
tick.vtSymbol = tick.symbol #'.'.join([tick.symbol, EXCHANGE_UNKNOWN]) tick.vtSymbol = tick.symbol #'.'.join([tick.symbol, tick.exchange])
tick.lastPrice = data['LastPrice'] tick.lastPrice = data['LastPrice']
tick.volume = data['Volume'] tick.volume = data['Volume']
tick.openInterest = data['OpenInterest'] tick.openInterest = data['OpenInterest']
tick.time = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)]) tick.time = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)])
# 这里由于交易所夜盘时段的交易日数据有误,所以选择本地获取 # 上期所和郑商所可以直接使用,大商所需要转换
#tick.date = data['TradingDay'] tick.date = data['ActionDay']
tick.date = datetime.now().strftime('%Y%m%d')
tick.openPrice = data['OpenPrice'] tick.openPrice = data['OpenPrice']
tick.highPrice = data['HighestPrice'] tick.highPrice = data['HighestPrice']
@ -358,6 +370,21 @@ class CtpMdApi(MdApi):
tick.askPrice1 = data['AskPrice1'] tick.askPrice1 = data['AskPrice1']
tick.askVolume1 = data['AskVolume1'] 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) self.gateway.onTick(tick)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -817,6 +844,9 @@ class CtpTdApi(TdApi):
# 推送 # 推送
self.gateway.onContract(contract) self.gateway.onContract(contract)
# 缓存合约代码和交易所映射
symbolExchangeDict[contract.symbol] = contract.exchange
if last: if last:
self.writeLog(text.CONTRACT_DATA_RECEIVED) self.writeLog(text.CONTRACT_DATA_RECEIVED)
@ -1457,3 +1487,9 @@ class CtpTdApi(TdApi):
log.gatewayName = self.gatewayName log.gatewayName = self.gatewayName
log.logContent = content log.logContent = content
self.gateway.onLog(log) self.gateway.onLog(log)