σμ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 8 · Stochastische Modelle und Machine Learning›Thema 8.5·~1 Std.Fortgeschritten

Barriereoptionen

Position in der SkillModul 8 von 11 · Thema 5 von 10
8.5 Barriereoptionen
—Lab-Punkte— / 100XP gesamt—Serie—

Optionen mit Falltür

Eine Barrier-Option ist ein Call oder Put mit einem Schalter. Eine Knock-out-Option erlischt, wenn der Preis die Barriere berührt; eine Knock-in-Option entsteht nur dann. Die Barriere kann über dem Start (up) oder darunter (down) liegen. Da der Käufer auf einen Teil der Auszahlung verzichtet, sind Barrier-Optionen billiger als einfache, deshalb sind sie beliebt, auch in strukturierten Produkten. Wie asiatische Optionen hängen sie vom ganzen Pfad ab, das natürliche Werkzeug ist die Simulation.

import numpy as np

paths = np.array([[100.0, 105.0, 112.0, 108.0],      # stays below 115
                  [100.0,  98.0, 103.0, 110.0],      # stays below 115
                  [100.0, 120.0,  95.0,  90.0]])     # touches 115 on day 1, then falls

hit_up = paths.max(axis=1) >= 115.0                  # the maximum of each path against the barrier
print(hit_up)                                        # [False False  True]
print(paths.min(axis=1) <= 96.0)                     # a down barrier at 96: [False False  True]
# hit_barrier for both directions, with an error for anything else
import numpy as np

def hit_barrier(paths, barrier, direction):
    if direction == "up":
        return paths.max(axis=1) >= barrier
    if direction == "down":
        return paths.min(axis=1) <= barrier
    raise ValueError("direction must be 'up' or 'down'")

paths = np.array([[100.0, 110.0, 105.0], [100.0, 109.9, 105.0]])
print(hit_barrier(paths, 110.0, "up"))                  # [ True False]: touching the barrier exactly counts
try:
    hit_barrier(paths, 110.0, "sideways")
except ValueError as error:
    print("rejected:", error)

Knock-out, Knock-in und die Summe

Berechnen Sie auf jedem Pfad die Auszahlung des einfachen Calls max(S_T - K, 0) und das Barrier-Flag. Der Knock-out-Call behält die Auszahlung dort, wo die Barriere *nicht* berührt wurde; der Knock-in-Call dort, wo sie berührt wurde. Jeder Pfad ist das eine oder das andere, also *In + Out = einfacher Call*, Pfad für Pfad, eine praktische Identität: Bewerten Sie die einfachere und erhalten Sie die andere gratis, und nutzen Sie sie als Test Ihres Codes. np.where(hit, a, b) wählt elementweise zwischen Arrays.

import numpy as np

paths = np.array([[100.0, 105.0, 112.0, 108.0],
                  [100.0,  98.0, 103.0, 110.0],
                  [100.0, 120.0,  95.0, 130.0]])
strike, barrier = 100.0, 115.0

vanilla = np.maximum(paths[:, -1] - strike, 0.0)
hit = paths.max(axis=1) >= barrier
knock_out = np.where(hit, 0.0, vanilla)
knock_in = np.where(hit, vanilla, 0.0)

print(vanilla, knock_out, knock_in)                      # [ 8. 10. 30.] [ 8. 10.  0.] [ 0.  0. 30.]
print(np.allclose(knock_in + knock_out, vanilla))        # True

Bewertung und der Bias der diskreten Beobachtung

Der Preis ist die abgezinste mittlere Auszahlung wie zuvor. Doch Vorsicht bei der Barrierenprüfung: Eine Simulation betrachtet den Preis nur an ihren Gitterterminen, während eine echte kontinuierliche Barriere auch *zwischen* ihnen durchbrochen wird. Bei wenigen Schritten überqueren simulierte Pfade die Barriere oft unbemerkt, ein Knock-out-Call wird zu teuer und ein Knock-in zu billig. Mehr Schritte verringern den Bias, ebenso Korrekturen, die die Barriere um etwa 0.5826 * sigma * sqrt(dt) verschieben.

import numpy as np

def simulate_paths(s0, rate, sigma, t, steps, n_paths, rng):
    dt = t / steps
    z = rng.standard_normal((n_paths, steps))
    moves = (rate - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * z
    return s0 * np.exp(np.hstack([np.zeros((n_paths, 1)), np.cumsum(moves, axis=1)]))

def knock_out_price(paths, strike, barrier, rate, t):
    vanilla = np.maximum(paths[:, -1] - strike, 0.0)
    payoff = np.where(paths.max(axis=1) >= barrier, 0.0, vanilla)
    return float(np.exp(-rate * t) * payoff.mean())

rng = np.random.default_rng(1)
for steps in (12, 52, 252):
    paths = simulate_paths(100.0, 0.05, 0.25, 1.0, steps, 40000, rng)
    print(steps, round(knock_out_price(paths, 100.0, 130.0, 0.05, 1.0), 3))        # the price falls as monitoring gets finer
Barrierenrisiko ist Gap-RisikoNahe der Barriere springen Delta und Gamma einer Barrier-Option, und eine winzige Preisbewegung kann die gesamte Auszahlung ein- oder ausschalten. Das macht das Hedgen eines Knock-outs nahe der Barriere schwer, und die Desks verlangen dafür Geld. Achten Sie auch darauf, wer den Preis nahe der Barriere kontrolliert: Verträge legen genau fest, welche Preise zählen (ein Schlusskurs, ein Börsenkurs), denn die Versuchung, den Markt zu bewegen, ist real.
  • Eine Barriere wird berührt, wenn das Maximum (up) oder Minimum (down) des Pfads sie an irgendeinem Termin erreicht; Knock-out stirbt bei Berührung, Knock-in entsteht bei Berührung.
  • Pro Pfad gilt Knock-in + Knock-out = Auszahlung des einfachen Calls; np.where(hit, a, b) wählt aus; Barrier-Optionen sind billiger als einfache.
  • Simulation auf einem Gitter verpasst Überschreitungen zwischen den Terminen, Knock-outs wirken zu teuer: mehr Schritte nutzen oder die Barriere verschieben; Vorsicht vor Gap-Risiko nahe der Barriere.

Als Nächstes: antithetische Variablen, eine Möglichkeit, dieselbe Monte-Carlo-Genauigkeit mit weniger Simulationen zu erreichen.

Lab: Was bewertet wird

  • Mit hit_barrier die Berührung erkennen25 Pkt.
  • Mit knock_out_call_payoff die Option beenden25 Pkt.
  • Mit knock_in_call_payoff zum Leben erwecken25 Pkt.
  • Mit barrier_price Auszahlungen in einen Preis verwandeln25 Pkt.
Explorer · lab-106-1
▾ lab-106-1
…
bash · im Browser
learner@quantcraft:~/lab-106-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-106-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