σμ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.2·~1 時間上級

マルチファクターモデル:ファーマ・フレンチ

ロードマップ上の位置モジュール 7/11 · トピック 2/9
7.2 マルチファクターモデル:ファーマ・フレンチ
—ラボスコア— / 100合計XP—連続日数—

動く理由は1つではない

CAPMの要因は市場の1つだけです。1992年にファーマとフレンチは、株式リターンの差の多くを、さらに2つの要因が説明することを示しました。規模(小さな企業は大きな企業より高いリターン、SMB=small minus big)とバリュー(簿価時価比で割安な株は割高な株より高いリターン、HML=high minus low)です。のちのモデルはモメンタム、収益性、投資を加えました。各ファクターはそれ自体がリターン系列で、資産のその系列への感応度(ローディング)は、どれだけ連動するかを表します。

import numpy as np

rng = np.random.default_rng(1)
n = 250
market = rng.normal(0.0004, 0.010, size=n)               # excess returns of three factors
smb = rng.normal(0.0001, 0.005, size=n)
hml = rng.normal(0.0001, 0.005, size=n)
factors = np.column_stack([market, smb, hml])             # shape (n, k) = (250, 3)

asset = 0.0002 + factors @ np.array([1.1, 0.5, -0.3]) + rng.normal(0, 0.004, size=n)
X = np.column_stack([np.ones(n), factors])                # design matrix: a column of ones for alpha
print(X.shape)                                            # (250, 4)
# The design matrix of three days and two factors
import numpy as np

factors = np.array([[0.010, -0.002], [-0.004, 0.001], [0.006, 0.003]])
X = np.column_stack([np.ones(len(factors)), factors])
print(X)                                           # a column of ones, then market and SMB

行列で書く最小二乗法

ファクターが複数あると、回帰は asset = alpha + b1 * f1 + ... + bk * fk + 誤差 です。ファクターを1の列と並べて行列 X にすると、最小二乗の係数は正規方程式 (X'X) c = X'y を解いて得られます。NumPy では np.linalg.solve(X.T @ X, X.T @ y) です。以前の単一資産の回帰と同じ仕組みで、未知数が k + 1 個になっただけです。最初の係数がアルファ、残りがローディングです。

import numpy as np

rng = np.random.default_rng(1)
n = 250
factors = np.column_stack([rng.normal(0.0004, 0.010, size=n), rng.normal(0.0001, 0.005, size=n), rng.normal(0.0001, 0.005, size=n)])
asset = 0.0002 + factors @ np.array([1.1, 0.5, -0.3]) + rng.normal(0, 0.004, size=n)

X = np.column_stack([np.ones(n), factors])
coef = np.linalg.solve(X.T @ X, X.T @ asset)
print(np.round(coef, 4))                                   # [alpha, market, SMB, HML]: the loadings come out near [1.1, 0.5, -0.3]

residual = asset - X @ coef
r2 = 1 - np.sum(residual ** 2) / np.sum((asset - asset.mean()) ** 2)
print(round(float(r2), 4))

ファクターはどれだけ説明するか

それに答えるのが決定係数 R²で、ファクターが説明する資産の変動の割合 1 - SSres / SStot です。0(何も説明しない)から1(すべて説明)の値を取ります。分散した株式ポートフォリオは、ファーマ=フレンチのファクターでR²が0.9を超えることが多く、リスクのほぼすべてがファクターリスクです。個別株はそれより低く、残りの残差の変動は企業固有です。ファクターを足すと標本内のR²は決して下がらないので、数が大きいだけではそのファクターが重要だとは言えません。

# What the model implies: the expected return from the loadings and the factor premia
import numpy as np

betas = np.array([1.1, 0.5, -0.3])             # market, SMB, HML loadings
premia = np.array([0.0006, 0.0002, 0.0002])    # expected daily factor returns
rf = 0.0001

expected = rf + np.sum(betas * premia)
print(round(float(expected), 6))               # 0.0008 per day, about 20% a year on 250 days
ファクターは賭けであり、ただ飯ではないファクタープレミアムは、悪い時期に痛みを伴うリスクへの報酬で、何年も消えたり逆転したりします。短い標本で推定したローディングはノイズが大きく、ファクター同士の相関が高いと、当てはまりが良くても個々の係数は不安定になりえます。ファクターモデルの主な用途は、リスクと成績の分解です。市場・規模・バリューに由来する分と、残るアルファがどれだけかを示します。
  • ファクターモデルは超過リターンを複数のファクターに回帰する:X = [1の列 | ファクター]、係数は [alpha, beta_1..beta_k]
  • 正規方程式 np.linalg.solve(X.T @ X, X.T @ y) を解く。R²は 1 - SSres / SStot で、ファクターを足しても下がらない
  • モデルは rf + sum(betas * premia) を意味する。ローディングもプレミアムも推定値で、ファクタープレミアムは消えうる

次は情報係数です。シグナルがそもそもリターンを予測しているかを測ります。

ラボ:採点される内容

  • design_matrix で回帰の準備をする25点
  • fit_factor_model でファクター感応度を推定する25点
  • r_squared で当てはまりを評価する25点
  • factor_expected_return で感応度に値を付ける25点
エクスプローラー · lab-94-1
▾ lab-94-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-94-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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