シャープレシオと最大ドローダウンとは?戦略の良し悪しを測る指標【Python】


「年利30%の戦略」と聞くと魅力的に見えます。でも、その裏で一時的に資産が半分になる場面があったらどうでしょう。多くの人はそこで耐えきれず、底値で売ってしまいます。

投資戦略はリターンだけで評価してはいけません。同じくらい大事なのが「どれだけのリスクを取ってそのリターンを得たか」です。この記事では、戦略の質を測る3つの基本指標——シャープレシオ・最大ドローダウン・カルマーレシオ——をPythonコード付きで解説します。

⚠️ 本記事は教育目的の情報共有です。投資は自己責任で行ってください。

目次

  1. なぜリターンだけではダメなのか
  2. 最大ドローダウン(MDD)
  3. シャープレシオ
  4. カルマーレシオ(リターン÷最大ドローダウン)
  5. 3指標をまとめて計算する関数
  6. まとめ

1. なぜリターンだけではダメなのか

2つの戦略を比べてみます。

戦略年率リターン途中の最大下落
A+20%-15%
B+25%-55%

リターンだけ見るとBの勝ちです。しかしBは途中で資産が半分以下になる場面があります。実際にこれを経験して持ち続けられる人は多くありません。

リスクを考慮すると、現実的に運用できるのはAの方です。リターンとリスクは必ずセットで見ます。

2. 最大ドローダウン(MDD)

最大ドローダウン(Maximum Drawdown, MDD) は「資産が最高値からどれだけ下落したか、その最大値」です。

  • MDD -30% = 「100万円が70万円になる瞬間に耐える」覚悟が必要
  • 戦略の精神的な耐えやすさを表す、最も実感に近い指標
import numpy as np
import pandas as pd

def max_drawdown(cumulative: pd.Series) -> float:
    """累積リターン系列から最大ドローダウン(%)を返す"""
    peak = cumulative.cummax()          # その時点までの最高値
    drawdown = (cumulative - peak) / peak
    return drawdown.min() * 100         # 最も深い下落

# 例: 日次リターンから累積を作って計算
# cumulative = (1 + daily_returns).cumprod()
# print(f"最大ドローダウン: {max_drawdown(cumulative):.1f}%")

💡 「平均的にどうか」ではなく「最悪どこまで落ちたか」を見るのがMDDの肝です。平均は耐えられても、最悪の一瞬で退場するからです。

3. シャープレシオ

シャープレシオ は「リスク1単位あたり、どれだけリターンを得たか」を表します。リスク調整後リターンの定番指標です。

$$ \text{シャープレシオ} = \frac{\text{リターンの平均} - \text{無リスク金利}}{\text{リターンの標準偏差}} $$

  • 標準偏差(ばらつき)が大きい=値動きが荒い=リスクが高い
  • 同じリターンなら、値動きが穏やかな方がシャープレシオは高い
def sharpe_ratio(daily_returns: pd.Series, risk_free=0.0, periods=252) -> float:
    """日次リターンから年率シャープレシオを返す(periods=年間営業日)"""
    excess = daily_returns - risk_free / periods
    if excess.std() == 0:
        return 0.0
    return excess.mean() / excess.std() * np.sqrt(periods)

目安

  • 1.0以上 → 良好
  • 2.0以上 → 優秀(ただし期間が短い・過剰最適化を疑う)
  • 0.5未満 → リスクの割にリターンが見合っていない

⚠️ シャープレシオが異常に高いときは、まず過剰最適化(オーバーフィッティング)を疑ってください。過去にフィットさせすぎた戦略は、見かけのシャープが跳ね上がります。

4. カルマーレシオ(リターン÷最大ドローダウン)

カルマーレシオ は「年率リターン ÷ 最大ドローダウンの絶対値」。私が個人的に一番重視している指標です。

$$ \text{カルマーレシオ} = \frac{\text{年率リターン(CAGR)}}{|\text{最大ドローダウン}|} $$

痛み(ドローダウン)1単位あたり、どれだけ稼げるか」を直接表します。

  • CAGR +20% / MDD -40% → カルマー 0.5
  • CAGR +15% / MDD -15% → カルマー 1.0(こちらの方が”効率的”)
def calmar_ratio(cagr_pct: float, mdd_pct: float) -> float:
    """CAGR(%)と最大ドローダウン(%)からカルマーレシオを返す"""
    if mdd_pct == 0:
        return 0.0
    return cagr_pct / abs(mdd_pct)

実運用では「耐えられないドローダウンの戦略は、リターンが高くても使えない」ので、カルマーは実感に直結します。

5. 3指標をまとめて計算する関数

日次リターン系列から一括で出すユーティリティです。

def evaluate(daily_returns: pd.Series, periods=252) -> dict:
    daily_returns = daily_returns.dropna()
    cumulative = (1 + daily_returns).cumprod()

    total_return = cumulative.iloc[-1] - 1
    years = len(daily_returns) / periods
    cagr = (cumulative.iloc[-1] ** (1 / years) - 1) * 100 if years > 0 else 0

    mdd = max_drawdown(cumulative)
    sr = sharpe_ratio(daily_returns, periods=periods)
    calmar = calmar_ratio(cagr, mdd)

    return {
        "総リターン(%)": round(total_return * 100, 1),
        "CAGR(%)": round(cagr, 1),
        "最大ドローダウン(%)": round(mdd, 1),
        "シャープレシオ": round(sr, 2),
        "カルマーレシオ": round(calmar, 2),
    }

# print(evaluate(df["strategy_return"]))

この5つを並べて初めて、戦略の「本当の顔」が見えます。

6. まとめ

  • リターンだけで戦略を評価しない。リスクと必ずセットで見る
  • 最大ドローダウン:最悪どこまで落ちるか=耐えられるかの実感
  • シャープレシオ:リスク1単位あたりのリターン。1.0以上が目安
  • カルマーレシオ:痛み1単位あたりのリターン。実運用の効率を表す
  • 指標が良すぎるときは過剰最適化を疑う

これらの指標は、戦略を実運用に乗せる前の「健康診断」です。まずは自分のバックテスト結果に当てはめてみてください。

バックテストの基礎はこちら → yfinanceで株価バックテストを始める方法 指標が良すぎるときの罠はこちら → ウォークフォワード検証とは?過剰最適化を見破る方法


質問や感想は X (@QuantNobu) までどうぞ。

⚠️ 免責:本記事は教育目的の情報共有であり、投資助言ではありません。実際の投資判断はご自身の責任で行ってください。