聊聊期权量化 - 3 - 期权策略的开发和回测

文摘   财经   2024-07-29 17:19   上海  
VeighNa社区【OptionStrategy期权策略分享】系列第2场,将于8月3日(周六)在深圳举办,本次活动将会深入剖析期权策略模板开发和回测引擎细节,并分享针对ETF期权市场的AdvancedSpreadStrategy策略源码,感兴趣的同学可以点击这里查看活动大纲或者直接扫描下方二维码报名:



确认数据需求

本文是《聊聊期权量化》系列的第三篇,还是先来回顾一下本系列计划探讨的主题:

  1. 期权策略投研中的难点(已探讨)
  2. 搭建本地化期权数据库(已探讨)
  3. 期权策略的开发和回测(本文主题)
  4. 实盘期权策略交易运维

在上一篇文章中,我们分享了基于迅投研数据服务搭建本地化期权数据库的代码脚本,以及增量化的每日期权数据更新方案。

对于数据管理这块感到头疼不想折腾的同学,也可以直接使用VeighNa Elite版的DataManager数据管理模块中提供的期权数据自动更新功能

  • 在【交易所】下拉框中选择需要更新下载期权数据的交易所,在【开始时间】编辑框中修改要下载期权数据的开始时间点;
  • 点击【更新期权数据】按钮,即可启动后台的数据下载更新任务进程,任务进程会以交易所为范围更新期权合约数据和历史K线数据
  • 点击【停止数据更新】按钮,等待若干秒后进程就会安全停止退出;
    在更新过程中不能关闭DataManager窗口,否则会中断更新任务。


期权策略开发

和VeighNa平台上的其他策略模块(CtaStrategy、PortfolioStrategy等)类似,OptionStrategy模块在开发策略时同样采用继承策略模板的方式来实现,整体的开发流程如下:

  1. 继承策略模板StrategyTemplate实现策略类
  2. 定义策略的外部入参Parameter和内部变量Variable
  3. 重载on_开头的回调函数实现策略的主体逻辑
  4. 满足条件时调用主动函数发起交易委托或辅助功能

相信接触过一定期权知识的同学,都有听到过所谓【新手买期权,老手卖期权】的说法。但某些传闻中效果拔群的期权交易策略到底绩效如何,这些传闻又没有给出任何数量化的结论。

那么接下来我们就借助OptionStrategy的精准回测功能,来看看一个经典的卖出期权跨式价差策略,在历史回测中的绩效到底如何:

  • 使用中金所股指期权(IO)数据回测
    • 价格跳动(pricetick):0.1
    • 合约乘数(size):100
    • 单边交易滑点(slippage):0.6
    • 固定金额手续费:16元/张
  • 每个月滚动做空当月的跨式价差
    • 基于当月期权链价格,计算ATM行权价
    • 选择ATM的看涨和看跌期权,分别做空N手
    • 随后持有上述空头仓位,直到期权合约到期
    • 到期后下一交易日,在新的当月期权链上重复

策略的代码实现并不复杂。首先导入相关的模块,并且继承实现策略类:

from vnpy.trader.object import TickData, BarData
from elite_optionstrategy import ( StrategyTemplate, Parameter, Variable, PortfolioData, ChainData, OptionData)

class ShortStraddleStrategy(StrategyTemplate): """持续做空跨式价差的策略"""
author: str = "用Python的交易员"
option_portfolio: str = Parameter("IO") # 期权产品代码 fixed_size: int = Parameter(1) # 交易的手数 percent_add: float = Parameter(0.02) # 委托超价比例
atm_strike: float = Variable(0) # 当前ATM行权价

然后实现策略状态控制相关的回调函数。主要注意在on_init初始化回调函数下,需要调用self.subscribe_options来订阅策略交易的期权产品组合

    def on_init(self):        """策略初始化"""        self.write_log("策略初始化")
self.subscribe_options(self.option_portfolio)
def on_start(self): """策略启动""" self.write_log("策略启动")
def on_stop(self): """策略停止"""        self.write_log("策略停止")

接下来在行情数据回调函数下实现策略的交易逻辑部分。由于本篇文章只涉及历史回测,所以跳过on_tick回调函数(实盘Tick推送):

    def on_tick(self, tick: TickData):        """Tick推送"""        pass
