特征工程:从原始数据到预测信号

做隐含波动率预测,说白了就是跟一堆乱七八糟的数据打交道。我刚开始做这个项目时,以为直接把历史波动率扔进模型就完事了。结果呢?模型跑出来跟随机猜差不多。后来我才明白——特征工程才是预测模型的灵魂

今天咱们就聊聊,怎么从四个维度把原始数据变成真正有用的特征。嗯,这四个维度分别是:时间序列特征、技术指标特征、市场微观结构特征、波动率曲面特征。

隐含波动率预测 · 特征工程四维体系 IV预测 特征工程 时间序列特征 滞后项 · 差分 滚动统计 · 季节性 技术指标特征 RSI · MACD · BOLL ATR · 成交量 微观结构特征 买卖价差 · 深度 订单流 · 成交率 曲面特征 偏斜 · 期限结构 曲率 · 微笑 四大特征维度共同构建预测模型的输入信号

一、时间序列特征:让历史说话

时间序列特征是最基础的一层。我个人习惯把这类特征分成三块:滞后特征、滚动统计特征、差分特征

1.1 滞后特征(Lag Features)

说白了,就是用过去的数据预测未来。比如用前一天的IV预测今天的IV。但这里有个坑——滞后阶数怎么选?

我在项目中遇到过这样的情况:把滞后阶数设到30天,结果模型过拟合得一塌糊涂。后来我总结了一个经验:先用PACF(偏自相关函数)看一眼,看看哪些滞后项显著相关。

核心经验:对于日频IV数据,滞后1、2、5、10、20天通常就够了。别贪多。
# 生成滞后特征的代码示例
import pandas as pd

def create_lag_features(df, col='implied_vol', lags=[1,2,5,10,20]):
    for lag in lags:
        df[f'{col}_lag_{lag}'] = df[col].shift(lag)
    return df

1.2 滚动统计特征

滚动均值、滚动标准差、滚动偏度……这些特征能捕捉IV的局部趋势和波动性。嗯,这里要注意:窗口大小的选择直接影响特征质量

我记得有一次做回测,用了5天滚动均值效果很好,但换成20天就差了很多。为什么?因为IV的均值回归速度很快,长窗口反而把信号给平滑掉了。

我的建议:滚动窗口选5-10天比较稳妥。对于波动率这类高频均值回归的变量,窗口太大反而丢失信息。

1.3 差分与季节性

差分特征能帮我们捕捉IV的变化速度。比如一阶差分就是IV的日变化量,二阶差分就是变化量的变化量。你想想看,如果IV突然跳升,一阶差分肯定能捕捉到。

季节性特征呢?我一般会加入星期几的哑变量。为什么?因为周五的IV和周一的表现往往不一样——周末效应嘛。

二、技术指标特征:借力传统分析

技术指标不是股票分析师的专利。我个人习惯把几个经典指标改造一下,用到IV预测上。

2.1 RSI(相对强弱指标)

RSI能告诉我们IV是否处于超买或超卖状态。当RSI > 70时,IV可能偏高,有回落风险;RSI < 30时,IV可能偏低,有反弹可能。

但注意:RSI的参数别用默认的14。IV的波动节奏比股价快,我一般用7或10。

2.2 MACD与布林带

MACD的交叉信号在IV预测中也有用。当MACD快线上穿慢线时,IV可能进入上升趋势。布林带呢?我主要用它来识别IV的极端位置——当IV突破上轨时,往往意味着市场恐慌情绪达到顶峰。

避坑指南:我曾经把布林带参数设成2倍标准差,结果发现IV突破上轨的频率太高了。后来改成2.5倍标准差,效果才稳定下来。不同标的的IV分布不一样,参数要调。

2.3 ATR与成交量

ATR(平均真实波幅)能反映标的资产的波动程度。IV和ATR之间往往存在正相关——标的波动大,期权自然贵。成交量特征呢?我一般用成交量变化率,而不是绝对成交量。

