股票行情少了几天:区分停牌、休市和下载缺口再补数
股票行情补缺前,先判断那根行情应不应该存在。把已下载键与适用市场日历、证券上市区间和已核个股状态对照,分开休市、上市前后、停牌、原因未知与有证据的取数失败。只有最后一类可以自动进入定向补拉,不能把所有缺日都当作下载器出了问题。
本文实际执行分类并修复一个合成缺口,保留没有依据生成观测的日期,不为每个工作日填前收。CoTrading对应修复流程仍为规划或待核实。状态证据在样例中明确提供,不查询真实停牌档案,也不从一个空响应推断停牌。最终交付包含价格与状态两张具有不同含义的表。
认真建立预期会话参考
请求区间使用适用市场日历及时区。NYSE日历是官方假期和时段安排示例,不是所有市场或所有证券的统一日历。提前收盘仍需明确会话处理,假日不应产生虚构日价格。周一至周五列表无法覆盖真实假期,也不能作为下载完整性的唯一分母。
加入证券有效上市区间,必要时处理证券标识变化。交易所可以在公司上市前或退市后正常开放,这些日子仍不属于该证券应有历史。当前活跃股票清单不能证明过去存续范围;区间不知道就保留不确定,不默认每个请求交易日都应有行情。本例直接提供边界,不解决历史证券主数据取得。
日历、上市边界与状态来源保留版本和生效时间。后来修订时,可以定位哪些缺口分类需要重开。不能只改当前证券名称,就让旧价格在另一个身份下继续存在。对同公司不同上市线,也分别按具体证券与交易所处理,避免错误拼成连续历史。
停牌证据与休市证据分开
假期是市场安排,停牌是某证券某时间区间的状态。缺一条价格不能单独证明任何一种。Nasdaq Trader停牌页提供当前、搜索和历史入口,并标明显示时间约定。真实核对应选择适用日期证据,不能把今天页面当旧事件证明,也不能只看没有列出就断言从未停牌。
还要区分整日无应有观测与盘中暂停。股票可能在盘中暂停前后成交,仍有合法日线。本例verified_suspended特指外供证据支持整个会话无需期待交易观测,扩展到盘中状态需要更细区间逻辑。不能把任何停牌消息都解释为整日价格应该缺失。
拿不到可靠状态历史,就保留未知。价格没变、其他文件量为零、接口没返回,都只能提示调查,不代替状态证据。尤其零量记录也可能是供应商占位或合成填充,真实成交与数据可用性需要分别核实。错误地给未知日贴停牌标签,会阻断本来应该补回的合法行情。
对样例日期逐项分类
样例涵盖2026年10月16至26日,给定市场会话集合。虚构AAA从19日至23日上市,初始19、23日已有接受行情。20日是已核整日停牌,21日已核活跃且记录请求失败,22日缺足够证据解释为何没有数据。24、25日不在会话集合,26日已超过给定上市区间。
| 日期 | 诊断 | 动作 |
|---|---|---|
| 10月16日 | 上市前 | 不期待该股价格 |
| 10月19日 | 已观察 | 保留来源 |
| 10月20日 | 停牌 | 保留状态,不造K线 |
| 10月21日 | 下载缺口 | 定向重试 |
| 10月22日 | 原因未知 | 查证据 |
| 10月23日 | 已观察 | 保留来源 |
| 10月24至25日 | 休市 | 不生成价格行 |
| 10月26日 | 上市区间后 | 不期待该股价格 |
这是构造的诊断情景,不是真实发行人报告。状态和上市日期不能挪用成市场事实,它们的作用是用紧凑输入覆盖不同分支。真实数据缺口可能同时涉及多个问题,应按证据逐项处理,而不是强行把所有原因归入一个成功或失败标签。
把分类转成具体补数请求
if day not in market_sessions:
state = "market_closed"
elif day < listed_from:
state = "before_listing"
elif day > listed_until:
state = "after_listing"
elif status.get(day) == "verified_suspended":
state = "suspended"
elif status.get(day) == "verified_active" and day in failed_requests:
state = "download_gap"
else:
state = "unknown_reason"
完整文件会先保留已有接受观测,补拉队列只包含下载缺口。真实请求附证券、日期、频率、复权口径、来源和为什么它属于取得失败的依据。定向取得后,还需验证确实返回目标日,不能用邻近日代替。范围外响应应单独处理,不扩大本次修复任务。
下载完整示例。使用Python 3.12+与标准库,全部合成输入,运行python R536.py。作者文件为docs/growth/research/round-5/examples/R536.py。
实际只重试21日,模拟修复增加收盘11,来源为synthetic-retry-1。19日原收盘10和23日13保留,价格表最终三行。22日继续未知,其余无观测日期仍留在诊断表,不会因为某项修复成功就全部关闭。输入原表也未被覆盖,前后可以对照。
补回后不抹掉合法缺席
断言核对唯一重试日、最终接受键、原输入未变和新增行来源,还验证停牌、未知与周末没有制造价格。即使全日期矩形表更容易画图,也不符合本政策。诊断表可以完整覆盖查询日期,价格表则只包含有来源观测,两者行数不同是有意设计,不是漏处理。
真实OHLCV补回行通过原数据相同结构、单位和时段检查。错误消息保存成文件不是修复,带目标日期却缺价格也不是。每次重试后重新对账接受键;持续失败保留缺口和有限尝试,不能因已经运行重试循环就宣称数据完整。
新证据改变分类时,把诊断更正与价格补回分别记录。疑似下载失败后来确认为停牌,是原因修订,不是价格修复。反过来发现停牌假设错误并取得真实行情,也需保留原判断及改变依据,不能插入数据同时默默删掉旧状态,让历史过程无法复查。
原因未知是不同机制反例
22日没有价格,也没有足够状态证据。用19日或21日前收填入,只是在没有解释原因的情况下生成观测。本例刻意将其排除于价格表,保留在still_unknown,不把未知原因变成无变化交易日。这类填充可能压低波动、改变量与成交假设,因此不是纯格式便利。
20日不同,样例有支持停牌的证据,诊断已解决但仍没有交易价格。可见诊断完整与价格行完整不是同一概念。填零量加重复收盘会模糊区别。若下游需要合成估值路径,应另建带标签派生层,不把它回写成原始市场观测。
价格和保留状态一起交付
保存原历史、日历、上市区间、个股状态、请求失败日志、诊断表与接受替换。下游在计算收益或对齐之前,应知道哪些缺席已解释,哪些未知。不能只导出三条价格,丢掉为什么其他日期没有数据的证据;也不能导出九条诊断行就称九条行情都已完成。
新停牌证据、上市历史更正或供应商响应到来时,重开受影响日期,保留先前诊断。多股逐证券执行,同一市场日可能一股有行情、另一股未知。批量下载覆盖只是起点,本流程增加个股证据与定向修复。成功标准是有支持的历史和清楚剩余边界,不是填满虚构OHLCV网格。
替换接受需证据与范围一致
每个修复项写请求键、为什么可补拉,以及返回观测来源。合并前与原请求比较,另一日期或另一复权基础的行不能关闭原缺口,即使价格很合理。若来源只返回区间而非指定日,也要逐日核接受键,不能把请求完成等同目标日期已经补回。
诊断改变时保留状态历史。新证据表明疑似停牌日其实活跃,就重开缺行情问题;原下载失败后来发现位于真实上市区间外,则以该原因结束取得任务,不造价格。原因更正与数值更正分别编号,读者才知道前后数据为何行数或状态变化。
消费者分别获得请求日期数、证券应有会话数、接受观测数、已解释缺席数与未知缺口数。这些数字不能互换。修复后价格少于市场会话仍可能合理,全日期矩形表也可能含大量无来源合成行。波动、成交额或策略计算开始前,需要接受这些覆盖边界,不由导入工具自动替用户决定。
对未知日期建立具体查证动作,例如取得适用停牌档案、核证券存续或检查原请求错误,而不是统一刷新整段历史。只新增相同来源的重复请求,并不会增加原因证据;反复失败后仍保留未知,比伪造一个已解释标签更有利于后续修复。
如果下游确实采用前值估值,派生层应保留填充标志与原缺口类别,原市场数据继续不变。这既允许明确用途的计算,也避免以后其他消费者把合成值当真实交易观测,造成输入含义在文件传递中丢失。
常见问题
每个缺失工作日都是下载错吗?
不是,先检查交易日、证券存续和个股状态,再生成重试。
不知道原因可以填前收吗?
不能当真实观测;下游合成填充政策应单独声明和标记。