读完这篇,你会得到一个 Python 脚本:输入股票代码和到期日,输出这样一张期权链表格(AAPL 实际运行结果,节选):
到期日: ['2026-10-19', '2026-10-21', '2026-10-23', '2026-10-26', ...] 2026-10-21 到期,共 34 个合约 合约 类型 行权价 最新价 买价 卖价 IV Delta Gamma Theta Vega 未平仓 O:AAPL261021C00340000 call 340 6.00 0.00 0.00 42.0% 0.586 0.0327 -0.945 0.113 522 O:AAPL261021C00342500 call 342.5 4.49 0.00 0.00 39.7% 0.503 0.0359 -0.926 0.113 454 O:AAPL261021C00345000 call 345 3.08 0.00 0.00 37.3% 0.410 0.0368 -0.836 0.114 2606 ... O:AAPL261021P00345000 put 345 4.32 0.00 0.00 25.8% -0.637 0.0524 -0.538 0.110 1029 O:AAPL261021P00347500 put 347.5 5.55 0.00 0.00 22.2% -0.789 0.0468 -0.345 0.077 3472 O:AAPL261021P00350000 put 350 8.36 0.00 0.00 - - - - - 1366
准备
- 一个开通了期权套餐的 API Key(查看套餐)。期权套餐可以单独购买,也可以叠加在股票套餐上,共用同一个 Key。
- Python 3.8 以上,安装 requests:
pip install requests
先写一个通用的翻页函数。列表类接口一次最多返回一页,响应里的 next_url 指向下一页,并且已经带上了全部查询条件,顺着它请求直到为空即可:
import requests
BASE = "https://marilux.dev"
API_KEY = "mh_live_your_key" # 换成你的 API Key
H = {"Authorization": f"Bearer {API_KEY}"}
def get_all(url, params=None):
"""请求一个列表接口,顺着 next_url 翻页,直到取完。"""
rows = []
while url:
r = requests.get(url, headers=H, params=params, timeout=30)
r.raise_for_status()
data = r.json()
rows.extend(data.get("results", []))
url, params = data.get("next_url"), None # next_url 已经带上了全部查询条件
return rows
第 1 步:查有哪些到期日
用合约列表接口 /v3/reference/options/contracts 查出某个标的在一段时间内的所有合约,再取出不重复的到期日:
contracts = get_all(f"{BASE}/v3/reference/options/contracts", {
"underlying_ticker": "AAPL",
"expiration_date.gte": "2026-10-19",
"expiration_date.lte": "2026-11-30",
"limit": 1000,
})
expirations = sorted({c["expiration_date"] for c in contracts})
print("到期日:", expirations)
默认只返回还没到期的合约;要查已经到期的历史合约,加上 "expired": "true"。
第 2 步:拉某个到期日的期权链
期权链快照接口 /v3/snapshot/options/{标的} 一次返回整条链上每个合约的最新价格、隐含波动率、希腊值和未平仓量。用 expiration_date 指定到期日,用 strike_price.gte / strike_price.lte 只取平值附近的行权价,可以少翻很多页:
expiry = expirations[1]
chain = get_all(f"{BASE}/v3/snapshot/options/AAPL", {
"expiration_date": expiry,
"strike_price.gte": 320,
"strike_price.lte": 360,
"limit": 250,
})
print(f"{expiry} 到期,共 {len(chain)} 个合约")
只要看涨或只要看跌,再加 "contract_type": "call" 或 "put"。limit 最大 250,设大一点翻页次数少,整体快得多。
第 3 步:取出价格、隐含波动率和希腊值
期权链里每个合约是一个对象,常用字段如下:
| 字段 | 含义 |
|---|---|
details.ticker | 期权代码,如 O:AAPL261021C00345000(格式说明) |
details.contract_type / strike_price / expiration_date | 看涨或看跌、行权价、到期日 |
day.close | 当日最新成交价(盘前为上一交易日收盘价) |
last_quote.bid / last_quote.ask | 最新买一价、卖一价 |
implied_volatility | 隐含波动率,0.373 表示 37.3%(什么是隐含波动率) |
greeks.delta / gamma / theta / vega | 希腊值(各自的含义) |
open_interest | 未平仓量(合约数) |
underlying_asset.price | 标的股票的最新价格 |
有些合约没有希腊值和隐含波动率(见下面常见问题),所以取值时用 .get(),缺失的显示成 "-",不要当成 0:
def fmt(v, width, spec=""):
"""接口没返回的字段显示成 -,不要当成 0。"""
return ("-" if v is None else format(v, spec)).rjust(width)
print("合约 类型 行权价 最新价 买价 卖价 IV Delta Gamma Theta Vega 未平仓")
for c in sorted(chain, key=lambda c: (c["details"]["contract_type"], c["details"]["strike_price"])):
d = c["details"]
day, quote, g = c.get("day", {}), c.get("last_quote", {}), c.get("greeks", {})
print(f"{d['ticker']:<22} {d['contract_type']:<5}"
f"{d['strike_price']:>7} {fmt(day.get('close'), 7, '.2f')}"
f"{fmt(quote.get('bid'), 7, '.2f')}{fmt(quote.get('ask'), 7, '.2f')}"
f"{fmt(c.get('implied_volatility'), 7, '.1%')}"
f"{fmt(g.get('delta'), 8, '.3f')}{fmt(g.get('gamma'), 8, '.4f')}"
f"{fmt(g.get('theta'), 8, '.3f')}{fmt(g.get('vega'), 8, '.3f')}"
f"{fmt(c.get('open_interest'), 8)}")
把上面三段代码按顺序放进一个 .py 文件就是完整脚本,运行后输出文章开头那张表。
常见问题
买价、卖价都是 0?
美股期权只在常规交易时段(美东 9:30–16:00)有报价,休市和盘前盘后时段 last_quote 的买卖价会是 0。需要价格时可以改用 day.close(最新成交价),或等开盘后再取。
有些合约没有希腊值和隐含波动率?
深度实值、长时间没有成交或报价的合约,算不出可靠的隐含波动率,接口就不返回 greeks 和 implied_volatility 字段。上面示例里行权价 350 以上的看跌期权就是这种情况。
只想查一个合约?
用 /v3/snapshot/options/{标的}/{期权代码},返回结构和期权链里的单个元素一样:
r = requests.get(f"{BASE}/v3/snapshot/options/AAPL/O:AAPL261023C00345000", headers=H, timeout=30)
print(r.json()["results"]["greeks"])
怎么存成表格或 CSV?
装了 pandas 的话,json_normalize 会把嵌套字段展开成 greeks.delta 这样的列:
import pandas as pd
df = pd.json_normalize(chain)
df.to_csv("aapl_chain.csv", index=False)
能用 Polygon SDK 写吗?
可以,SDK 会自动翻页,代码更短。见 用 Polygon SDK 接入美股数据。