问题描述
run_monthly/run_weekly/run_daily这类定时任务里的函数
函数最长运行时间是多长呢?
解决方案
在 JoinQuant(聚宽)量化平台中,无论是 run_daily、run_weekly 还是 run_monthly 这类定时任务注册的函数,还是 handle_data 等其他回调函数,每个函数的最长运行时间限制均为 1800 秒(即 30 分钟)。
为什么会有时间限制?
由于回测和模拟盘的服务器资源有限,为了防止恶意攻击或死循环导致资源被长期占用,平台在底层引擎中设置了严格的资源限制:
- 运行时间限制:每个函数运行时间不能超过 1800s。
- 内存限制:进程占用内存不能超过 3G。
- 状态保存限制:模拟交易序列化之后的状态大小不能超过 30M。
如果您的函数运行时间超过了 1800 秒,系统会强制关闭该进程,并在日志中抛出如下错误提示:
TimeoutError: function 'xxx' runs more than 1800 seconds
运行超时的优化建议
如果您的策略在定时任务中处理的数据量过大导致超时,建议采取以下方法进行优化:
-
使用性能分析工具定位瓶颈:
在策略代码最上方调用enable_profile()开启性能分析功能。运行一段较短时间的回测后,查看性能分析报告,找出耗时最长的代码行(如复杂的循环、低效的 DataFrame 操作等)进行针对性优化。 -
拆分任务到不同时间段:
如果一个函数需要处理全市场几千只股票的复杂计算,可以将其拆分。例如,利用run_daily在不同的时间点(如09:30,10:00,10:30)分别处理一部分股票池,从而避免单个函数单次执行超过 1800 秒。 -
优化数据获取与计算逻辑:
- 尽量使用向量化运算(如 Pandas/NumPy 的内置方法),避免使用
for循环逐行遍历 DataFrame。 - 避免在盘中高频调用耗时的财务数据查询(如
get_fundamentals),可以将其移至before_trading_start或盘后的定时任务中预先计算好并存入全局变量g中。
- 尽量使用向量化运算(如 Pandas/NumPy 的内置方法),避免使用
-
内存回收:
如果涉及大量临时变量,可以引入 Python 的gc模块,在适当时机手动调用gc.collect()释放内存,避免因内存不足导致的性能下降或崩溃。