期权量化交易系列教程(二):期权基础——规则、数据与定价模型
摘要本文是“从零开始搭建期权量化交易系统”系列的第二篇。上一篇我们讨论了期权量化交易的意义今天将正式踏入期权世界的大门。我们将梳理期权交易的核心术语、国内期权市场格局然后使用免费开源的akshare库获取真实期权数据。在此基础上我们会用 Python 实现 Black-Scholes 期权定价模型并计算期权的五大希腊字母Delta、Gamma、Theta、Vega、Rho为后续的策略回测和风险管理打下坚实基础。大家好我是你们的老朋友。上一篇文章我们聊了期权量化交易的优势非线性收益、多维度交易、以及量化系统如何克服主观交易的局限。但工欲善其事必先利其器。在动手写任何期权策略之前我们必须先把基础打好。今天这篇文章我们就来系统地学习期权交易的核心概念、数据获取方法以及最重要的——用 Python 实现 Black-Scholes 定价模型和希腊字母计算。这些代码将成为我们后续所有策略回测的基石。一、期权核心术语详解在进入代码之前先把概念搞清楚。以下是期权交易中最常见的术语它们会在代码中反复出现。1.1 行权价与权利金行权价期权合约约定的买卖标的资产的价格。比如沪深300ETF期权行权价 4.0 元意味着买方有权以 4.0 元买入或卖出。权利金买方为了获得这个权利而支付给卖方的费用。它是期权的市场价格。1.2 内在价值与时间价值期权的价格权利金由两部分组成内在价值如果现在立即行权期权能赚多少钱。看涨期权的内在价值 max(标的价格 - 行权价, 0)看跌期权 max(行权价 - 标的价格, 0)。内在价值不可能为负。时间价值权利金减去内在价值。反映的是未来不确定性带来的溢价。离到期日越远时间价值越高。1.3 实值、平值与虚值根据标的价格与行权价的关系期权可以分为三种状态实值内在价值 0。对于看涨期权标的价格 行权价。平值标的价格 ≈ 行权价。虚值内在价值 0。对于看涨期权标的价格 行权价。虚值期权只有时间价值没有内在价值。它们很便宜但到期时成为实值的概率较低。1.4 隐含波动率与历史波动率历史波动率用标的历史价格数据计算的实际波动率反映过去一段时间价格的“颠簸”程度。隐含波动率从期权当前市场价格反推出来的波动率代表市场对未来波动的预期。隐含波动率越高期权越贵。隐含波动率是期权交易的核心变量。很多期权策略如跨式策略、波动率套利本质上都是在交易隐含波动率与实际波动率之间的差异。二、国内期权市场概况目前国内期权市场主要分为三大板块2.1 金融期权交易所交易上证50ETF期权代码510050在上海证券交易所交易是国内最早上市的场内股票期权2015年。沪深300ETF期权有两个上交所的代码510300深交所的代码1599192019年上市。中证500ETF期权上交所代码510500深交所代码1599222022年上市。股指期权中国金融期货交易所的沪深300股指期权IO和中证1000股指期权MO是现金交割的。这些期权的合约乘数通常为 10000 份。即一张期权合约代表 10000 份 ETF 份额。2.2 商品期货期权大连、郑州、上海三家商品交易所都有商品期货期权覆盖农产品、金属、能源化工等品种如豆粕期权、白糖期权、铜期权、铁矿石期权等。商品期权以对应的期货合约为标的乘数取决于具体品种。2.3 交易规则简述行权方式国内 ETF 期权采用欧式行权只能在到期日行权商品期货期权大多采用美式行权到期前任何交易日可随时行权。合约月份通常有当月、下月及随后两个季月共四个到期月份。到期日ETF 期权为到期月份的第四个星期三股指期权为到期月份的第三个星期五。个人投资者参与期权交易有资金门槛50万资产、考试和仿真交易经历要求但可以通过模拟盘或购买期权相关的书籍和工具来学习。三、用 akshare 获取期权数据akshare提供了免费的期权数据接口可以获取合约列表、实时行情和历史数据。无需注册安装即可用。pip install akshare3.1 获取 ETF 期权合约列表以获取上交所沪深300ETF510300的期权合约列表为例importakshareasak# 获取上交所沪深300ETF期权合约列表option_listak.option_sse_list(symbol510300)print(option_list.head(10))返回的 DataFrame 包含合约代码、行权价、到期日等信息。合约代码中包含了标的信息、到期月份、行权价和期权类型C 为看涨P 为看跌。3.2 获取单个合约的日线历史行情得到合约代码后可以获取其日线数据# 获取某只期权合约的历史日线数据# 以 510300C2503M04000 为例代码格式可能随akshare更新变化option_dailyak.option_sse_daily(symbol10006871)# 使用akshare返回的合约代码print(option_daily.tail())注意akshare接口的参数和返回值可能随版本更新而变化请参考最新文档。如果接口暂时不可用也可以从东方财富等网站直接下载期权数据或使用tqsdk等商业数据源。3.3 获取标的资产价格同一代码下的标的 ETF 数据可以通过之前系列中使用的股票数据接口获取importakshareasak etf_dailyak.fund_etf_hist_em(symbol510300,perioddaily,start_date20240101,end_date20241231)etf_daily[日期]pd.to_datetime(etf_daily[日期])etf_daily.set_index(日期,inplaceTrue)print(etf_daily[[收盘]].tail())四、Black-Scholes 期权定价模型4.1 模型简介与公式Black-ScholesBS模型是期权定价的基石。它假设标的资产价格服从对数正态分布市场上不存在无风险套利机会。对于不分红的欧式看涨期权BS 公式为C S * N(d1) - K * e^(-rT) * N(d2)对于看跌期权P K * e^(-rT) * N(-d2) - S * N(-d1)其中d1 [ln(S/K) (r σ²/2) * T] / (σ * √T) d2 d1 - σ * √T符号含义S标的价格K行权价T剩余到期时间年化r无风险利率年化σ波动率年化N()标准正态分布的累积分布函数4.2 Python 实现使用scipy.stats.norm来计算 N(d1) 和 N(d2)importnumpyasnpfromscipy.statsimportnormdefblack_scholes(S,K,T,r,sigma,option_typecall): 计算欧式期权的理论价格 Parameters: - S: 标的现价 - K: 行权价 - T: 剩余到期时间年 - r: 无风险利率 - sigma: 年化波动率 - option_type: call 或 put Returns: - 期权理论价格 ifT0:# 到期时价格就是内在价值ifoption_typecall:returnmax(0,S-K)else:returnmax(0,K-S)d1(np.log(S/K)(r0.5*sigma**2)*T)/(sigma*np.sqrt(T))d2d1-sigma*np.sqrt(T)ifoption_typecall:priceS*norm.cdf(d1)-K*np.exp(-r*T)*norm.cdf(d2)else:priceK*np.exp(-r*T)*norm.cdf(-d2)-S*norm.cdf(-d1)returnprice4.3 应用示例假设沪深300ETF现价 3.8 元行权价 3.9 元剩余30天无风险利率 2%波动率 20%S3.8K3.9T30/365# 剩余30天转换成年r0.02sigma0.20call_priceblack_scholes(S,K,T,r,sigma,call)put_priceblack_scholes(S,K,T,r,sigma,put)print(f看涨期权理论价格{call_price:.4f})print(f看跌期权理论价格{put_price:.4f})4.4 隐含波动率的计算隐含波动率是已知期权市场价格反解 BS 公式中的 σ。由于 BS 公式无法直接求逆通常使用牛顿迭代法等数值方法求解。我们在后续文章中将专门介绍。这里给出一个简单的二分法实现思路defimplied_volatility(price,S,K,T,r,option_typecall,tol1e-6,max_iter100):lo,hi0.001,5.0for_inrange(max_iter):mid(lohi)/2bs_priceblack_scholes(S,K,T,r,mid,option_type)ifabs(bs_price-price)tol:returnmidifbs_priceprice:lomidelse:himidreturn(lohi)/2五、希腊字母的计算希腊字母衡量期权价格对各个变量的敏感度。它们在风险管理中至关重要。5.1 DeltaDelta 衡量期权价格对标的资产价格变化的敏感度。看涨期权的 Delta 在 0 到 1 之间看跌期权在 -1 到 0 之间。defdelta(S,K,T,r,sigma,option_typecall):d1(np.log(S/K)(r0.5*sigma**2)*T)/(sigma*np.sqrt(T))ifoption_typecall:returnnorm.cdf(d1)else:returnnorm.cdf(d1)-15.2 GammaGamma 衡量 Delta 对标的资产价格变化的敏感度即 Delta 的变化速率。Gamma 对于平值期权最大对于深度实值或虚值期权趋近于零。defgamma(S,K,T,r,sigma):d1(np.log(S/K)(r0.5*sigma**2)*T)/(sigma*np.sqrt(T))returnnorm.pdf(d1)/(S*sigma*np.sqrt(T))5.3 ThetaTheta 衡量期权价格对时间流逝的敏感度通常为负值表示时间每过去一天期权价值损耗多少。买方每天在“流血”卖方每天在“收租”。deftheta(S,K,T,r,sigma,option_typecall):d1(np.log(S/K)(r0.5*sigma**2)*T)/(sigma*np.sqrt(T))d2d1-sigma*np.sqrt(T)term1-(S*norm.pdf(d1)*sigma)/(2*np.sqrt(T))ifoption_typecall:term2r*K*np.exp(-r*T)*norm.cdf(d2)return(term1-term2)/365# 每日thetaelse:term2r*K*np.exp(-r*T)*norm.cdf(-d2)return(term1term2)/3655.4 VegaVega 衡量期权价格对隐含波动率变化的敏感度。Vega 总是正值且对于平值期权最大。由于 BS 假设波动率恒定Vega 并不存在于 BS 公式中但我们通常计算 BS 价格的 σ 导数。defvega(S,K,T,r,sigma):d1(np.log(S/K)(r0.5*sigma**2)*T)/(sigma*np.sqrt(T))returnS*norm.pdf(d1)*np.sqrt(T)/100# 每1%波动率变化对应的价格变化5.5 RhoRho 衡量期权价格对无风险利率变化的敏感度。对于短期期权Rho 的影响很小通常忽略不计。defrho(S,K,T,r,sigma,option_typecall):d1(np.log(S/K)(r0.5*sigma**2)*T)/(sigma*np.sqrt(T))d2d1-sigma*np.sqrt(T)ifoption_typecall:returnK*T*np.exp(-r*T)*norm.cdf(d2)/100else:return-K*T*np.exp(-r*T)*norm.cdf(-d2)/1005.6 希腊字母计算示例S,K,T,r,sigma3.8,3.9,30/365,0.02,0.20print(fCall Delta:{delta(S,K,T,r,sigma,call):.4f})print(fGamma:{gamma(S,K,T,r,sigma):.4f})print(fTheta (per day):{theta(S,K,T,r,sigma,call):.4f})print(fVega (per 1% vol):{vega(S,K,T,r,sigma):.4f})print(fRho (per 1% rate):{rho(S,K,T,r,sigma,call):.4f})六、本篇总结今天我们完成了期权量化交易的奠基工作核心术语明确了行权价、权利金、内在价值、时间价值、实值/平值/虚值以及隐含波动率与历史波动率的区别。市场概况了解了国内 ETF 期权、商品期权和股指期权的交易场所和基本规则。数据获取用akshare获取了期权合约列表和日线历史数据。定价模型用 Python 实现了 Black-Scholes 公式能够计算欧式期权的理论价格。希腊字母实现了五大希腊字母的计算这是风险管理和动态对冲的基础。有了这些工具我们就能够开始构建和回测期权交易策略了。在下一篇文章中我们将深入期权量化的核心——波动率分析如何计算历史波动率如何从市场数据中提取隐含波动率以及如何利用 GARCH 模型预测波动率。这些是判断期权贵贱、执行波动率交易策略的关键。下一篇预告期权量化交易系列三——波动率分析与预测隐含波动率、波动率曲面与GARCH模型你准备好深入期权定价的“黑箱”了吗咱们下篇见