投資戦略のパフォーマンスを評価する際、「リターンが高い」だけでは不十分です。リスクに対してどれだけのリターンが得られているかを示す指標が重要です。この記事ではシャープレシオ・ソルティノレシオ・カルマー比率の違いと計算方法を解説します。
なぜリスク調整後リターンが重要か
年率30%のリターンでも、毎月±50%の激しい値動きをする戦略と、安定的に上昇する戦略では、投資家にとっての価値が全く異なります。リスク調整後リターンはこの「安定性」を考慮した指標です。
シャープレシオ(Sharpe Ratio)
概要
1966年にウィリアム・シャープが考案した最も有名なリスク調整後リターン指標です。
シャープレシオ = (ポートフォリオリターン – 無リスク金利) / 標準偏差
- 1.0以上:良好
- 2.0以上:非常に良好
- 3.0以上:優秀
Pythonでの計算
import yfinance as yf
import pandas as pd
import numpy as np
def sharpe_ratio(returns, risk_free_rate=0.001, periods=252):
"""
シャープレシオを計算する
Args:
returns: 日次リターンのSeries
risk_free_rate: 年率無リスク金利(デフォルト0.1%)
periods: 年換算日数(株式=252, FX=252)
Returns:
float: シャープレシオ
"""
excess_returns = returns - risk_free_rate / periods
return np.sqrt(periods) * excess_returns.mean() / excess_returns.std()
# トヨタ自動車で計算
df = yf.download("7203.T", period="3y", progress=False)
daily_returns = df['Close'].pct_change().dropna()
sr = sharpe_ratio(daily_returns)
print(f"シャープレシオ: {sr:.2f}")
シャープレシオの限界
標準偏差はプラスの変動もマイナスの変動も同等に「リスク」として扱います。しかし投資家にとって上昇はリスクではありません。この問題を解決したのがソルティノレシオです。
ソルティノレシオ(Sortino Ratio)
概要
下方リスク(損失方向の変動)のみをリスクとして計算するため、シャープレシオより実態に近いリスク評価ができます。
ソルティノレシオ = (ポートフォリオリターン – 無リスク金利) / 下方標準偏差
Pythonでの計算
def sortino_ratio(returns, risk_free_rate=0.001, periods=252):
"""
ソルティノレシオを計算する
下方リスク(マイナスリターン)のみをリスクとして扱う
"""
excess_returns = returns - risk_free_rate / periods
# 下方リターンのみ抽出
downside_returns = excess_returns[excess_returns < 0]
# 下方標準偏差(年率換算)
downside_std = np.sqrt(periods) * downside_returns.std()
# 年率リターン
annual_return = excess_returns.mean() * periods
return annual_return / downside_std if downside_std != 0 else np.nan
sr_sortino = sortino_ratio(daily_returns)
print(f"ソルティノレシオ: {sr_sortino:.2f}")
print(f"シャープレシオ: {sharpe_ratio(daily_returns):.2f}")
print(f"差分(正 = 上昇が多い): {sr_sortino - sharpe_ratio(daily_returns):.2f}")
カルマー比率(Calmar Ratio)
概要
年率リターンを最大ドローダウン(高値から安値への最大下落率)で割った指標です。「どれだけ大きな損失を被る可能性があるか」に対する収益性を測ります。
カルマー比率 = 年率リターン / |最大ドローダウン|
Pythonでの計算
def max_drawdown(returns):
"""最大ドローダウンを計算する"""
cumulative = (1 + returns).cumprod()
rolling_max = cumulative.cummax()
drawdown = (cumulative - rolling_max) / rolling_max
return drawdown.min()
def calmar_ratio(returns, periods=252):
"""カルマー比率を計算する"""
annual_return = returns.mean() * periods
mdd = max_drawdown(returns)
return annual_return / abs(mdd) if mdd != 0 else np.nan
calmar = calmar_ratio(daily_returns)
mdd = max_drawdown(daily_returns)
print(f"カルマー比率: {calmar:.2f}")
print(f"最大ドローダウン: {mdd:.1%}")
3指標の比較まとめ
| 指標 | リスクの定義 | 特徴 | 適した用途 |
|---|---|---|---|
| シャープレシオ | 全変動の標準偏差 | 最も普及している | 一般的な評価 |
| ソルティノレシオ | 下方変動のみの標準偏差 | 損失リスクを重視 | 損失回避型戦略 |
| カルマー比率 | 最大ドローダウン | 最悪ケースを重視 | 長期保有・引退資金 |
総合評価関数
def comprehensive_evaluation(returns, benchmark_returns=None, periods=252):
"""
戦略の総合パフォーマンス評価
"""
# 基本指標
total_return = (1 + returns).prod() - 1
annual_return = returns.mean() * periods
volatility = returns.std() * np.sqrt(periods)
# リスク調整後リターン
sr = sharpe_ratio(returns)
st = sortino_ratio(returns)
cr = calmar_ratio(returns)
mdd = max_drawdown(returns)
win_rate = (returns > 0).mean()
results = {
"総リターン": f"{total_return:.1%}",
"年率リターン": f"{annual_return:.1%}",
"年率ボラティリティ": f"{volatility:.1%}",
"シャープレシオ": f"{sr:.2f}",
"ソルティノレシオ": f"{st:.2f}",
"カルマー比率": f"{cr:.2f}",
"最大ドローダウン": f"{mdd:.1%}",
"勝率": f"{win_rate:.1%}",
}
for key, val in results.items():
print(f"{key}: {val}")
return results
# 使用例
print("=== トヨタ自動車 買い持ち戦略 ===")
comprehensive_evaluation(daily_returns)
まとめ
3つの指標はそれぞれリスクの定義が異なります。シャープレシオは汎用的、ソルティノレシオは損失リスクを重視、カルマー比率は最悪ケースの損失を重視します。戦略評価では複数の指標を組み合わせて判断しましょう。

