学习/时间序列

历史汇率与时间序列数据

使用 /v1/range 获取多种货币的历史汇率,并加载到 pandas 或其他工具。

ERexchangerate.dev·2026年6月19日·阅读约 6 分钟

范围接口返回带分页、来源和填充标记的已保存观测。

要点
JSON 每页最多 366 条观测值;has_more 为 true 时,用 next_cursor 获取下一页。
1,830 天是请求上限,不代表每个货币对都有这么深的历史。检查 source、行和 data: []。
示例没有 2026 年 6 月 13 日,因为范围接口返回保存的观测,不会为每个日历日创建行。
不可以。这些是指示性汇率;请查看 notice 和 source。

使用范围接口

start_date 和 end_date 包含首尾日期。base 默认为 USD,symbols 用逗号分隔。也可以打开英文历史工具。

data 包含保存的观测行。继续使用 has_more 和 next_cursor;CSV 和 Parquet 可下载支持窗口。

GET /v1/rangecopy
$ curl -G "https://api.exchangerate.dev/v1/range" \
    -H "Authorization: Bearer exr_live_..." \
    --data-urlencode "base=USD" \
    --data-urlencode "symbols=EUR,GBP" \
    --data-urlencode "start_date=2026-06-10" \
    --data-urlencode "end_date=2026-06-13"

读取 JSON 响应

data 包含保存的观测行。继续使用 has_more 和 next_cursor;CSV 和 Parquet 可下载支持窗口。

JSONcopy
{
  "result": "success",
  "base": "USD",
  "start_date": "2026-06-10",
  "end_date": "2026-06-13",
  "data": [
    { "date": "2026-06-10", "rates": { "EUR": 0.86663, "GBP": 0.74727 },
      "source": "ecb_daily", "is_forward_filled": false },
    { "date": "2026-06-11", "rates": { "EUR": 0.86678, "GBP": 0.74829 },
      "source": "ecb_daily", "is_forward_filled": false },
    { "date": "2026-06-12", "rates": { "EUR": 0.86453, "GBP": 0.74613 },
      "source": "ecb_daily", "is_forward_filled": false }
  ],
  "has_more": false,
  "next_cursor": null
}

缺少的日历日期

示例没有 2026 年 6 月 13 日,因为范围接口返回保存的观测,不会为每个日历日创建行。

用 Python 分页

这个循环会跟随每一个游标。

Python · requestscopy
import requests

API = "https://api.exchangerate.dev/v1"
KEY = "exr_live_..."   # free key at https://exchangerate.dev/signup

params = {
    "base": "USD",
    "symbols": "EUR,GBP",
    "start_date": "2026-06-10",
    "end_date": "2026-06-13",
}

rows = []
while True:
    resp = requests.get(
        f"{API}/range",
        headers={"Authorization": f"Bearer {KEY}"},
        params=params,
        timeout=10,
    )
    resp.raise_for_status()
    data = resp.json()
    rows.extend(data["data"])
    if not data["has_more"]:
        break
    cursor = data.get("next_cursor")
    if not cursor or cursor <= params.get("cursor", ""):
        raise RuntimeError("Incomplete historical response")
    params["cursor"] = cursor

for row in rows:
    filled = row["is_forward_filled"]
    print(row["date"], row["rates"]["EUR"], row["rates"]["GBP"], "filled" if filled else "")

区分观测值和顺延值

范围观测的 is_forward_filled 为 false;日期查询可能返回之前的值并标记为 true。

周末不是观测值
范围结果省略 2026 年 6 月 13 日。直接查询该日期可能返回之前的值,并标记 is_forward_filled 为 true。

选择日期查询或范围查询

单日查询适合检查一天;范围查询适合图表、回填和批量分析。

维度日期查询范围查询
请求每个日期一次一次请求加分页
响应一天data 数组

检查覆盖范围

1,830 天是请求上限,不代表每个货币对都有这么深的历史。检查 source、行和 data: []。

pandas

加载到 pandas 后按日期排序,并在计算前排除顺延值。

Python · pandascopy
import pandas as pd

# rows contains every page from the loop above
df = pd.json_normalize(rows)
df["date"] = pd.to_datetime(df["date"])
df = df.set_index("date").sort_index()

# keep only rows that were actually published that day
df = df[~df["is_forward_filled"]]

print(df[["rates.EUR", "rates.GBP"]].tail())

pandas 不是必需的;也可以使用其他工具处理相同的行。

在历史汇率工具中查询日期(英文)

ER
exchangerate.dev
FX 数据集成实用指南

继续阅读

Tutorial用 Python 获取汇率阅读
比较Fixer vs exchangerate.dev比较Open Exchange Rates vs exchangerate.dev比较Currencylayer vs exchangerate.dev指南用 JavaScript 和 Node.js 进行货币换算指南用 Python 获取汇率指南在 Next.js 与 TypeScript 中使用汇率实时汇率EUR/USD实时汇率GBP/USD实时汇率USD/JPY