从 Alpha Vantage 迁移到 Narwhal

从 Alpha Vantage 迁移时,把 apikey 查询参数换成 Authorization: Bearer 请求头,并把每个 function 对应到 Narwhal 的路径。CPI、失业率、外汇、股票报价、日线、金属、石油和加密货币都有直接对应的接口,技术指标、期权和新闻情绪则没有。

谁该迁移,谁该留下

团队转用 Narwhal 是出于许可和配额方面的原因。Alpha Vantage 将免费密钥和高级密钥限于个人非商业用途,除非你们另有书面约定,而每个 Narwhal 账户都包含商业应用使用权。Alpha Vantage 免费密钥每天允许 25 次请求;Narwhal 为每个账户在前 12 个月内每月提供 $10 免费额度。Alpha Vantage 的经济序列仅覆盖美国,而 Narwhal 可读取 37 个国家的经济数据。一个 Narwhal 密钥也可通过 MCP 使用,适合智能体项目。

技术指标、期权和新闻情绪请继续使用 Alpha Vantage。它列出了 25 年以上的日线历史,而 Narwhal 返回每个系列的完整历史。Narwhal 的股票覆盖 42 家交易所,其中不包括东京。

把每个 function 对应到端点

下列每个路径都在 2026 年 11 月 3 日用有效密钥调用过。Narwhal 的 ID 带有交易所前缀,例如 XNYS:IBM,所以请先用 /v1/equities/search 查找股票。

Alpha Vantage 函数Narwhal 端点差异
CURRENCY_EXCHANGE_RATEGET /v1/fx/rates/{base}?currencies=一次调用可获取多种货币。rate 带有时间戳,没有买价和卖价。
FX_DAILYGET /v1/fx/rates/{base}/observations每天一个汇率。如需开盘价、最高价、最低价和收盘价,请以 USD 为基础货币调用 /v1/fx/rates/USD/bars。
GLOBAL_QUOTEGET /v1/equities/{id}/pricechange_percent 不带百分号。
TIME_SERIES_DAILYGET /v1/equities/{id}/bars?interval=1d周线和月线没有对应端点,请自行汇总日线。
SYMBOL_SEARCHGET /v1/equities/search用 country 缩小结果范围。
DIGITAL_CURRENCY_DAILYGET /v1/crypto/{pair}/bars交易对写作 BTC-USD。
CPIGET /v1/economics/{country}/cpi/observations使用 period,而不是 date。
INFLATIONGET /v1/economics/{country}/inflation/observations提供月度同比、环比和年初至今,而 Alpha Vantage 给出的是年度百分比。
UNEMPLOYMENTGET /v1/economics/{country}/unemployment/observations字段名为 rate。
REAL_GDPGET /v1/economics/{country}/gdp-growth/observations仅提供增长率。/gdp 返回的是年化水平值,比较之前请先核对其定义。
FEDERAL_FUNDS_RATEGET /v1/economics/USA/central-bank/policy-rate/history给出的是以 lower_bound 和 upper_bound 表示的目标区间,而不是有效利率。
TREASURY_YIELDGET /v1/economics/USA/yield-curve/history?maturity=10y期限使用小写,如 10y。
RETAIL_SALES, DURABLES, NONFARM_PAYROLLGET /v1/economics/calendar读取每次发布的 values。非农就业人数以千人为单位的月度变化给出。
GOLD_SILVER_SPOT, WTI, BRENTGET /v1/commodities/spot/{commodity}/{currency}最新价格,例如 XAU/USD。历史数据在 /bars。
INCOME_STATEMENT, BALANCE_SHEET, CASH_FLOWGET /v1/companies/{company_id}/financials?statement=基于 usa:0000051143 这类 ID 的申报文件数据。

Narwhal 中没有对应功能的部分

这些功能请继续使用 Alpha Vantage 或其他数据源。

  • 技术指标:SMA、RSI、MACD 等 53 个 function。
  • 期权,包括实时和历史数据。
  • NEWS_SENTIMENT 和 IPO_CALENDAR。
  • 指数覆盖面:INDEX_DATA 列出 200 多个指数,而 Narwhal 提供价格的有 18 个。

