在加密期权交易里,波动率曲面是一张能瞬间捕捉“市场贪婪与恐惧”的三维地图:X 轴是行权价、Y 轴是剩余到期时间、Z 轴为隐含波动率(IV)。对 BTC 期权来说,曲面越陡峭,说明市场对极端行情定价越高;曲面平坦,则预示着震荡预期。
本篇将以一段 70 行代码的 Python 脚本为例,手把手教你把实时 BTC 期权数据变成交互式 3D 曲面图。无需调整任何浏览器代理,也绝不触碰任何违法接口,只靠公开 REST API 与开源库即可完成。
准备环境
只需安装 5 个轻量包,一行命令解决依赖:
pip install requests pandas matplotlib plotly mplcursors版本差异容忍度高,plotly 用来生成交互式 3D,mplcursors 辅助做二维 hover,方便边调试边核对数据。
第一步:批量获取 BTC 期权元数据
很多平台把“合约对象”和“市场快照”拆分在两个端点,我们只需元数据就能完成曲面构造:
import requests, time, itertools
BASE_URL = "https://api.bybit.com"
def fetch_btc_options():
"""拉取所有 BTC-USDC 期权的合约信息"""
url = f"{BASE_URL}/v5/market/instruments-info"
params = {"category": "option", "baseCoin": "BTC", "limit": 1000}
res = requests.get(url, params=params).json()
return res["result"]["list"]返回列表里每条字典都包含行权价 strikePrice、到期日 deliveryTime 以及期权类型 optionsType。我们事先无需处理希腊值,只要把在场且未被下架的合约筛出来即可。
第二步:合并实时 Ticker,提取隐含波动率
拿到合约 symbol 列表以后,需要再调一次 Ticker 端点取 markIv:
def fetch_iv(syms):
"""一次性批量取得最新 Mark IV"""
params = {"category": "option", "symbols": ",".join(syms)}
tick = requests.get(f"{BASE_URL}/v5/market/tickers", params=params).json()
iv_map = {d["symbol"]: float(d.get("markIv", 0)) for d in tick["result"]["list"]}
return iv_map小贴士:为避免一次请求过长导致 414,我们可以用 itertools.islice 每 25 条切 1 次,再合并结果。第三步:清洗 DataFrame,生成建模字段
把两个 API 回来的数据揉成一个干净的 DataFrame:行权价 → 浮点;到期日期 → 剩余天数 → 年化剩余期限;隐含波动率 → 百分比小数。
import pandas as pd
def build_surface_df(info_list, iv_map):
rows = []
for c in info_list:
symbol = c["symbol"]
if symbol not in iv_map or iv_map[symbol] <= 0:
continue
expiry_sec = int(c["deliveryTime"]) / 1000
dte = (expiry_sec - time.time()) / 86400 # 剩余天数
strike = float(c["strikePrice"])
iv = iv_map[symbol]
rows.append({"strike": strike, "dte": dte, "iv": iv})
return pd.DataFrame(rows)这样我们就拥有 (strike, dte, iv) 三元组,足以绘制 3D 曲面。
第四步:Plotly 交互式 3D 曲面
仅需 8 行代码:
import plotly.graph_objects as go
def plot_surface(df):
pivot = df.pivot(index="dte", columns="strike", values="iv").sort_index(ascending=False)
fig = go.Figure(data=[go.Surface(
x=pivot.columns, # strike
y=pivot.index, # dte
z=pivot.values, # iv
colorscale="Turbo",
hovertemplate="Strike: %{x}<br>DTE: %{y}<br>IV: %{z}<br>"
)])
fig.update_layout(
scene=dict(
xaxis_title="行权价",
yaxis_title="剩余天数 (DTE)",
zaxis_title="隐含波动率"
),
title="BTC 期权隐含波动率曲面"
)
fig.show()在本地浏览器打开后会生成一张可旋转、可放大、可 Tooltip 取值的 3D 图像,代码里 不残留任何第三方 cookie。
第五步:异常值与空白格处理
在实盘中,经常会出现某些奇异合约 IV 缺失,导致 3D 曲面呈“锯齿”。折中方案:
- 用线性插值填补孔洞:
pivot = pivot.interpolate(method="linear", axis=1) - 超过 2.5σ 的 IV 作为异常值截掉,然后再次插值。
实战案例:回撤 2024-Q4 曲面
为了让你直观感受,脚本随机抓取 2024-09-13 15:00 (UTC) 的快照:
| 观察点 | 数值 |
|---|---|
| ATM IV (行权价 60,000) | 0.69 |
| 7 DTE Skew 25D | -9.8% |
| 极远端 OTM (行权价 100,000) | 1.12 |
可以看到临交割的平价波动率异常抬升,这与当时市场押注 ETF 审批时间点高度相关。👀 立即查看完整代码与测试数据
常见问题 FAQ
Q1:免费 API 每分钟能调多少次?会不会被限流?
A:大部分交易所公开 REST 端口允许 20QPS 以上。建议每轮批量 ≤25 个合约,同时加 100 ms sleep 即可。
Q2:我没服务器,只有笔记本,跑脚本会不会很慢?
A:从拉取 500+ 条期权到绘图,家用带宽 + i5 只需 3~5 秒。所有运算都在本地,安全无云端依赖。
Q3:曲面形状很复杂,如何判断牛熊变盘?
A:在曲面对比里,若 ATM 曲面“整体下陷”且远端 Put Skew 上升,可视为宏观避险需求增加;反之则是风险偏好修复。
Q4:Python 可否导出为网页嵌入?
A:plotly.offline.plot(fig, include_plotlyjs='cdn', output_type='div') 把 JS 嵌入到一个 <div>,能无缝拷进内部 CMS。
Q5:需要付费行情才能拿到高精度 Iv 吗?
A:一般 Mark IV 就足够做宏观研判;如需 greeks 精度,再考虑订阅烛口级单腿撮合流。
Q6:能否用 Matplotlib 画同款?
A:可行,但交互体验差。若想发文章静态贴图,可用 mpl_toolkits.mplot3d 取代。Plotly 的旋转缩放优势不言而喻。
延伸玩法:扫描曲面畸变快速套利
在校准模型后,把曲面保存到本地 SQLite:
CREATE TABLE iv_curve(
capture_time INTEGER,
strike REAL,
dte REAL,
iv REAL
);每到收 15:00 (UTC) 自动跑批,利用波动率偏离度指标:
z_score = (iv_actual - iv_model) / iv_stdev当某张合约 |z| > 2 且盘口 Δ ≤5%,可触发短线多空对冲。📈 这里有回测模板可直接套用
总结
通过 70 行纯 Python 代码,我们完成了“数据采集 → IV 提取 → 3D 曲面建模 → 可视化”一条龙流程。波动率曲面不仅是 Straddle、Calendar、Skew Trade 的前提,更是衡量市场情绪的晴雨表。掌握本节技巧后,你可以无缝迁移到 ETH、SOL 等其他资产,继续挖掘加密期权市场的 Alpha。祝你交易顺利!