DEV Community

Cover image for 一套 API 对接全球跨资产行情:股票、外汇、指数、贵金属、加密货币统一接入实战
San Si wu
San Si wu

Posted on

一套 API 对接全球跨资产行情:股票、外汇、指数、贵金属、加密货币统一接入实战

前阵子要做个跨资产的监控小工具,把港股、美股、外汇、黄金还有比特币放一块儿看。原以为很简单,真开工才发现光数据源就够折腾:股票要接 A 源、外汇要接 B 源、加密货币又是另一套,每个源的鉴权方式、字段结构、K线周期定义全都不一样。数据接回来还得自己统一成一套格式,光字段映射就写了一百多行。

后来换了个思路,找一套能把多资产统一起来的行情 API,花了两个晚上把整个管道跑通了。这篇文章把接入过程写下来,代码都是能直接跑的,重点讲怎么用一个统一模型去接股票、外汇、指数这些不同资产,避免在数据格式转换上重复造轮子。

先搞清楚核心:多资产接口到底统一在哪

市面上多数行情源是按资产类别各做一套 API,字段名、时间戳单位、周期枚举全都对不上。这也是跨资产开发最头疼的地方。

我这次用的这套 API 核心逻辑是:所有资产类别走同一种 endpoint 结构、同一种鉴权、同一种 K 线数据结构。你只需要按资产类别换一下路径前缀,比如股票是 stock、外汇是 forex、指数是 indices,参数区就是三件套——region(市场代码)、code(产品代码)、kType(K线周期)。

举个例子,这是官网文档里的标准调用,拿港股腾讯控股(700)的 1 分钟线:

import requests

url = "https://api.itick.org/stock/kline?region=HK&code=700&kType=1"
headers = {
    "accept": "application/json",
    "token": "你的token"
}

resp = requests.get(url, headers=headers).json()
print(resp["code"], resp["msg"])
Enter fullscreen mode Exit fullscreen mode

返回的 K 线是标准的 OHLCV 结构:o/h/l/c 是开高低收,v 是成交量,t 是毫秒时间戳,tu 是成交额。这个结构在外汇、指数上完全一致。

一个函数打通多资产:股票、外汇、指数

既然结构统一,那干脆写一个通用函数,资产类别做成参数。外汇这边市场代码有点特别,EURUSD 的 region 是 GB,别照搬股票那套 US/HK 逻辑。指数像标普 500 用 SPX,region 同样是 GB

import requests

TOKEN = "你的token"

def fetch_kline(asset: str, region: str, code: str, ktype: int, limit: int = 10):
    """统一的K线拉取函数:asset 传 stock/forex/indices 等资产类别"""
    url = f"https://api.itick.org/{asset}/kline"
    params = {"region": region, "code": code, "kType": ktype, "limit": limit}
    resp = requests.get(url, params=params, headers={"accept": "application/json", "token": TOKEN})
    data = resp.json()
    if data["code"] != 0:
        raise RuntimeError(f"接口返回异常: {data['msg']}")
    return data["data"]

# 港股日线(kType=8 是日线)
hk_700 = fetch_kline("stock", "HK", "700", 8, 30)

# 外汇 EURUSD 5分钟线(kType=2)
eurusd = fetch_kline("forex", "GB", "EURUSD", 2, 30)

# 标普500 指数 1小时线(kType=5)
spx = fetch_kline("indices", "GB", "SPX", 5, 30)

print(f"港股700 最近收盘: {[k['c'] for k in hk_700][-1]}")
print(f"EURUSD 最近收盘: {[k['c'] for k in eurusd][-1]}")
print(f"SPX 最近收盘: {[k['c'] for k in spx][-1]}")
Enter fullscreen mode Exit fullscreen mode

kType 的映射建议对着文档确认,不要凭感觉猜:常见的 1 是 1 分钟、2 是 5 分钟、5 是 1 小时、8 是日线、9 是周线、10 是月线。不同资产类别的周期档位略有差异,外汇还有 2 小时、4 小时这些档位。

这样写的好处很明显:以后要加新的资产,只改一行 asset 参数,不用再写一套映射逻辑。

用统一结构算跨资产相关性

数据结构统一了,后面做分析就顺了。我把拉回来的几类资产收盘价塞进 pandas,算一下日收益率的相关性矩阵,看看港股、美股、黄金、比特币之间到底联动强不强:

