黄金行情API怎么用?用Python复盘CPI前后的金价变化

TickDB Research ·

摘要:面向需要黄金行情API的量化研究人员,本文以CPI事件复盘为例,获取XAUUSD历史K线,对齐公布时刻,计算不同观察窗口的价格变化。文章提供实际运行的Python示例、结果表及数据检查方法,帮助团队统一比较基准,整理可复核的事件样本,为后续研究与策略回测准备输入。

把同一场CPI公布后的黄金行情按两个起点重算,前5分钟的变化分别约为−0.91%和−0.32%。终点没有变,起点的选择却让研究表少算了一段行情。

做事件研究,先固定公布时刻、公布前的比较基准和观察窗口,再取数计算,结果才有办法比较。这次使用TickDB的黄金历史K线作为输入。TickDB是统一市场数据服务,本例通过REST按时间范围取回行情,研究表与检查逻辑由Python生成。

下面把一次已发生的CPI行情,整理成可以重复计算的事件样本。你可以沿用同样的方法,逐次积累研究数据。

先确定你想从CPI行情里研究什么

CPI对黄金的影响,值得研究的地方在于市场如何重新理解通胀与利率前景。

黄金的购买力保护作用、持有黄金相对于有息资产的机会成本、美元计价资产的变化,都可能参与其中。芝加哥联储2021年的《What Drives Gold Prices?》讨论了通胀预期、实际利率与宏观悲观预期等因素;不同阶段,这些关系的表现也有差异。

世界黄金协会2022年9月的一篇分析提供了很好的反例:当时通胀处在高位,但利率上升与强美元给黄金带来压力。直接把“通胀高”翻译成“金价应该涨”,会省略不少判断。

因此,整理事件样本时,至少要先回答两个问题:你研究的是公布后的第一段价格变化,还是变化能否延续?你比较的是每次事件的同一个窗口,还是事后挑出的高低点?

本例采用固定窗口:公布后1、5、15、30和60分钟,共用一个公布前基准。这样后续再加入其他事件时,研究表有相同的计算定义。

把事件时刻与行情数据对齐

示例选择2026年10月14日公布的美国9月CPI。BLS归档公告标明,发布时间为当天美东08:30,对应UTC 12:30、北京时间20:30。

日期不能丢。2026年11月10日的美东08:30,对应北京时间21:30,已经换了一个小时。脚本使用America/New_York按事件日期转换,不手工写死北京时间。

这次查询的是XAUUSD一分钟K线,范围从公布前10分钟到公布后60分钟之前,共70根。2026年11月9日实际运行时,所需记录没有分钟缺口或重复时间戳,开高低收关系检查也通过。

一分钟K线的时间标记还需要核对。本例另外取了同段五分钟K线:14组完整五分钟记录的开高低收,与时间标签从t到t+4分钟的一分钟聚合全部相符。因此,下面按周期起点解释本例时间标签。

对应到计算中:

用途采用的记录为什么这样选
公布前基准UTC 12:29这一分钟的收盘报价取公布前最后一根完整分钟记录
前5分钟终值UTC 12:34这一分钟的收盘报价对应12:35窗口结束之前的末根记录
前30分钟终值UTC 12:59这一分钟的收盘报价对应13:00窗口结束之前的末根记录

K线标签与收盘价的可用时刻要分开理解。标着12:30的一分钟K线,收盘报价已经包含公布后的那一分钟,不能再把它当作公布前输入。

同一段行情怎样算出不同结果

这次返回的报价中,公布前基准为4152.48,前5分钟末根收盘为4114.72。

按统一公式计算:

窗口价格变化 =(窗口末值 ÷ 公布前基准 − 1)× 100%
             =(4114.72 ÷ 4152.48 − 1)× 100%
             ≈ −0.9093%

如果把事件首分钟的收盘4127.85误当作基准,同一个终点就会得到约−0.3181%。首分钟的跌幅已经被放进起点,后面的计算自然少了一段。

image.png

图中采用同一真实终点报价,仅改变比较基准。对照用的事件首分钟收盘已经包含公布后行情。

这种差异会影响研究表对事件反应强度的描述。把基准价、所属K线和窗口定义一起保存,后续交接时就能沿原始输入重新计算。

本例各窗口结果如下,报价均沿用接口原值,变化率共用4152.48这一基准。

观察窗口窗口末根收盘报价相对基准变化
1分钟4127.85−0.5931%
5分钟4114.72−0.9093%
15分钟4092.75−1.4384%
30分钟4097.22−1.3308%
60分钟4089.55−1.5155%

image.png

