5.68K 浏览
0

一开始用“每个进程执行一个策略实例”的方法,后面发现同一网络最大只能启动30个API.

经管理员介绍:目前按https://doc.shinnytech.com/pysdk/latest/advanced/multi_strategy.html

经真实代码测试,程序只创建1个线程,但在感应价格跳动时,总是会慢,随着时间的推移,相差时间越来越长。

而不用线程的方法,同一台电脑,“每个进程执行一个策略实例”,就不会有时间延迟的问题。这是什么原因呢?

按下图的时间跳动,已经跟系统时间相差5分钟左右了,打印时间是14:49:40,系统时间:14:54。系统时间是与网络同步的。

参考的例子如下:

Paul Yu 已回答的问题 2020年2月26日
0

python的多线程就是有性能问题啊。

我的策略,最初多线程版本挺好的。当时限制只有5个线程。后来真正实用的时候,加到20个线程以上,python的性能,完全无法胜任。

你百度搜python GIL就知道了。

ishanning 发表新评论 2020年2月26日

感谢分享。

用多线程也是没办法的事情,因为平台限制同一IP最大30 API。

我现在的想法是这样:成交量较大的合约大概50个,初步拆成5个合约共用一个进程,等于要启动10个进程,分两台电脑跑,每台跑5个。

方便私信留个联系方式吗?以后多交流。

0

请问能稳定重现吗?方便提供代码吗? 在子线程代码中,是否一直在循环调用wait_update()呢?

或者你直接运行示例中的代码,看是否也能重现这个情况

west 发表新评论 2020年2月26日

可以重现,我还录了一个视频,视频怎么给你。

代码方面:我先贴出来一个结构,首先是从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你再发一下

0

是否有在代码中使用 time.sleep()函数,如果是的话请参考如下

https://www.shinnytech.com/question/7973/

ishanning 发表新评论 2020年2月26日

完全没有用到time.sleep(),策略就是在判断有价格变动时就做一些”其他计算”。如果把”其他计算”注释掉不执行,时间方面就没那么明显延迟。奇怪的是,如果是电脑性能方面不好,也不对。因为同一电脑同时测试运行10个非多线程的策略,打印时间也不会延迟。