σμ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 ロードマップ›モジュール 4 · 債券とオプションの価格計算›トピック 4.5·~50 分中級

イールドカーブと補間

ロードマップ上の位置モジュール 4/11 · トピック 5/16
4.5 イールドカーブと補間
—ラボスコア— / 100合計XP—連続日数—

満期ごとに1つの金利

ここまでは1つの利回りで債券のすべての支払いを割り引いていました。実際には、6か月、2年、10年貸したお金は異なる金利を稼ぎ、満期ごとのパターンがイールドカーブです。ゼロレートは、途中のクーポンのない、ある日付の1回の支払いに対する年率です。通常、カーブは満期とともに上がります(長く待つ分、多くを求めるため)が、フラットになったり、短期金利が長期金利を上回る逆イールドになったりし、市場はそれを成長への警告と読みます。

import numpy as np

maturities = np.array([0.5, 1, 2, 5, 10, 30])                      # years where the market quotes a rate
rates = np.array([0.040, 0.042, 0.045, 0.048, 0.050, 0.052])       # an upward-sloping curve

# The rate at 3 years is not quoted: interpolate linearly between 2 years (4.5%) and 5 years (4.8%)
print(float(np.interp(3, maturities, rates)))                        # 0.046
print(np.interp([0.25, 7, 40], maturities, rates).tolist())          # [0.04, 0.0488, 0.052]   flat outside the quoted range

割引係数とフォワードレート

満期 t のゼロレート r から割引係数 (1 + r) ** -t(t に支払われる1単位の今日の価値)が得られます。カーブには期待も隠れています。2年間4.5%で貸すことは、1年間4.2%で貸し、さらに1年間を合意した金利 f で貸すことに等しいはずです:(1 + 4.5%)² = (1 + 4.2%)(1 + f)、したがって f = 4.80%。このフォワードレートが、今日固定される2年目の損益分岐金利です。一般には f = ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1 です。

def discount_factor(rate, t):
    return (1 + rate) ** -t

print(round(float(discount_factor(0.045, 2)), 5))                  # 0.91573   one unit paid in 2 years

r1, t1, r2, t2 = 0.042, 1, 0.045, 2
forward = ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1
print(round(forward, 5))                                            # 0.04801   the rate for year 2, implied by the curve
print(round((1 + r1) ** t1 * (1 + forward) ** (t2 - t1), 5), round((1 + r2) ** t2, 5))   # 1.09 1.09   both routes agree

カーブ全体での価格付け

単一の利回りでの価格付けは、1年後の支払いと10年後の支払いを同じに扱います。カーブを使う方法のほうが忠実です。各支払いについて、その日付のゼロレートを読み(必要なら補間)、割引係数にして フロー * 係数 を合計します。同じキャッシュフローを持つ2つの債券は、提示利回りに関係なく同じ価格でなければならず、銀行が債券を時価評価するのもこの方法です。このカーブ上の3年・5%の債券は1011.25で、フラットな4.6%なら1010.98です。カーブがなだらかなのでここでは近い値ですが、カーブがねじれると債券ごとに反応が異なります。

times = np.array([1.0, 2.0, 3.0])
flows = np.array([50.0, 50.0, 1050.0])                              # a 3-year 5% bond with annual coupons

zero = np.interp(times, maturities, rates)
print(zero.tolist())                                                 # [0.042, 0.045, 0.046]
print((discount_factor(zero, times)).round(5).tolist())              # [0.95969, 0.91573, 0.87379]
print(round(float((flows * discount_factor(zero, times)).sum()), 4))   # 1011.2462   on the curve
print(round(float((flows / 1.046 ** times).sum()), 4))               # 1010.9752   with one flat 4.6% instead
# The forward rates between the quoted maturities, in one array expression
t = np.array([1.0, 2.0, 5.0])
r = np.array([0.042, 0.045, 0.048])
forwards = ((1 + r[1:]) ** t[1:] / (1 + r[:-1]) ** t[:-1]) ** (1 / np.diff(t)) - 1
print(forwards.round(5).tolist())       # [0.04801, 0.05]   year 2 and years 3 to 5: an upward-sloping curve implies rising forwards
補間はモデリング上の選択ゼロレートの線形補間は最も単純な規則ですが唯一ではなく、実務では割引係数の対数を補間したりスプラインを使ったりし、その選択は提示点の間のフォワードレートと価格を変えます。最後の提示満期より先では np.interp は金利を一定に保ちますが、これは慣習であり事実ではありません。カーブを公表するときは、方法を必ず明記しましょう。
  • イールドカーブは満期ごとのゼロレート。ない満期は補間で読む(np.interp、範囲外は一定)
  • 割引係数 (1 + r) ** -t、フォワードレート ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1
  • 価格 = 各フローをその日付のゼロレートで割り引いた フロー * 割引係数 の合計。補間方法を明記する

次はオプションのペイオフです。コールやプットが満期に支払う額、オプション価格付けの出発点です。

ラボ:採点される内容

  • interpolate_rate で提示された満期の間の金利を読む25点
  • discount_factor で金利を割引係数にする25点
  • forward_rate でカーブに隠れた将来の金利を読む25点
  • price_on_curve でカーブ全体で支払いの流れを評価する25点
エクスプローラー · lab-70-1
▾ lab-70-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-70-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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