# 技术指标特征生成示例
def add_technical_features(df, price_col='close'):
    # RSI
    delta = df[price_col].diff()
    gain = delta.where(delta > 0, 0).rolling(7).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(7).mean()
    rs = gain / loss
    df['rsi_7'] = 100 - (100 / (1 + rs))
    
    # 布林带
    df['bb_mid'] = df[price_col].rolling(20).mean()
    df['bb_std'] = df[price_col].rolling(20).std()
    df['bb_upper'] = df['bb_mid'] + 2.5 * df['bb_std']
    df['bb_lower'] = df['bb_mid'] - 2.5 * df['bb_std']
    
    return df

三、市场微观结构特征:从订单流中挖信号

这部分特征,说白了就是看市场里的人在干什么。我刚开始做的时候觉得这玩意儿太复杂,后来发现——微观结构特征往往是最强的预测因子

3.1 买卖价差

买卖价差反映了市场流动性。价差扩大,说明做市商在避险,IV往往要涨。价差缩小,说明市场情绪稳定,IV可能回落。

我记得有一次,某只股票的IV突然飙升,但价差却没怎么变。我当时就觉得不对劲——后来发现是数据出错了。所以我现在做特征工程时,一定会把价差和IV放在一起看,互相验证。

3.2 订单流不平衡

订单流不平衡 = (买方成交量 - 卖方成交量) / 总成交量。这个指标能反映市场的买卖压力。当买方压力大时,IV往往上升——因为大家都在买期权对冲。

3.3 成交率与深度

成交率(成交笔数/订单笔数)能反映市场的交易活跃度。深度呢?我一般用最优买卖价位的挂单量之和。深度越浅,市场越脆弱,IV越容易大幅波动。

核心经验:微观结构特征最好用5分钟或15分钟的高频数据来算,然后聚合到日频。直接用日频数据算出来的微观结构特征,信息损失太大了。

四、波动率曲面特征:三维视角看IV

这是最核心的部分。IV不是孤立的——不同行权价、不同到期日的IV之间存在着内在联系。把这些关系提炼成特征,能大幅提升预测效果。

4.1 偏斜(Skew)

偏斜 = 虚值看跌期权IV - 虚值看涨期权IV。偏斜越大,说明市场越恐慌。我一般用25-delta的偏斜,因为25-delta的期权流动性最好,数据最可靠。

4.2 期限结构

期限结构 = 短期IV - 长期IV。当短期IV高于长期IV时,说明市场近期有风险事件。当期限结构倒挂时,往往预示着市场即将出现剧烈波动。

4.3 曲率与微笑

曲率衡量的是IV微笑的弯曲程度。曲率越大,说明市场对极端行情的定价越高。我一般用10-delta和90-delta的IV差值来近似曲率。

# 曲面特征提取示例
def extract_surface_features(surface_df):
    features = {}
    # 25-delta偏斜
    features['skew_25'] = surface_df.loc['put_25d', 'iv'] - surface_df.loc['call_25d', 'iv']
    # 期限结构(30天 vs 90天)
    features['term_structure'] = surface_df.loc['atm', '30d'] - surface_df.loc['atm', '90d']
    # 曲率近似
    features['curvature'] = surface_df.loc['put_10d', 'iv'] - surface_df.loc['call_10d', 'iv']
    return features

特征工程的核心原则

做了这么多项目,我总结出三条原则:

  1. 少即是多:别一股脑把所有特征都扔进去。我见过有人搞了200多个特征,结果模型跑都跑不动。选20-30个高质量特征就够了。
  2. 特征要可解释:如果你自己都说不清这个特征为什么有用,那模型大概率也不靠谱。
  3. 注意特征的时间对齐:所有特征必须用T-1时刻的数据来预测T时刻的IV。千万别用未来数据——我见过有人犯这个错,回测结果漂亮得离谱,实盘直接崩了。
最后说一句:特征工程没有标准答案。同样的特征,在不同标的、不同市场环境下表现可能天差地别。多试、多调、多验证——这才是做特征工程的正确姿势。

公众号:蓝海数据掘金营,微信deep3321