取数与返回结构
investpy 历史数据怎么取:返回列、日期格式与函数选择
investpy 的每个资产类别都有一组固定命名的函数:历史数据、近期数据、概览、名录、字典。它们的返回结构并不相同——历史数据给 DataFrame,概览给带额外字段的表,字典给可直接 JSON 化的结构。搞清楚返回什么,比记函数名更重要。
返回值结构
utils/data.py 的 stock_to_dict() 整理。注意 exchange 虽然在对象属性里存在,但不会出现在历史数据的 DataFrame 中;官方 README 的示例输出与此一致。六类函数族:同一个资产,六种取法
每类资产都按同一套后缀组织函数。先认清你要的是「数据」「概览」还是「名录」,可以少走很多弯路。
| 函数族 | 命名示例(以股票为例) | 返回 | 需要联网 | 适用场景 |
|---|---|---|---|---|
| 历史数据 | get_stock_historical_data(stock, country, from_date, to_date) | DataFrame(Date 索引 + OHLCV + Currency) | 是 | 回测、指标计算、画图 |
| 近期数据 | get_stock_recent_data(stock, country) | DataFrame,字段同上 | 是 | 只看最近几根 K 线,不指定区间 |
| 概览 | get_stocks_overview(country, n_results) | DataFrame,含名称/代码/最新价等横截面字段 | 是 | 做筛选、看某个市场的整体情况 |
| 信息 | get_stock_information(stock, country) | DataFrame 或 dict(as_json=True) | 是 | 确认代码、交易所、币种等静态属性 |
| 名录 | get_stocks_list(country) / get_stocks_dict(country, columns) | list / list[dict] | 否 | 离线枚举代码清单,可当字典用 |
| 国家枚举 | get_stock_countries() | list | 否 | 确认 country 参数的合法取值 |
关键区分:只有「名录」与「国家枚举」两类函数是离线的。其余四类都要走 Investing.com 端点,因此在本站实测中全部不可用。这也是为什么「investpy 还能不能用」要分层回答。
历史数据返回的 DataFrame 长什么样?
官方 README 给了一个 AAPL 的示例输出,本站据此与源码中的映射函数逐列核对。utils/data.py 负责把抓到的每行数据组装成字典,再由 pandas 转成表。
Open High Low Close Volume Currency
Date
2010-01-04 30.49 30.64 30.34 30.57 123432176 USD
2010-01-05 30.66 30.80 30.46 30.63 150476160 USD
(示例取自官方 README 的 AAPL 输出;本站因端点 403 未能复现)
| 列 / 索引 | 类型 | 含义 | 使用注意点 |
|---|---|---|---|
Date(索引) | datetime | 交易日期,成为 DataFrame 的索引而非普通列 | 用 reset_index() 才会变成列;按日期切片时注意它是索引 |
Open | float | 开盘价 | 币种由 Currency 列给出,跨市场比较前必须先对齐 |
High / Low | float | 最高价 / 最低价 | 用于振幅类指标;口径以 Investing.com 页面为准 |
Close | float | 收盘价 | 官方未声明是否复权,做回测前需自行验证(见口径审计页) |
Volume | 整数 | 成交量 | 单位随市场不同(股 / 手 / 张),跨市场汇总前要确认 |
Currency | str | 该行的计价币种 | 同一 API 返回不同市场的数据时币种会变 |
exchange | — | 在数据对象中存在,但不写入 DataFrame | 想拿交易所信息得走 get_stock_information 或搜索结果 |
日期怎么传:格式、区间与常见错误
日期格式写错是最常见的调用失败之一。investpy 用的是 dd/mm/yyyy,不是 ISO 格式——这一点在把它接到已有脚本里时特别容易踩坑。
| 参数 | 要求的格式 | 正例 | 反例 |
|---|---|---|---|
from_date | dd/mm/yyyy 字符串 | '01/01/2019' | '2019-01-01'(ISO 写法,会校验失败) |
to_date | dd/mm/yyyy 字符串 | '31/12/2019' | '12/31/2019'(美式月在前,会被当成 12 月 31 日以外的日期) |
| 区间方向 | from 早于 to | 01/01/2019 → 01/01/2020 | 反向传参会触发参数校验错误 |
| 区间长度 | 源码内部会按区间切分成多次请求 | 十年区间会被拆分下载 | 超长区间意味着更多请求次数,也更容易触发对方限流 |
| 交易日 | 返回结果只含交易日 | 周末与假期不会出现 | 不要用日期数量反推自然日跨度 |
建议在调用前统一做一次格式转换:pd.to_datetime(d).strftime('%d/%m/%Y')。把 ISO 字符串直接传进去是新手最常见的一类失败,而且报错信息不一定直指日期,排查成本很高。
各资产类可用的时间粒度并不相同
源码里有两张粒度表:通用的 INTERVAL_FILTERS 与基金专用的 FUNDS_INTERVAL_FILTERS。基金只支持三种粒度。
| 粒度 | 通用支持 | 基金支持 | 适用场景 |
|---|---|---|---|
1min | 是 | 否 | 极短周期研究,数据量与限流风险都高 |
5mins / 15mins / 30mins | 是 | 否 | 日内策略;注意区分交易日跨度 |
1hour | 是 | 否 | 日内到小波段 |
5hours | 是 | 否 | 使用较少,务必先验证返回是否连续 |
daily | 是 | 是 | 最常见的回测粒度 |
weekly / monthly | 是 | 是 | 长期趋势与资产配置研究 |
| 传入非法值 | ERR#0120: introduced interval value does not exist | 报错会附上可用值清单,照抄即可 | |
注意参数名不同:历史数据函数用的是 interval,而 technical_indicators 用的也是 interval,但后者还额外要求 product_type(单数形式)。两处枚举不是同一套,混用会分别报 ERR#0120 与 ERR#0119。
历史数据取不到时,按这张表排查
六个真实错误码,分别对应「你写错了」和「对方拒绝了」两种情况。前者可修,后者不可修。
| 现象 / 错误码 | 源码触发条件 | 定性 | 处理方式 |
|---|---|---|---|
ERR#0027 | stock 不是字符串 | 调用方 | 传字符串代码,不要传数字 |
ERR#0039 / ERR#0025 | country 为 None 或不在枚举表内 | 调用方 | 先用 get_stock_countries() 拿合法值(全小写) |
ERR#0056 | 包内名录取不到(FileNotFoundError) | 环境 | 安装不完整,重装并确认 sdist 解包正常 |
ERR#0033 | 信息不可得(IndexError) | 对方 / 数据 | 该标的在 Investing.com 上没有对应字段,换标的或换字段 |
ERR#0015: error 403 | HTTP 状态码非 200 | 对方 / 网络 | 本机实测恒为 403,属当前不可修复类 |
ERR#0004 | 抓取成功但解析失败 | 双方 | 对方页面结构变更;需等库更新或自行改写解析 |
FAQ
investpy 常见问题:还能装吗、还能取数吗、换什么
investpy 返回的 DataFrame 有 exchange 列吗?
Data 对象确实保存了 exchange 属性,但 stock_to_dict() 只映射 Date / Open / High / Low / Close / Volume / Currency 七个键,交易所不会进入 DataFrame。需要交易所信息时请改用 get_stock_information,或从搜索结果的 exchange 字段读取。以源码实现为准。from_date 可以直接传 datetime 对象吗?
dd/mm/yyyy 字符串为准。本站不建议依赖隐式转换——最稳的做法是显式格式化:pd.to_datetime(d).strftime('%d/%m/%Y')。传 ISO 格式(YYYY-MM-DD)是最常见的失败来源之一。近期数据和历史数据有什么区别?
retrieve_recent_data() 只需资产标识、拿回的条数由对方决定,而 get_stock_historical_data 需要显式给 from_date 与 to_date。如果你需要可控区间,用后者;只想知道最新状态,用前者,但不要假设它一定包含当天数据。为什么同一只股票在不同国家下都能查到?
country 参数筛选很重要——只给代码不给国家时,容易命中另一个市场的同名记录。做数据入库时应把「代码 + 国家」当作联合主键。返回的数据是复权的吗?
现在还能调用这些函数吗?
ConnectionError: ERR#0015: error 403;离线名录类函数正常。本页的函数与字段说明来自 investpy 1.0.8 源码与官方 README,不是实测成功的调用结果,请以你自己环境的复测为准。