迁移三个调用

  1. 设置密钥 获取免费密钥并保存在 NARWHAL_API_KEY 中。Narwhal 从 Authorization: Bearer 请求头读取密钥,因此请从每个 URL 中删除 apikey。
  2. 替换 CPI 调用 Narwhal 的路径写明国家,并返回最新值。需要历史数据时,追加带 start 和 end 的 /observations,返回的指数值与 Alpha Vantage 列出的相同。
    curl,CPI 迁移前后对比
    # Ran 2026-11-03: Alpha Vantage 200 OK with the demo key, Narwhal 200 OK both calls
    # Before: Alpha Vantage, CPI
    curl "https://www.alphavantage.co/query?function=CPI&interval=monthly&apikey=demo"
    
    # After: Narwhal, latest US CPI
    curl "https://api.narwhalapi.com/v1/economics/USA/cpi" \
      -H "Authorization: Bearer $NARWHAL_API_KEY"
    
    # After: Narwhal, CPI for July to September
    curl -G \
      --url "https://api.narwhalapi.com/v1/economics/USA/cpi/observations" \
      -d start=2026-07 -d end=2026-09 \
      -H "Authorization: Bearer $NARWHAL_API_KEY"
  3. 替换报价和外汇调用 Narwhal 通过上市 ID 查找股票,通过基础货币查询汇率,目标货币放在 currencies 中。
    curl,报价和外汇迁移前后对比
    # Ran 2026-11-03: Alpha Vantage quote 200 OK (demo key), Narwhal quote and FX 200 OK
    # Before: Alpha Vantage, last price for IBM
    curl "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=IBM&apikey=demo"
    
    # After: Narwhal, same stock (ids look like XNYS:IBM)
    curl "https://api.narwhalapi.com/v1/equities/XNYS:IBM/price" \
      -H "Authorization: Bearer $NARWHAL_API_KEY"
    
    # Before: Alpha Vantage, USD to JPY (request taken from its documentation, not run)
    curl -G \
      --url "https://www.alphavantage.co/query" \
      -d function=CURRENCY_EXCHANGE_RATE -d from_currency=USD \
      -d to_currency=JPY -d apikey=YOUR_ALPHA_VANTAGE_KEY
    
    # After: Narwhal, USD to JPY
    curl "https://api.narwhalapi.com/v1/fx/rates/USD?currencies=JPY" \
      -H "Authorization: Bearer $NARWHAL_API_KEY"
  4. 重写解析器 字段不再带编号,系列变成数组。该脚本会执行全部三个 Narwhal 调用。
    Python,Narwhal 上的三个调用
    # Ran 2026-11-03: 200 OK for all three calls
    import os
    import requests
    
    session = requests.Session()
    session.headers["Authorization"] = f"Bearer {os.environ['NARWHAL_API_KEY']}"
    
    
    def get(path, **params):
        r = session.get("https://api.narwhalapi.com" + path, params=params, timeout=10)
        r.raise_for_status()
        return r.json()
    
    
    cpi = get("/v1/economics/USA/cpi")  # was function=CPI
    print(cpi["period"], cpi["value"])
    
    ibm = get("/v1/equities/search", q="IBM", country="USA")["results"][0]["id"]
    print(ibm, get(f"/v1/equities/{ibm}/price")["price"])  # was GLOBAL_QUOTE
    
    fx = get("/v1/fx/rates/USD", currencies="JPY")["rates"][0]  # was CURRENCY_EXCHANGE_RATE
    print(fx["currency"], fx["rate"])
  5. 对比输出 用相同的输入运行两个提供方。2026-09 的美国 CPI 在两边都是 336.940,11 月 2 日 IBM 的收盘价在两边都是 252.51。

响应有何不同

Alpha Vantage 把汇率嵌套在 Realtime Currency Exchange Rate 之下,并使用带编号的键。Narwhal 返回 rates 数组,每种货币一个对象。

