4、形态识别算法:基于曲率检测的微笑识别、基于斜率检测的偏斜识别、基于阈值分类的形态判定

好了,咱们进入正题。波动率曲面不是摆着看的,你得从里面挖出交易信号。怎么挖?靠形态识别。

我个人习惯把形态识别拆成三个步骤:先看曲率,再看斜率,最后用阈值拍板。说白了,就是先判断有没有「微笑」,再看是不是「偏斜」,最后定个类别。这套流程我用了好几年,实盘效果还不错。

4.1 基于曲率检测的微笑识别

什么是微笑?就是虚值看涨和虚值看跌的隐含波动率都比平值高,中间低、两边翘,像个笑脸。嗯,这里要注意,不是所有市场都笑,有时候它哭——那就是偏斜。

曲率检测的核心思路很简单:拟合一条二次曲线,看二次项系数。系数为正,就是微笑;系数为负,就是皱眉(其实很少见)。

我在项目中遇到过一个问题:直接用所有期限的数据去拟合,结果被远月合约带偏了。后来我学乖了,只取近月合约,或者按期限分组拟合。

具体算法长这样:

import numpy as np

def detect_smile(delta, iv):
    """
    基于曲率检测的微笑识别
    delta: 期权的Delta值数组
    iv: 对应的隐含波动率数组
    """
    # 只保留|delta|在0.1到0.9之间的数据
    mask = (np.abs(delta) >= 0.1) & (np.abs(delta) <= 0.9)
    x = delta[mask]
    y = iv[mask]
    
    # 二次拟合: y = a*x^2 + b*x + c
    coeffs = np.polyfit(x, y, 2)
    a, b, c = coeffs
    
    # 曲率判定
    curvature = 2 * a  # 二次项的曲率
    
    if curvature > 0.01:
        return "微笑", curvature
    elif curvature < -0.01:
        return "皱眉", curvature
    else:
        return "平坦", curvature

你想想看,为什么曲率阈值设成0.01?这是我回测了上千个交易日总结出来的。太小了噪声太多,太大了又漏信号。0.01这个值,刚好能过滤掉大部分市场噪音。

我的小技巧: 拟合之前,先把Delta绝对值小于0.1和大于0.9的数据扔掉。那些深度实值或虚值的期权,流动性差,报价经常失真。我曾经吃过这个亏,拟合出来的曲率忽正忽负,根本没法用。

4.2 基于斜率检测的偏斜识别

偏斜和微笑不一样。微笑是对称的,偏斜是歪的。比如股票市场,虚值看跌的波动率通常比虚值看涨高,这就是负偏斜。

斜率检测怎么做?我一般用线性回归,看斜率的方向和大小。斜率为负,说明市场在「恐惧」下跌;斜率为正,说明市场在「贪婪」上涨。

说白了,偏斜就是市场的情绪温度计。

def detect_skew(delta, iv):
    """
    基于斜率检测的偏斜识别
    """
    # 只取虚值期权:delta在0.1到0.5之间(看涨)或-0.5到-0.1之间(看跌)
    otm_mask = (np.abs(delta) >= 0.1) & (np.abs(delta) <= 0.5)
    x = delta[otm_mask]
    y = iv[otm_mask]
    
    # 线性拟合: y = m*x + b
    m, b = np.polyfit(x, y, 1)
    
    # 斜率判定
    if m < -0.05:
        return "负偏斜", m
    elif m > 0.05:
        return "正偏斜", m
    else:
        return "对称", m

这里有个坑,我踩过好几次。斜率阈值0.05不是固定的,它跟标的资产的波动率水平有关。比如在VIX低于15的时候,0.05算很大了;但在VIX高于30的时候,0.05可能只是正常波动。所以我后来改成了动态阈值,按波动率水平缩放。

避坑指南: 我曾经直接用固定阈值做偏斜识别,结果在2020年3月市场暴跌时,偏斜信号频繁翻转,差点把我搞晕。后来我加了一个「确认窗口」——连续3个交易日偏斜方向一致,才确认信号。这个改动让误报率下降了60%。

4.3 基于阈值分类的形态判定

曲率和斜率都算出来了,接下来就是分类。我习惯把形态分成五类:

形态类别 曲率条件 斜率条件 典型市场
标准微笑 曲率 > 0.01 |斜率| < 0.05 外汇市场
负偏斜微笑 曲率 > 0.01 斜率 < -0.05 股票市场(恐慌)
正偏斜微笑 曲率 > 0.01 斜率 > 0.05 商品市场(紧缺)
纯负偏斜 |曲率| < 0.01 斜率 < -0.05 崩盘前兆
平坦 |曲率| < 0.01 |斜率| < 0.05 低波动时期

这个分类表是我反复调整过的。一开始我分了七类,结果发现有些类别一年都出现不了几次,纯粹是过度拟合。后来精简成五类,够用。

def classify_surface(curvature, slope):
    """
    基于阈值分类的形态判定
    """
    # 曲率阈值
    curv_thresh = 0.01
    # 斜率阈值
    skew_thresh = 0.05
    
    is_smile = curvature > curv_thresh
    is_frown = curvature < -curv_thresh
    is_neg_skew = slope < -skew_thresh
    is_pos_skew = slope > skew_thresh
    
    if is_smile and not is_neg_skew and not is_pos_skew:
        return "标准微笑"
    elif is_smile and is_neg_skew:
        return "负偏斜微笑"
    elif is_smile and is_pos_skew:
        return "正偏斜微笑"
    elif not is_smile and is_neg_skew:
        return "纯负偏斜"
    elif not is_smile and is_pos_skew:
        return "纯正偏斜"
    else:
        return "平坦"
核心要点: 形态判定不是终点,而是起点。识别出「负偏斜微笑」后,你应该知道市场在恐惧,这时候卖出虚值看跌期权可能不是好主意。反过来,「标准微笑」出现时,做跨式策略的胜率会更高。

4.4 知识体系总览

下面这张图,是我自己画的一个流程框架。你看一眼,就能明白这三个步骤是怎么串起来的。

波动率曲面形态识别流程 原始曲面数据 步骤1:曲率检测 二次拟合 → 微笑/皱眉 步骤2:斜率检测 线性拟合 → 正/负偏斜 步骤3:阈值分类 曲率+斜率 → 五类形态 输出:形态标签 + 交易信号 曲率决定「形状」,斜率决定「方向」,阈值决定「类别」 曲率 斜率 分类

你看,整个流程其实就三步。但每一步都有细节,细节决定成败。曲率检测时要注意数据质量,斜率检测时要注意阈值动态调整,分类时要注意不要过度细分。

嗯,这套方法我用了三年,实盘效果稳定。但我也得说一句:形态识别只是工具,不是圣杯。它告诉你市场现在是什么状态,但不告诉你未来一定会怎样。交易决策还得结合其他因素,比如持仓量、期限结构、宏观事件等等。

最后一个小建议: 刚开始做形态识别时,别急着上实盘。先用历史数据回测三个月,看看你的分类结果跟后续行情走势有没有相关性。我当初就是这么干的,发现「纯负偏斜」出现后,未来5个交易日市场下跌的概率是68%。这个统计结果,比任何理论都管用。

专注资料整理