第19章:基差回归中的风险管理:VaR计算、压力测试、止损策略设计

做基差交易,说白了就是吃价差回归的饭。但饭里有没有沙子?有。而且不少。

我见过太多人,模型跑得漂亮,回测曲线跟教科书一样完美。结果一上实盘,三天就被市场教育了。为什么?因为只盯着收益,忘了风险才是亲爹。

这一章,咱们就聊聊基差回归里的风险管理三板斧:VaR计算、压力测试、止损策略设计。这三样东西,缺一个,你的交易系统就是瘸腿的。

19.1 基差回归中的VaR计算

VaR,Value at Risk,风险价值。说白了就是:在给定的置信水平下,未来一段时间内,你的头寸最多可能亏多少钱

举个例子:95%置信水平下,日VaR是10万。意思是,100天里,有95天亏损不会超过10万。剩下5天?嗯,那5天才是真正要命的。

19.1.1 参数法(方差-协方差法)

这个方法假设基差收益率服从正态分布。计算很简单:

VaR = Z_α × σ × √T × 头寸规模

其中:

  • Z_α:置信水平对应的分位数(95%对应1.645,99%对应2.326)
  • σ:基差收益率的标准差
  • T:持有期天数

我在项目中遇到过一个问题:基差数据经常有尖峰厚尾特征。用正态分布去拟合,VaR会被严重低估。说白了,尾部风险比你想象的大得多。

⚠️ 注意:参数法只适用于基差波动相对稳定的品种。像股指期货这种流动性好的品种还行。但像某些商品期货,基差波动剧烈,参数法基本就是自欺欺人。

19.1.2 历史模拟法

这个方法我比较喜欢。它不假设任何分布,直接用历史数据来算。

步骤很简单:

  1. 取过去N天的基差收益率数据(我一般用500天以上)
  2. 按收益率从小到大排序
  3. 取第5%分位数(95%置信水平)或第1%分位数(99%置信水平)
import numpy as np

def historical_var(basis_returns, confidence=0.95):
    sorted_returns = np.sort(basis_returns)
    index = int((1 - confidence) * len(sorted_returns))
    return sorted_returns[index]

# 示例:过去500天的基差收益率
basis_returns = np.random.normal(0, 0.02, 500)  # 模拟数据
var_95 = historical_var(basis_returns, 0.95)
print(f"95% VaR: {var_95:.4f}")
💡 我的习惯:历史模拟法虽然简单,但有个坑——历史会重演,但不会简单重复。我一般会结合最近3个月的数据加权,给近期数据更高权重。

19.1.3 蒙特卡洛模拟法

这个方法最灵活,但计算量也最大。适合做复杂策略的VaR计算。

基本思路:

  1. 估计基差收益率的分布参数(均值、方差、偏度、峰度)
  2. 生成大量随机路径(我一般跑10000次以上)
  3. 统计每条路径的最终损益,取分位数
import numpy as np

def monte_carlo_var(mu, sigma, days=1, n_sim=10000, confidence=0.95):
    # 模拟基差路径
    returns = np.random.normal(mu, sigma, (n_sim, days))
    # 计算累积收益
    cum_returns = np.sum(returns, axis=1)
    # 取分位数
    var = np.percentile(cum_returns, (1 - confidence) * 100)
    return var

# 示例
mu, sigma = 0.001, 0.03  # 日收益率均值和标准差
var_mc = monte_carlo_var(mu, sigma, days=5, n_sim=10000)
print(f"5天95% VaR (蒙特卡洛): {var_mc:.4f}")

19.2 压力测试:极端情况下的生存能力

VaR告诉你的是「正常情况」下的风险。但真正让你爆仓的,从来不是正常情况。

压力测试,就是模拟极端市场环境。比如:

  • 2020年3月原油暴跌
  • 2008年金融危机
  • 2015年A股股灾
  • 某个品种的逼仓行情

19.2.1 历史情景模拟

直接拿历史上最极端的基差波动来测试你的策略。

我曾经做过一个测试:把2015年股灾期间股指期货的基差数据,喂给一个看似完美的回归策略。结果呢?最大回撤直接翻了三倍。嗯,从那以后,我再也不信「历史回测完美」这种鬼话了。

def stress_test(strategy, historical_stress_data):
    """
    压力测试函数
    :param strategy: 策略函数
    :param historical_stress_data: 历史极端行情数据
    """
    pnl = []
    for data_point in historical_stress_data:
        # 模拟策略在极端行情下的表现
        result = strategy(data_point)
        pnl.append(result)
    
    max_drawdown = np.min(pnl) - np.max(np.maximum.accumulate(pnl))
    return {
        'total_pnl': np.sum(pnl),
        'max_drawdown': max_drawdown,
        'sharpe_ratio': np.mean(pnl) / np.std(pnl) if np.std(pnl) > 0 else 0
    }

