期权量化交易系列教程(四):经典方向性策略——备兑、保护性看跌与价差组合
摘要:本文是“从零开始搭建期权量化交易系统”系列的第四篇。前三篇我们学习了期权基础、Black-Scholes定价模型以及波动率分析。今天,我们将正式进入策略构建阶段,系统实现四种经典的期权方向性策略:备兑策略(Covered Call)、保护性看跌(Protective Put)、牛市看涨价差(Bull Call Spread)以及熊市看跌价差(Bear Put Spread)。每种策略都配有详细的逻辑说明、简化回测代码和绩效对比图表。学完本文,你将掌握如何用Python构建期权组合,评估收益风险,并理解不同市场环境下的最优策略选择。
大家好,我是你们的老朋友。
如果说前三篇是在学习制造武器的材料(定价模型、波动率、希腊字母),那么从今天开始,我们要真正走进“兵工厂”,组装能够上战场的期权策略。
今天聚焦的是方向性策略。这类策略有一个共同特点:它们对你的市场方向判断进行押注,但通过期权组合,可以精确控制最大亏损、降低持仓成本,甚至在不温不火的市场中也赚到钱。
我们不会停留在理论讲解,每一个策略都会给出可运行的Python回测代码,让你直观感受不同策略的盈亏曲线和风险收益特征。
一、四种基础操作快速回顾
在组合策略之前,再回顾一下期权的四种基础操作:
- 买入看涨:看大涨,亏损限于权利金,收益无限。
- 买入看跌:看大跌,亏损限于权利金,收益接近行权价。
- 卖出看涨:看不涨或小跌,收益限于权利金,亏损无限。
- 卖出看跌:看不跌或小涨,收益限于权利金,亏损接近行权价。
我们今天构建的四种策略都是基于这些基础操作的组合。
二、策略一:备兑策略——降低持仓成本
备兑策略(Covered Call)是最受稳健投资者欢迎的期权策略之一。如果你已经持有标的资产(如沪深300ETF),并且短期不认为它会大涨,那么备兑策略可以帮你每个月“收租”。
策略逻辑:持有10000份沪深300ETF的同时,卖出一张虚值看涨期权。卖出期权收到的权利金可以降低持仓成本。如果到期时标的价格没有涨过行权价,权利金稳稳落袋;如果大涨超过行权价,你的ETF会被行权卖出,虽然放弃了超额收益,但依然以满意的价格卖出。
简化回测设计:假设每月滚动操作一次。每月初买入ETF,同时卖出当月到期的虚值看涨期权(行权价选择高于现价5%的水平)。到期时,如果标的价格低于行权价,期权作废,继续滚动;如果高于行权价,以行权价卖出ETF,结算后重新开始。
以下是回测代码示例,使用假设参数来模拟这一过程(实际回测需要完整的期权历史数据,这里我们简化为基于标的价格和BS模型的理论权利金)。
importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltfromscipy.statsimportnorm# 简化BS公式用于计算理论权利金defbs_call(S,K,T,r,sigma):ifT<=0:returnmax(0,S-K)d1=(np.log(S/K)+(r+0.5*sigma**2)*T)/(sigma*np.sqrt(T))d2=d1-sigma*np.sqrt(T)returnS*norm.cdf(d1)-K*np.exp(-r*T)*norm.cdf(d2)# 生成模拟的ETF价格路径np.random.seed(42)n_days=252*2# 两年daily_ret=np.random.normal(0.0005,0.015,n_days)price=100*np.exp(np.cumsum(daily_ret))dates=pd.date_range('2020-01-01',periods=n_days,freq='B')# 回测参数r=0.02sigma=0.20capital=100000# 初始资金shares_per_lot=10000# 合约乘数# 记录净值nav_covered=[1.0]nav_buyhold=[1.0]position='etf'# 当前持仓状态strike=Noneexpiry_day=Noneforiinrange(1,len(price)):S=price[i]# 每月第一个交易日操作ifdates[i].month!=dates[i-1].month:# 如果持有ETF,卖出虚值看涨ifposition=='etf':strike=S*1.05# 虚值5%T=21/252# 约一个月premium=bs_call(S,strike,T,r,sigma)# 卖出期权收取权利金capital+=premium*shares_per_lot position='covered'expiry_day=i+21# 简化:21个交易日后到期elifposition=='covered'andi>=expiry_day:# 到期结算ifS>strike:# 被行权,卖出ETFcapital+=strike*shares_per_lot# 卖出ETF收到现金position='cash'else:# 期权作废,继续持有ETFposition='etf'elifposition=='cash':# 重新买入ETFcapital-=S*shares_per_lot position='etf'# 计算每日净值ifposition=='etf'orposition=='covered':equity=capital+S*shares_per_lotelse:equity=capital nav_covered.append(equity/100000)# 简单买入持有净值nav_buyhold.append((100000+(S-100)*shares_per_lot)/100000)# 绘图plt.figure(figsize=(12,6))plt.plot(dates,nav_covered,label='备兑策略净值')plt.plot(dates,nav_buyhold,label='单纯持有ETF净值')plt.title('备兑策略 vs 单纯持有(模拟回测)')plt.xlabel('日期')plt.ylabel('净值')plt.legend()plt.grid(alpha=0.3)plt.show()策略特点:
- 在震荡或温和上涨市场中持续获得权利金收入,跑赢单纯持有。
- 在大牛市中收益封顶,可能跑输。
- 在大跌中仍然面临ETF的下跌风险,权利金仅起到有限的缓冲作用。
三、策略二:保护性看跌——给持仓上保险
如果你长期看好一只ETF,但短期担心市场大跌(比如财报季、议息会议),保护性看跌策略是你的“保险单”。
策略逻辑:持有ETF的同时,买入一张虚值看跌期权。如果市场大跌,看跌期权的盈利可以弥补ETF的亏损,将最大损失锁定在“行权价 + 权利金成本”附近;如果市场上涨,你只损失了权利金,依然享受大部分涨幅。
简化回测设计:同样按月滚动,每月初买入ETF和当月虚值看跌期权(行权价低于现价5%)。到期时结算,然后重新开仓。
# 保护性看跌回测(接上一段代码的数据)nav_protective=[1.0]capital_pp=100000position_pp='etf'strike_pp=Noneexpiry_pp=Noneforiinrange(1,len(price)):S=price[i]ifdates[i].month!=dates[i-1].month:ifposition_pp=='etf':strike_pp=S*0.95# 虚值5%看跌T=21/252premium_put=bs_call(S,strike_pp,T,r,sigma)-S+strike_pp*np.exp(-r*T)# 看跌-看涨平价简算# 简化计算看跌价格:使用BS公式d1=(np.log(S/strike_pp)+(r+0.5*sigma**2)*T)/(sigma*np.sqrt(T))d2=d1-sigma*np.sqrt(T)premium_put=strike_pp*np.exp(-r*T)*norm.cdf(-d2)-S*norm.cdf(-d1)capital_pp-=premium_put*shares_per_lot position_pp='protected'expiry_pp=i+21elifposition_pp=='protected'andi>=expiry_pp:ifS<strike_pp:# 行权,以行权价卖出ETFcapital_pp+=strike_pp*shares_per_lot position_pp='cash'else:position_pp='etf'elifposition_pp=='cash':capital_pp-=S*shares_per_lot position_pp='etf'ifposition_pp=='etf'orposition_pp=='protected':equity_pp=capital_pp+S*shares_per_lotelse:equity_pp=capital_pp nav_protective.append(equity_pp/100000)plt.figure(figsize=(12,6))plt.plot(dates,nav_buyhold,label='单纯持有ETF')plt.plot(dates,nav_protective,label='保护性看跌策略')plt.title('保护性看跌 vs 单纯持有(模拟回测)')plt.xlabel('日期')plt.ylabel('净值')plt.legend()plt.grid(alpha=0.3)plt.show()策略特点:
- 有效限制下行风险,在市场暴跌时表现优异。
- 成本是定期支付权利金,在震荡上涨行情中会拖累收益。
- 适合对波动敏感的长线投资者。
四、策略三:牛市看涨价差——低成本押注上涨
如果你看好标的上涨,但不想支付全额权利金,或者希望精确控制最大亏损,牛市看涨价差是一个精致的选择。
策略逻辑:买入一张平值(或浅虚值)看涨期权,同时卖出一张相同到期日、更高行权价的看涨期权。卖出期权收到的权利金可以抵消部分成本。最大收益被锁定在(高行权价 - 低行权价 - 净权利金支出),最大亏损就是净权利金支出。
到期盈亏图绘制:
defbull_call_spread(S_range,K_low,K_high,premium_low,premium_high):payoff=np.maximum(S_range-K_low,0)-np.maximum(S_range-K_high,0)pnl=payoff-(premium_low-premium_high)returnpnl S_range=np.linspace(2.5,5.5,100)K_low,K_high=3.8,4.2prem_low,prem_high=0.25,0.10pnl_spread=bull_call_spread(S_range,K_low,K_high,prem_low,prem_high)plt.figure(figsize=(10,5))plt.plot(S_range,pnl_spread,label='牛市看涨价差盈亏')plt.axhline(0,color='black',linestyle='--')plt.title('牛市看涨价差到期盈亏图')plt.xlabel('标的价格')plt.ylabel('盈亏')plt.legend()plt.grid(alpha=0.3)plt.show()策略特点:
- 成本比单纯买看涨低,最大亏损小。
- 收益有上限,适合温和看涨的行情。
- 构建简单,是期权入门的第一个价差策略。
五、策略四:熊市看跌价差——低成本押注下跌
对于看跌市场,可以构造对称的熊市看跌价差。
策略逻辑:买入一张平值(或浅虚值)看跌期权,同时卖出一张相同到期日、更低行权价的看跌期权。同样是限制收益和亏损的策略。
到期盈亏图绘制:
defbear_put_spread(S_range,K_high,K_low,premium_high,premium_low):payoff=np.maximum(K_high-S_range,0)-np.maximum(K_low-S_range,0)pnl=payoff-(premium_high-premium_low)returnpnl K_high_put,K_low_put=4.2,3.8prem_high_put,prem_low_put=0.28,0.12pnl_put_spread=bear_put_spread(S_range,K_high_put,K_low_put,prem_high_put,prem_low_put)plt.figure(figsize=(10,5))plt.plot(S_range,pnl_put_spread,label='熊市看跌价差盈亏')plt.axhline(0,color='black',linestyle='--')plt.title('熊市看跌价差到期盈亏图')plt.xlabel('标的价格')plt.ylabel('盈亏')plt.legend()plt.grid(alpha=0.3)plt.show()六、四种策略对比总结
| 策略 | 市场观点 | 最大收益 | 最大亏损 | 适用场景 |
|---|---|---|---|---|
| 备兑策略 | 小涨/震荡 | 有限(权利金+价差) | ETF下跌风险 | 长期持有+增收 |
| 保护性看跌 | 怕大跌 | 无限(减去权利金) | 有限(下行锁定) | 避险+保留上涨 |
| 牛市看涨价差 | 温和看涨 | 有限 | 有限(净权利金) | 低成本做多 |
| 熊市看跌价差 | 温和看跌 | 有限 | 有限(净权利金) | 低成本做空 |
七、本篇总结
今天我们通过四套组合拳,感受到了期权如何通过巧妙搭配来精确表达市场观点、管理风险。备兑和保护性看跌是与现货持仓结合的“增强”与“保险”工具;价差策略则提供了低成本、风险可控的方向性押注手段。
在下一篇中,我们将脱离方向预测的框架,进入波动率与套利策略的精彩世界——跨式、宽跨式、蝶式,以及真正意义上的波动率套利。你将会看到,即使不判断涨跌,也能在市场中稳定获利。
下一篇预告:期权量化交易系列(五)——波动率与套利策略:跨式、蝶式与波动率套利
我们下篇见!
