第二十五章:策略风险管理:风险指标、VaR与CVaR、压力测试、回撤控制、止损策略

做量化交易这么多年,我见过太多人只盯着收益率看。说实话,这是新手最容易犯的错。你策略赚了50%,但回撤40%,这有什么意义?我有个朋友,2015年股灾前策略年化80%,结果一周亏光所有利润。嗯,从那以后,风险管理就成了我所有策略的第一道防线。

今天这一章,咱们就把风险管理的几个核心模块拆开揉碎。你想想看,一个成熟的交易系统,风险控制至少占一半的权重。说白了,活得久比赚得快重要得多。

25.1 核心风险指标:你该盯哪些数字?

我个人习惯,每天开盘前先扫一眼这几个指标。它们就像汽车的仪表盘,告诉你发动机有没有过热。

指标 含义 我的经验阈值
最大回撤 (Max Drawdown) 从峰值到谷底的最大跌幅 超过20%就要停手检查
夏普比率 (Sharpe Ratio) 每单位风险获得的超额收益 低于1.0的策略我不上实盘
卡玛比率 (Calmar Ratio) 年化收益 / 最大回撤 大于3才算合格
胜率 (Win Rate) 盈利交易占比 别迷信高胜率,盈亏比更重要
盈亏比 (Profit/Loss Ratio) 平均盈利 / 平均亏损 至少2:1,我偏好3:1以上
我的小技巧: 别只看整体回撤。我习惯把回撤按时间切片——日内回撤、周回撤、月回撤。有一次我发现策略日回撤很小,但周回撤很大,查了半天才发现是隔夜跳空造成的。这个细节,很多人会忽略。

25.2 VaR与CVaR:你的钱到底有多危险?

VaR(Value at Risk)这个词,听起来高大上,其实说白了就是:在95%或99%的置信水平下,你最多会亏多少钱。举个例子,日VaR(95%) = 10万,意思是有95%的把握,明天亏损不超过10万。

但这里有个坑。我曾经吃过这个亏——VaR只告诉你「最多亏多少」,但它不告诉你「如果真的亏了,平均亏多少」。这就是CVaR(Conditional VaR)要解决的问题。CVaR计算的是「最坏那5%情况下的平均亏损」。我建议你两个指标一起看。

import numpy as np
import pandas as pd

def calculate_var_cvar(returns, confidence=0.95):
    """
    计算VaR和CVaR
    returns: 收益率序列
    confidence: 置信水平,默认95%
    """
    # 排序收益率
    sorted_returns = np.sort(returns)
    
    # VaR:第(1-confidence)分位数
    var_index = int(len(sorted_returns) * (1 - confidence))
    var = -sorted_returns[var_index]
    
    # CVaR:尾部损失的均值
    tail_losses = sorted_returns[:var_index]
    cvar = -np.mean(tail_losses)
    
    return var, cvar

# 模拟使用
np.random.seed(42)
daily_returns = np.random.normal(0.001, 0.02, 1000)  # 模拟日收益率
var_95, cvar_95 = calculate_var_cvar(daily_returns, 0.95)
print(f"95% VaR: {var_95:.4f}")
print(f"95% CVaR: {cvar_95:.4f}")
避坑指南: 我曾经用历史模拟法算VaR,结果忽略了极端行情。2015年股灾期间,VaR显示最大亏损5%,但实际一天亏了12%。为什么?因为历史数据里没有包含这种极端情况。后来我改用蒙特卡洛模拟,加入肥尾分布,才更贴近真实。

25.3 压力测试:把策略扔进「地狱模式」

压力测试,说白了就是模拟极端行情。我习惯做三件事:

  1. 历史重现:把2008年金融危机、2020年新冠熔断的数据喂给策略,看它怎么死。
  2. 假设情景:比如「明天大盘跌10%」、「流动性枯竭」、「波动率飙升3倍」。
  3. 参数扰动:把策略参数随机打乱,看鲁棒性。

