风险与绩效指标
夏普比率、最大回撤、年化收益、胜率、卡玛比率
回测报告里一堆指标,新手很容易只看"总收益"。但总收益高不代表策略好——可能是运气、可能波动巨大、可能回撤吓人。这一篇我们彻底搞懂常用的绩效指标。
收益类指标
1. 总收益(Total Return)
最直观的指标,简单粗暴:
pythontotal_return = (1 + returns).prod() - 1 # 或者 total_return = cum_value[-1] / cum_value[0] - 1
用途:快速看策略赚不赚钱 陷阱:不考虑时间长度和波动
2. 年化收益(Annualized Return)
把不同时间长度的收益拉到同一标准:
pythonn_years = len(returns) / 252 # 252 个交易日 = 1 年 annual_return = (1 + total_return) ** (1 / n_years) - 1
用途:跨策略、跨周期对比 注意:复利计算,不是简单平均
风险类指标
3. 年化波动率(Annualized Volatility)
衡量收益的不稳定程度:
pythonimport numpy as np annual_vol = returns.std() * np.sqrt(252)
用途:判断策略是否平稳 理解:年化波动 20% 意味着一年内收益大概率在 ±20% 之间波动
4. 最大回撤(Max Drawdown,MDD)
从历史最高点到最低点的最大跌幅,新手最该关注的指标。
pythondef max_drawdown(returns): cum = (1 + returns).cumprod() peak = cum.cummax() dd = (cum - peak) / peak return dd.min() mdd = max_drawdown(df['strategy_return']) print(f'最大回撤: {mdd:.2%}')
为什么重要:
- 一个年化 30% 但最大回撤 50% 的策略,你能拿得住吗?
- 真实交易中,回撤决定你会不会爆仓、会不会割肉
经验值:
- 优秀策略:MDD < 15%
- 可接受:15% - 25%
- 危险:> 30%
5. 回撤持续时间(Drawdown Duration)
不只是回撤多深,还要看多久才能回本:
pythondef max_drawdown_duration(returns): cum = (1 + returns).cumprod() peak = cum.cummax() in_dd = cum < peak # 连续回撤的最大长度 durations = [] cur = 0 for x in in_dd: if x: cur += 1 else: if cur > 0: durations.append(cur) cur = 0 return max(durations) if durations else 0
用途:评估策略的"忍耐成本" 经验:超过 1 年的回撤,大部分人都拿不住
风险调整收益
收益和风险都重要,单独看任一个都不够。下面是把两者结合的指标。
6. 夏普比率(Sharpe Ratio)
最经典的风险调整收益指标:
pythondef sharpe_ratio(returns, rf=0.0, periods_per_year=252): excess = returns - rf / periods_per_year return excess.mean() / excess.std() * np.sqrt(periods_per_year)
公式:(年化收益 - 无风险利率) / 年化波动率
经验值:
-
2 → 非常好
- 1 - 2 → 不错
- 0.5 - 1 → 一般
- < 0.5 → 不太行
⚠️ 夏普比率的陷阱 它把"上行波动"和"下行波动"一视同仁。一个稳定向上但偶尔大涨的策略,夏普会被"惩罚"。
7. 索提诺比率(Sortino Ratio)
夏普的改进版,只看下行波动:
pythondef sortino_ratio(returns, rf=0.0, periods_per_year=252): excess = returns - rf / periods_per_year downside = excess[excess < 0].std() * np.sqrt(periods_per_year) if downside == 0: return np.nan return (excess.mean() * periods_per_year) / downside
用途:更符合人对"风险"的直觉感知 经验:通常比夏普高,因为分母更小
8. 卡玛比率(Calmar Ratio)
收益与最大回撤的比值:
pythondef calmar_ratio(returns, periods_per_year=252): annual_return = (1 + returns).prod() ** (periods_per_year / len(returns)) - 1 mdd = abs(max_drawdown(returns)) return annual_return / mdd if mdd > 0 else np.nan
用途:直接告诉你"为了 1% 的回撤,你能赚多少" 经验:
-
3 → 极佳
- 1 - 3 → 不错
- < 1 → 一般
交易类指标
9. 胜率(Win Rate)
pythondef win_rate(returns): positive = (returns > 0).sum() nonzero = (returns != 0).sum() return positive / nonzero if nonzero > 0 else 0
陷阱:胜率高不一定赚钱。如果每次小赚(+1%)每次大亏(-10%),胜率 80% 也是亏的。
10. 盈亏比(Profit/Loss Ratio)
pythondef profit_loss_ratio(returns): wins = returns[returns > 0] losses = returns[returns < 0] if len(wins) == 0 or len(losses) == 0: return np.nan return wins.mean() / abs(losses.mean())
用途:和胜率配合看 经验:胜率 50% + 盈亏比 1.5 > 胜率 70% + 盈亏比 0.5
11. 凯利公式仓位(Kelly Criterion)
理论最优仓位比例:
pythondef kelly_fraction(win_rate, profit_loss_ratio): return win_rate - (1 - win_rate) / profit_loss_ratio
用途:参考用,实战要用半凯利或更保守
完整的指标计算函数
把上面的指标整合成一个工具:
pythonimport pandas as pd import numpy as np def calc_metrics(returns, periods_per_year=252): """ 输入:日收益率 Series 输出:所有指标 dict """ returns = returns.dropna() if len(returns) == 0: return {} # 收益 total = (1 + returns).prod() - 1 n_years = len(returns) / periods_per_year annual = (1 + total) ** (1 / n_years) - 1 if n_years > 0 else 0 # 风险 vol = returns.std() * np.sqrt(periods_per_year) cum = (1 + returns).cumprod() dd = (cum / cum.cummax() - 1) mdd = dd.min() # 风险调整收益 sharpe = (returns.mean() / returns.std() * np.sqrt(periods_per_year)) if returns.std() > 0 else 0 downside = returns[returns < 0].std() * np.sqrt(periods_per_year) if (returns < 0).any() else 0 sortino = (returns.mean() * periods_per_year / downside) if downside > 0 else np.nan calmar = (annual / abs(mdd)) if mdd != 0 else np.nan # 交易 win_rate = (returns > 0).sum() / (returns != 0).sum() if (returns != 0).sum() > 0 else 0 wins = returns[returns > 0] losses = returns[returns < 0] pl_ratio = wins.mean() / abs(losses.mean()) if len(losses) > 0 and losses.mean() != 0 else np.nan return { '总收益': f'{total:.2%}', '年化收益': f'{annual:.2%}', '年化波动': f'{vol:.2%}', '最大回撤': f'{mdd:.2%}', '夏普比率': f'{sharpe:.2f}', '索提诺比率': f'{sortino:.2f}', '卡玛比率': f'{calmar:.2f}', '日胜率': f'{win_rate:.2%}', '盈亏比': f'{pl_ratio:.2f}', }
怎么综合判断一个策略
不要看单一指标,要看组合:
| 指标 | 看什么 |
|---|---|
| 年化收益 | 是否值得做 |
| 最大回撤 | 是否拿得住 |
| 夏普比率 | 风险收益比 |
| 卡玛比率 | 回撤的代价 |
| 胜率 + 盈亏比 | 心理可承受性 |
| 回撤持续时间 | 是否会让你怀疑人生 |
好策略的特征:
- ✅ 年化 > 15%
- ✅ 最大回撤 < 20%
- ✅ 夏普 > 1
- ✅ 卡玛 > 1
- ✅ 净值曲线平滑、向右上
小结
到这里你已经会用十几个指标全方位评估一个策略。下一篇 多因子选股入门,我们从单股票策略升级到组合选股。
📌 新手常见误区
- 只看总收益 → 忽略了风险
- 追求超高夏普 → 往往是过拟合
- 看不见回撤 → 实盘必爆仓
- 用太短的回测期 → 没经历过完整牛熊
一个策略至少要经历3 年以上的回测才有参考价值。