自动化交易通道搭建-文件单读写冲突处理

背景

本人实现自动化交易通道搭建过程中,已知:某股票交易客户端系统本身支持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

结语

该通道目前实盘中。搭建你自己的交易系统,实现自动化交易下单,通道是关键。

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