我记得有一次,一个看起来完美的套利策略,在压力测试下暴露了致命缺陷——当市场波动率突然上升时,滑点成本直接吃掉所有利润。嗯,还好没上实盘。

def stress_test(strategy_returns, scenarios):
    """
    压力测试框架
    scenarios: 字典,包含不同情景下的收益率调整
    """
    results = {}
    for scenario_name, shock in scenarios.items():
        # 对原始收益率施加冲击
        stressed_returns = strategy_returns * (1 + shock)
        
        # 计算关键指标
        sharpe = np.mean(stressed_returns) / np.std(stressed_returns) * np.sqrt(252)
        max_dd = (stressed_returns.cumsum().cummax() - stressed_returns.cumsum()).max()
        
        results[scenario_name] = {
            'sharpe': sharpe,
            'max_drawdown': max_dd
        }
    return results

# 定义压力情景
scenarios = {
    '正常市场': 0.0,
    '小幅下跌': -0.2,
    '大幅下跌': -0.5,
    '流动性危机': -0.8
}

# 假设策略日收益率
np.random.seed(42)
returns = pd.Series(np.random.normal(0.001, 0.02, 252))
stress_results = stress_test(returns, scenarios)
print(stress_results)

25.4 回撤控制:别让利润坐过山车

回撤控制,我把它分成三个层级:

  • 硬止损:总资金回撤达到15%,强制清仓。这个没得商量。
  • 软止损:回撤达到8%,减半仓位,进入观察模式。
  • 动态调整:根据波动率自动调整仓位。波动率越高,仓位越低。

你想想看,为什么很多人赚了钱又吐回去?就是因为没有回撤控制。我见过最惨的一个案例,账户从100万做到300万,然后一个月跌回80万。为什么?因为他觉得「回撤是暂时的,会涨回来的」。结果呢?市场教他做人。

核心原则: 回撤控制不是限制你赚钱,而是保护你活下去。我宁愿少赚20%,也不愿意承受一次50%的回撤。

25.5 止损策略:该割肉时就割肉

止损,是量化交易里最反人性的操作。我刚开始做的时候,也经常「再等等看」。结果呢?小亏变大亏。后来我总结了几种止损方式:

止损类型 触发条件 适用场景
固定比例止损 亏损达到2% 趋势跟踪策略
移动止损 从最高点回落5% 趋势跟踪策略
时间止损 持仓超过5天不盈利 均值回归策略
波动率止损 亏损超过2倍ATR 所有策略通用
def trailing_stop(current_price, highest_price, trail_percent=0.05):
    """
    移动止损逻辑
    """
    drawdown = (highest_price - current_price) / highest_price
    if drawdown >= trail_percent:
        return True  # 触发止损
    return False

def volatility_stop(current_price, entry_price, atr, multiplier=2):
    """
    波动率止损
    """
    loss_pct = (entry_price - current_price) / entry_price
    if loss_pct > multiplier * atr / entry_price:
        return True
    return False
我的经验: 止损不是越紧越好。太紧的止损,比如0.5%,很容易被市场噪音扫出去。我一般用ATR(平均真实波幅)来动态设定止损宽度。波动大的时候放宽,波动小的时候收紧。这样既不会频繁止损,也不会让亏损失控。

25.6 知识体系总览

下面这张图,是我做风险管理时的完整框架。你可以把它当成一个检查清单,每次上线新策略前,逐项过一遍。

策略风险管理 核心风险指标 VaR与CVaR 压力测试 回撤控制 最大回撤 夏普比率 卡玛比率 历史模拟法 蒙特卡洛模拟 参数法 历史情景重现 假设情景分析 参数扰动测试 硬止损 软止损 动态调整 核心目标:在控制风险的前提下,最大化收益 活得久 → 赚得多 → 复利效应

嗯,这一章的内容就到这里。风险管理不是束缚,而是你策略的「安全带」。系好它,你才能在市场的惊涛骇浪里,稳稳地走下去。

无相订单流研究社 微信Lucian808555