19.2.2 假设情景模拟

历史不会完全重复。所以还需要自己构造极端情景:

  • 基差瞬间扩大3倍标准差
  • 流动性枯竭(滑点放大10倍)
  • 多品种同时出现极端基差
🔑 关键原则:压力测试不是为了证明策略有多强,而是为了找到策略的「死亡边界」。知道什么情况下会死,才能提前做好防护。

19.3 止损策略设计

VaR和压力测试是「诊断」,止损是「治疗」。没有止损的交易,就像没有安全带的赛车。

19.3.1 基于基差绝对水平的止损

最简单粗暴的方法:设定一个基差阈值,到了就砍。

def absolute_basis_stop(current_basis, entry_basis, threshold=0.05):
    """
    基于基差绝对水平的止损
    :param current_basis: 当前基差
    :param entry_basis: 开仓基差
    :param threshold: 止损阈值(基差点数)
    """
    deviation = abs(current_basis - entry_basis)
    if deviation > threshold:
        return True  # 触发止损
    return False

这个方法有个问题:不同品种的基差波动范围不一样。螺纹钢的基差可能就几十点,而铁矿石可能几百点。统一阈值不现实。

19.3.2 基于统计分布的止损

我比较推荐这个方法。用基差的历史分布来设定止损线。

比如:

  • 以开仓时的基差为均值
  • 用历史波动率计算标准差
  • 设定止损在均值±3倍标准差的位置
def statistical_stop(current_basis, entry_basis, basis_std, z_score=3):
    """
    基于统计分布的止损
    :param current_basis: 当前基差
    :param entry_basis: 开仓基差
    :param basis_std: 基差历史标准差
    :param z_score: 止损的Z值
    """
    upper_bound = entry_basis + z_score * basis_std
    lower_bound = entry_basis - z_score * basis_std
    
    if current_basis > upper_bound or current_basis < lower_bound:
        return True
    return False
💡 实战经验:我习惯用滚动窗口计算标准差,比如过去60个交易日。这样能自适应市场波动率的变化。市场波动大的时候,止损线自动放宽;波动小的时候,止损线收紧。

19.3.3 基于时间衰减的止损

基差回归是有时间成本的。如果持仓时间过长,基差还没回归,说明你的判断可能错了。

我常用的做法:

  • 设定最大持仓天数(比如20个交易日)
  • 每天检查基差是否向预期方向移动
  • 如果超过最大天数还没回归,强制平仓
def time_decay_stop(holding_days, max_days=20, basis_progress=0):
    """
    基于时间衰减的止损
    :param holding_days: 已持仓天数
    :param max_days: 最大持仓天数
    :param basis_progress: 基差回归进度(0-1)
    """
    if holding_days >= max_days:
        return True  # 超时止损
    
    # 如果持仓时间过半,但回归进度不到30%,也考虑止损
    if holding_days > max_days * 0.5 and basis_progress < 0.3:
        return True
    
    return False

19.4 综合风险管理框架

把上面三样东西整合起来,形成一个完整的风险管理流程:

基差回归风险管理框架 基差数据输入 VaR计算 参数法/历史模拟/蒙特卡洛 压力测试 历史情景/假设情景 止损策略 绝对水平/统计/时间衰减 风险限额 压力阈值 止损线 综合风险决策 继续持有 / 减仓 / 平仓

19.5 实战中的几个坑

最后,分享几个我踩过的坑:

  • 别把VaR当圣杯:VaR只是工具,不是真理。它假设市场是连续的、可预测的。但现实是,市场经常出现跳空。
  • 压力测试要定期更新:市场结构在变,去年的极端行情,今年可能只是常态。我每季度会重新审视压力测试情景。
  • 止损不是越紧越好:止损太紧,频繁被扫;止损太松,亏损太大。找到那个平衡点,需要不断回测和调整。
  • 别忘了流动性风险:基差交易通常涉及两个品种。如果其中一个品种流动性枯竭,你的止损可能根本执行不了。
📌 一句话总结:风险管理不是限制你赚钱,而是确保你能活到赚钱的那一天。VaR告诉你风险有多大,压力测试告诉你最坏情况有多坏,止损策略则是在最坏情况发生时,你还能活着出来。

嗯,这一章的内容就到这里。记住,在基差交易这个行当里,活得久比赚得快更重要。


公众号:蓝海资料掘金营,微信deep3321