σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academyロードマップ
Ctrl K
AO
+1.2k 人の学習者
ログイン参加する ↗
ロードマップ
AO
+1.2k 人の学習者
ログイン
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python ロードマップ›モジュール 7 · アルファ研究とリスク›トピック 7.1·~55 分上級

CAPMとベータ

ロードマップ上の位置モジュール 7/11 · トピック 1/9
7.1 CAPMとベータ
—ラボスコア— / 100合計XP—連続日数—

市場リスクを表す1つの数

ほとんどの株は市場が上がれば上がり、下がれば下がります。資産のベータはその度合いを測る数で、ベータ1.5なら市場が1%動くと平均して資産が1.5%動きます。資産のリターンを市場のリターンに対してプロットしたときの傾き、covariance(asset, market) / variance(market) です。ベータは分散では消せないリスクの部分です。市場のどの資産もそれを抱えているからです。

import numpy as np

market = np.array([0.01, -0.02, 0.015, 0.005, -0.01, 0.02])
asset = 1.5 * market + np.array([0.002, -0.001, 0.003, 0.0, -0.002, 0.001])      # moves 1.5x the market, plus noise

market_dev = market - market.mean()
covariance = np.sum((asset - asset.mean()) * market_dev) / (len(market) - 1)
variance = np.sum(market_dev ** 2) / (len(market) - 1)
print(round(float(covariance / variance), 4))                 # 1.5972: about 1.5, the noise moves it a little
print(round(float(np.polyfit(market, asset, 1)[0]), 4))       # the regression slope gives the same number
# Beta does not care about a constant, and scales with the asset
import numpy as np

def beta(asset, market):
    market_dev = market - market.mean()
    return float(np.sum((asset - asset.mean()) * market_dev) / np.sum(market_dev ** 2))

rng = np.random.default_rng(4)
market = rng.normal(0, 0.01, size=100)
print(round(beta(2.5 * market, market), 4))               # 2.5   an asset that moves 2.5x the market
print(round(beta(market + 0.01, market), 4))              # 1.0   adding a constant changes nothing
print(round(beta(-market, market), 4))                    # -1.0  a perfect hedge

資本資産価格モデル

CAPMはこれをリスクの価格に変えます。投資家は市場リスクを負うことに対してだけ報われるので、資産の期待リターンは無リスク金利にベータ×市場リスクプレミアム(市場リターンから無リスク金利を引いたもの)を足したもの、E[R] = rf + beta * (E[R_m] - rf) です。ベータ0なら無リスク金利、ベータ1なら市場リターン、ベータ2なら無リスク金利にプレミアムの2倍を足したものを稼ぎます。

def capm_expected_return(rf, beta_value, market_return):
    return rf + beta_value * (market_return - rf)

rf, market_return = 0.01, 0.06
for b in (0.0, 0.5, 1.0, 1.5, 2.0):
    print(b, round(capm_expected_return(rf, b, market_return), 4))     # 0.01, 0.035, 0.06, 0.085, 0.11

アルファ:残るもの

CAPMが正しければ、資産はベータが正当化するリターンをちょうど稼ぎます。実際の稼ぎとCAPMの予想との差がジェンセンのアルファで、mean(asset) - (rf + beta * (mean(market) - rf)) です。アルファが正なら市場リスクで説明できる以上の成績を出したことになり、アクティブ運用者が売るのはこれで、最も見つけにくいものです。市場で説明できない値動きの部分は残差リスクで、回帰残差の標準偏差で測り、分散して消すことができます。

# Alpha and residual risk of an asset with a little skill in it
import numpy as np

rng = np.random.default_rng(2)
market = rng.normal(0.0004, 0.01, size=500)
asset = 0.0003 + 1.2 * market + rng.normal(0, 0.005, size=500)       # true alpha 3 bps a day, beta 1.2, residual 0.5%
rf = 0.0001

market_dev = market - market.mean()
b = np.sum((asset - asset.mean()) * market_dev) / np.sum(market_dev ** 2)
alpha = asset.mean() - (rf + b * (market.mean() - rf))
a = asset.mean() - b * market.mean()
residual = asset - (a + b * market)
print(round(float(b), 3), round(float(alpha), 5), round(float(np.sqrt(np.sum(residual ** 2) / (len(asset) - 2))), 4))
ベータは定数ではなく統計量60日で推定したベータは誤差の幅が大きく、市場の局面や指数の選び方で変わります。日次と月次のリターンでは数も違います。CAPM自体も単純化で、のちの研究でリターンを説明する別の要因が見つかりました。それが次のトピックです。ベータは、測定された不確かな入力として扱いましょう。
  • ベータ=covariance(asset, market) / variance(market)、市場に対する傾き。分散できないリスクの部分
  • CAPM:rf + beta * (market - rf)。ジェンセンのアルファは平均リターンからそれを引いたもの、市場リスクを超える腕(または運)
  • 残差リスクは asset - (a + b * market) の標準偏差(n - 2 で割る)。分散できる。ベータ自体もノイズが大きい

次はマルチファクターモデル(ファーマ=フレンチ)です。市場以外の要因でもリターンを説明します。

ラボ:採点される内容

  • beta で市場への感応度を測る25点
  • capm_expected_return でリスクを値付けする25点
  • jensen_alpha で、あれば運用の腕を見つける25点
  • residual_vol で残りのリスクを測る25点
エクスプローラー · lab-93-1
▾ lab-93-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-93-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

このトピックをリセットしますか?

lab-93-1 の内容はすべてスターターファイルに戻り、ターミナルも消去されます。現在の解答は失われ、元に戻せません。

リセットされるもの
  • main.py → スターターコード
  • ターミナル履歴とテスト出力
  • 未提出の変更
保持されるもの
  • ラボの最高スコア
  • XPと連続日数
  • 講義の進捗とメモ

コードを実行するにはログインしてください。

レクチャーはすべて無料で読めます。コードの実行、テスト、ラボの提出にはアカウントの作成かログインが必要です。

  • ブラウザ内IDEとbashターミナル。インストール不要
  • 即時採点、XP、ロードマップでの現在地
アカウントを作成ログイン
または
GitHubで続ける