跳到正文

研究指南

股票数据准备

批量下载股票历史行情:逐只检查日期覆盖和下载失败

批量股票历史数据是否完整,要相对于明确请求和预期覆盖来判断。目录里每个代码都有文件,仍可能存在截断响应、失败股票和区间内部缺日。应保存请求台账,分别检查每只股票的响应,再针对未解决缺口形成补拉清单。下载进程没有抛异常,不等于数据已经齐全。

本文用三只虚构股票、三个明确给定的样例交易日,模拟供应商响应,实际执行覆盖分类和重复安全的补拉合并。标准库脚本不发网络请求,不证明有数据权限,也不代表CoTrading下载服务已可用。真实交易日历、凭证、数据授权和历史深度仍须另行核实。

请求前固定范围和口径

请求台账至少包括带市场的证券标识、起止日期、频率、时区或交易日口径、复权方式和来源编号。明确区间端点是否包含,保存请求版本。否则第一次取原始日线、补拉时取复权日线,日期虽然补齐,数值却不能一起使用。代码别名或交易所后缀的变化也要保留转换依据。

应核对供应商当前参数说明。Alpha Vantage日线接口文档区分紧凑响应和更完整历史,并说明访问条件。成功返回也可能短于研究者预期。本地封装函数接收很长的起止日期,不证明上游接口真正按该范围返回。请求参数、实际响应元数据和预期范围都需要留档。

采用有限批次,给每只请求股票保留状态。不要用一个大范围异常捕获直接跳过失败项,让其从台账消失。记录请求及响应时间、错误类别、尝试次数和保存响应编号;报告与文件名不能含凭证。权限不够与临时网络失败的下一步不同,不能统一排成无限重试。

建立预期交易日参考

合成样例明确给定2026-10-19、2026-10-20、2026-10-21三个日期,不声称这是脚本自动生成的交易所日历。请求AAA、BBB、CCC。AAA返回全部三日,BBB只返回后两日,CCC没有取得响应。覆盖判断只对这个声明范围负责。

真实任务应先取得正确市场日历,再结合证券上市区间、停牌等已知事实判断个股预期观测。按星期一到星期五生成工作日,无法包含交易所节假日。新上市公司不能提供上市前价格;这属于结构性历史边界,不能靠重复请求修复。退市证券也应按实际身份和存续区间查数据。

Python datetime文档支持日期和时区的明确处理,但不提供股票交易日历。日历应作为独立输入保存。“市场有交易日”“该证券当日可以交易”“供应商返回一条行情”是不同事实。不能为每个日历日期凭空造一根K线,也不能把供应商缺行一概解释为休市。

逐只计算覆盖状态和缺口

对每只股票收集唯一返回日期,与预期集合比较。保存实际首日、末日、唯一行数、缺失日期和超范围日期。只看首末日期不够:中间漏一天,端点仍可能完全正确。重复日期如果未去重,也可能让行数看起来足够,从而掩盖缺口。

股票初始返回状态缺少日期
AAA10月19、20、21日成功无
BBB10月20、21日部分10月19日
CCC没有响应失败三日全部

BBB已有两条可用观测,应保留并调查缺失首日;CCC尚未取得任何历史。两者不能因为目录里有同名文件就进入成功组。空文件、错误消息文件与合法零行响应也需要区分,避免下游把接口提示当作行情内容读取。

for symbol, response in responses.items():
    store[symbol] = set(response or [])
    missing = sorted(set(sessions) - store[symbol])
    status = "failed" if response is None else "partial" if missing else "success"
    coverage[symbol] = {"status": status,
                        "rows": len(store[symbol]), "missing": missing}
    if missing:
        retry[symbol] = missing

完整文件为docs/growth/research/round-5/examples/R529.py,实际执行的初始行数是AAA三行、BBB两行、CCC零行。补拉清单只有BBB的10月19日和CCC的三个缺失日期。脚本模拟补拉成功,并把相同补拉结果合并两次,断言最终每只股票仍恰好三个唯一日期,没有重复追加。

下载完整示例。使用Python 3.12+,仅需标准库,全部为合成数据;下载后运行python R529.py。

