3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在期权组合管理与量化交易中,希腊字母(Greeks,包括 Delta, Gamma, Vega, Theta, Rho)是衡量投资组合风险暴露的核心指标。本文将介绍如何在 ptrade 平台中通过获取期权及标的实时行情,结合 Black-Scholes (B-S) 定价模型进行希腊字母的实时计算,并实现简单的 Delta 中性风险对冲策略。
在 ptrade 交易或回测环境中,可以通过 get_snapshot 或 get_history 接口获取期权合约及其标的资产的实时价格与历史行情。
注意:期权标的代码包含上海股票期权(后缀
.XSHO)与深圳股票期权(后缀.XSZO)。
# 示例:在 before_trading_start 或 handle_data 中订阅并获取快照
def initialize(context):
g.option_code = '10004000.XSHO' # 示例期权代码
g.underlying = '510300.SS' # 标的ETF
set_universe([g.option_code, g.underlying])
def handle_data(context, data):
# 获取标的与期权快照
snapshot = get_snapshot([g.option_code, g.underlying])
underlying_price = snapshot[g.underlying]['last_px']
option_price = snapshot[g.option_code]['last_px']
利用 scipy.stats.norm 模块,可基于 Black-Scholes 公式计算欧式期权的 Delta 与 Gamma:
import math
from scipy.stats import norm
def calc_greeks(S, K, T, r, sigma, option_type='call'):
"""
S: 标的价格
K: 行权价
T: 剩余到期时间(年)
r: 无风险利率
sigma: 隐含波动率
option_type: 'call' 或 'put'
"""
if T <= 0 or sigma <= 0:
return {'delta': 0.0, 'gamma': 0.0}
d1 = (math.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * math.sqrt(T))
d2 = d1 - sigma * math.sqrt(T)
if option_type == 'call':
delta = norm.cdf(d1)
else:
delta = norm.cdf(d1) - 1.0
gamma = norm.pdf(d1) / (S * sigma * math.sqrt(T))
return {'delta': delta, 'gamma': gamma}
Delta 中性对冲旨在通过持有标的资产(或标的期货/ETF)来抵消期权持仓的 Delta 风险暴露,使得组合总 Delta 保持为 0。
import math
from scipy.stats import norm
def initialize(context):
g.option_code = '10004000.XSHO' # 期权合约
g.underlying = '510300.SS' # 标的ETF
g.K = 4.0 # 行权价
g.r = 0.025 # 无风险利率
g.sigma = 0.20 # 估计/计算出的隐含波动率
g.expire_date = '2023-12-25' # 到期日
set_universe([g.option_code, g.underlying])
run_daily(context, rebalance_delta, time='14:30')
def get_time_to_expiry(context):
# 简化的到期时间计算(单位:年)
current_dt = context.blotter.current_dt
# 实际开发中可用 datetime 解析开盘天数换算年化 T
return 0.25
def calc_greeks(S, K, T, r, sigma, option_type='call'):
if T <= 0 or sigma <= 0:
return {'delta': 0.0, 'gamma': 0.0}
d1 = (math.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * math.sqrt(T))
delta = norm.cdf(d1) if option_type == 'call' else norm.cdf(d1) - 1.0
gamma = norm.pdf(d1) / (S * sigma * math.sqrt(T))
return {'delta': delta, 'gamma': gamma}
def rebalance_delta(context):
snapshot = get_snapshot([g.option_code, g.underlying])
if not snapshot:
return
S = snapshot[g.underlying]['last_px']
T = get_time_to_expiry(context)
# 1. 计算单张期权 Delta
greeks = calc_greeks(S, g.K, T, g.r, g.sigma, option_type='call')
option_delta = greeks['delta']
# 假设持有一手(10000份)看涨期权多头
option_amount = 10000
total_option_delta = option_delta * option_amount
# 2. 计算标的资产所需对冲数量 (Delta 中性需要标的数量 = -总期权Delta)
target_underlying_amount = -int(total_option_delta)
# 3. 获取当前标的持仓,进行动态再平衡
current_pos = get_position(g.underlying).amount
trade_amount = target_underlying_amount - current_pos
if abs(trade_amount) >= 100: # 满足最小交易手倍数
order(g.underlying, trade_amount)
log.info(f"对冲再平衡: 标的价格={S}, 期权Delta={option_delta:.4f}, 交易标的数量={trade_amount}")
def handle_data(context, data):
pass