20、曲面交易系统的回测框架:回测数据准备、回测中的Vega计算、回测结果评估与优化

做曲面交易这几年,我踩过最大的坑就是回测。说实话,很多策略在纸上看着完美,一上实盘就崩。为什么?回测框架没搭好。今天我就把这块硬骨头啃下来,从数据准备到Vega计算,再到结果评估,一条龙讲清楚。

20.1 回测数据准备:别让数据坑了你

回测的第一步,数据。这步做不好,后面全是白搭。我个人习惯把数据准备分成三个层次:

  • 底层数据:期权链的Tick级数据,包括行权价、到期日、隐含波动率、买卖价差
  • 中间层数据:插值后的波动率曲面,按固定Delta和期限网格排列
  • 上层数据:策略信号所需的特征,比如曲面斜率、曲率、期限结构

嗯,这里要注意一点。回测用的数据必须和实盘能拿到的数据一致。我曾经犯过一个错误——用收盘价做回测,结果实盘时发现盘中滑点直接把利润吃掉了。所以我的建议是:

避坑指南:回测数据至少要用分钟级数据,最好用Tick级。如果条件不允许,也要在回测中加上合理的滑点模型。我一般加0.5-1个Tick的滑点,具体看合约流动性。

数据清洗也很关键。期权数据里经常有异常值,比如某个深度虚值期权的隐含波动率突然飙到200%。这种数据不处理,回测结果会失真。我常用的方法是:

# 波动率曲面数据清洗示例
def clean_surface_data(df):
    # 剔除波动率超过5倍历史均值的异常点
    df = df[df['iv'] < df['iv'].rolling(20).mean() * 5]
    # 剔除买卖价差过大的合约(流动性不足)
    df = df[df['spread'] < 0.05 * df['underlying_price']]
    # 剔除剩余期限小于7天的合约(临近到期不稳定)
    df = df[df['ttm'] > 7/365]
    return df

你想想看,如果不清洗,一个异常点可能让你的策略在回测中赚得盆满钵满,实盘却亏得底裤都不剩。说白了,数据质量决定了回测的可信度。

20.2 回测中的Vega计算:别用错公式

Vega计算是曲面交易回测的核心。很多人直接用Black-Scholes公式算Vega,但曲面交易里有个坑——你交易的是波动率曲面的形状变化,不是单个期权的Vega。

我个人习惯把Vega拆成三部分:

  1. 绝对Vega:整个组合对波动率水平变化的敏感度
  2. 倾斜Vega:组合对波动率曲面斜率变化的敏感度
  3. 曲率Vega:组合对波动率曲面凸度变化的敏感度

回测时怎么算?我举个例子。假设你有一个蝶式价差策略,买入低行权价和高行权价的期权,卖出中间行权价的期权。这个策略的Vega不是简单的加减,而是要看曲面形状变化时它的表现。

核心公式:曲面Vega = Σ (期权Vega × 曲面因子载荷)

具体实现时,我建议用有限差分法。比如要算倾斜Vega,就先把曲面斜率向上微调1%,再向下微调1%,看组合价值变化多少。代码大概是这样的:

def calculate_surface_vega(portfolio, surface, shift=0.01):
    # 原始曲面下的组合价值
    base_value = portfolio.value(surface)
    
    # 向上调整曲面斜率
    surface_up = surface.copy()
    surface_up.slope += shift
    value_up = portfolio.value(surface_up)
    
    # 向下调整曲面斜率
    surface_down = surface.copy()
    surface_down.slope -= shift
    value_down = portfolio.value(surface_down)
    
    # 有限差分法计算倾斜Vega
    slope_vega = (value_up - value_down) / (2 * shift)
    return slope_vega

这里有个细节要注意。回测中计算Vega时,一定要用当时的市场数据,不能用事后数据。我见过有人用整个回测期的平均波动率来算Vega,结果回测曲线漂亮得不行,实盘却一塌糊涂。为什么?因为波动率是时变的,用平均数据会平滑掉很多风险。

20.3 回测结果评估:别只看夏普比率

回测跑完了,怎么评估?很多人只看夏普比率和最大回撤。但曲面交易有个特点——它的收益分布往往不是正态的。你想想看,波动率曲面突变时,可能一天亏掉三个月的利润。

我常用的评估指标有这些:

