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

債券価格

ロードマップ上の位置モジュール 4/11 · トピック 2/16
4.2 債券価格
—ラボスコア— / 100合計XP—連続日数—

債券は約束の連なり

債券は、取引可能な小口に分けられた貸付です。発行体は各期に固定のクーポンを、満期に額面(パー)を支払うと約束します。額面1000、クーポン5%(年2回払い)の10年債は、半年ごとに25、最後の支払いに加えて1000を約束します。その価格は、これらの約束が今日いくらの価値かということで、市場がそのリスクと満期に今求める利回りで割り引いたキャッシュフローの現在価値です。

import numpy as np

def bond_cashflows(face, coupon_rate, years, freq):
    n = int(round(years * freq))                       # number of payments
    times = np.arange(1, n + 1) / freq                 # in years: 0.5, 1.0, 1.5, ...
    flows = np.full(n, face * coupon_rate / freq)      # a coupon each time
    flows[-1] += face                                  # and the face value with the last one
    return times, flows

times, flows = bond_cashflows(1000, 0.05, 2, 2)        # a 2-year bond, to keep the output short
print(times.tolist())    # [0.5, 1.0, 1.5, 2.0]
print(flows.tolist())    # [25.0, 25.0, 25.0, 1025.0]

価格と利回りは逆に動く

(1 + ytm / freq) ** (freq * time) で各フローを割り引いて合計します。利回りがクーポン率と等しいとき、債券の価値はちょうど額面です(パーで取引)。市場利回りがクーポンを上回ると、新発債のほうがこの債券より多く支払うので、価格はパーを下回ります(ディスカウント)。利回りが下がればプレミアムで取引されます。前のトピックと同じ仕組みを、実際の支払日で行うだけです。クーポンを価格で割った直接利回りは手軽ですが、満期時の損益を無視するため不完全です。

def bond_price(face, coupon_rate, ytm, years, freq=2):
    times, flows = bond_cashflows(face, coupon_rate, years, freq)
    return (flows / (1 + ytm / freq) ** (freq * times)).sum()

for ytm in (0.03, 0.05, 0.06, 0.08):
    print(ytm, round(bond_price(1000, 0.05, ytm, 10), 2))
# 0.03 1171.69   yield below the coupon: premium
# 0.05 1000.0    yield = coupon: par
# 0.06 925.61    yield above the coupon: discount
# 0.08 796.15

print(round(50 / bond_price(1000, 0.05, 0.06, 10), 5))    # 0.05402   current yield: 5.40%, not the 6% yield to maturity

長い債券ほど大きく反応する

利回りが一定幅動いたときの価格の相対変化は満期に依存します。遠い将来の支払いは大きなべき乗で割り引かれるため、金利に非常に敏感です。利回りが1ポイント上がると、1年債は約1%、10年債は約7%、30年債は14%近く下がります。だから債券投資家は金利リスクを語り、次のトピックではそれを定量化する指標(最終利回り、デュレーション)を作ります。

for years in (1, 5, 10, 30):
    change = bond_price(1000, 0.05, 0.06, years) / 1000 - 1     # the coupon is 5%, the yield rises to 6%
    print(years, round(change, 4))
# 1 -0.0096
# 5 -0.0427
# 10 -0.0744
# 30 -0.1384
# The same 6% yield with annual, semiannual and monthly coupons: the quoting convention matters a little
for freq in (1, 2, 12):
    print(freq, round(bond_price(1000, 0.05, 0.06, 10, freq), 2))
# 1 926.4
# 2 925.61
# 12 924.94
提示利回りには規約がある半年ごとのクーポンで利回り6%は、実効年率6%ではありません。年2回複利なので実効金利は6.09%です。利回りには必ず複利の頻度(freq)を添えましょう。実際の債券にはクーポン日の間の経過利息や日数計算の慣行もありますが、このラボはクーポン日での価格付けでそれらを無視しています。
  • 価格 = フロー / (1 + ytm / freq) ** (freq * 時点) の合計。各期にクーポン、最後に額面
  • 利回り=クーポン率なら価格はパー、利回りがクーポン超ならディスカウント、下回ればプレミアム。価格と利回りは逆に動く
  • 満期が長いほど、同じ利回り変動でも価格変化が大きい。この金利リスクを次にデュレーションが測る

次は最終利回りです。逆向きに、市場価格から利回りを求めます。

ラボ:採点される内容

  • bond_cashflows で債券の支払いを並べる25点
  • bond_price で支払いを割り引いて価格にする25点
  • current_yield でクーポンと価格を比べる25点
  • price_change で利回り変動の影響を見る25点
エクスプローラー · lab-67-1
▾ lab-67-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-67-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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