补拉合并不能掩盖冲突价格

样例用日期集合,因为验证范围仅是覆盖。真实行情应按证券、日期、频率、复权口径及必要的来源版本建键。完全相同的重复行情可以识别为重复;同一天价格不同则要作修订判定,不能用集合去重把冲突值丢掉。覆盖完整与数值一致是两个验收维度。

新数据先写暂存结果,校验后再发布包含新覆盖表的完整版本。已经被研究引用的旧版本应继续可追溯。补拉再次失败时,保留最初成功行,只更新未解决状态与尝试历史。处理完补拉队列不等于补齐了数据,最终状态还要基于合并后的实际键集合重算。

给重试设置次数和耗时上限。临时失败可以按供应商规则等待后再试;不支持的证券、权限不足、上市前区间需要调查。预算用尽后明确输出部分结果,是控制流程正常结束,但数据请求仍未全部完成。不要把停止重试转换成成功标签。

用短历史反例区分故障原因

假设后续确认BBB缺少的10月19日发生在上市之前。就可取得历史而言,采集可能已经结束;但原始请求覆盖仍未满足。记录结构性限制和真实可用起日,不要用10月20日收盘价填补,也不要永远补拉一个不存在的观测。调整研究起点属于下游决策,应另存选择依据。

如果原因其实是接口使用紧凑模式,则在权限允许时改变参数,保存新尝试记录,再取缺失范围。同样表现为“历史太短”,修复路径却不同。这说明缺口检测之后,还要查数据源和证券元数据,不能从缺日直接跳到机械重试,更不能把短历史伪装成完整三年历史。

把文件与边界一起交付

最终包包括逐股行情文件、请求台账、覆盖矩阵、重试或调查清单。每只请求股票恰好有一个当前状态,不能只统计成功数。合并行数要等于旧键与新接受键的并集,再抽查几条修复行对应的保存响应。对外汇报时明确哪些响应被模拟、哪些来自真实取得,不能混写。

下游应声明是否接受部分覆盖。比较三年策略时,一只股票只有两个月历史不能悄悄混入。不同市场、币种和数据源分组取得,并分别核实支持范围。该流程改善的是数据取得的可靠性,不保证全球完整历史,也不证明行情适合任何回测。

更换供应商、扩大日期范围、修改复权口径或发现上市区间变化时,重新计算预期覆盖。保留一个固定的失败与部分成功样例,检查新版本仍会给每只股票明确状态。这样批量下载不仅能结束,还能说明取得了什么、缺什么,以及下一次只需要处理哪些对象。

保留能够重放的补拉台账

每条补拉项应指向原请求、未解决日期、最新错误类别和下一次允许动作。新观测只有通过初次响应相同的结构、价格口径和单位检查后,缺口才算修好。返回了目标日期但收盘列装着错误字符串,不能称为已补齐;覆盖统计应基于被接受的行情键,而不是响应消息数量。

CCC在合成成功分支补齐三个日期,真实重跑却可能只修好其中一天。此时从已接受存储键重新计算覆盖,把剩余两天继续保留,而不是重置整个请求,也不能假设发起过重试的项目都成功。再次执行相同成功响应时,唯一键保证不重复追加,冲突价格则仍走单独修订分支。

最终台账与文件一起归档。以后来源覆盖或日历假设改变,可以对保留响应重放分类,不必重新下载无关成功观测。这样既减少重复请求,也让每一个“成功”状态对应到实际存在、可读且口径一致的数据,而不是一条已经结束的进程。

批次之间还要检查请求范围是否相互覆盖。重叠请求可以存在,但合并依据仍是唯一行情键;不能把不同批次的行数简单相加当作覆盖总数。若后一次响应修订了旧价格,另记修订版本,不把它解释为新增交易日。这样覆盖矩阵与数值修订记录各自有明确含义。

常见问题

首末日期一致就算覆盖完整吗?

不算,还要检查区间内部预期交易日与唯一行数。

缺日都能用上一收盘价填吗?

不能。先查原因;填充会制造合成观测,只能作为明确的下游政策另行处理。

相关阅读