国内期货行情数据源选型:四家交易所-底层制度拆解,三份实测验证行情数据源:帮你做决策
作者: TickDB Research · 发布: 2026/9/8 · 阅读: 72
标签: 知乎
国内期货数据源选型这件事,大多数人从第一天就做错了。他们从“哪个数据源的接口好用”开始,而不是从“国内期货的制度规则和其他市场差多少”开始。结果是:你选了一个接口很顺手的数据源,但你的回测从第一根 K 线起,就在一个错误的时间框架里运行。
2025 年全年,中国期货市场成交额超过 766 万亿元(中期协口径),商品期货成交量占全球的 72.3%(FIA 口径)。这个量级的市场里没有新手保护期。它的数据复杂性来自一个很多人没意识到的事实:上期所、大商所、郑商所、中金所,四家交易所的交易制度本身就各不相同。结算价算法不同,夜盘时段不同,合约月份设计不同。这些差异全部是明文规定,不是数据商的自由裁量。
你花三个月写的策略,实盘亏的钱可能不是策略的错,是数据源替你做的拼接决定——回测里那部分收益根本不存在,实盘一跑就蒸发。三个月推倒重来,亏的是真金白银加时间。
选国内期货数据源,第一件事不是调行情接口,是先回答三个问题:你要交易的品种,在它所属的交易所里,合约怎么设计?结算价怎么算?夜盘怎么归属?答不上来,数据源给什么你就信什么——这是最贵的信。
全文导览:第一节拆解国内期货的制度分层——这是所有数据问题的根源;第二节讲数据源应该承担的角色;第三节用真实代码验证制度信息是否被保留;第四节给选型判断框架;文末附 TickDB 期货行情的体系化能力图谱。
一、同样叫“期货”,四家交易所的制度分层
1.1 合约月份设计:换月不是数据源的问题,是制度的问题
国内期货没有“这只品种”的价格,只有“这个合约”的价格。每个合约有独立到期日,到期前必须把持仓迁到下一个合约——这就是换月。但“下一个合约”是什么,取决于交易所的合约月份设计:
| 品种 | 交易所 | 合约月份 | 最后交易日 |
|---|---|---|---|
| 阴极铜 | 上期所 | 1–12 月,全年有合约 | 合约月份第 15 日 |
| 豆粕 | 大商所 | 1/3/5/7/8/9/11/12 月 | 合约月份第 10 个交易日 |
| 白糖 | 郑商所 | 1/3/5/7/9/11 月(仅奇数月) | 合约月份第 10 个交易日 |
| 沪深300 股指 | 中金所 | 当月 + 下月 + 两个季月 | 到期月第三个星期五 |
解读这张表:沪铜任何时候都有 12 个月份的合约同时在交易,豆粕有 4 个月份是空的,白糖隔月才有合约,股指期货是季月嵌套。同一个“主力合约切换”,在不同品种上意味着完全不同的时间节奏。
换月跳空不是数据错误,它是两个合约价格差异的直接体现。这个差异有定价依据——持仓成本:资金利息、仓储费用、便利收益的合力。数据源把新旧合约价格直接拼接后,跳空被当成趋势信号计算。策略被教着去交易展期价差,而这个价差在实盘中需要真金白银承担。回测赚的是虚拟钱,实盘亏的是真钱。
做三年回测,你面对的是 36 个不同的沪铜合约。连续合约是一个合成物——它的构造方式应该由你的策略逻辑决定,而不是由数据源在黑盒里替你决定。
1.2 结算价与收盘价:同一个“价”字,两种制度功能
股票的收盘价就是最后一笔成交价。期货不是。
国内期货有两个核心价格:收盘价——最后一笔成交价,反映最后时刻的市场均衡;结算价——交易所计算的当日成交量加权平均价,用于保证金计算和下一交易日涨跌停板基准。
关键不在于有两个价格,而在于:“结算价”这个词,在不同交易所的定义不同。 上期所和大商所的日结算价是当日全部成交的成交量加权平均;中金所股指期货的日结算价是最后一小时成交的成交量加权平均。如果品种有夜盘,上期所/大商所的结算价计算包含夜盘时段;中金所没有夜盘,结算价只覆盖日盘。
假设你做跨交易所价差策略,一手沪铜、一手股指期货。两个数据源都给你“结算价”,一个覆盖夜盘四个小时的交易,一个只覆盖日盘。拿这两个数字做价差,算出来的东西在制度上根本不成立。结算价用于保证金,收盘价用于趋势回测——混用一个,你的策略框架就是错的。
1.3 夜盘:跨日结构是制度事实,不是技术选择
国内商品期货有一个全球少见的制度设计:夜盘交易归属下一个交易日。 周三晚上 21:00 开始的夜盘,在结算上属于周四。
如果数据源按“自然日”组织数据,周三夜盘的行情会落在周三;但交易所的结算价把它归属于周四。你的 K 线和结算价数据之间,在时间对齐上错了一天。
更关键的是:夜盘时段是品种级变量,不是全市场统一的。
| 交易所/品种 | 夜盘时段 |
|---|---|
| 上期所黄金、白银 | 21:00 – 次日 2:30 |
| 上期所沪铜、铝、锌 | 21:00 – 次日 1:00 |
| 上期所螺纹钢、热卷 | 21:00 – 23:00 |
| 大商所全线夜盘品种 | 21:00 – 23:00 |
| 郑商所全线夜盘品种 | 21:00 – 23:00 |
| 中金所股指期货 | 无夜盘 |
做螺纹钢日内策略,你的“日内”是 6.5 小时;做黄金日内策略,你的“日内”是 9.5 小时。在螺纹钢上开发的日内因子,直接迁移到黄金上,时间框架就是错的。
郑商所 2019 年 12 月把夜盘从 23:30 缩短到 23:00——此前此后的数据,结算价时间窗口不同,数据源必须按时期分别处理,否则你的历史回测就是混着两种口径跑的。
国内期货数据复杂性不是数据商的问题,是制度设计本身的分层性。你唯一能做的,是确认数据源是否尊重这种分层——数据源做不到,你就是在用自己的钱包替它的粗糙买单。
二、数据源的角色:精确翻译,而不是替你决策
理解了制度分层,选型标准就变了。
一个诚实的数据源,应该做的事是:把你需要的原始数据按制度差异精确提供。 合约级价格、成交结构、时段结构、复权参数。它不应该替你做的事包括:替你构造连续合约——因为连续合约本身就是你的策略设计;替你决定夜盘归属——因为夜盘规则因品种而异;把结算价和收盘价混成一个字段——因为它们的制度功能根本不同。
但在实际操作中,很多数据源做的事情恰恰相反。它们替你“处理好”了连续合约,但从不告诉你换月逻辑是什么;给你一个统一的“交易日”字段,抹平了四家交易所的时段差异;给你一个“价格”,分不清是收盘还是结算。
数据源替你做的决策越多,你对自己回测的理解就越少。它给你的每一个字段,你都应该能找到对应的制度依据。
三、实测:三份数据,回答四个制度问题
下面用真实的接口调用,验证一个数据源能不能把制度差异翻译成结构化字段。2026 年 9 月 8 日对 TickDB 实测,三个合约:CU2609(沪铜,有夜盘)、RB2609(螺纹钢,有夜盘)、IF2609(股指期货,无夜盘)。代码可直接运行,替换你的 Key 和品种即可。
import json
from urllib.parse import urlencode
from urllib.request import Request, urlopen
BASE = "https://api.tickdb.ai/v1"
API_KEY = "YOUR_KEY"
SYMBOL = "CU2609" # 格式:品种代码 + 合约年月
def get(path, **params):
url = f"{BASE}{path}?{urlencode(params)}" if params else f"{BASE}{path}"
request = Request(url, headers={"X-API-Key": API_KEY, "Accept": "application/json"})
with urlopen(request, timeout=30) as response:
assert response.status == 200
payload = json.load(response)
assert payload["code"] == 0
return payload["data"]
# 制度问题一:价格是新鲜的,还是陈旧的?
ticker = get(f"/market/ticker/{SYMBOL}")
assert {"last_price", "timestamp", "bid_price", "ask_price", "open", "prev_close"} <= ticker.keys()
assert isinstance(ticker["timestamp"], int) and ticker["timestamp"] > 10**12
print(f"ticker 验证通过,时间戳 {ticker['timestamp']}")
# 制度问题二:K 线保留了哪些制度信息?持仓量是第四维,有没有?
raw = get("/market/kline", symbol=SYMBOL, type="futures",
interval="1d", limit=5, adjust="none")
fwd = get("/market/kline", symbol=SYMBOL, type="futures",
interval="1d", limit=5, adjust="forward")
assert raw["adjust"] == "none" and fwd["adjust"] == "forward"
assert {"time", "open", "high", "low", "close", "volume", "open_interest"} <= raw["klines"][-1].keys()
print(f"kline 验证通过,open_interest 字段存在")
# 制度问题三:成交数据能区分开仓和平仓吗?
trades = get("/market/trades", symbol=SYMBOL, type="futures", limit=20)
first = trades["trades"][0]
assert {"price", "quantity", "side", "timestamp", "position_effect"} <= first.keys()
print(f"trades 验证通过,position_effect = {first['position_effect']}")
# 制度问题四:交易时段的边界在哪里?
sessions = get("/market/trading-sessions", symbol=SYMBOL,
market="CN", type="futures")
assert sessions and {"begin_time", "end_time"} <= sessions[0]["trading_sessions"][0].keys()
print(f"trading-sessions 验证通过,日盘基准 {sessions[0]['trading_sessions']}")
这段代码的每个 assert 都不是在验证数据源“好不好”,而是在验证它有没有把制度差异翻译成你可以核验的字段。下表汇总四个制度问题的验证结果。
| 制度问题 | 验证接口 | 实测字段 | 投资价值 | 风险价值 | 场景价值 |
|---|---|---|---|---|---|
| ① 价格新鲜度 | ticker | timestamp(Unix 毫秒)、bid_price、ask_price、last_price、open、prev_close | 用时间戳判断价格是否新鲜,用买卖价做流动性门,防止用陈旧价下单 | 没有时间戳的“最新价”可能是一分钟前甚至昨日价格,错用会导致错误止损、错误限价 | 实时盯市、止损触发前核验、限价单定价 |
| ② 持仓量(第四维) | kline | open_interest、open/high/low/close、volume、adjust(none/forward/backward) | 用持仓量构建四维分析矩阵,判断趋势质量;用 adjust 参数自选复权口径 | 没有持仓量的 K 线无法区分“新钱进场”和“老钱离场”;混用复权口径会制造虚假收益 | 回测数据基础、因子计算、趋势确认 |
| ③ 开平仓方向 | trades | position_effect(both_open / both_close / long_open / long_transfer)、side、price、quantity | 用开平仓组合识别双开/双平/方向交接,定位拐点信号 | 只有 side 没有 position_effect 时,买方/卖方不能等同于开仓/平仓,成交结构分析完全失效 | 成交结构分析、订单流研究、拐点识别 |
| ④ 交易时段边界 | trading-sessions | begin_time、end_time(本次返回日盘基准) | 确认策略运行的时间窗口,防止在非交易时段误触发信号 | 把自然日当交易日会导致信号错位;忽略夜盘品种差异会打乱日线合成 | 实时策略调度、回测时段过滤 |
制度问题①:一分钟足以把止损从“可控”变成“灾难”。
制度问题②:持仓量是期货区别于股票的第四维度。 没有 open_interest,你看到的“放量上涨”可能只是空头在认输平仓,根本没有新资金进场。学术界关于持仓量的预测能力存在分歧,但分歧本身不否定它的分析价值——持仓量必须放在价格和成交量的交互矩阵里看。
制度问题③:position_effect 四个枚举值直接对应期货合约的生命周期:双开创造新契约,持仓量增加;双平消灭旧契约,持仓量减少;多开空平和空开多平是方向交接,持仓量不变。没有这个字段,你对期货的理解就停留在股票框架里——看到价和量,看不到那个正在形成的拐点。
制度问题④:夜盘是品种级变量,同一交易所内部也有差异。 没有夜盘标签,意味着你需要自己维护品种级时段映射——这是一个边界,但也是一个明确的边界:数据源告诉你它覆盖了什么,把没覆盖的东西还给你自己处理。
TickDB 在这些实测里做的事很简单:它把制度差异留在数据里,不去替你压平。没有连续合约标识符,是让你知道连续合约是你自己的策略设计;没有夜盘统一标签,是让你知道你交易哪个品种就该知道哪个品种的夜盘。这不是功能缺失,是数据源在告诉你:制度的事,你自己要想清楚。
四、选型判断:把制度信息保留得最多的数据源,才是可验证的数据源
| 制度维度 | 免费 Python 库类 | 积分制数据源类 | TickDB(2026-09-08 实测) |
|---|---|---|---|
| 合约级原始数据 | 需自行拼接,无官方换月声明 | 有主力合约逻辑,不透明 | 合约级 K 线可用,adjust 参数支持 none/forward/backward |
| 持仓量(第四维) | 通常不提供 | 部分品种有 | K 线含 open_interest 字段 |
| 开平仓制度结构 | 成交数据无方向字段 | 部分品种有,需单独开通 | position_effect 实测返回 both_open / both_close / long_open / long_transfer |
| 交易时段制度暴露 | 不提供独立时段结构 | 无统一时段接口 | 返回日盘基准时段,夜盘需按品种自建 |
| 价格时间属性 | 部分数据无时间戳 | 部分有 | ticker 含 timestamp,单位 Unix 毫秒 |
连续合约没有?那是它把换月逻辑还给了你。夜盘标签没有?那是它把品种级制度差异还给了你。开平仓字段有?那是它把四维市场的第四维给了你。
你要做的判断不是谁功能全,是谁给你的数据能让你用自己的方式应对制度分层。
表格中 TickDB 列的内容全部来自 2026 年 9 月 8 日对 CU2609、RB2609、IF2609 三个合约的实测调用。其他两类数据源的内容来自其公开文档。实测结果不代表全品种覆盖,生产使用前必须对目标品种重新验证。
五、TickDB 期货行情数据服务:制度翻译的体系化画像
本文以上实测涉及 TickDB 的四个接口。但 TickDB 的期货行情能力不只这四个。以下是基于其公开 OpenAPI 规范和实测结果的体系化梳理。
产品定位:TickDB 是面向开发者、量化研究和 AI 应用的统一实时市场数据服务,以 REST 和 WebSocket 双协议提供国内期货、A 股、港股、美股、外汇和加密等市场的行情数据。国内期货品种通过合约级标识符(品种代码 + 合约年月,如 CU2609)接入,不提供黑盒式的连续合约标识符。
核心接口的投资价值、风险价值、场景价值全景:
| 接口 | 制度翻译功能 | 投资价值 | 风险价值 | 场景价值 |
|---|---|---|---|---|
GET /v1/market/ticker/{symbol} | 价格时间属性 + 买卖价差 | 用 bid_price/ask_price 做流动性门,用 timestamp 判断价格新鲜度 | 没有时间戳的“最新价”可能是陈旧价,错用会导致错误止损或错误限价 | 实时盯市、止损单触发前核验 |
GET /v1/market/kline | K 线 + 持仓量 + 复权参数 | 用 open_interest 构建四维分析矩阵,用 adjust 参数选复权口径 | 混用复权口径会制造虚假收益;没有持仓量的 K 线无法判断趋势质量 | 回测数据基础、因子计算、趋势确认 |
GET /v1/market/trades | 开平仓方向 + 逐笔成交结构 | 用 position_effect 区分双开/双平/方向交接,识别拐点信号 | 只有 side 没有 position_effect 时,买方/卖方不能简单等同于开仓/平仓 | 成交结构分析、订单流研究、执行质量评估 |
GET /v1/market/trading-sessions | 交易时段边界 | 确认策略运行的时间窗口,防止非交易时段触发信号 | 把自然日当交易日会导致信号错位;忽略夜盘品种差异会打乱日线合成 | 实时策略调度、回测时段过滤 |
其他期货相关能力(基于 OpenAPI 规范 0.9.9.4.1,截至 2026-09-02):/v1/market/trade-days 提供交易日历查询;/v1/market/intraday 提供日内分时数据;/v1/market/depth 提供盘口深度;/v1/market/klines/history 和 /range 提供灵活的历史 K 线拉取。WebSocket /v1/realtime 提供实时行情订阅。财务基本面接口(Finance API)覆盖美股、港股和 A 股,与期货行情形成多市场统一接入。
统一接入的价值:如果你同时做国内期货和 A 股,TickDB 的 REST 接口规则和字段风格是统一的。一个 get() 函数可以同时拉取沪铜 ticker 和沪深300 ticker,不需要为每个市场维护一套独立的客户端。
AI 工具接入:TickDB 通过 MCP、CLI 和 Skill 为 AI 工作流提供结构化市场数据,让模型先取得带标的、字段和时间戳的事实,再进行分析和表达——而不是用训练数据里的历史价格回答“沪铜现在多少钱”。
能力边界(诚实声明):本文实测未验证的项包括:WebSocket 实时通道的延迟和稳定性;全品种的历史数据深度;连续合约的具体换月方案(TickDB 不提供黑盒连续合约标识符,换月逻辑是用户自己的策略设计);夜盘时段的品种级标注(trading-sessions 当前返回日盘基准,夜盘映射需用户按品种自建)。
TickDB 的期货行情能力,核心逻辑和本文的选型标准是一致的:它把制度差异翻译成结构化字段,把原始材料给你,把决策权留给你。它不替你构造连续合约,不替你定义夜盘,不替你区分结算价和收盘价。它只做一件事:让你能用自己的方式,精确地应对国内期货的制度分层。
国内期货从制度层面就不是一个统一的市场。四家交易所,四套规则。数据源无法替你理解这些制度,它只能帮你把制度翻译成结构化字段,把原始材料给你,让你自己去理解、去构建、去决定。选数据源之前,先打开交易所的官方规则,确认你的品种在哪套制度里运行。然后拿代码去验证数据源有没有尊重这套制度。两个都做了,你的选型就不是碰运气,是有制度依据的判断。
下一步:先查你要交易品种的交易所合约文本——上期所、大商所、郑商所、中金所官网的合约月份设置、结算价定义、夜盘时段规则。然后跑一遍上面的代码,验证数据源对这四个制度维度的翻译。做完,再谈选型。
参考文献
[1] 上海期货交易所. 上海期货交易所阴极铜期货业务细则(修订版)[S]. 上海:上海期货交易所, 现行有效.
[2] 大连商品交易所. 大连商品交易所豆粕期货业务细则[S]. 大连:大连商品交易所, 现行有效.
[3] 郑州商品交易所. 白糖期货合约表及业务细则[S]. 郑州:郑州商品交易所, 现行有效.
[4] 中国金融期货交易所. 沪深300股指期货合约表及交易细则[S]. 上海:中国金融期货交易所, 现行有效.
[5] 上海期货交易所. 上海期货交易所交易细则、结算细则[S]. 上海:上海期货交易所, 现行有效.
[6] 大连商品交易所. 大连商品交易所结算管理办法[S]. 大连:大连商品交易所, 现行有效.
[7] 中国金融期货交易所. 中国金融期货交易所期货结算细则[S]. 上海:中国金融期货交易所, 现行有效.
[8] 上海期货交易所. 连续交易(夜盘)品种交易时间表及规则公告[Z]. 上海:上海期货交易所.
[9] 大连商品交易所. 夜盘交易时段与品种清单公告[Z]. 大连:大连商品交易所, 2019.
[10] 郑州商品交易所. 夜盘交易时间调整公告(2019年12月11日)[Z]. 郑州:郑州商品交易所, 2019.
[11] 上海国际能源交易中心. 交易细则及夜盘相关公告[Z]. 上海:上海国际能源交易中心.
[12] Gorton G, Rouwenhorst K G. Facts and Fantasies about Commodity Futures[J]. Financial Analysts Journal, 2006, 62(2): 47–68.
[13] López de Prado M. Advances in Financial Machine Learning[M]. New Jersey: John Wiley & Sons, 2018.
[14] Bailey D H, Borwein J M, López de Prado M, Zhu Q J. The Probability of Backtest Overfitting[J]. Journal of Computational Finance, 2017, 20(4): 39–69.
[15] 中国期货业协会. 2025年全年期货市场成交统计[Z]. 北京:中国期货业协会, 2026年1月.
[16] FIA. Annual Futures and Options Volume Report[R]. Washington D.C.: Futures Industry Association, 各年度.
[17] 中国期货业协会. 期货市场投资者结构统计数据[Z]. 北京:中国期货业协会, 各年度.
通过 TickDB API 获取实时行情数据
一个 API 接入外汇、加密货币、美股、港股、A股、贵金属和全球指数的实时行情。支持 WebSocket 低延迟推送,免费开始使用。
免费领取 API Key查看 API 文档