问题描述
解决方案
备兑开仓(Covered Call)是一种常见的增强收益策略,其核心逻辑是:在持有标的证券(如股票或ETF)的同时,卖出相应数量的认购期权(Call Option)。如果标的价格上涨,期权被行权,投资者以行权价卖出标的获利;如果标的价格下跌或横盘,投资者赚取期权权利金以降低持仓成本。
策略实现思路
在 PTrade 中实现该策略,我们需要完成以下步骤:
- 初始化:设置标的股票代码、期权合约代码以及合约乘数(例如 50ETF 期权通常对应 10000 份标的)。
- 买入标的:检查账户是否持有足够数量的标的证券,如果不足则买入。
- 卖出期权:在确认持有足额标的后,卖出相应数量的看涨期权(开空仓)。
注意事项
- 合约代码:由于提供的 API 文档中未包含动态获取期权链(Option Chain)的接口(如根据到期日筛选合约),本示例代码需要您手动填入具体的期权合约代码。
- 下单接口:PTrade 中卖出期权通常使用
order函数传入负数数量(代表卖出/做空),或者在部分柜台环境下可能兼容期货的sell_open接口。本示例使用通用的order接口。 - 合约乘数:务必确认期权的合约乘数(Contract Multiplier),确保标的持仓足够覆盖期权义务。
PTrade 策略代码
def initialize(context):
"""
策略初始化函数
"""
# 1. 设置标的资产 (以50ETF为例)
g.security = '510050.SS'
# 2. 设置要卖出的看涨期权合约代码
# 注意:此处需要您根据实际市场情况填入具体的期权代码
# 例如:'1000XXXX.XSHO' (上海证券交易所期权)
g.call_option = '1000XXXX.XSHO'
# 3. 设置合约乘数 (一张50ETF期权合约通常对应10000份ETF)
g.multiplier = 10000
# 4. 设置股票池,包含标的和期权
set_universe([g.security, g.call_option])
# 5. 设定交易费率 (可选,根据实际情况调整)
# 股票佣金万三,期权通常按张收费,此处仅作示例
set_commission(commission_ratio=0.0003, min_commission=5.0, type='STOCK')
def handle_data(context, data):
"""
盘中运行函数,负责执行交易逻辑
"""
# 获取标的资产的持仓信息
stock_position = get_position(g.security)
# ---------------------------------------------------
# 第一步:构建标的持仓 (Long Stock)
# ---------------------------------------------------
# 如果标的持仓不足以覆盖一张期权合约,则买入标的
if stock_position.amount < g.multiplier:
# 计算需要买入的数量
target_amount = g.multiplier
# 下单买入标的
order_target(g.security, target_amount)
log.info("标的持仓不足,买入标的: %s,目标数量: %d" % (g.security, target_amount))
# 买入标的后,当前周期可能无法立即获取最新持仓(取决于回测/实盘模式)
# 因此本周期暂不进行期权操作,等待下一周期确认持仓后再卖出期权
return
# ---------------------------------------------------
# 第二步:卖出看涨期权 (Short Call)
# ---------------------------------------------------
# 获取期权的持仓信息
option_position = get_position(g.call_option)
# 检查是否已经持有期权空头头寸
# short_amount 表示空头持仓数量
if option_position.short_amount == 0:
# 确保标的充足后,卖出1张期权合约
# 在 order 函数中,负数表示卖出
order(g.call_option, -1)
log.info("持有足额标的,执行备兑开仓:卖出期权 %s" % g.call_option)
# ---------------------------------------------------
# (可选) 第三步:到期或止损逻辑
# ---------------------------------------------------
# 此处可以添加逻辑:如果期权临近到期,或者标的价格大幅波动,
# 可以选择平仓期权 (买入平仓) order(g.call_option, 1)
代码解析
-
initialize:- 定义了全局变量
g.security(标的)和g.call_option(期权)。 g.multiplier设置为 10000,这是做备兑策略的关键,必须保证“标的数量 >= 期权张数 * 合约乘数”。- 使用
set_universe将两者加入股票池,确保能获取到行情和持仓数据。
- 定义了全局变量
-
handle_data:- 买入标的逻辑:首先检查
get_position(g.security).amount。如果持仓少于 10000 股,使用order_target补足持仓。为了防止裸卖空期权,如果当次循环进行了买入操作,直接return,等待下一个交易周期确认持仓到位。 - 卖出期权逻辑:当确认标的持仓充足(
>= g.multiplier)且当前没有期权空头持仓(short_amount == 0)时,使用order(g.call_option, -1)卖出 1 张期权合约。
- 买入标的逻辑:首先检查
常见问题 (Q&A)
Q: 如何获取期权合约代码?
A: 在 PTrade 的 API 文档中,并未提供根据到期日或行权价动态筛选期权合约的专用函数(如 get_option_chain)。通常需要在策略外部查询好代码(如 '10004321.XSHO'),或者在 initialize 中手动更新代码列表。
Q: 为什么使用 order 传入负数而不是 sell_open?
A: 虽然 PTrade 对期货支持 buy_open/sell_open 等开平仓函数,但对于期权,通常兼容股票的 order 接口。传入负数(如 -1)即代表卖出。如果您的账户是两融或特定衍生品账户,且柜台要求严格区分开平仓,请咨询券商是否支持 sell_open 用于期权。
Q: 回测和实盘有什么区别?
A: 在回测中,order 下单后通常在下一个 bar 成交(分钟级回测)。在实盘中,需要考虑委托是否成交。上述代码在 handle_data 中通过检查 get_position 来确认持仓,这是一种稳健的做法,可以避免在标的未成交时就卖出期权导致变成“裸卖空”。