python CTP 8193 心跳超時程式崩潰解決方法——8193錯誤
終於,終於,終於!!!!
博主千辛萬苦把CTP 8193心跳超時導致程式崩潰的問題解決了!!!!!經歷了一天一夜的測試後,第二天親眼看到CTP返回了8193錯誤後,我的程式沒有崩潰!第二天早上9:00一到,又自己正常運行了。敲開心~~~
博主的血淚史,就是搜遍國內外全網,不止博主一個人遇到8193後程序崩潰,但只有提問8193錯誤的,沒有一個回答8193錯誤的解決方法。所以博主就決定了,一旦等到博主解決8193錯誤那一日,就一定要把解決方法公諸於世!
先說一說博主的8193錯誤導致崩潰的原因。
眾所周知,8193錯誤就是CTP當中的,一旦引發,ctp就會呼叫回撥函式“onFrontDisconnected”,返回錯誤碼(目前博主見得最多的就是4097和8193)。
這個時候根據上期所官方CTP_API介面原文,API會自動重新連線,客戶端理論上可以不做任何處理。
但是!!博主要說,這邊所謂的不做處理,是指不用做任何重新連線前置機的處理。
CTP雖然會幫我們自動重連前置機(前提是,你之前註冊的前置列表裡的前置機可以連線得上,註冊多個前置機方法詳見博主的另外一篇文章:https://blog.csdn.net/mooncrystal123/article/details/83269296),但是CTP不會幫我們重新登入!
然而,CTP的業務API必須要登陸後才能使用!登入後才能使用!!登陸後才能使用!!!
重要的事情說三遍。
業務API就是下單啊,查詢賬戶餘額啊,查詢市場最新tick行情啊等等等…………
所以博主的崩潰來自於兩個方面
1. 前期
只註冊了一個前置機,前置機壞掉後,無法重連,導致下單查詢的業務執行緒無法獲得必須的返回結果屬性,導致後續業務邏輯報attributeError失敗,崩潰。
2. 後期
註冊了一堆前置機,但是重連後沒登入,導致業務邏輯執行緒進入死迴圈,執行緒無法自動停止。
註冊了一堆前置機,但是登陸方法寫在了CTP的回撥函式當中,然後登陸失敗,導致程式崩潰。
所以,綜上所述,博主經過多番實驗找到了辦法。
首先,最重要的就是在回撥函式中不加任何重新登入的方法,只負責列印或者記錄CTP斷連後onFrontDisconnected返回的錯誤碼,然後等待CTP自動重連,重連成功後CTP會呼叫onFrontConnected。
注:self.logoutCode是博主自設的用來鑑別是手動登出時導致的斷連還是CTP自身原因導致的斷連。
def onFrontDisconnected(self,n):
# n的type是int
print(n)
# 手動登出
if self.logoutCode == 1:
self.onFrontDisconnectedCode = 0
else:
self.onFrontDisconnectedCode = n
def onFrontConnected(self):
"""伺服器連線"""
print("onFrontDisconnectedCode: " + str(self.onFrontDisconnectedCode))
CTP呼叫回撥函式的時候,會自動開啟一個新執行緒來處理,我們稱之為A執行緒。
然後,我們要做的就是把重新登入的方法寫在我們程式執行的執行緒裡面,預設就是B執行緒。
下面就是我自己封裝的CTP類的斷連檢查+重新登入的方法。
# 斷連狀態檢查:給所有的業務類方法前加上去
def reloginCheck(self):
stat = 0
# 檢視前置機是不是自己斷連過
if self.api.onFrontDisconnectedCode != 0:
loginReq = {} # 建立一個空字典
loginReq['UserID'] = self.userid
loginReq['Password'] = self.password
# loginReq['BrokerID'] = '9999'
loginReq['BrokerID'] = self.brokerid
self.reqid = self.reqid + 1 # 請求數必須保持唯一性
self.api.reqUserLogin(loginReq, self.reqid)
sleep(1)
if hasattr(self.api,'loginErrorID'):
if self.api.loginErrorID == 0:
stat = 1
# 前置機沒有斷連過
else:
stat = 1
print('relogstat: '+str(stat))
return stat
這個方法在業務邏輯中插入的位置:
# 判斷simnow是否開啟
if simnowStat == 1:
frontStat = sarProjectTest.Api.reloginCheck()
# 檢查CTP是否斷連
if frontStat == 1:
while optSuccess == 0:
sarProjectTest.Api.BuyOpen(self.id, num)
orderResult = self.ordertools.orderInsertJudge(sarProjectTest.Api.api,num,1)
optSuccess = orderResult['optSuccess']
if optSuccess == 0:
print('下單失敗')
self.apptools.logGenerate('買開下單失敗')
# 未開啟simnow
else:
optSuccess = 1
---------------------
作者:mooncrystal123
來源:CSDN
原文:https://blog.csdn.net/mooncrystal123/article/details/83269296
版權宣告:本文為博主原創文章,轉載請附上博文連結!
通過這樣的處理,即使CTP報8193或者4097,我們的程式也不會崩潰,可以等待CTP重連。
一般來說,CTP前置機最不穩定的時間為傍晚4:30-7:00,這段時間是各方前置機維護關機時段,如果程式要過夜的話,這段時間不能因為CTP前置機不穩定而宕機是最關鍵的。