自動化交易通道搭建-文件單讀寫衝突處理

背景

本人實現自動化交易通道搭建過程中,已知:某股票交易客戶端系統本身支持python寫交易策略,調用下單接口,實現自動下單。現需要:把外面的交易系統的下單信號通過該股票交易客戶端系統實現下單。採用的大概方案如下:
在這裏插入圖片描述
結構非常簡單,交易系統有信號的時候以追加寫的方式寫這個中間文件。另一邊,股票交易系統中,構建一個python策略,定時(10ms或更短時間)讀這個文件,再調用自身的下單接口下單,爲了防止重複信號,讀完刪除這個文件。

實現

寫文件實現

void writeOrder(const string &orderStr)
{
    try {
        string filename = "order.csv";
        string fullpath = filepath + "/" + filename;
        std::ofstream ofs;
        while(true){
            ofs.open(fullpath, std::ios_base::app);
            if(!ofs.is_open()) {
                //有一定概率打開文件失敗,是因爲股票系統策略那邊正在操作。這裏需要sleep一下。再打開,防止漏單。
                Sleep(1);
                continue;
            }
            ofs << orderStr;
            ofs.close();
            break;
        }
    } catch (const exception &e) {
        //出錯日誌
    }
}

股票交易系統中,python策略讀文件實現

#定時函數
def insertOrder():
	#order_file中間文件
	if os.path.exists(order_file):
		print('start',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
		for line in open(order_file,'r'): #讀取文件單
			#處理對應信號,調用下單接口下單。或保存信號。後面刪除文件後再下單。
			pass
		print('end read file',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
		os.remove(order_file) #刪去文件
	else:
		return

問題

上面的讀寫中間文件看着是沒有問題的,但是python策略直接讀原文件order_file,讀完後,再刪除原文件。 這種方式,因爲讀取過程中需要時間較多如100ms,當外面的交易系統那邊頻繁報單寫文件的時候,因爲order_file不是獨佔的。python這邊讀取的過程中,外面的交易系統那邊也寫入了很多單,那麼python策略這裏隨後刪除文件時,刪除了還沒有讀取的新寫入的單子。導致漏單!!

解決

中間的讀寫文件最好是讀的時候不能寫,寫的時候不能讀,讀寫互斥。如果是同一個系統的話是很好實現的,加一個文件鎖就可以了。或者別的鎖。 讀寫文件的時候都需要獲得鎖。 但是現在是雙系統,這個加鎖的方式不現實。
有沒有一種方式,能控制我讀文件的時候,別的一切程序都不能寫?
沒找到!!

換一種思路?
問題:因爲讀的過程耗時較多,期間寫入了額外的信號,導致刪除文件的 時候,把額外的信號也刪除了,導致漏單。
分析:刪除文件是需要的,否則引發重複單更麻煩。讀耗時是關鍵。
那麼:怎麼辦呢?

答案

修改一下Python策略定時函數,讀文件之前,先重命名,重命名耗時短,一旦另一邊正在寫,那麼重命名就失敗。失敗就能下一個定時點就行。這樣只要重命名成功,那麼就做到了讀寫分開啦!妙!!!
代碼處理如下:

#定時函數
def insertOrder():
	#order_file中間文件
	#order_file_new 中間文件重命名後文件名
	if os.path.exists(order_file):
		#lsl:用rename的方式,當自動化下單那麼正在寫文件時,這裏會失敗,那麼股票交易系統會捕捉異常,等待下一個時間點再觸發,衝突概率小,且是可控的,最多延遲幾個定時時間點下單。
		os.rename(order_file, order_file_new)
		print('start',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
		for line in open(order_file_new,'r'): #讀取文件單
			#處理對應信號
			pass
		print('end read file',datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
		os.remove(order_file_new) #刪去文件
	else:
		return

結語

該通道目前實盤中。搭建你自己的交易系統,實現自動化交易下單,通道是關鍵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章