def on_bars(self, bars: dict[str, BarData]): """K线推送""" # 如果已有目标则不操作(持有到期) if self.pos_data: return
# 获取期权组合对象 portfolio: PortfolioData = self.get_portfolio(self.option_portfolio)
        # 更新期权价格到组合 price_data: dict[str, float] = {} for bar in bars.values(): price_data[bar.vt_symbol] = bar.close_price
portfolio.update_price(price_data)
# 获取当月期权链 front_chain: ChainData = portfolio.get_chain_by_level(0) if not front_chain: self.write_log("无法获取当月期权链,请检查是否正确添加了期权合约") return
# 计算平值期权 front_chain.calculate_atm() self.atm_strike = front_chain.atm_strike
# 卖出跨式价差 atm_call: OptionData = front_chain.get_option_by_level(cp=1, level=0) atm_put: OptionData = front_chain.get_option_by_level(cp=-1, level=0)
self.set_target(atm_call.vt_symbol, -self.fixed_size) self.set_target(atm_put.vt_symbol, -self.fixed_size)
# 执行具体的委托交易        self.execute_trading(price_data, self.percent_add)

以上代码中:

  • PortfolioData对象提供了期权策略中常用的期权合约动态查询功能,包括根据到期月份顺序筛选期权链、在期权链上根据虚值档位筛选指定行权价的期权合约等功能,详细说明可以参考官方文档中的章节
  • OptionStrategy的交易执行,采用了类似PortfolioStrategy的目标仓位执行模式,用户无需直接执行挂撤单操作,而是通过set_target函数设置下一时刻在每个合约上希望持有的目标仓位后,调用execute_trading函数由策略引擎自动生成对应的买卖委托并发送,大幅简化多合约交易场景下的委托逻辑开发难度。


历史回测评估

将上述策略代码保存为short_straddle_strategy.py文件后,即可通过Elite Lab交互式投研环境来执行回测,回测相关的代码如下(粘贴到Jupyeter单元格中执行):

# 加载功能模块from datetime import datetime
from vnpy.trader.constant import Intervalfrom elite_optionstrategy import BacktestingEngine
from short_straddle_strategy import ShortStraddleStrategy
# 创建回测引擎engine = BacktestingEngine()
engine.set_parameters( interval=Interval.MINUTE, start=datetime(2021, 1, 1), end=datetime(2022, 12, 31), rate=0, slippage=0.6 + (16 / 100),)
engine.add_strategy(ShortStraddleStrategy, {})
# 历史数据回放engine.run_backtesting()
# 计算每日盈亏engine.calculate_result()
# 统计绩效结果result = engine.calculate_statistics()
# 显示资金图表engine.show_chart()

使用2021-2022这两年时间的IO期权数据,回测结果的绩效图表如下:


可以看到作为一个大方向上卖出波动率的期权策略,在回测周期的两年间实现了整体的盈利,且大部分交易时间中都能够通过收Theta的方式在不断积累微小但稳定的收入。但由于策略简单的无脑做空,几乎全程持有跨式价差的空头仓位,在市场出现巨幅波动的2021年2-3月和2022年的2-3月也都遭遇了巨大的回撤,导致策略的收益和Sharpe并不理想。

当然策略的改进空间还有很多,通过结合标的物趋势预测、复合期权价差、动态风险调仓等技术后优化完成的AdvancedSpreadStrategy绩效如下:


AdvancedSpreadStrategy感兴趣的同学,欢迎报名即将举办的【VeighNa社区2024年第8次社区活动 - OptionStrategy期权策略分享系列2】,现场交流更多关于期权策略的投研开发和实盘运维技术细节。



你对于期权回测数据的准备策略的开发有什么疑问,或者希望在后续文章中看到的内容?欢迎在评论区留言告诉我们!!!






免责声明
文章中的信息或观点仅供参考,作者不对其准确性或完整性做出任何保证。读者应以其独立判断做出投资决策,作者不对因使用本报告的内容而引致的损失承担任何责任。

VeighNa开源量化
VeighNa官方公众号。免责声明:本公众号内的文章旨在为更多想要学习Python的学员提供帮助,VeighNa管理者及运营者不对任何利用VeighNa社区或相关软件技术直接或间接从事违反中国法律以及社会公德的行为负责。
 最新文章