σμ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.3·~45 分中級

最終利回り

ロードマップ上の位置モジュール 4/11 · トピック 3/16
4.3 最終利回り
—ラボスコア— / 100合計XP—連続日数—

価格から利回りへ戻る

市場では債券は価格で提示されますが、投資家は利回りで債券を比べます。最終利回り(YTM)は、債券のすべてのキャッシュフローの現在価値が価格に等しくなる唯一の割引率で、今買って満期まで持ち、すべての支払いが行われた場合に得られる年率リターンです。クーポン5%、価格925.61の10年債では6%になります。価格と違って、未知数が高次の多項式の中にあるため、YTMには閉じた式がありません。

import numpy as np

def bond_price(face, coupon_rate, ytm, years, freq=2):
    n = int(round(years * freq))
    times = np.arange(1, n + 1) / freq
    flows = np.full(n, face * coupon_rate / freq)
    flows[-1] += face
    return (flows / (1 + ytm / freq) ** (freq * times)).sum()

price = bond_price(1000, 0.05, 0.06, 10)
print(round(price, 4))                                       # 925.6126   the market price we pretend to observe

# A back-of-the-envelope yield: annual coupon plus the yearly share of the discount, over the average of price and par
coupon = 1000 * 0.05
print(round((coupon + (1000 - price) / 10) / ((1000 + price) / 2), 5))     # 0.05966   close to 6%, but not exact

探索:二分法

利回りが上がると価格は着実に下がるので、探索できます。答えを確実に含む区間 [low, high](0%〜100%)を取り、中点で債券を評価します。価格が目標より高ければ利回りはもっと高いはずなので low を中点に上げ、そうでなければ high を下げます。1回ごとに区間は半分になり、40回で1兆分の1に縮みます。二分法は他の方法より遅いものの、答えが区間内にある限り失敗しないため、安全な切り札になります。

low, high = 0.0, 1.0
for step in range(6):
    mid = (low + high) / 2
    price_mid = bond_price(1000, 0.05, mid, 10)
    print(step, round(mid, 5), round(price_mid, 2))
    if price_mid > price:      # priced too high: the yield must be higher
        low = mid
    else:
        high = mid
# 0 0.5 110.38
# 1 0.25 275.86
# 2 0.125 578.47
# 3 0.0625 908.08
# 4 0.03125 1159.97
# 5 0.04688 1024.72      the interval keeps shrinking around 6% (the target price is 925.61)

より速い探索:ニュートン法

ニュートン法は傾きを使います。f(y) = bond_price(y) - 目標 とおき、f(y) = 0 を解きます。現在の推定値で接線をたどってゼロに下ろします:y_new = y - f(y) / f'(y)。傾きは微小な刻み h による数値微分 (f(y + h) - f(y - h)) / (2h) で推定できます。答えの近くでは正しい桁数が1回ごとにほぼ倍増するため、二分法で40回かかるところが4〜5回で済みます。出発点が悪い、傾きが平ら、といった場合は失敗しうるので、回数の上限を設け、収束しなければ二分法に戻りましょう。

y, h = 0.05, 1e-6                            # start at the coupon rate
for step in range(5):
    f = bond_price(1000, 0.05, y) - price
    slope = (bond_price(1000, 0.05, y + h) - bond_price(1000, 0.05, y - h)) / (2 * h)
    print(step, round(y, 8), round(f, 6))
    y = y - f / slope
# 0 0.05 74.387374
# 1 0.05954347 3.245932
# 2 0.05999903 0.006916
# 3 0.06 0.0
# 4 0.06 0.0        converged to 6% after 3 steps
# Check the answer by pricing the bond at the yield we found
print(round(bond_price(1000, 0.05, y, 10), 4), round(price, 4))      # 925.6126 925.6126   the same price: the yield is right
利回りは比較でき、価格は比較できない最終利回りは、各クーポンを同じ利回りで再投資でき、発行体が全額を支払うことを前提にしており、予測ではなく約束です。非常に高い利回りで取引されている債券は、たいてい市場が返済を疑っているものです。利回りの比較は、リスクと満期が似た債券どうしに限りましょう。
  • YTMは債券の現在価値を価格に一致させる割引率。閉じた式がないので探索して求める
  • 二分法:[low, high] を半分にし続ける(価格が目標より高ければ low を上げる)。遅いが安全
  • ニュートン法:数値微分の傾きで y = y - f / slope。数回で収束するが、回数上限と良い出発点が必要

次はデュレーションとコンベクシティです。債券価格が利回りにどれだけ敏感かを測ります。

ラボ:採点される内容

  • approx_ytm で利回りを概算する25点
  • bisect_yield で区間を半分にして利回りを求める25点
  • newton_yield でより速く利回りを求める25点
  • classify_price で債券の状態を分類する25点
エクスプローラー · lab-68-1
▾ lab-68-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-68-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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