图按每根一分钟K线结束位置排列收盘结果。来源为2026年11月9日查询的TickDB XAUUSD历史行情;基准为公布前末根完整分钟收盘。

从15分钟到30分钟,报价收回了部分跌幅;到60分钟,相对公布前基准的跌幅又扩大。只看一个终点,很容易把不同阶段混成一句“公布后跌了多少”。固定窗口能保留这种过程差异。

用Python生成可复核的研究表

下面是此次实际运行的脚本。使用Python 3.10及以上版本,安装requests,并在本机设置TICKDB_API_KEY环境变量。Key需要具备目标品种及指定历史范围的查询权限。若运行环境缺少时区数据库,可安装tzdata供ZoneInfo使用。

将代码保存为gold_cpi_replay.py后运行。它会保存原始响应、请求参数、K线CSV与窗口结果。API报错、出现重复记录或缺少所需分钟时,脚本会停止,留给研究者检查。

"""Python 3.10+; pip install requests. Key comes from TICKDB_API_KEY."""
import os, json, csv
from pathlib import Path
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
from decimal import Decimal
import requests

EVENT = datetime(2026, 10, 14, 8, 30, tzinfo=ZoneInfo('America/New_York'))
T = int(EVENT.timestamp() * 1000)
STEP = 60_000

def fetch(out):
    params = dict(symbol='XAUUSD', type='forex', interval='1m',
                  start_time=T-10*STEP, end_time=T+60*STEP-1, limit=1000)
    r = requests.get('https://api.tickdb.ai/v1/market/kline', params=params,
                     headers={'X-API-Key': os.environ['TICKDB_API_KEY']}, timeout=30)
    (out/'response.json').write_bytes(r.content)
    meta = dict(http_status=r.status_code, params=params,
                retrieved_utc=datetime.now(timezone.utc).isoformat())
    (out/'request.json').write_text(json.dumps(meta, indent=2))
    r.raise_for_status()
    body = r.json()
    if body.get('code') != 0:
        raise RuntimeError(f"API returned code={body.get('code')}; inspect saved response")
    data=body['data']
    if data.get('symbol')!='XAUUSD' or data.get('interval')!='1m':
        raise ValueError('Unexpected symbol or interval')
    return data['klines']

def calculate(rows,out):
    # Sample cross-interval audit supports bar-start labels. A close becomes
    # available at that bar's END; never use the event bar close as pre-event input.
    by_time={int(r['time']):r for r in rows}
    if len(by_time)!=len(rows):raise ValueError('Duplicate bar timestamp')
    expected=set(range(T-10*STEP,T+60*STEP,STEP))
    missing=sorted(expected-set(by_time))
    if missing:raise ValueError(f'Missing {len(missing)} expected bars; do not fill silently')
    bars=[by_time[t] for t in sorted(expected)]
    for r in bars:
        o,h,l,c=(Decimal(r[k]) for k in ('open','high','low','close'))
        if not (0<l<=min(o,c)<=max(o,c)<=h):raise ValueError('Invalid OHLC')
    baseline=Decimal(by_time[T-STEP]['close'])
    result=[]
    for minutes in (1,5,15,30,60):
        last=by_time[T+(minutes-1)*STEP]
        close=Decimal(last['close'])
        result.append(dict(minutes=minutes,baseline=str(baseline),
            last_bar_start_utc=datetime.fromtimestamp(last['time']/1000,timezone.utc).isoformat(),
            window_end_utc=datetime.fromtimestamp((T+minutes*STEP)/1000,timezone.utc).isoformat(),
            close=str(close),change_pct=str((close/baseline-1)*100)))
    with (out/'windows.csv').open('w',newline='') as f:
        w=csv.DictWriter(f,fieldnames=list(result[0]));w.writeheader();w.writerows(result)
    with (out/'klines.csv').open('w',newline='') as f:
        w=csv.DictWriter(f,fieldnames=['time','open','high','low','close','volume'],extrasaction='ignore');w.writeheader();w.writerows(bars)
    summary=dict(symbol='XAUUSD',event_utc=EVENT.astimezone(timezone.utc).isoformat(),
        expected_bars=len(expected),received_bars=len(rows),used_bars=len(bars),missing=missing,
        baseline_bar_start_utc=datetime.fromtimestamp((T-STEP)/1000,timezone.utc).isoformat(),
        baseline=str(baseline),windows=result)
    (out/'summary.json').write_text(json.dumps(summary,indent=2))
    return summary

def main():
    out=Path(os.environ.get('GOLD_OUTPUT_DIR','gold_cpi_output'));out.mkdir(parents=True,exist_ok=True)
    result=calculate(fetch(out),out)
    print(json.dumps(result,ensure_ascii=False,indent=2))

