σμ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 AcademySkills
Ctrl K
AO
+1,2 Tsd. Lernende
AnmeldenBeitreten ↗
Skills
AO
+1,2 Tsd. Lernende
Anmelden
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python-Skill›Modul 4 · Bewertung von Anleihen und Optionen›Thema 4.2·~45 Min.Mittelstufe

Anleihepreise

Position in der SkillModul 4 von 11 · Thema 2 von 16
4.2 Anleihepreise
—Lab-Punkte— / 100XP gesamt—Serie—

Eine Anleihe ist ein Strom von Versprechen

Eine Anleihe ist ein in handelbare Stücke zerlegter Kredit. Der Emittent verspricht in jeder Periode einen festen Kupon und bei Fälligkeit den Nennwert. Eine 10-jährige Anleihe mit Nennwert 1000 und 5 % Kupon, zweimal jährlich gezahlt, verspricht alle sechs Monate 25 und mit der letzten Zahlung zusätzlich 1000. Ihr Preis ist der heutige Wert dieser Versprechen: der Barwert der Zahlungen, abgezinst mit der Rendite, die der Markt derzeit für dieses Risiko und diese Laufzeit verlangt.

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]

Preis und Rendite bewegen sich gegenläufig

Zinsen Sie jede Zahlung mit (1 + ytm / freq) ** (freq * time) ab und addieren Sie. Entspricht die Rendite dem Kuponsatz, ist die Anleihe genau ihren Nennwert wert (sie notiert zu pari). Steigen die Marktrenditen über den Kupon, zahlen neue Anleihen mehr als diese, ihr Preis fällt also unter pari (ein Disagio); sinken sie, notiert sie mit Aufschlag. Es ist derselbe Mechanismus wie im vorigen Thema, nun mit echten Zahlungsterminen. Die laufende Rendite, Jahreskupon durch Preis, ist ein schnelles, aber unvollständiges Maß, weil sie Gewinn oder Verlust bei Fälligkeit ignoriert.

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

Längere Anleihen reagieren stärker

Die relative Preisänderung bei einer gegebenen Renditebewegung hängt von der Laufzeit ab. Ferne Zahlungen werden mit einer hohen Potenz abgezinst und reagieren daher stark auf den Zins. Eine 1-jährige Anleihe verliert etwa 1 %, wenn die Renditen um einen Punkt steigen, eine 10-jährige etwa 7 %, eine 30-jährige fast 14 %. Deshalb sprechen Anleiheanleger vom Zinsänderungsrisiko, und deshalb entwickeln die nächsten Themen Maße (Rendite bis Fälligkeit, Duration), um es zu quantifizieren.

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
Quotierte Renditen folgen einer KonventionEine Rendite von 6 % mit halbjährlichen Kupons ist kein effektiver Jahreszins von 6 %: Sie wird zweimal im Jahr aufgezinst, ihr effektiver Satz beträgt 6,09 %. Nennen Sie neben einer Rendite immer die Verzinsung (freq). Echte Anleihen haben zudem Stückzinsen zwischen den Kupon-Terminen und Tageszählkonventionen, die dieses Lab ignoriert, indem es an Kuponterminen bewertet.
  • Preis = Summe aus Zahlung / (1 + ytm / freq) ** (freq * Zeit); Kupons in jeder Periode, der Nennwert mit der letzten.
  • Rendite = Kuponsatz: Preis = pari; Rendite über dem Kupon: Disagio; darunter: Aufschlag. Preis und Rendite bewegen sich gegenläufig.
  • Je länger die Laufzeit, desto größer die Preisänderung bei gleicher Renditebewegung: Dieses Zinsrisiko misst als Nächstes die Duration.

Als Nächstes: die Rendite bis Fälligkeit, in die andere Richtung: vom Marktpreis zurück zur Rendite.

Lab: Was bewertet wird

  • Mit bond_cashflows die Zahlungen einer Anleihe auflisten25 Pkt.
  • Mit bond_price die Zahlungen zu einem Preis abzinsen25 Pkt.
  • Mit current_yield den Kupon mit dem Preis vergleichen25 Pkt.
  • Mit price_change die Wirkung einer Renditebewegung sehen25 Pkt.
Explorer · lab-67-1
▾ lab-67-1
…
bash · im Browser
learner@quantcraft:~/lab-67-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-67-1 wird auf die Startdateien zurückgesetzt und das Terminal geleert. Ihre aktuelle Lösung geht verloren – das lässt sich nicht rückgängig machen.

Wird zurückgesetzt
  • main.py → Startcode
  • Terminal-Verlauf und Testausgabe
  • Nicht eingereichte Änderungen
Bleibt erhalten
  • Beste Lab-Punktzahl
  • Ihre XP und Ihre Serie
  • Vorlesungsfortschritt und Notizen

Melde dich an, um deinen Code auszuführen.

Alle Lektionen kannst du kostenlos lesen. Erstelle ein Konto oder melde dich an, um Code auszuführen, Tests zu starten und dieses Lab abzugeben.

  • IDE im Browser mit Bash-Terminal — nichts zu installieren
  • Sofortige Bewertung, XP und dein Platz auf der Skill
Konto erstellenAnmelden
ODER
Weiter mit GitHub