打开任意一家平台的交易软件,同一时刻你会看到三个不一样的黄金价格:
- 你手上这家平台的黄金差价合约报价
- 市场上的黄金现货价(XAUUSD)
- 纽约商品交易所的黄金期货价
三个数字彼此差着几美元,甚至十几美元。笔者写作时的一次真实快照里,现货 XAUUSD 报 4064.5 美元,而 COMEX 黄金期货主力合约报 4119.5 美元,硬生生差了 55 美元。
如果你问哪个才是真的金价,答案是:它们都是真的,只是各自回答的是不同的问题。而绝大多数讲 CFD 的文章,从来不解释这几个价格为什么不一样、差价里藏着谁的成本。它们还停留在比较浅的科普,比如CFD 不持有实物、赚差价、有杠杆,然后直接跳到风险提示。
今天我们来换一个角度:把 CFD 的价格当成一个数据问题来拆。 差价合约的价格不是凭空来的,它是做市商基于某个底层市场加工出来的一份镜像。搞清楚这份镜像由谁生成、和底层差在哪、差价里各项成本怎么算,你才真正看懂了自己在为什么付费。
文中所有说法,都会配上可以自己跑一遍的代码去验证,而不是给你几个虚构的示意数字。
一、CFD 差价合约是什么?
说实话,这部分网上已经写烂了,不多花笔墨,只留最关键的三点,因为后面全靠它们:
- CFD 是一份「差价」合约。 你和交易商约定,就某个标的从开仓到平仓的价格变动结算差额,中间你完全不碰实物,不交割原油、不过户股票。
- CFD 是保证金(杠杆)交易。 你只付合约总价值的一小部分作为保证金,剩下的相当于向交易商借。这一点是后面隔夜利息的根源。
- CFD 的对手方就是交易商本身。 你不是在一个公开交易所里和别的交易者撮合,而是和你的平台对赌。所以你看到的价格,是这家平台报给你的价格,不是某个中央市场的唯一价格(敲黑板,这点很重要)。
第三点非常重要!既然价格是平台报的,那就必然有一个问题:它照着什么报?
二、CFD 的价格是怎么生成的
CFD 没有中央交易所,也没有全市场统一的收盘价。每家交易商的报价引擎,本质上都在做同一件事:盯住一个底层参考市场,在它的基础上加上自己的点差和风险调整,生成一对买价 / 卖价推给你。
按交易商怎么处理你的订单,业内大致分两种模式:
- 做市商模式(Market Maker / B-book)。 交易商自己做你的对手方,你的报价由它内部的报价引擎生成。它可以参考底层市场,但报价和风险敞口由它管理。好处是即使标的流动性一般,你也总能成交;代价是你和交易商存在利益对立,极端行情下它有动机、也有能力调整点差或杠杆。
- 直通 / 撮合模式(STP / ECN / A-book)。 交易商把你的订单传给上游的流动性提供商(银行、大型做市商、ECN 池),你的价格来自这些流动性来源的聚合报价,交易商赚点差或佣金,不与你对赌。
不管哪种模式,报价的源头都是底层参考价:
| CFD 类别 | 底层参考市场 | CFD 价格 ≈ |
|---|---|---|
| 股票 CFD | 该股票所在交易所的实时价 | 交易所价 + 点差(+ 分红 / 融资调整) |
| 股指 CFD | 对应的股指期货 | 期货价 + 点差 ± 基差调整 |
| 商品 CFD(原油、黄金) | 现货市场或主力期货合约 | 参考价 + 点差 ± 展期 / 持有成本 |
| 外汇 CFD | 银行间外汇市场 | 银行间中间价 + 点差 |
这张表说明了一件很多人没意识到的事:你 CFD 报价里的每一分不一样,都是可以被独立数据源量出来的。 只要你手里有一份中立的底层行情,你就能算出自己这家平台到底加了多少点、有没有在偷偷扩点差。下一节就来做这件事。
三、用独立数据,量出你 CFD 报价里的真实点差
下面的代码用的是一个把股票、外汇、能源、贵金属、期货统一成同一套接口的聚合行情服务, Infoway API 作为独立数据源。它的意义不在于简单的市场行情报价,而在于它是和你的交易平台无关的第三方参考,中立的数据正好可以拿来当尺子,量你平台的报价。
三个接口共用一个放在请求头里的 apiKey。要点:外汇、能源、贵金属、期货这些非股票品种统一走 /common/ 前缀,股票走 /stock/ 前缀。
3.1 商品 / 外汇 CFD:现货参考价 vs 平台报价
先把黄金现货(XAUUSD)和它的盘口拉回来。盘口的买一、卖一之差,就是这个底层市场本身的点差;你平台的点差如果显著更宽,宽出来的部分就是平台的加价。
import requests
BASE = "https://data.infoway.io"
HEADERS = {"apiKey": "你的APIKey"}
def get_trade(codes, market="common"):
"""最新成交价。market: common=外汇/商品/贵金属/期货, stock=股票"""
url = f"{BASE}/{market}/batch_trade/{codes}"
r = requests.get(url, headers=HEADERS, timeout=10)
r.raise_for_status()
return {d["s"]: float(d["p"]) for d in r.json()["data"]}
def get_depth(codes, market="common"):
"""最优买卖盘,用来量底层市场自身的点差"""
url = f"{BASE}/{market}/batch_depth/{codes}"
r = requests.get(url, headers=HEADERS, timeout=10)
r.raise_for_status()
out = {}
for d in r.json()["data"]:
best_ask = float(d["a"][0][0]) # 卖盘价格数组第一档
best_bid = float(d["b"][0][0]) # 买盘价格数组第一档
out[d["s"]] = (best_bid, best_ask, best_ask - best_bid)
return out
spot = get_trade("XAUUSD")["XAUUSD"]
bid, ask, ref_spread = get_depth("XAUUSD")["XAUUSD"]
print(f"黄金现货参考价:{spot}")
print(f"底层市场点差:买一={bid} 卖一={ask} 点差={ref_spread:.3f} 美元")
# 把你平台此刻的黄金 CFD 买卖价填进来,一比就知道被加了多少
broker_bid, broker_ask = 0.0, 0.0 # ← 填你交易软件上的数字
if broker_bid and broker_ask:
print(f"平台点差={broker_ask - broker_bid:.3f},"
f"其中加价≈{(broker_ask - broker_bid) - ref_spread:.3f} 美元")虽然每家CFD平台都会公布自己的点差/收费,但上面的代码把点差真实地验证了一遍。底层市场的点差通常很窄,你平台报价里多出来的部分,才是真正落进交易商口袋的那一块。
3.2 个股 CFD:它应该紧贴交易所价
股票 CFD 的底层参考是最干净的,它的参考来源就是那只股票在交易所的实时成交价。理论上,你在价差合约平台的苹果 CFD 中间价应该几乎等于纳斯达克的苹果股价;偏离部分来自点差、平台加价,以及(持仓过夜时的)分红与融资调整。
ref = get_trade("AAPL.US", market="stock")["AAPL.US"]
print(f"苹果交易所实时参考价:{ref}")
broker_mid = 0.0 # ← 填你平台苹果 CFD 的中间价(买卖价取平均)
if broker_mid:
diff = broker_mid - ref
print(f"平台 CFD 偏离交易所价 {diff:+.3f} 美元({diff / ref * 100:+.3f}%)")如果这个偏离在盘中稳定地偏向某个方向、而且明显超过合理点差,你就有理由怀疑平台在报价上做了手脚。
3.3 为什么期货金价和现货金价不一样
商品和股指 CFD 常常盯的是期货而不是现货,于是又多出一层价差:基差。
以黄金为例,期货价几乎总是略高于现货价,这个结构叫升水(contango)。原因是持有成本(cost of carry):把资金锁在黄金上要付出利息机会成本,再加仓储、保险。粗略地说:
期货升水 ≈ 无风险利率 + 仓储费
所以当利率高的时候,升水会明显走阔,这不是行情看涨,纯粹是因为融资成本变贵了。(2024 年 COMEX 与伦敦现货之间的 EFP 价差一度飙到每盎司约 60 美元,就是这条链路被极端放大的一次典型事件。)
你可以把现货和期货的主力连续合约放在一起,把基差直接算出来:
# 黄金期货主力连续合约:COMEX 的 GC,连续合约写作 GC1!
# (1! 后缀由数据源自动处理换月;查 type=FUTURES 产品列表可确认代码)。
GOLD_FUT = "GC1!"
px = get_trade(f"XAUUSD,{GOLD_FUT}")
spot, fut = px["XAUUSD"], px[GOLD_FUT]
basis = fut - spot
print(f"现货={spot} 期货={fut} 基差={basis:+.2f} 美元 "
f"({'升水/contango' if basis > 0 else '贴水/backwardation'})")想理解一个盯期货的商品 CFD 长期持有为什么越拿越亏,基差就是答案之一:期货随着到期逼近会向现货收敛,升水会一点点被磨掉,而这块成本会通过展期 / 隔夜费用转嫁到你头上。这引出了下一节:真正吃掉长期持仓者利润的隐藏成本。
四、计算隐藏成本
CFD 的成本,网上你应该看过不少:点差、隔夜利息、(部分股票的)佣金。现在我们来实际计算一下:持有 N 天到底要花多少钱。
4.1 隔夜利息
隔夜利息(swap / overnight financing)的根源是杠杆,你开仓等于借了钱,持仓过夜就得付这笔借款的利息。常见的近似公式是:
每日隔夜费 ≈ 合约名义价值 × 年化融资利率 ÷ 365关键在于年化融资利率不是一个小数字。它通常是基准利率 + 交易商加点。在基准利率约 4%~5% 的环境里,交易商加点常在 2%~3%,做多方付出的年化融资率摸到 6%~8% 并不稀奇。代进去看看黄金:
def overnight_cost(notional, annual_rate):
daily = notional * annual_rate / 365
return daily
spot = get_trade("XAUUSD")["XAUUSD"]
lots = 1.0
contract_size = 100 # 1 手黄金 = 100 盎司(以你平台合约规格为准)
notional = spot * lots * contract_size
annual_rate = 0.07 # 做多黄金年化融资率,示例 7%
daily = overnight_cost(notional, annual_rate)
print(f"名义价值={notional:,.0f} 美元")
print(f"每日隔夜费≈{daily:.2f} 美元")
print(f"持仓 30 天≈{daily * 30:.2f} 美元,90 天≈{daily * 90:.2f} 美元")假设金价在 2400 美元附近,1 手名义价值约 24 万美元,7% 年化下每天约 46 美元,持仓 30 天就是约 1380 美元、90 天约 4140 美元。这笔钱和金价本身涨没涨一点关系都没有,只要你拿着,它每天照扣。用金价来衡量,持有 90 天,光隔夜费就吃掉你几十美元的价格空间,而这还没算点差。
4.2 周末跳空
CFD 周末休市,但底层世界不休息。周五收盘到周一开盘之间,一旦有重大消息,价格会直接跳过去,你的止损可能在一个远比预期差的价位成交。我们用日线数据就能量出历史上的跳空有多大:
def weekend_gaps(code, market="common", weeks=52):
"""统计最近若干根日线里,相邻两根之间的跳空幅度"""
body = {"klineType": 8, "klineNum": min(weeks * 5, 500), "codes": code}
url = f"{BASE}/{market}/v2/batch_kline"
bars = requests.post(url, headers=HEADERS, json=body, timeout=15
).json()["data"][0]["respList"]
bars = list(reversed(bars)) # respList 从新到旧,反转成时间正序
gaps = []
for prev, cur in zip(bars, bars[1:]):
prev_close, cur_open = float(prev["c"]), float(cur["o"])
pct = (cur_open - prev_close) / prev_close * 100
gaps.append(abs(pct))
gaps.sort(reverse=True)
print(f"{code} 最近 {len(gaps)} 个交易日间隔,最大跳空 {gaps[0]:.2f}%,"
f"前 5 大平均 {sum(gaps[:5]) / 5:.2f}%")
weekend_gaps("XAUUSD")把这个数字和你的杠杆一乘,就知道最坏情况下一次跳空能对你的保证金造成多大冲击。
4.3 CFD 适合短、不适合长
把点差(开仓一次性)+ 隔夜费(每天累积)+ 潜在跳空风险加在一起,结论其实很清楚:
CFD 是为短线设计的工具
持有周期越长,隔夜费越是把杠杆的收益一点点侵蚀掉。如果你的判断是看好未来半年,直接持有底层资产、或用持有成本更低的工具(比如把展期成本一次性打进价格的远期 / 期货合约),往往更省钱。
五、CFD vs 期货 vs 现货
这部分网上虽然也有讨论,但是给出的对比还是比较基础,比如什么CFD 灵活啦、期货标准化啦、现货无杠杆啦,但你真正应该关心的是:同一笔看涨判断,持有 N 天,三种工具各花多少钱? 把它写成一个函数,答案一目了然:
spot = get_trade("XAUUSD")["XAUUSD"]
_, _, ref_spread = get_depth("XAUUSD")["XAUUSD"]
fut = get_trade("GC1!")["GC1!"]
basis = fut - spot
contract_size = 100 # 1 手黄金 = 100 盎司
notional = spot * contract_size # 名义价值
spread_cost = ref_spread * contract_size # 点差换算成每手美元
roll_cost = abs(basis) * contract_size # 展期成本≈升水随到期收敛给出去的钱
annual_rate = 0.07 # 假设:做多黄金年化融资率(此项非实时)
def holding_cost(days, tool):
"""粗略估算持有成本(不含标的盈亏本身)"""
if tool == "cfd": # 点差(开平各一次)+ 每日隔夜费
return spread_cost * 2 + notional * annual_rate / 365 * days
if tool == "futures": # 点差 + 展期成本(升水按约一个季度到期线性摊)
return spread_cost * 2 + roll_cost * (days / 90)
if tool == "spot": # 现货无杠杆,只有买卖点差,无每日融资
return spread_cost * 2
for tool in ("cfd", "futures", "spot"):
row = " ".join(f"{d}天={holding_cost(d, tool):,.0f}" for d in (7, 30, 90))
print(f"{tool:8} {row}")这段代码在本文写作时跑出来的真实结果:
| 工具 | 持有 7 天 | 持有 30 天 | 持有 90 天 |
| CFD | 约 698 | 约 2,490 | 约 7,167 |
| 期货 | 约 580 | 约 1,985 | 约 5,652 |
| 现货 | 约 152 | 约 152 | 约 152 |
这个真实结果,恰恰打破了一个流行的错觉:CFD 更便宜。
就持有成本而言,期货在每个周期都比 CFD 更省。 原因不难理解:CFD 的隔夜融资率是:市场持有成本 + 平台加点,而期货价里隐含的升水,本质就是那个市场持有成本本身、没有平台加点这一层,所以 CFD 每天多付的,正是交易商在融资上的抽成。现货则几乎没有时间成本,代价是你得压上全额资金、且用不了杠杆、也不能做空。
所以这三者的真正区别不是谁更便宜,而是你在为什么买单:
- 现货无时间成本但要全额占款
- 期货买的是低碳持有成本但要管到期与固定合约规模
- CFD 买的则是便利,极低的资金占用、可任意拆分的手数、没有到期日、做空和做多一样简单
CFD 的溢价是为这份灵活性付的,不是因为它便宜。
六、把数据用起来
到这里,思路可以分两个方向落地,分别对应两类读者。
6.1 交易者:搭一个 basis / 点差异常监控
如果你在做交易,前面所有的计算都可以自动化成一个持续运行的监控:定时拉底层参考价,和你平台的报价比对,一旦点差异常扩大、或基差跑到历史极端,就告警。核心逻辑就是把第三节的比对放进循环:
import time
def monitor(code, market, ref_puller, threshold_pct=0.15, interval=30):
"""底层参考价异常监控:偏离超过阈值就提示"""
base = ref_puller(code, market)[code]
while True:
cur = get_trade(code, market)[code]
drift = (cur - base) / base * 100
flag = "⚠️ 异常" if abs(drift) > threshold_pct else "正常"
print(f"{code} 参考价={cur} 偏离基线={drift:+.3f}% {flag}")
time.sleep(interval)
# monitor("XAUUSD", "common", get_trade) # 生产中把 base 换成滚动基线真要盯盘,别用高频轮询 REST 去模拟实时流,改用 WebSocket 订阅推送更稳、也更省配额,外汇、商品、贵金属、期货统一走 business=common,股票走 business=stock,一套客户端参数化就能同时盯多类资产。
6.2 交易所 / 券商:底层行情源,就是你的报价与风控地基
反过来看,如果你是要运营一个 CFD价差合约交易平台的团队,那么这篇文章里所有底层参考价,正是你自己报价引擎的输入。一个 CFD 平台的报价、风控、清算,全都建立在一条可靠、低延迟、多市场覆盖的行情源之上:
- 报价引擎需要在底层参考价上叠加点差生成客户端报价
- 风控系统需要实时盯住敞口对应的底层价格,触发保证金追缴和强平
- 对账与清算需要一份权威的收盘 / 结算参考价
这几件事的共同前提,是把股票、外汇、能源、贵金属、期货用同一套格式、同一条链路接进来,而不是分别对接七八个交易所各自的协议。Infoway 面向交易所运营方提供的交易所工具箱就是这个思路的参考实现,多市场 WebSocket 网关、盘口聚合器、K 线数据仓库等生产级组件,帮助你拿到干净的多市场底层行情,剩下的报价与风控逻辑你专注去做。说到底,CFD 平台卖的是价格,而价格的质量,取决于你脚下那条数据源。
八、常见问题
为什么我平台的 CFD 报价和交易所 / 现货价不一样?
因为 CFD 价格是交易商在底层参考市场基础上,叠加自己的点差和风险调整生成的。个股 CFD 盯交易所价,商品 / 股指 CFD 常盯期货(于是多一层基差),外汇盯银行间价。差价里包含点差、平台加价,以及持仓过夜的融资 / 分红调整。拿一份独立的第三方行情,就能把这块差价量出来。
CFD 适合长期持有吗?
通常不适合。隔夜融资费每天累积,杠杆越高、持仓越久,侵蚀越明显。本文用真实数据实测,约 40.6 万美元名义的黄金多头在 7% 年化下,持仓 90 天光隔夜费就约 7000 美元,且这一持有成本高于同期的期货(约 5700 美元)。长期看好某资产,直接持有或用持有成本更低的工具往往更划算。
基差(basis)是什么?为什么重要?
基差是期货价与现货价之差。黄金等品种正常处于升水(期货高于现货),反映持有成本(利率 + 仓储)。盯期货的商品 / 股指 CFD 长期持有时,期货向现货收敛的过程会把升水磨掉,这部分成本通过展期转嫁给持仓者。
做市商(B-book)和直通(STP/ECN)有什么区别?
做市商自己做你的对手方,报价由其内部引擎生成,流动性有保障但存在利益对立;直通模式把订单传给上游流动性提供商,价格来自聚合报价,交易商不与你对赌。两者都以底层参考价为源头,区别在于订单去向和利益结构。
怎么判断一家平台有没有在报价上做手脚?
用一个和平台无关的独立行情源作参照:股票 CFD 应紧贴交易所价,商品 / 外汇 CFD 的点差不应显著宽于底层市场点差。持续比对、记录偏离,若盘中稳定偏向某一方向且超出合理点差,就值得警惕。本文第三节的代码即为此而写。