if __name__=='__main__':main()

运行后,windows.csv记录每个窗口的基准、末根时间、窗口结束时刻、末值和变化率;response.json保留对应原始返回。把这些文件与事件信息一起保存,团队就有了可重复计算的研究输入。

从一次复盘走向事件研究

下一步可以按相同定义增加事件日期,观察不同CPI背景下的价格变化分布。需要研究“是否超预期”时,再加入公布前已经形成、来源和时点明确的预期数据;公布值与预期必须是相同指标和口径。

进一步做策略回测,还要定义何时能生成信号、何时成交,以及点差、滑点、手续费等假设。分钟最高价和最低价适合描述区间,不能直接拿来充当可成交进出场价格。

需要查询同类数据时,可查看黄金与外汇行情API的覆盖及接入说明,核对品种与历史范围,再按本文的固定窗口增加研究样本。

先把每一次事件的原始输入和计算定义留下来。等样本积累起来,团队才能比较哪些现象反复出现,哪些只是某一次行情的特点。

参考资料

  • 美国劳工统计局,Consumer Price Index News Release,2026年10月14日归档公告。

  • 美国劳工统计局,Consumer Price Index发布日程及CPI Frequently Asked Questions,核对日期2026年11月9日。

  • 芝加哥联邦储备银行,What Drives Gold Prices?,Chicago Fed Letter第464期,2021年11月。

  • 世界黄金协会,Why has gold not performed better in 2022 despite high inflation?,2022年9月22日。

  • TickDB,K线查询与产品查询文档;XAUUSD历史行情实际调用,2026年11月9日。

  • Python官方文档,zoneinfo模块的数据来源说明,核对日期2026年11月9日。

相关文章

免费股票API怎么选?从个人研究到产品上线,先分清这几种限制

面向准备将研究原型交付为行情看板的金融产品负责人,本文以“20只美股、每10秒刷新”为例,拆解免费股票API的数据范围、更新频率、额度、订阅和使用条件。结合AKShare、Alpha Vantage、Twelve Data与TickDB的官方说明,以及一次TickDB MCP调用记录,提供可填写的选型判断表和可运行的用量计算代码,帮助团队判断免费方案能用到哪一步、交付前还需补什么。

TickDB Research ·

外汇行情还在更新吗?用 Python 订阅 EURUSD 并记录双时间

适合正在开发外汇报价监控、需要确认脚本持续收到行情的 Python 开发者。使用 TickDB 的 WebSocket 行情订阅,记录 EURUSD 报价、数据时间和本机接收时间,生成原始消息与 CSV。通过目标报价数量、接收间隔和数据时间推进情况,区分连接仍在、消息到达与数据更新。本次30秒订阅观察收到38条目标报价;代码支持有限运行和自动保存结果,方便在自己的环境复查。

TickDB Research ·

一个 API 同时接 A 股、港股、美股、加密和外汇,怎样验证才算数?

直接答案 多数人把行情 API 的覆盖列表当成菜单,以为列出来的就能点。实际上,那是一份意向书,不是交付承诺。判断一个 API 是否真正实现了多资产统一接入,你需要挑 A 股、港股、美股、加密货币和外汇各一个真实品种,用同一次查询验证五件事:同一次调用能否通过鉴权并返回结果,五个品种代码能否被正确解析,返回结构是否共享一套核心字段,时间戳格式是否明确且一致,以及无效 symbol 是报错、忽略

TickDB Research ·

股票API选型必备:国内外主流服务商与工具大全(44种方案完整指南)

Wind、同花顺iFinD、东方财富Choice、Tushare、AKShare、Bloomberg、LSEG、FactSet、TickDB、Massive、Alpha Vantage、Databento、Morningstar,该从哪一种开始?这份指南将44种国内外数据服务、平台与工具分成10类,按个人研究、量化回测、行情监控、应用开发、AI投研和交易连接等需求提供查找路径,逐项说明核心能力、适用人群、接入流程与使用条件,并附可运行代码、需求模板和验收清单,选型时查,接入时用。

TickDB Research ·

美股数据源选型指南:看盘、回测、做产品,别把钱花错地方

给量化团队选美股数据源,或为行情产品接入API,花出去的除了订阅费,还有接入、核对、重跑和维护的时间。看盘、历史回测、客户展示,各自需要什么数据?本文从具体交付任务出发,拆清价格对象、历史口径、持续更新与使用权限,结合官方资料和真实接口返回,给出一张需求验收表与可运行代码,帮助采购负责人、研究员和产品经理在付款前对齐要求。

TickDB Research ·