import pandas as pd
import numpy as np

def closes_to_series(klines, name):
    df = pd.DataFrame(klines)
    df["dt"] = pd.to_datetime(df["t"], unit="ms")
    df = df.set_index("dt").sort_index()
    return df["c"].rename(name)

# 拉几类资产的日线(这里用前面封装的函数)
assets = {
    "HK700": fetch_kline("stock", "HK", "700", 8, 60),
    "SPX": fetch_kline("indices", "GB", "SPX", 8, 60),
    "XAUUSD": fetch_kline("forex", "GB", "XAUUSD", 8, 60),
    "BTCUSDT": fetch_kline("crypto", "GB", "BTCUSDT", 8, 60),
}

# 合并成一张表,计算日收益率
px = pd.concat(
    [closes_to_series(kl, name) for name, kl in assets.items()],
    axis=1
)
ret = px.pct_change().dropna()

# 相关性矩阵
corr = ret.corr().round(3)
print(corr)
Enter fullscreen mode Exit fullscreen mode

这里有两个点要留意。第一,不同资产的时间戳是按各自市场撮合时间记录的,合并前 sort_indexdropna 是必须的,否则对不齐。第二,加密货币是 7×24 小时交易,股票周末没行情,时间序列天然就不对齐,算相关性前先确认口径是"按交易日对齐"还是"按自然日对齐",不然结果会偏。

数据质量验证:别拿到数据就信

跨资产管道最容易被忽略的是数据质量。我一般拿到 K 线会做三道检查:

def validate_klines(klines):
    """基础数据质量检查"""
    if not klines:
        return "空数据"
    df = pd.DataFrame(klines)
    # 1. OHLC 逻辑校验:high 必须 >= open 和 close
    bad_ohlc = df[(df["h"] < df[["o", "c"]].max(axis=1))].shape[0]
    # 2. 时间戳单调递增
    monotonic = df["t"].is_monotonic_increasing
    # 3. 周期完整性:相邻K线时间戳间隔应该一致
    gaps = df["t"].diff().dropna().unique()
    return {
        "bad_ohlc_rows": bad_ohlc,
        "timestamps_monotonic": bool(monotonic),
        "unique_intervals": len(gaps),
    }

print(validate_klines(hk_700))
Enter fullscreen mode Exit fullscreen mode

做过一次就会知道,这种检查不是走形式——有的数据源在停牌日会返回重复时间戳,有的在极速行情下会出现 high 小于 close 的脏数据。统一结构 + 统一校验函数,换资产类别时检查逻辑一次复用。

几个踩过的坑

  1. 外汇的 region 别套股票逻辑:EURUSD、XAUUSD 这些 region 是 GB,一开始我按股票习惯填了别的市场代码,直接返回空。不同资产类别的 region 取值,看文档的枚举最靠谱。
  2. kType 档位不是全资产通用:股票、指数、外汇的周期枚举不完全一样,比如外汇多 2 小时、4 小时档。写通用函数时,周期档位要做成配置,别硬编码。
  3. 时间戳单位要确认:返回的时间戳是毫秒,pd.to_datetime(..., unit="ms") 别漏了 unit 参数,漏了会把日期算到 1970 年去。
  4. 免费档有调用频率限制:REST 接口每分钟有次数上限,批量拉多资产历史数据时记得加 time.sleep() 控制节奏,不然会被限流。
  5. token 放环境变量:代码里别写死,尤其是要推到 GitHub 的时候,这个坑我踩过不止一次。

小结

跨资产行情接入这件事,选对数据源能省掉一大半工作量。核心就看三点:数据结构是否统一、寻址方式是否一致、鉴权是否简单。这套 API 把股票、外汇、指数、贵金属、加密货币都收敛到同一个 OHLCV 模型下,对我来说最大的收益是少写了上百行字段映射代码。

如果你也在做跨资产的监控、回测或者数据管道,建议先拿免费档把两三个资产类别的 K 线拉通,重点验证数据结构和时间戳对齐这两个环节,跑通了再往上层加分析逻辑。详细的接口字段和 kType 映射,可以参考官方文档,Python/Java/Go 的 SDK 都有现成的示例,官网在这里

Top comments (0)