第四章:备兑开仓策略
备兑开仓,英文叫 Covered Call。说白了,就是你已经持有股票,然后卖出对应的看涨期权。
我刚开始做期权的时候,觉得这策略太简单了。不就是收点权利金嘛。后来真金白银做进去才发现,这里面的门道比想象中深得多。
策略原理
备兑开仓的核心逻辑就一句话:用股票做担保,卖出一个看涨期权。
你手上有100股某股票,比如茅台。你觉得短期内股价不会大涨,但又不想卖掉股票。这时候你就可以卖出一张茅台的看涨期权,收一笔权利金。
为什么叫「备兑」?因为你有股票做备付,万一期权被行权,你直接交股票就行,不需要额外掏钱买。
这个策略的本质,其实是把股票的一部分上涨空间「卖」给了别人。你放弃了股价超过行权价的超额收益,换来了确定的权利金收入。
关键点:备兑开仓是「收入型」策略,不是「增长型」策略。你的主要目的是赚权利金,不是赚股价上涨的钱。
适用场景
我个人经验里,备兑开仓最适合以下三种情况:
- 震荡市或慢牛市:股价不大涨也不大跌,横盘或者小幅上涨。这时候卖期权收权利金最舒服。
- 你已经持有股票,且不打算近期卖出:比如你长期看好某只股票,但短期觉得涨不动了。那就卖个虚值看涨期权,赚点零花钱。
- 想降低持仓成本:权利金收入可以直接降低你的股票买入成本。我有个朋友,靠备兑开仓把茅台的成本从1800降到了1500。
但要注意,这个策略不适合大牛市。为什么?因为股价一旦暴涨,你的收益就被锁死了。你想想看,股价从100涨到200,你只能赚到行权价那部分,剩下的全归买方。
避坑指南:我曾经在2020年对特斯拉做过备兑开仓,结果股价一个月翻倍。我眼睁睁看着收益被锁死在行权价,那种感觉...嗯,后来我再也不在强势上涨的股票上做备兑了。
收益风险特征
备兑开仓的收益曲线,说白了就是「有上限的收益,有下限的风险」。
| 股价走势 | 收益情况 | 说明 |
|---|---|---|
| 股价大跌 | 亏损 | 股票亏损超过权利金收入,整体亏损 |
| 股价小涨或横盘 | 盈利 | 权利金收入 + 股票小幅增值 |
| 股价大涨超过行权价 | 收益封顶 | 只能赚到行权价 + 权利金,超额收益归买方 |
最大收益 = (行权价 - 买入价) + 权利金
最大亏损 = 买入价 - 权利金(股价跌到0的情况)
嗯,这里要注意一点:备兑开仓并不能对冲下跌风险。股价跌了,你的股票照样亏钱,权利金只能稍微弥补一下。
实战代码实现
下面我用 Python 实现一个完整的备兑开仓策略回测。代码里我会用真实的市场数据,模拟从建仓到平仓的全过程。
import numpy as np
import pandas as pd
import yfinance as yf
from datetime import datetime, timedelta
class CoveredCallStrategy:
"""
备兑开仓策略实现
核心逻辑:持有股票 + 卖出看涨期权
"""
def __init__(self, ticker, stock_quantity=100):
self.ticker = ticker
self.stock_quantity = stock_quantity # 股票数量,默认100股
self.stock_price = 0
self.option_price = 0
self.strike_price = 0
self.premium_received = 0
self.entry_date = None
self.exit_date = None
def fetch_data(self, start_date, end_date):
"""获取股票历史数据"""
stock = yf.download(self.ticker, start=start_date, end=end_date)
return stock
def calculate_option_price(self, stock_price, strike_price, days_to_expiry,
risk_free_rate=0.03, volatility=0.3):
"""
使用Black-Scholes模型计算看涨期权价格
这里简化处理,实际可以用期权链数据
"""
# 简化版:假设期权价格 = 内在价值 + 时间价值
intrinsic_value = max(0, stock_price - strike_price)
time_value = stock_price * volatility * np.sqrt(days_to_expiry/365) * 0.3
return intrinsic_value + time_value
def build_position(self, stock_price, strike_price, days_to_expiry):
"""构建备兑开仓头寸"""
self.stock_price = stock_price
self.strike_price = strike_price
# 计算期权价格
self.option_price = self.calculate_option_price(
stock_price, strike_price, days_to_expiry
)
# 收到的权利金
self.premium_received = self.option_price * 100 # 一张期权对应100股
print(f"建仓价格: {stock_price:.2f}")
print(f"行权价: {strike_price:.2f}")
print(f"期权价格: {self.option_price:.2f}")
print(f"收到权利金: {self.premium_received:.2f}")
def calculate_pnl(self, current_stock_price, option_expired=True):
"""
计算盈亏
option_expired: 期权是否到期
"""
# 股票盈亏
stock_pnl = (current_stock_price - self.stock_price) * self.stock_quantity
# 期权盈亏
if option_expired:
# 期权到期,看是否被行权
if current_stock_price > self.strike_price:
# 被行权,损失超额收益
option_pnl = (self.strike_price - current_stock_price) * 100
else:
# 期权作废,赚取全部权利金
option_pnl = self.premium_received
else:
# 期权未到期,按当前价格计算
current_option_price = self.calculate_option_price(
current_stock_price, self.strike_price, 1
)
option_pnl = (self.option_price - current_option_price) * 100
total_pnl = stock_pnl + option_pnl
return total_pnl, stock_pnl, option_pnl
def run_backtest(self, start_date, end_date, strike_percent=1.05):
"""
运行回测
strike_percent: 行权价相对于当前价格的百分比,1.05表示虚值5%
"""
# 获取数据
data = self.fetch_data(start_date, end_date)
if data.empty:
print("无法获取数据")
return
# 取第一天作为建仓日
entry_price = data['Close'].iloc[0]
strike_price = round(entry_price * strike_percent, 2)
# 假设30天到期
self.build_position(entry_price, strike_price, 30)
# 模拟每日盈亏
results = []
for i, (date, row) in enumerate(data.iterrows()):
current_price = row['Close']
# 判断期权是否到期(假设30天后到期)
option_expired = i >= 20 # 简化处理
total_pnl, stock_pnl, option_pnl = self.calculate_pnl(
current_price, option_expired
)
results.append({
'date': date,
'stock_price': current_price,
'total_pnl': total_pnl,
'stock_pnl': stock_pnl,
'option_pnl': option_pnl
})
# 转换为DataFrame
results_df = pd.DataFrame(results)
# 计算关键指标
total_return = results_df['total_pnl'].iloc[-1]
max_drawdown = (results_df['total_pnl'].cummax() - results_df['total_pnl']).max()
print(f"\n=== 回测结果 ===")
print(f"总盈亏: {total_return:.2f}")
print(f"最大回撤: {max_drawdown:.2f}")
print(f"胜率: {len(results_df[results_df['total_pnl'] > 0]) / len(results_df) * 100:.1f}%")
return results_df
# 使用示例
if __name__ == "__main__":
# 创建策略实例
strategy = CoveredCallStrategy("AAPL", stock_quantity=100)
# 运行回测
results = strategy.run_backtest(
start_date="2023-01-01",
end_date="2023-06-30",
strike_percent=1.05 # 虚值5%
)
# 打印最后10天的结果
if results is not None:
print("\n最后10天数据:")
print(results.tail(10))
个人经验:我建议你在实盘之前,先用这个代码跑一遍历史数据。看看你的股票在什么行情下最适合做备兑。我一般会选波动率中等、趋势不明显的股票。波动率太低,权利金太少;波动率太高,容易被行权。
策略优化建议
做了几年备兑开仓,我总结了几条优化经验:
- 行权价选择:我个人习惯选虚值5%-10%的行权价。太实值容易被行权,太虚值权利金太少。
- 到期时间:30-45天是最佳窗口。太短的时间价值衰减太快,太长又不好管理。
- 滚动操作:如果股价接近行权价,可以提前平仓,再卖下一个月的期权。这叫「滚动」,能避免被行权。
- 分批建仓:不要一次性把所有股票都做备兑。留一部分仓位应对突发行情。
核心要点:备兑开仓不是「一劳永逸」的策略。你需要持续监控,根据市场变化调整行权价和到期日。我见过太多人卖出期权就不管了,结果被行权后追悔莫及。
知识体系结构图
好了,备兑开仓的核心内容就这些。记住一句话:这个策略赚的是时间价值,不是方向判断。你不需要预测股价涨跌,只需要判断它短期内不会大涨就行。
代码我已经给你写好了,拿回去跑一跑,看看你的持仓股票适合不适合做备兑。有什么问题,欢迎交流。