看懂合约溢价怎么算、避开两个最常见的误读,以及怎么放进策略。
合约价格比现货高,就代表市场很乐观吗?市场情绪看的是 Binance 永续合约比指数价格高出多少,但它用的是 USDT 价差、而且只跟自己近 30 天比——这两点是最多人读错的地方。
市场情绪(Market Sentiment,MS)是 Blave 的合约溢价指标:比较 Binance USDT 本位永续合约与 Binance 指数价格的收盘价差,换算成相对该币近 30 天的 z-score。指数价格是 Binance 以多家交易所现货报价加权而成,不是单一交易所的现货价。计算分三步:
| 步骤 | 算的是什么 |
|---|---|
| 1. 价差 | 每 5 分钟,永续合约收盘价减指数价格收盘价,单位是 USDT。大于 0 是合约溢价,小于 0 是折价。 |
| 2. 平滑 | 对价差取 1 天滚动中位数,滤掉短时间的跳动。 |
| 3. 标准化 | 用近 30 天的平均与标准差换算成 z-score,得到最后的数值。 |
因为是 z-score,数值没有上下限,各币种能放在同一把尺上比较。正值代表价差比近 30 天平常大,多方愿意用更高的价格在合约上进场;数据里没有多空人数,也没有持仓。Studio 的状态徽章用以下门槛分级:
| 数值 | Studio 徽章 | 意思 |
|---|---|---|
| ≥ +3 | 过度乐观 | 价差远高于近 30 天常态,属极端值 |
| +2 ~ +3 | 高度乐观 | 价差明显高于常态 |
| +0.5 ~ +2 | 乐观 | 价差高于常态 |
| −0.5 ~ +0.5 | 中立 | 与近 30 天常态差不多 |
| ≤ −0.5 | 悲观/高度悲观/过度悲观 | 与正值对称,门槛是 −0.5、−2、−3:价差低于常态,合约相对指数偏弱 |
市场情绪的原料是「合约价 − 指数价格」的 USDT 差额,整个计算过程没有除以价格。所以溢价比例不变时,同一个币的价格涨得越多,USDT 价差就越大;不同币之间则因为各自标准化,不受币价高低影响。
举个假设的例子:某币 30 天前价格约 1 USDT,合约比指数高 0.001 USDT,溢价 0.1%;之后币价涨到 2 USDT,合约仍比指数高 0.1%,价差却变成 0.002 USDT。溢价比例完全没变,但价差高于近 30 天平均,市场情绪会被推高。币价在 30 天内大跌时则相反,数值会被压低。
z-score 比的是这个币自己近 30 天的平均。一个连续两个月合约都比指数高出差不多价差的币,平均会被垫高,市场情绪回到 0 附近——这时 0 的意思是「跟近 30 天差不多」,不是「没有溢价」。
反过来,一个币从大幅溢价回落到小幅溢价,价差低于近 30 天平均,数值可能转成负的,但合约其实仍然比指数贵。同样是 +2,放在不同币、不同月份,背后的实际价差也可能差很多。
目前没有任何官方策略使用市场情绪,以下三种用法都是示意、未回测。代码里的 ±0.5 与 3 是借用 Studio 徽章门槛当起点,不是参数扫描的结果,实际使用前都要自己回测。
最直接的写法:市场情绪高于进场门槛时做多,跌破离场门槛就空仓。两个门槛中间留一段缓冲,避免数值在单一门槛附近来回时频繁进出。
ENTRY_TH = 0.5 # 示意:借用「乐观」徽章门槛
EXIT_TH = -0.5 # 示意:借用「悲观」徽章门槛
def compute_signals(df, entry_th=ENTRY_TH, exit_th=EXIT_TH):
# df['MS'] = 该币的市场情绪数值
signal = pd.Series(np.nan, index=df.index)
signal[df['MS'] > entry_th] = 1.0 # 价差高于常态 → 做多
signal[df['MS'] < exit_th] = 0.0 # 价差低于常态 → 空仓
return signal
因为数值先取过 1 天中位数,这个信号跟着日级的价差变化走,不会对几分钟内的价格跳动反应。它没有回测;门槛与方向(顺势或反向)都要自己扫描验证。
数值到 ±3,代表价差相对近 30 天已经非常极端。一种保守的用法是不把它当进场信号,而是加在既有策略的进场条件上,极端时先不开新仓:
# 示意:|MS| ≥ 3(过度乐观或过度悲观)时不进场 too_hot = df['MS'].abs() >= 3 entry = compute_entry(df) & ~too_hot
这不是反转信号,也没有回测:Blave 没有验证过数值到 ±3 之后价格会反转,也没有验证过避开极端值能改善绩效;这里只是把「价差已经极端」当成暂停开新仓的条件。±3 是相对近 30 天,价差长期很稳的币,小变动也能到 ±3。compute_entry 换成你原本策略的进场条件。
市场情绪是日级的慢信号,适合当背景滤网:只在它大于 0 时,才接受短窗口指标(例如多空力道)给出的做多信号;市场情绪回到 0 以下就空仓。以下是结构示意,compute_fast_entry 换成你自己的条件:
ms = fetch_market_sentiment(SYMBOL, INTERVAL, START, END, hdrs) df['MS'] = ms['alpha'] regime_long = df['MS'] > 0 # 示意:价差高于近 30 天平均才做多 fast_entry = compute_fast_entry(df) # 例如短窗口的多空力道条件 signal = pd.Series(np.nan, index=df.index) signal[regime_long & fast_entry] = 1.0 signal[~regime_long] = 0.0
这个组合没有回测,门槛 0 只是示意;实际使用前要扫描参数、看扣掉手续费后的表现。
市场情绪只有一个设置:K 线周期(period),可选 5min、15min、1h、4h、8h、1d,最短 5 分钟。它没有巨鲸警报那种时间窗口参数;而且不管选哪个周期,数值都是先取过 1 天中位数的结果,周期只决定多久取一次值,不会去掉底层的 1 天中位数平滑。
| 周期 | Studio 默认显示范围 | 注意 |
|---|---|---|
5min / 15min | 5min:3 天;15min:7 天 | 画得最密,但看到的仍是日级平滑后的变化,不适合拿来抓短线 |
1h / 4h | 1h:14 天;4h:30 天 | 策略想每几小时检查一次时使用 |
8h / 1d | 8h:60 天;1d:180 天 | 适合看一段期间的情绪走向 |
选周期的依据是策略多久检查一次,不要期待短周期能抓到短线。数据从 2020-01-01 起(晚上市的币从上市日起);z-score 需要 30 天样本,所以比较有意义的数值大约从 2020-01-31 开始,新上市的币前 30 天也是同样道理。
| 页面 | 看什么 |
|---|---|
| 总览 | 整体情绪半圆仪表(全币种以未平仓价值(USDT 计价)加权平均的市场情绪)+乐观、悲观两张排行,字段有币种、24 小时涨跌、指数与状态。 |
| 板块 | 各板块的市场情绪排行,板块数值是板块内各币以未平仓价值加权的平均。 |
| 历史 | 单一币种的市场情绪柱状图叠上价格,可选 5min~1d 周期,并附 stat 字段;非 Pro 用户最近 7 天的数据延后显示。 |
以下是组合思路,不是验证过的结论:
| 组合 | 用途 |
|---|---|
| 市场情绪 + 巨鲸警报 | 价差升高时,用巨鲸警报看未平仓量有没有同时反常增加,协助判断溢价背后是否伴随新开仓。 |
| 市场情绪 + 多空力道 | 市场情绪反应慢,用多空力道看短窗口的主动买卖,补上它看不到的短期动态。 |
API 端点是 GET /market_sentiment/get_alpha,参数有 symbol、period 与起止日期(start_date、end_date);Blave Agent 里对应 fetch_market_sentiment。币种只涵盖 Binance USDT 本位永续,其他交易所不在内。只返回已收盘的 K 线,字段是 timestamp、alpha 与 stat,不含价格;没给起始日时默认取最近 365 天,区间超过 365 天会自动截短。
stat 对象描述最新一条数值,含义跟名字不完全一样:
| 字段 | 实际算法 |
|---|---|
up_prob | 用近 365 天的数据训练逻辑回归模型,以市场情绪预测 24 小时后涨跌,输出上涨的概率。训练数据包含当下这段,属样本内估计,不是样本外胜率。 |
avg_up_return /avg_down_return | 近 365 天所有「24 小时后上涨/下跌」时点的平均报酬,不分市场情绪水位。 |
exp_value | up_prob × avg_up_return +(1 − up_prob)× avg_down_return,是小数,不是百分比。 |
is_data_sufficient | 该币数据是否早于 365 天前就开始,不是「这个水位的样本够不够」。 |
stat 也是样本内的估计——任何门槛都要用你自己的回测验证。