波动率管理:历史波动率计算、波动率锥、基于波动率的仓位调整
波动率这东西,说白了就是市场的「脾气」。
我做了这么多年量化,最深的体会就是:你永远无法预测市场往哪走,但你可以衡量它走得有多「颠」。轮动策略里,波动率管理不是锦上添花,而是保命符。今天我们就来聊聊,怎么用波动率这把尺子,量出仓位该下多重。
一、历史波动率计算:别被「历史」两个字骗了
历史波动率,听起来像是翻旧账。其实它是在回答一个问题:过去N天,这个资产每天上蹿下跳的幅度有多大?
我习惯用对数收益率来计算。为什么不用简单收益率?因为对数收益率在时间序列上可加,统计性质更好。你想想看,连续复利的概念,天然适合做波动率建模。
公式其实很简单:
σ = std(ln(P_t / P_{t-1})) * √252
这里有个坑,我曾经踩过——年化因子用252还是365? 股票市场用252个交易日,加密货币用365。别搞混了,否则波动率直接差20%。
来看一段我常用的计算代码:
import numpy as np
import pandas as pd
def calc_historical_volatility(price_series, window=20, annual_factor=252):
"""
计算历史波动率
:param price_series: 价格序列(pandas Series)
:param window: 滚动窗口天数
:param annual_factor: 年化因子
:return: 年化波动率序列
"""
log_returns = np.log(price_series / price_series.shift(1))
rolling_std = log_returns.rolling(window=window).std()
annualized_vol = rolling_std * np.sqrt(annual_factor)
return annualized_vol
# 使用示例
prices = pd.Series([100, 102, 101, 105, 103, 107, 106])
vol = calc_historical_volatility(prices, window=5)
print(vol)
二、波动率锥:一眼看穿波动率的「季节」
光算一个历史波动率,其实不够。为什么?因为不同时间尺度下,波动率的表现完全不一样。
举个例子:某只股票过去5天的波动率是30%,但过去60天的波动率只有20%。这说明什么?短期波动在放大,长期趋势还没变。 波动率锥就是用来可视化这种「期限结构」的。
波动率锥的构建方法:
- 取不同窗口长度(5天、10天、20天、60天、120天)
- 对每个窗口,计算滚动历史波动率
- 统计每个窗口的分位数(25%、50%、75%、最大值、最小值)
- 把这些分位数连成线,就得到一个「锥形」
我画个图帮你理解:
看到这个锥形了吗?短期波动率的范围比长期宽得多。5天窗口的波动率可以从5%到35%,而120天窗口基本稳定在15%-25%之间。这就是波动率回归的特性。
三、基于波动率的仓位调整:让仓位跟着「路况」走
好了,现在我们知道怎么算波动率,也知道了当前波动率在历史中的位置。下一步就是——怎么用它来调仓位?
我常用的方法叫「目标波动率仓位调整」。核心思想很简单:让每笔交易承担的风险(波动率)保持恒定。
公式:
目标仓位 = 基准仓位 × (目标波动率 / 当前波动率)
举个例子:
- 你设定的目标波动率是20%(年化)
- 当前资产的历史波动率是40%
- 那么仓位应该降到基准仓位的50%
反过来,如果当前波动率只有10%,仓位可以翻倍。
来看完整实现:
def position_sizing_by_volatility(current_vol, target_vol=0.20, base_position=1.0,
min_position=0.1, max_position=2.0):
"""
基于波动率的仓位调整
:param current_vol: 当前年化波动率
:param target_vol: 目标年化波动率(默认20%)
:param base_position: 基准仓位(默认1.0表示全仓)
:param min_position: 最小仓位限制
:param max_position: 最大仓位限制
:return: 调整后的仓位比例
"""
if current_vol <= 0:
return base_position
# 核心公式
raw_position = base_position * (target_vol / current_vol)
# 仓位限幅
adjusted_position = np.clip(raw_position, min_position, max_position)
return adjusted_position
# 实战场景
vol_scenarios = [0.10, 0.20, 0.30, 0.40, 0.50]
for vol in vol_scenarios:
pos = position_sizing_by_volatility(vol)
print(f"当前波动率: {vol:.0%} → 建议仓位: {pos:.0%}")
四、完整的波动率管理流程
把上面三块串起来,就是一个完整的闭环:
- 计算历史波动率:用20天滚动窗口,年化到252天
- 构建波动率锥:对比当前波动率在历史分位中的位置
- 判断市场状态:波动率处于锥体上沿 → 高风险;下沿 → 低风险
- 调整仓位:高风险减仓,低风险加仓
- 定期再平衡:每周或每两周检查一次
我自己的经验是,这套流程在震荡市中特别有效。趋势行情里反而容易踏空——因为波动率放大时你减仓了,结果行情继续猛涨。所以我会加一个条件:如果趋势指标(比如均线)显示强势,波动率仓位调整的权重降低一半。
五、写在最后
波动率管理不是万能药,但它能让你在市场发疯的时候保持清醒。记住一句话:波动率是市场的体温计,不是天气预报。它告诉你现在有多热,但没法告诉你明天会不会降温。
用好波动率锥和仓位调整公式,你的轮动策略至少能活过大多数熊市。剩下的,就看你对市场的理解了。
公众号:蓝海资料掘金营,微信deep3321