在做美股数据处理时,历史行情并不是天然连续的时间序列。有些日期会直接缺失,有的是停牌,有的是交易所休市,还有部分是接口返回不完整。
如果直接把这些数据放入回测或指标计算中,均线、收益率、波动率等都会出现偏差。为了保证计算结果可靠,需要先明确缺失来源,再做对应处理。
美股历史数据缺失大体可以分为三类:
| 类型 | 特征 | 处理方式 |
|---|---|---|
| 停牌 | 单个标的全天无成交 | 前向填充或标记停牌 |
| 节假日 | 全市场空缺 | 可跳过 |
| 数据断点 | 随机缺失 | 重新拉取或插值 |
分清来源后,处理方式会更明确。
对停牌日,常用做法是前向填充,用上一交易日收盘价延续当前状态,这样计算均线等指标不会中断。
import pandas as pd
df = pd.DataFrame(data)
df["date"] = pd.to_datetime(df["date"])
df = df.sort_values("date")
# 停牌日连续性处理
df["close"] = df["close"].ffill()
# 标记原始缺失
df["is_missing"] = df["close"].isna()
节假日不需要填充,直接跳过即可,因为策略计算本身不会包含非交易日。
很多时候,直接用 API 返回的时间序列会导致不同标的对齐出错。更稳妥的做法是用交易日构建索引,再把行情数据对齐:
all_days = pd.date_range(start=df["date"].min(), end=df["date"].max(), freq="B")
df = df.set_index("date").reindex(all_days)
这样可以保证跨标的计算时时间轴一致,避免错位。
以 AllTick API 为例,可以先获取历史行情,再做时间轴处理:
from alltick import AllTick
import pandas as pd
# 使用 AllTick API 获取历史数据
client = AllTick(api_key="YOUR_API_KEY")
data = client.get_stock_history(symbol="AAPL", start="2026-01-01", end="2026-03-31", interval="1d")
df = pd.DataFrame(data)
df["date"] = pd.to_datetime(df["date"])
df = df.sort_values("date")
# 前向填充保证连续性
df["close"] = df["close"].ffill()
df["is_missing"] = df["close"].isna()
这里核心是先保证时间轴稳定,再做策略或指标计算。
| 字段 | 类型 | 说明 |
|---|---|---|
| date | datetime | 交易日 |
| open | float | 开盘价 |
| high | float | 最高价 |
| low | float | 最低价 |
| close | float | 收盘价 |
| volume | int | 成交量 |
有了字段说明,读者可以更直观理解处理逻辑。
缺失值不处理,均线可能断线,收益率统计会缺少自然交易区间,波动率偏低。跨标的计算时,如果交易日不一致,会出现对比错位。
时间序列处理尽量在进入指标计算前完成。
停牌标的前向填充不要无限延续,长期停牌可以保留空值。
跨标的计算时统一交易日索引,避免时间错位。
高频或盘中策略,需要额外 tick 数据补充,不要依赖日线填充。
处理美股历史数据缺失的核心是让时间序列稳定,一旦时间轴一致,策略和指标计算才能可靠。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048654/viewspace-3173152/ ,如需转载,请注明出处,否则将追究法律责任。