方面Alpha VantageNarwhal
字段名带编号,如 05. price简洁,如 price
序列以日期为键的对象,最新的在前observations 或 bars 数组,最旧的在前
数字字符串字符串,因此请按十进制数解析
分页无;outputsize 可选择 100 个点或全部next_cursor
错误HTTP 200,附带 Information 或 Error MessageHTTP 错误状态码,以及包含 code 的响应体
Alpha Vantage 的 CPI(节选)
{
  "name": "Consumer Price Index for all Urban Consumers",
  "interval": "monthly",
  "unit": "index 1982-1984=100",
  "data": [
    { "date": "2026-09-01", "value": "336.940" },
    { "date": "2026-08-01", "value": "334.980" }
  ]
}
Narwhal 的 CPI(节选)
{
  "country": "USA",
  "period": "2026-09",
  "value": "336.940",
  "index_base": "1982-84=100",
  "released_on": "2026-10-14"
}
Alpha Vantage 的报价(节选)
{
  "Global Quote": {
    "01. symbol": "IBM",
    "05. price": "252.5100",
    "07. latest trading day": "2026-11-02",
    "08. previous close": "257.8100",
    "10. change percent": "-2.0558%"
  }
}
Narwhal 的报价(节选)
{
  "id": "XNYS:IBM",
  "symbol": "IBM",
  "currency": "USD",
  "price": "252.51",
  "previous_close": "257.81",
  "change_percent": "-2.06",
  "market_session": "closed",
  "timestamp": "2026-11-02T21:00:00Z",
  "stale": false
}

应对速率限制

Alpha Vantage 免费密钥每天允许 25 次请求。其付费方案每分钟 75 到 1,200 次请求,没有每日上限,每月 $49.99 起。Narwhal 在免费额度下每分钟允许 50 次请求,有付费额度后每分钟 500 次,调用费用为每 1,000 次 $2 到 $10。

Alpha Vantage 在 200 响应内部报告问题,所以只检查状态码会漏掉;对于示例之外的调用,演示密钥返回了 Information 提示。Narwhal 在你发送过快时返回 429 rate_limit_exceeded:等待 Retry-After 请求头给出的时间后重试。余额用完时返回 402 insufficient_credits:请充值。两者都不计费。每个成功响应都带有 X-RateLimit-Remaining 和 X-RateLimit-Reset。缓存请参阅缓存响应并处理 429 错误。

Python,按 Retry-After 重试
# 200 OK on both test calls; the 402 and 429 branches follow the documented codes
import os
import time
import requests

session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['NARWHAL_API_KEY']}"


def get(path, **params):
    for attempt in range(4):
        r = session.get("https://api.narwhalapi.com" + path, params=params, timeout=10)
        if r.status_code == 402:
            raise RuntimeError("Out of credit; add credit in the dashboard.")
        if r.status_code == 429:
            time.sleep(float(r.headers.get("Retry-After", 2)))
            continue
        r.raise_for_status()
        return r.json()
    raise RuntimeError(f"Gave up on {path}")

如何查找股票的 ID?

调用 /v1/equities/search?q=IBM&country=USA。每条结果都有一个用于价格和 K 线的 id(如 XNYS:IBM),以及一个用于财务数据的 company_id(如 usa:0000051143)。

其余部分可以继续用 Alpha Vantage 吗?

可以。每个提供商都有各自的密钥和计费,因此只迁移表中的系列,指标、期权和情绪数据保留在原处。其他差异请参阅Narwhal 与 Alpha Vantage 的对比。

迁移检查清单

  • 列出代码调用的每个 function,并对照表格逐一标记。
  • 将股票代码一次性解析为上市 ID,并保存这些 ID。
  • 将密钥移到 Bearer 请求头,并从日志里的 URL 中去掉。
  • 重写解析器,以适配简洁的名称、最旧在前的数组和字符串形式的数字。
  • 将对 Information 的检查替换为对状态码和 code 的检查。
  • 比较数值之前,先确认 GDP 和联邦基金利率的定义。
  • 按 Retry-After 重试,遇到 insufficient_credits 时停止。
  • 切换之前,让两个提供方并行运行并比较数值。

发布于。

后续步骤