只取最近 60 个交易日,却每次拉全历史:量化脚本变慢的原因与改法

一句话结论:如果策略只需要最近 60 个交易日,反复请求全历史 K 线会让网络传输、解析和数据处理的成本随历史数据量增长;应先明确所需日期范围,再按范围获取,并用本地缓存和增量更新避免重复下载。

摘要

量化脚本每次启动都拉取全历史 K 线,即使最终只保留最近 60 个交易日,也会重复承担请求、传输、解析和 DataFrame 筛选成本。解决重点不是下载后再裁剪,而是在数据请求前确定时间范围,并设计本地缓存与增量更新。本文还会说明交易日范围、分钟线数据量和复权口径需要注意的地方,以及 QuantDash 公开支持的相关查询能力。

1. 为什么只用 60 天,脚本仍然很慢

典型的低效流程是:

text 复制代码
请求某标的全历史 K 线
→ 接收全部数据
→ 解析响应并构造 DataFrame
→ 按日期筛选最近 60 个交易日
→ 计算指标或生成信号

问题在于,最后的筛选只能减少后续计算量,不能撤销已经发生的请求、网络传输和数据解析。假设历史数据从较早年份开始,脚本每次运行都会重复处理大量策略实际用不到的记录。

总耗时通常来自几个环节:

  • 请求与网络传输:返回行数越多,传输的数据通常越多;等待服务响应和网络传输也会占用时间。
  • 响应解析:JSON 或其他响应数据需要被解码、转换为 Python 对象。
  • DataFrame 构造与筛选:数据量较大时,创建对象、转换类型和过滤都会产生额外开销。
  • 重复工作:定时任务或多次研究运行反复拉取相同历史数据,成本不断累积。

可以先记录每次运行的请求耗时、响应数据量、解析耗时、筛选耗时和最终保留的行数。若最终只留下很少的数据,而请求和解析耗时占比明显,就应优先检查是否在获取阶段请求了过宽的历史范围。

2. "最近 60 个交易日"不是"最近 60 个自然日"

交易日和自然日不能直接画等号。周末、节假日以及不同市场的休市安排,会让最近 60 个交易日跨越超过 60 个自然日。因此,简单用当前日期减去 60 天,通常不能准确得到 60 个交易日的起始日期。

更稳妥的处理方式是:

  1. 明确策略使用的市场和交易日定义。
  2. 根据对应的交易日历,定位最近 60 个已完成交易日。
  3. 将这 60 个交易日对应的起止日期用于数据查询。
  4. 取回数据后,再检查实际交易日期数量、缺失日期和重复记录。

如果没有交易日历,可以用一段更宽的自然日范围作为候选区间,再依据可靠的交易日历过滤;但不能把"自然日范围内有 60 个日期"当作"有 60 个交易日"。如果策略还涉及盘中运行,也要明确当天未完成的 K 线是否应该参与计算。

3. 分钟线场景,范围过宽的代价更明显

日线与分钟线的单个交易日记录数差别很大。即使策略只分析最近 60 个交易日,若每次都请求多年分钟线历史,下载和处理的数据量也可能远超策略需要。

对分钟线任务,建议额外确认:

  • 策略需要的周期是 1m、5m、15m、30m 还是 60m。
  • 指标是否确实需要完整的盘中序列,还是只需要特定时段的数据。
  • 当前交易日的数据是否已经结束,未完成 K 线如何处理。
  • 不同交易日的分钟记录是否完整,时间戳和交易时段口径是否一致。

不要仅通过缩短历史范围来掩盖数据质量问题。若某个交易日缺少分钟记录,指标序列可能断裂;若重复下载后直接拼接,也可能产生重复 K 线。范围控制和数据校验应该同时做。

4. 更合适的获取方式:范围查询、缓存与增量更新

4.1 在请求前确定起止日期

首先由策略需求计算查询范围,而不是先拉全历史再筛选。对于最近 60 个交易日,应由交易日历确定起始交易日,并根据策略是否使用当日未完成数据决定结束日期。

4.2 用本地缓存保存已获取数据

可以按市场、标的、周期、复权口径和日期范围组织本地数据。下次运行时,只检查缓存覆盖到哪一天,再获取缺少的部分。

缓存键不能只包含标的代码和周期。若复权方式不同,或者数据字段口径不同,应视为不同的数据序列,避免把不一致的数据混在一起。

4.3 增量更新,而不是反复全量刷新

常见流程是:

text 复制代码
读取本地缓存
→ 找出缓存中最后一个完整数据日期
→ 确定需要补齐的日期范围
→ 请求缺失部分
→ 检查日期、重复记录和数据口径
→ 合并并保存
→ 为策略提供所需窗口

对于当日可能变化的行情,不要简单假设缓存中的最新记录永久不变。可以根据策略运行时点定义更新规则,并在合并时处理同一标的、同一周期、同一时间戳的重复记录。

4.4 批量请求要与本地分批处理配合

批量查询可以减少逐个标的发起请求的工程开销,但请求范围仍然要控制。批量请求全历史并不等于高效;合理做法是同时限制标的集合和时间区间,并依据实际返回量安排本地处理。

5. 用代码表达流程,但不猜测 API 方法

下面是通用伪代码,用于说明数据流程,不是 QuantDash SDK 的可运行调用示例。具体交易日历来源、缓存格式和 API 参数,应按项目所用数据源及其官方文档实现。

python 复制代码
# 通用伪代码:不是 QuantDash API 调用示例
symbols = load_symbol_universe()
period =
相关推荐
鬼手点金1 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
孟健2 小时前
从5000亿Token到83%字节匹配:AI逆向工程与重构的工程闭环实践
后端·架构·ai编程
阿里嘎多学长2 小时前
2026-10-12 GitHub 热点项目精选
开发语言·程序员·github·代码托管
码事漫谈2 小时前
丢得静悄悄,谈一谈 Agent 的记忆是怎么没的
后端
迪飞特科技3 小时前
智慧物业平台实战:Spring Boot 整合小程序实现报修巡检费用全流程
spring boot·后端·小程序
考虑考虑3 小时前
@JsonInclude注解使用
spring boot·后端·spring
IT_陈寒3 小时前
Vite的这个问题坑了我三天,原来如此解决!
前端·人工智能·后端
网易云信3 小时前
大模型能上岗做销售吗?我们让 12 款国产模型交了 420 份作业
前端·后端
CCblandy3 小时前
HTTP 长连接 3 类故障实测:[WinError 10053]、99 个 TIME_WAIT、69 次多余握手,4 种对策怎么选
后端·python·网络协议·http·云原生·性能优化·架构