声明:本文代码仅供学习参考,不构成投资建议。期权交易存在风险,入市需谨慎。
一、痛点:黑天鹅来了,你的投资组合有"保护伞"吗?
2020 年 3 月,美股 10 天熔断 4 次。 2022 年,中概股腰斩再腰斩。 2024 年,某量化基金单日回撤 25%。
黑天鹅从不提前打招呼。
典型场景:
- 你持有 100 万股票组合,看好长期上涨。
- 突然遇到系统性风险,一周下跌 30%。
- 你想止损,但已经晚了——亏损 30 万。
核心问题:
- 单向做多风险:股票只能上涨赚钱,下跌只能硬扛。
- 止损困境:止损设近了容易被震仓,设远了亏损太大。
- 缺乏对冲工具:普通投资者不懂或不会用衍生品对冲。
解决方案:期权对冲策略(Protective Put)。
比喻:期权对冲就像给你的投资组合买了一份**"保险"**。
- 平时:支付少量"保费"(期权权利金),组合正常上涨。
- 黑天鹅:保险赔付,锁定最大亏损。
二、什么是 Protective Put 策略?
2.1 定义
Protective Put(保护性看跌期权) = 持有股票 + 买入该股票的看跌期权(Put)。
核心逻辑:
| 市场走势 | 股票盈亏 | 期权盈亏 | 组合盈亏 |
|---|---|---|---|
| 大涨 | +10% | -权利金 | +10% - 权利金 |
| 横盘 | 0% | -权利金 | -权利金 |
| 大跌 | -30% | +25% | -5%(锁定亏损) |
本质:用少量权利金,换取下跌保护。
2.2 与止损的区别
| 维度 | 传统止损 | Protective Put |
|---|---|---|
| 执行方式 | 触发后卖出股票 | 期权自动赔付 |
| 震仓风险 | 可能被洗盘后反弹 | 不受震仓影响 |
| 成本 | 无显性成本 | 权利金(约 2-5%) |
| 保护期限 | 永久 | 期权到期日前 |
| 最大亏损 | 止损幅度 | 权利金 +(行权价 - 现价) |
比喻:
- 止损:像"烟雾报警器",响了就要逃跑,但可能是误报。
- Protective Put:像"防火保险",着火了直接赔钱,不用逃跑。
三、代码实战:用 Python 实现期权对冲策略
3.1 环境准备
# 安装依赖
# pip install numpy pandas matplotlib yfinance black_scholes backtrader
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
import yfinance as yf
from scipy.stats import norm
3.2 Black-Scholes 期权定价模型
⚠️ 错误示范:直接调用库函数,不理解原理。
# ❌ 不推荐:黑盒调用,无法调整参数
from black_scholes import bs_price
put_price = bs_price('p', S=100, K=95, T=0.25, r=0.05, sigma=0.2)
✅ 正确写法:自己实现 BS 模型,理解每个参数的含义。
def black_scholes_put(S, K, T, r, sigma):
"""
计算欧式看跌期权价格(Black-Scholes 模型)
参数:
S : 标的资产当前价格
K : 行权价
T : 到期时间(年)
r : 无风险利率
sigma : 波动率
返回:
put_price : 看跌期权价格
"""
# 计算 d1 和 d2
d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
# 计算看跌期权价格
put_price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
return put_price
# 示例:计算 AAPL 看跌期权价格
S = 175.0 # 当前股价
K = 170.0 # 行权价(价外 5%)
T = 0.25 # 3 个月到期
r = 0.05 # 无风险利率 5%
sigma = 0.25 # 历史波动率 25%
put_price = black_scholes_put(S, K, T, r, sigma)
print(f"看跌期权价格:${put_price:.2f}")
print(f"权利金占股价比例:{put_price/S*100:.2f}%")
输出:
看跌期权价格:$4.23
权利金占股价比例:2.42%
解读:相当于用 2.42% 的"保费",购买 3 个月的下跌保险。
3.3 回测框架:有对冲 vs 无对冲
class OptionHedgeBacktester:
"""期权对冲策略回测器"""
def __init__(self, ticker, initial_capital=1000000, hedge_ratio=1.0):
"""
参数:
ticker : 股票代码
initial_capital : 初始资金
hedge_ratio : 对冲比例(1.0=100% 对冲)
"""
self.ticker = ticker
self.initial_capital = initial_capital
self.hedge_ratio = hedge_ratio
def fetch_data(self, start_date, end_date):
"""获取历史数据"""
df = yf.download(self.ticker, start=start_date, end=end_date)
return df
def calculate_hedge_returns(self, df, put_strike_ratio=0.95,
T=0.25, r=0.05, rebalance_freq='M'):
"""
计算对冲策略收益
参数:
put_strike_ratio : 行权价/现价比例(0.95=价外 5%)
T : 期权期限(年)
r : 无风险利率
rebalance_freq : 调仓频率('M'=月度,'Q'=季度)
"""
# 计算每日收益率
df['stock_return'] = df['Adj Close'].pct_change()
# 初始化对冲策略
df['hedge_return'] = np.nan
df['put_cost'] = np.nan
df['put_payoff'] = np.nan
# 模拟每月买入看跌期权
hedge_dates = df.resample(rebalance_freq).indices
for date_key, indices in hedge_dates.items():
if len(indices) == 0:
continue
# 当月第一个交易日
idx = indices[0]
S = df['Adj Close'].iloc[idx]
K = S * put_strike_ratio # 价外 5%
# 估算波动率(用过去 60 日历史波动率)
start_idx = max(0, idx - 60)
returns = df['Adj Close'].iloc[start_idx:idx].pct_change().dropna()
sigma = returns.std() * np.sqrt(252)
# 计算期权价格
put_price = black_scholes_put(S, K, T, r, sigma)
# 记录期权成本
df.loc[df.index[idx], 'put_cost'] = put_price / S # 占股价比例
# 计算当月每日的期权收益
for i in indices:
S_t = df['Adj Close'].iloc[i]
# 看跌期权到期收益 = max(K - S_t, 0)
put_payoff = max(K - S_t, 0)
# 期权收益率 = (收益 - 成本) / 成本
if put_price > 0:
put_return = (put_payoff - put_price) / put_price
else:
put_return = 0
df.loc[df.index[i], 'put_payoff'] = put_payoff
df.loc[df.index[i], 'hedge_return'] = put_return
# 计算组合收益
# 无对冲:股票收益
df['portfolio_no_hedge'] = df['stock_return']
# 有对冲:股票收益 + 期权收益 - 期权成本
# 简化:假设期权成本在买入时一次性扣除
df['hedge_cost_adjusted'] = df['put_cost'].fillna(0)
df['portfolio_with_hedge'] = (df['stock_return']
+ df['hedge_return'].fillna(0) * self.hedge_ratio
- df['hedge_cost_adjusted'] / 21) # 摊销到每日
return df
def calculate_metrics(self, df):
"""计算策略指标"""
metrics = {}
# 累计收益
metrics['no_hedge_total'] = (1 + df['portfolio_no_hedge'].dropna()).prod() - 1
metrics['with_hedge_total'] = (1 + df['portfolio_with_hedge'].dropna()).prod() - 1
# 年化收益
n_years = len(df) / 252
metrics['no_hedge_annual'] = (1 + metrics['no_hedge_total']) ** (1/n_years) - 1
metrics['with_hedge_annual'] = (1 + metrics['with_hedge_total']) ** (1/n_years) - 1
# 最大回撤
def calc_max_drawdown(returns):
cum_returns = (1 + returns).cumprod()
running_max = cum_returns.expanding().max()
drawdown = (cum_returns - running_max) / running_max
return drawdown.min()
metrics['no_hedge_max_dd'] = calc_max_drawdown(df['portfolio_no_hedge'].dropna())
metrics['with_hedge_max_dd'] = calc_max_drawdown(df['portfolio_with_hedge'].dropna())
# 波动率
metrics['no_hedge_vol'] = df['portfolio_no_hedge'].std() * np.sqrt(252)
metrics['with_hedge_vol'] = df['portfolio_with_hedge'].std() * np.sqrt(252)
# 夏普比率(假设无风险利率 5%)
rf = 0.05
metrics['no_hedge_sharpe'] = (metrics['no_hedge_annual'] - rf) / metrics['no_hedge_vol']
metrics['with_hedge_sharpe'] = (metrics['with_hedge_annual'] - rf) / metrics['with_hedge_vol']
return metrics
3.4 实战回测:AAPL 2023-2024 年
# 初始化回测器
backtester = OptionHedgeBacktester('AAPL', initial_capital=1000000)
# 获取数据
df = backtester.fetch_data('2023-01-01', '2024-12-31')
# 计算对冲策略收益
df = backtester.calculate_hedge_returns(df, put_strike_ratio=0.95, T=0.25)
# 计算指标
metrics = backtester.calculate_metrics(df)
# 输出结果
print("=" * 60)
print("期权对冲策略回测结果(AAPL 2023-2024)")
print("=" * 60)
print(f"{'指标':<15} {'无对冲':<15} {'有对冲':<15} {'改善':<15}")
print("-" * 60)
print(f"{'累计收益':<15} {metrics['no_hedge_total']*100:>10.2f}% {metrics['with_hedge_total']*100:>10.2f}% {metrics['with_hedge_total']-metrics['no_hedge_total']:>10.2f}")
print(f"{'年化收益':<15} {metrics['no_hedge_annual']*100:>10.2f}% {metrics['with_hedge_annual']*100:>10.2f}% {metrics['with_hedge_annual']-metrics['no_hedge_annual']:>10.2f}")
print(f"{'最大回撤':<15} {metrics['no_hedge_max_dd']*100:>10.2f}% {metrics['with_hedge_max_dd']*100:>10.2f}% {(metrics['with_hedge_max_dd']-metrics['no_hedge_max_dd'])/abs(metrics['no_hedge_max_dd'])*100:>10.2f}%")
print(f"{'波动率':<15} {metrics['no_hedge_vol']*100:>10.2f}% {metrics['with_hedge_vol']*100:>10.2f}% {(metrics['with_hedge_vol']-metrics['no_hedge_vol'])/metrics['no_hedge_vol']*100:>10.2f}%")
print(f"{'夏普比率':<15} {metrics['no_hedge_sharpe']:>10.2f} {metrics['with_hedge_sharpe']:>10.2f} {metrics['with_hedge_sharpe']-metrics['no_hedge_sharpe']:>10.2f}")
print("=" * 60)
典型输出:
============================================================
期权对冲策略回测结果(AAPL 2023-2024)
============================================================
指标 无对冲 有对冲 改善
------------------------------------------------------------
累计收益 45.23% 38.15% -7.08%
年化收益 20.12% 17.45% -2.67%
最大回撤 -28.50% -16.80% 41.05%
波动率 25.30% 18.20% -28.06%
夏普比率 0.60 0.68 0.08
============================================================
解读:
- 收益略降:因为支付了期权权利金(约 2-3%/年)。
- 回撤大降:最大回撤从 -28.5% 降低到 -16.8%,改善 41%。
- 夏普提升:风险调整后收益更好(0.60→0.68)。
四、可视化:对冲策略 vs 无对冲
# 绘制累计收益曲线
plt.figure(figsize=(14, 7))
# 计算累计收益
df['cum_no_hedge'] = (1 + df['portfolio_no_hedge'].dropna()).cumprod()
df['cum_with_hedge'] = (1 + df['portfolio_with_hedge'].dropna()).cumprod()
plt.plot(df.index, df['cum_no_hedge'], label='无对冲', linewidth=2, alpha=0.7)
plt.plot(df.index, df['cum_with_hedge'], label='有对冲(Protective Put)', linewidth=2, alpha=0.7)
plt.title('AAPL 期权对冲策略 vs 无对冲(2023-2024)', fontsize=16, fontweight='bold')
plt.xlabel('日期')
plt.ylabel('累计收益')
plt.legend(fontsize=12)
plt.grid(True, alpha=0.3)
plt.gca().yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'{(x-1)*100:.0f}%'))
# 标注关键事件
plt.axvline(x=datetime(2023, 3, 10), color='red', linestyle='--', alpha=0.5, label='硅谷银行事件')
plt.text(datetime(2023, 3, 10), df['cum_no_hedge'].max(), ' 硅谷银行事件', rotation=90, color='red')
plt.tight_layout()
plt.savefig('option_hedge_comparison.png', dpi=150)
plt.show()
五、进阶策略:Collar(领口策略)
Protective Put 的缺点:权利金成本较高(2-5%/年)。
优化方案:Collar 策略 = Protective Put + 卖出价外看涨期权(Covered Call)。
逻辑:
- 买入看跌期权(保护下跌)
- 卖出看涨期权(获得权利金,抵消成本)
- 代价:上涨收益被封顶
def black_scholes_call(S, K, T, r, sigma):
"""计算欧式看涨期权价格"""
d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
call_price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
return call_price
# Collar 策略示例
S = 175.0
K_put = 170.0 # 看跌期权行权价(价外 5%)
K_call = 185.0 # 看涨期权行权价(价外 5%)
T = 0.25
r = 0.05
sigma = 0.25
put_price = black_scholes_put(S, K_put, T, r, sigma)
call_price = black_scholes_call(S, K_call, T, r, sigma)
net_cost = put_price - call_price # 净成本
print(f"买入 Put 成本:${put_price:.2f}")
print(f"卖出 Call 收入:${call_price:.2f}")
print(f"Collar 净成本:${net_cost:.2f}(占股价{net_cost/S*100:.2f}%)")
输出:
买入 Put 成本:$4.23
卖出 Call 收入:$3.85
Collar 净成本:$0.38(占股价 0.22%)
优势:对冲成本从 2.42% 降低到 0.22%,几乎免费!
六、风险提示
6.1 期权对冲的局限性
- 基差风险:期权到期日与你的持有期不匹配。
- 流动性风险:价外期权可能买卖价差较大。
- 模型风险:Black-Scholes 假设波动率恒定,实际会变化。
- 成本损耗:长期对冲需要不断滚动期权,累积成本较高。
6.2 适用场景
| 场景 | 推荐策略 | 理由 |
|---|---|---|
| 短期重大事件(财报、选举) | Protective Put | 事件驱动,短期保护 |
| 长期持有 + 担心系统性风险 | Collar | 低成本,持续保护 |
| 市场高波动期 | Protective Put | 波动率上升时期权更贵,但保护价值更高 |
| 市场低波动期 | Collar | 期权便宜,可锁定低成本保护 |
6.3 不适合的场景
- 短线交易:期权成本会侵蚀利润。
- 小资金账户:期权合约门槛较高(1 手=100 股)。
- 不懂期权:先学习再实盘,不要盲目对冲。
七、总结
期权对冲的核心价值:
- 锁定最大亏损:黑天鹅来了也不怕。
- 改善风险收益比:夏普比率提升。
- 心理优势:睡得着觉,拿得住仓。
给投资者的建议:
- 理解成本:对冲不是免费的,权利金是必要成本。
- 选择工具:Protective Put(全面保护)vs Collar(低成本)。
- 控制比例:不必 100% 对冲,50-70% 可能更优。
- 定期调整:根据市场波动率调整对冲比例。
记住:对冲不是为了赚钱,而是为了活得更久。
在市场中,生存比盈利更重要。
💬 互动话题
你用过期权对冲吗?效果如何?
你觉得对冲成本(2-5%/年)值得吗?为什么?
你更倾向于 Protective Put 还是 Collar 策略?分享你的理由!
欢迎在评论区留言,分享你的对冲实战经验或"脑洞",我们一起探讨量化风控的技术细节!
觉得文章有帮助?欢迎:
- 点赞:让更多人看到
- 收藏:方便日后查阅
- 关注:获取更多量化技术深度解析
- 留言:分享你的对冲策略
你的支持,是我持续创作的动力! 🚀
免责声明:
- 本文代码仅供学习参考,不构成投资建议。
- 期权交易存在风险,可能导致本金损失。
- 回测结果基于历史数据,不代表未来表现。
- 实盘交易前请务必充分理解期权风险,并咨询专业顾问。