数据口径 · 回测前置检查
investpy 的数据能用于回测吗:六项口径审计清单
就算端点恢复、数据取到了,也不代表能直接进回测。复权口径、成交量单位、时区、币种、缺失值、标的变更这六项官方都没有声明,每一项都能让回测结果失真。这一页给出可执行的检查方法,而不是一句「数据不准」。
六项口径检查
六项口径:官方怎么说的、你该怎么验
下表每一项都给出「官方是否声明」「验证方法」「不验的后果」三列。判定标准请以 Investing.com 的页面与你的权威数据源为准。
| 口径项 | 官方是否声明 | 怎么验证 | 不做验证的后果 |
|---|---|---|---|
| 复权 | 未声明 | 取一个已知除权日的标的,比对除权前后价格是否发生跳变 | 回测会把除权缺口当成真实下跌,策略信号全部失真 |
| 成交量单位 | 未声明 | 与交易所公布的成交量量级比对(股 / 手 / 张) | 跨市场加总或换手率计算出现数十倍偏差 |
| 时区 | 未声明 | 检查 Date 索引的时区属性与最后一条数据的日期 | 跨市场对齐时「同一天」实际不是同一天 |
| 币种 | 有 Currency 列 | 抽样确认该列是否随标的变化 | 把港股价格与 A 股价格直接相减,跨币种计算无意义 |
| 缺失值 | 未声明 | 统计日期缺口,对照交易日历排除休市 | 把停牌当成「价格不变」,动量类指标被系统性低估 |
| 标的变更 | 未声明 | 核对名称/代码在区间内是否发生更名或转换 | 长期序列里混入不同标的,回测结论不可复现 |
先明确一件事:本页不是「investpy 数据有问题」的指控。这些是任何第三方数据源都会遇到的口径问题,只是 investpy 官方文档没有给出承诺,因此责任完全在使用者一侧。把它当作一次数据尽调清单使用。
复权怎么验:三步即可判断
复权是影响最直接、也最容易验证的一项。找一个已知发生分红或拆股的标的,取除权日附近的数据,看价格是否连续。
挑一个已知除权事件的标的
选择有明确分红或拆股记录的股票,记下除权日与公告比例。预期:你手上有一份可与数据对照的「外部事实」。
取除权日前后的价格序列
get_stock_historical_data(stock='…', country='…', from_date='…', to_date='…')。预期输出:除权日当天若存在缺口(如直接跳到前一日收盘价的 1/2 或某个比例),说明序列未做复权。比对收益率分布
计算日收益率的极值。预期:未复权序列会在除权日出现远高于日常的异常值;若该异常值恰好等于除权比例,基本可确认未复权。若数据源已复权,则不应出现这一跳变。
本机现状:因为联网端点在本机实测返回 403,本站没有拿到真实数据,因此**没有**对 investpy 的复权口径下任何结论。上面是方法与判定标准,不是结论。
成交量、时区与币种的三个常见误判
这三项的差异往往不会让程序报错,只会让分析结论悄悄偏掉,因此更需要显式检查。
| 项 | 容易发生的误判 | 检查方法 | 发现异常后怎么办 |
|---|---|---|---|
| 成交量 | 假定所有市场单位都是「股」 | 与交易所公布量级比对;观察数值是否有明显的 100 倍差 | 按市场建立单位换算表,在入库时统一 |
| 成交量(复权影响) | 以为成交量与价格一样会复权 | 拆股后观察成交量是否同步跳动 | 成交量与价格要分别处理,不能一起复权 |
| 时区 | 假定 Date 索引是本地时区或 UTC | 打印索引的 tz 属性与最后一条数据的日期 | 显式统一到目标时区,再做跨市场对齐 |
| 时区(跨市场) | 把美股与 A 股按同一日期对齐 | 检查同一自然日两边是否都有数据 | 按交易日历而不是自然日对齐 |
| 币种 | 忽略 Currency 列直接计算 | 抽样查看该列取值是否随市场变化 | 入库时保留币种,跨市场计算前先换算 |
| 缺失值 | 用 ffill 无脑填停牌日 | 统计日期缺口并与交易日历对照 | 停牌日应标记而非填值,避免虚假的可交易性 |
进入回测前的六条最低要求
无论数据来自 investpy、AkShare 还是交易所,下面六条都成立。把它们写进你的取数脚本,比换数据源更能提升结论可靠性。
| 要求 | 为什么 | 怎么落地 |
|---|---|---|
| 记录数据来源与采集时间 | 结论要可复现,就要能说清数据是哪个源、什么时候取的 | 在数据表里加 source 与 fetched_at 字段 |
| 固定复权口径 | 同一策略在不同复权口径下结果可能反向 | 统一到前复权或后复权,并在结论里写明 |
| 对齐交易日历 | 自然日对齐会引入不存在的交易日 | 以交易所日历为准做对齐与重采样 |
| 显式处理停牌与缺失 | 填补会让策略「买到」实际无法交易的标的 | 缺失标记为不可交易而非填值 |
| 样本内外的切分固定 | 否则无法判断策略是否过拟合 | 把切分日期写进配置并版本化 |
| 保留可交易约束 | 涨跌停、T+1 等规则会显著改变收益 | 把约束建模进撮合逻辑,而不是事后剔除 |
本站能证明什么、不能证明什么
这一页最容易写过头,因此把证据边界单独列出来,避免把方法当成结论。
| 关于 investpy 数据的说法 | 本站的证据状态 | 能不能写进你的研究结论 |
|---|---|---|
| 官方没有声明复权口径 | 已核验:README、PyPI 页面、源码中均无复权相关说明 | 可以,这是文档事实 |
| DataFrame 只有七列且不含 exchange | 已核验:源码 stock_to_dict() | 可以,这是代码事实 |
| investpy 的数据未复权 | 未验证:联网端点 403,本站未取到任何真实数据 | 不可以,属推测 |
| investpy 的成交量单位是股 | 未验证:同上 | 不可以 |
| investpy 数据不适合回测 | 未验证:口径未明不等于数据有错 | 不可以,应写成「口径未声明、需自行验证」 |
为什么把这一段写出来:中文技术圈常见的写法和上面第 3–5 行一样——因为跑不通就顺手说「数据不准」。本站不做这种推断:没拿到数据,就不对数据质量下结论。
FAQ