指标 说明 我的经验阈值
夏普比率 风险调整后收益 > 1.5 才算合格
最大回撤 从峰值到谷底的最大跌幅 < 15% 比较安全
收益偏度 收益分布是否对称 负偏度要警惕尾部风险
Vega风险暴露 组合对曲面变化的敏感度 需控制在总资金的20%以内
胜率与盈亏比 交易胜率和平均盈亏比 胜率>40%且盈亏比>2

我个人最看重的是Vega风险暴露。为什么?因为曲面交易的本质就是赌曲面形状变化。如果你的策略在回测中Vega暴露一直很大,那说明你其实是在赌方向,而不是在交易曲面。真正的曲面交易应该是Vega中性或接近中性的。

实战技巧:回测时把Vega暴露画成时间序列图。如果Vega暴露经常超过阈值,说明你的策略需要加对冲。我一般要求Vega暴露在±5%以内。

20.4 回测优化:过拟合是最大的敌人

回测优化这块,我吃过不少亏。说实话,优化参数太容易了——你总能找到一组参数让回测曲线完美向上。但这样的策略上了实盘,大概率是亏钱的。

我的优化原则有三条:

  • 参数要少:超过3个可调参数的策略,我基本不碰。参数越多,过拟合风险越大。
  • 要跨周期验证:把数据分成训练期和验证期。训练期表现好不算什么,验证期也能赚钱才是真本事。
  • 要加压力测试:模拟极端行情,比如2008年金融危机、2020年新冠暴跌。如果策略在这些时期扛不住,那就不算好策略。

我曾经优化过一个曲面套利策略,回测夏普比率高达3.0。结果实盘第一个月就亏了8%。后来复盘发现,那组参数在回测中完美捕捉了某次特定的曲面形态变化,但那种形态在实盘里再也没出现过。说白了,就是过拟合。

怎么避免?我建议用Walk-Forward分析。简单说就是滚动回测:用前一段数据训练,后一段数据验证,不断向前滚动。这样能有效检验策略的稳定性。

# Walk-Forward分析框架
def walk_forward_analysis(data, train_window=252, test_window=63):
    results = []
    for i in range(0, len(data) - train_window - test_window, test_window):
        train_data = data[i:i+train_window]
        test_data = data[i+train_window:i+train_window+test_window]
        
        # 在训练集上优化参数
        params = optimize_params(train_data)
        
        # 在测试集上验证
        perf = backtest(test_data, params)
        results.append(perf)
    
    return results

嗯,这里还要提一句。回测结果评估时,别忘了看交易成本。曲面交易通常需要频繁调仓,交易成本可能吃掉很大一部分利润。我一般按双边万三算手续费,再加上滑点成本。如果扣除成本后策略还能赚钱,那才算真的有效。

总结一下:曲面交易回测框架的核心就三件事——数据要干净、Vega要算准、评估要全面。别被漂亮的回测曲线迷惑,多想想实盘会是什么样子。记住,回测的目的是发现策略的弱点,而不是证明策略有多牛。

最后送大家一句话:回测是门艺术,不是科学。数据、模型、参数,每个环节都有主观判断。保持怀疑,多问几个「为什么」,你的策略才能经得起实盘的考验。

我的习惯:每次回测完,我都会问自己三个问题——这个策略在什么情况下会亏钱?亏多少?我能不能承受?如果三个问题都能回答清楚,那这个策略就值得上实盘。
曲面交易系统回测框架 回测数据准备 底层数据(Tick级) → 中间层(曲面插值) → 上层(特征工程) 数据清洗:剔除异常IV、流动性不足、临近到期合约 回测中的Vega计算 绝对Vega(水平) → 倾斜Vega(斜率) → 曲率Vega(凸度) 方法:有限差分法 + 曲面因子载荷分解 回测结果评估 夏普比率 | 最大回撤 | 收益偏度 | Vega风险暴露 | 胜率与盈亏比 重点:Vega暴露需控制在±5%以内 回测优化与防过拟合 参数精简(≤3个) | 跨周期验证 | 压力测试 | Walk-Forward分析 核心:回测的目的是发现弱点,不是证明策略多牛 曲面交易回测框架:数据 → Vega → 评估 → 优化,闭环迭代
公众号:蓝海资料掘金营,微信deep3321