从零搭建期权波动率曲面可视化平台:FastAPI + Vue 3 实战
在国内期权领域,想要看到一张实时、可交互的波动率曲面图有多难?本文记录了我从数据采集到 3D 可视化全链路实现的完整过程。
为什么做这个项目?
做期权交易的朋友都知道,国内主流行情软件(同花顺、通达信)虽然能提供期权行情,但在隐含波动率可视化方面相当欠缺------
- 波动率曲面?没有
- IV Smile?没有
- 期限结构对比?也没有
而国外的 OptionMetrics、VolAnalytics 等工具不仅收费昂贵,且数据源不对接国内 A 股/期货期权。
作为一个量化爱好者,我想做一个完全开源、能跑起来、本地就能用的期权分析工具 。于是,option-platform 诞生了。
先看效果
项目运行后,你会得到这样一个全栈系统:
| 页面 | 功能 |
|---|---|
| Dashboard | 数据总览面板,实时快照 |
| 实时行情 | 期权合约买卖盘口、最新价格 |
| 波动率曲面 | 3D 交互式曲面,支持旋转缩放 |
| IV Smile | 隐含波动率偏度曲线 |
| 期限结构 | 不同到期日 IV 走势 |
| K线图表 | 标的期货/ETF 历史 K 线 |
| 合约详情 | B-S 定价 + Greeks 全量输出 |
技术选型
dart
前端:Vue 3 + Vite + Element Plus + ECharts
后端:FastAPI + Python 3.11
数据:AKShare(实时期权行情)
存储:SQLite(隐含波动率历史)
部署:uvicorn + Nginx 反向代理
选择 FastAPI 而不是 Flask,主要因为:
- 原生 async 支持,适合高频轮询场景
- 自动 OpenAPI 文档,调试接口不用 Postman
- Pydantic 模型校验,减少边界条件 bug
前端选 Vue 3 而非 React,因为组合式 API 写复杂的状态管理(曲面数据 + 行情轮询)更清爽。
核心技术拆解
1. B-S 定价引擎
纯 Python 实现,零外部依赖,核心代码不到 100 行:
python
from dataclasses import dataclass
import math
from typing import Optional
@dataclass
class BSParams:
S: float # 标的现价
K: float # 行权价
T: float # 到期时间(年)
r: float = 0.025 # 无风险利率(年化)
sigma: float = 0.25 # 波动率(年化)
def bs_price(params: BSParams, option_type: str) -> float:
"""计算期权理论价格"""
d1 = (math.log(params.S / params.K) + (params.r + 0.5 * params.sigma ** 2) * params.T) \
/ (params.sigma * math.sqrt(params.T))
d2 = d1 - params.sigma * math.sqrt(params.T)
if option_type == "call":
return params.S * norm_cdf(d1) - params.K * math.exp(-params.r * params.T) * norm_cdf(d2)
else:
return params.K * math.exp(-params.r * params.T) * norm_cdf(-d2) - params.S * norm_cdf(-d1)
def bs_greeks(params: BSParams) -> dict:
"""计算 Greeks: Delta, Gamma, Vega, Theta, Rho"""
# ... 完整实现见项目代码
这个项目最有意思的地方在于:Greeks 不是简单套公式,而是结合实时行情数据动态计算。比如 Delta 会直接影响对冲比例,我把它做到了毫秒级更新。
2. 数据采集层
使用 AKShare 对接国内期权行情:
python
# data_service.py 核心逻辑
import akshare as ak
import pandas as pd
def fetch_option_chain(symbol: str) -> pd.DataFrame:
"""获取期权合约链"""
df = ak.stock_option_contract_info_em(symbol=symbol)
# 清洗 + 合并 + 计算隐含波动率
return df
AKShare 的好处是接口稳定、不需要 API Key、覆盖上交所/深交所/中金所期权品种。
难点在于数据清洗------原始数据的格式不统一,行权价单位、到期日格式都需要标准化。这块花了我最多时间。
3. 3D 波动率曲面渲染
这是整个项目技术含量最高的部分。前端用纯 Canvas 2D 实现透视投影,配合 CSS3D transform 做辅助渲染:
vue
// Surface3D.vue
<template>
<canvas ref="surface" @mousedown="onMouseDown" />
</template>
<script setup>
const drawSurface = () => {
// 透视投影:3D坐标 -> 2D屏幕
// 网格线绘制
// 颜色映射(波动率高低 -> 色阶)
// 旋转交互
}
</script>
曲面数据格式如下:
json
{
"expiries": ["2026-08", "2026-09", "2026-10"],
"strikes": [4800, 4900, 5000, 5100, 5200],
"iv_matrix": [[28.5, 30.2, 32.1], [27.8, 29.5, 31.3], ...]
}
后端从 SQLite 读取 IV 历史数据,计算当前曲面点,前端收到数据后实时渲染。
4. 自动轮询与数据修复
后台使用 asyncio 定时任务每 30 秒自动拉取行情,更新 IV 数据库:
python
# main.py
import asyncio
@asynccontextmanager
async def lifespan(app):
# 启动后台轮询任务
app.state.task = asyncio.create_task(poll_data_loop())
yield
app.state.task.cancel()
async def poll_data_loop():
while True:
await asyncio.sleep(30)
await fetch_and_update()
同时加入了数据异常检测------当检测到某条数据明显偏离历史分布时,自动标记并触发修复流程。
项目架构
bash
option-platform/
├── backend/
│ ├── main.py # FastAPI 入口
│ ├── bs_model.py # B-S 定价 + Greeks
│ ├── data_service.py # AKShare 数据采集
│ ├── iv_store.py # IV 历史存储(SQLite)
│ └── models.py # Pydantic 模型
├── frontend/
│ ├── src/views/ # 页面组件
│ ├── src/components/ # Surface3D.vue 等
│ └── src/utils/ # CSS 变量读取等工具
└── README.md
前后端分离,通过 RESTful API 通信,API 文档自动生成(/docs)。
如何本地运行
bash
git clone https://github.com/Marvelous-dot/option-platform.git
cd option-platform
# 后端
cd backend
pip install -r requirements.txt
python run.py
# 前端
cd ../frontend
npm install
npm run dev
# 浏览器访问 http://localhost:5173
环境要求:Python 3.11+、Node 18+
写在最后
这个项目从想法到第一个可用版本花了大概两周时间。最大的收获不是技术,而是第一次真正从 0 搭建了一个全栈量化工具。
目前项目还处在早期阶段,后续计划:
- 增加更多期权品种(50ETF、300ETF、500ETF)
- 策略回测模块
- Docker 一键部署
- 移动端适配
如果你也在做期权相关的工作,或者对量化可视化感兴趣,欢迎来 GitHub 看看:
Star 一下,有问题随时提 Issue 🙌
本文基于项目开源代码撰写,MIT License,欢迎 Fork。