VNPY2 中凌晨0點時間戳的處理問題,和夜盤資料時間戳分析

張國平發表於2021-07-16


今天在群裡面,看到有人反映vnpy2中0點0分0秒這一秒的時間戳有問題,如下圖倒序的tick資料,第三條應該是6-29 00:00:00 

這個時間,但是儲存時候,日報變成了2021-06-28日。 WECHAT_EMPTY_TITLE


這個問題在Github的issue 中也有人提了, 提問者也做了分析。

我這邊在重複分析下原因。

tick的資料接受處理實在CtpMdApi這個類中的onRtnDepthMarketData方法,這個是一個被介面呼叫方法,傳入的是叫做data字典格式的tick資料。。

從下面程式碼節段,可以看出,時間戳timestamp是用本地的日期(self.current_date) 和傳入tick data的時間data['UpdateTime'] 和毫秒data['UpdateMillisec']組合出來的。

timestamp: str = f"{self.current_date} {data['UpdateTime']}.{int(data['UpdateMillisec']/100)}"
dt: datetime = datetime.strptime(timestamp, "%Y%m%d %H:%M:%S.%f")
dt = CHINA_TZ.localize(dt)
.....
datetime=dt,


self.current_date這個本地日期資料並不是實時讀取,而且用如下方法更新,這個方法是定時事件處理每秒出發跑一次更新。

為什麼這樣做,因為tick資料可能一秒有多少不同品種tick的傳入,如果每次都用datetime.now()方法計算,太佔用時間了。所以就一秒更新一次,節約運算。

def update_date(self) -> None:
    """更新當前日期"""
    self.current_date = datetime.now().strftime("%Y%m%d")

但是在凌晨0秒時候,這個current_date還沒有更新,還是昨天的時間,造成上面錯誤。



其實印象中這個錯誤在之前vnpy v1版本看到有人提出過,查了下在v1.9.2版本已經修復過。 v1.9.2程式碼如下

# 上期所和鄭商所可以直接使用,大商所需要轉換
tick.date = data['ActionDay']
# 大商所日期轉換
if tick.exchange == EXCHANGE_DCE:
    tick.date = datetime.now().strftime('%Y%m%d')

這裡可以看到,對於上期所和鄭商所使用tick中帶日期的actionDay,而只有大商所採用本地時間,因為大商所夜盤到11點,所以完全OK。


這裡好像問題解決差不多了,好像是在vnpy2版本把之前的休息忘記了。 只要按照v1.9.2版改改就差不多了。這個倒是不難。

但是為什麼要用本地日期了,而不直接用tick 資料自己帶的日期了,一查發現還是有些彎彎道道的。


首先tick資訊裡面其實有兩個日期,TradingDay 和ActionDay,其實tradingDay可以理解為交易日,比如夜盤交易通常算第二天的,夜盤的掛單到第二天還是有效;而ActionDay可以理解為實際日期,就是還是當天。

如下圖 

VNPY2 中凌晨0點時間戳的處理問題,和夜盤資料時間戳分析

但是,很奇怪的事情發現了,大商所的ActionDay竟然就是交易日TradingDay,所以沒法預設統統使用ActionDay,不然大商所的資料就亂,當天夜盤日期反而是明天。

所以該法就是分析交易所,如果是大商所用本地時間,其他用tick的ActionDay.


截圖引用的連結被自動吃了,沒有顯示,實在抱歉

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22259926/viewspace-2781665/,如需轉載,請註明出處,否則將追究法律責任。

相關文章