一开始用“每个进程执行一个策略实例”的方法,后面发现同一网络最大只能启动30个API.
经管理员介绍:目前按https://doc.shinnytech.com/pysdk/latest/advanced/multi_strategy.html
经真实代码测试,程序只创建1个线程,但在感应价格跳动时,总是会慢,随着时间的推移,相差时间越来越长。
而不用线程的方法,同一台电脑,“每个进程执行一个策略实例”,就不会有时间延迟的问题。这是什么原因呢?
按下图的时间跳动,已经跟系统时间相差5分钟左右了,打印时间是14:49:40,系统时间:14:54。系统时间是与网络同步的。
参考的例子如下:
python的多线程就是有性能问题啊。
我的策略,最初多线程版本挺好的。当时限制只有5个线程。后来真正实用的时候,加到20个线程以上,python的性能,完全无法胜任。
你百度搜python GIL就知道了。
请问能稳定重现吗?方便提供代码吗? 在子线程代码中,是否一直在循环调用wait_update()呢?
或者你直接运行示例中的代码,看是否也能重现这个情况
可以重现,我还录了一个视频,视频怎么给你。
代码方面:我先贴出来一个结构,首先是从mysql读出要创建线程的合约,然后价格跳动时就找信号等
import threading
import datetime
from tqsdk import TqApi,TqAccount
from lib.Mysql import *
from lib.Function import *
#全局变量
tacticsName = “PMM” #策略名称
accountPercent = 10001
machineName = “AA01” #机器相对应合约
dayNight = “A” #夜盘合约之分
masterTable = “TQ_SYMBOL_MASTER”
class WorkerThread(threading.Thread):
#类变量
signalName = “PMM”
signalType = signalName + “-M.M.M-DDHH” # 信号名称
signalAddType = “-A.” # 补仓区别
AccountCapitalPercent = 150 # 资金:可用/占用
orderTable = “tq_order_daily”
#初始化
def __init__(self,api,symbolIndex,symbol):
threading.Thread.__init__(self)
self.api = api
self.symbol = symbol
self.symbolIndex = symbolIndex
#释放方法
def __del__(self):
self.api.close()
#程序开始
def run(self):
quote = self.api.get_quote(self.symbol)
while True:
self.api.wait_update()
#交易系统时间
vTime = datetime.datetime.strptime(str(quote.datetime), “%Y-%m-%d %H:%M:%S.%f”).strftime(“%Y-%m-%d %H:%M:%S”)
if self.api.is_changing(quote, “last_price”):
print(“n时间:”,vTime,” 合约:%-16s” %self.symbol,” 报价:%-16s” %quote.last_price)
#调用其他方法:
# 包括1.找信号 2.判断是否止盈平仓等 这些设置都是来源数据库
#如果这里不调用其他方法,执行起来时间差就不那么明显
#========================================================程序开始入口========================================================
if __name__ == “__main__”:
print(“################################################” + tacticsName + “策略开始运行################################################”)
try:
api_master = TqApi()
#api_master = TqApi(TqAccount(“快期模拟”, “test@qq.com”, “test”))
except Exception as Ex:
print(“行情服务连有问题:”,Ex)
#账户资金
Account = api_master.get_account()
if (float(Account.margin) != 0):
accountPercent = Account.available / Account.margin * 100;
print(“n净值:”, format(Account.available + Account.margin, ‘.2f’), ” 可用资金:”, format(Account.available, ‘.2f’), ” 占用资金: “, format(Account.margin, ‘.2f’),” 浮动盈亏: “, format(Account.float_profit, ‘.2f’),” 风险比率: “, format(accountPercent, ‘.2f’),”n”)
# 线程列表
try:
thread = []
conn = dataBaseConn()
cursor = conn.cursor()
sql = “select r.symbolIndex,r.symbol from “+ masterTable +” r where r.signalName ='”+ tacticsName +”‘ and r.serverName = ‘”+ machineName +”‘ and r.dayNight'”+ dayNight +”‘ order by r.symbolOrder asc”
print(sql)
cursor.execute(sql)
ret = cursor.fetchall()
#循环添加新线程
symbolCount = 0
for row in ret:
thread.append( WorkerThread(api_master.copy(),row[0],row[1]))
symbolCount = symbolCount + 1
#循环启动新线程
for iLoop in range(0,symbolCount,1):
thread[iLoop].start()
except Exception as Ex:
print(localTime(),” 程序有异常: “,Ex)
finally:
cursor.close()
conn.close()
#进程跟踪行情跳动
while True:
api_master.wait_update()
你加一下qq 1948530632吧,代码格式贴上来之后不对,加了qq你再发一下
是否有在代码中使用 time.sleep()函数,如果是的话请参考如下
完全没有用到time.sleep(),策略就是在判断有价格变动时就做一些”其他计算”。如果把”其他计算”注释掉不执行,时间方面就没那么明显延迟。奇怪的是,如果是电脑性能方面不好,也不对。因为同一电脑同时测试运行10个非多线程的策略,打印时间也不会延迟。
感谢分享。
用多线程也是没办法的事情,因为平台限制同一IP最大30 API。
我现在的想法是这样:成交量较大的合约大概50个,初步拆成5个合约共用一个进程,等于要启动10个进程,分两台电脑跑,每台跑5个。
方便私信留个联系方式吗?以后多交流。