Als leitender Finanztechnologie-Ingenieur mit über acht Jahren Erfahrung in der Derivatepreisbewertung habe ich zahlreiche Volatilitätsmodelle für Kryptowährungsoptionen implementiert und evaluiert. In diesem deep-dive Artikel vergleiche ich zwei der leistungsfähigsten Ansätze — das lokale Volatilitätsmodell (Local Volatility, LV) und das SABR-Modell — hinsichtlich ihrer mathematischen Grundlagen, Implementierungseffizienz und praktischen Anwendbarkeit im Produktionsumfeld.
1. Theoretischer Hintergrund und mathematische Grundlagen
Die Preisgestaltung von Kryptowährungsoptionen stellt uns vor einzigartige Herausforderungen: extreme Volatilität, Fat-Tailed-Verteilungen, Regime-Shifts und die berüchtigte Volatility-Smile-Sruktur, die bei Bitcoin- und Ethereum-Optionen besonders ausgeprägt ist.
1.1 Lokales Volatilitätsmodell (Dupire-Framework)
Das lokale Volatilitätsmodell, formalisiert durch den Dupire-Gleichung, leitet die即时波动率Oberfläche direkt aus den beobachtbaren Marktpreisen ab:
"""
Lokales Volatilitätsmodell nach Dupire
Implementierung für Kryptowährungsoptionen
"""
import numpy as np
from scipy.interpolate import CubicSpline
from scipy.optimize import brentq
class LocalVolatilityModel:
def __init__(self, spot: float, rate: float, dividend: float = 0.0):
self.S = spot # Spot-Preis (z.B. BTC/USD)
self.r = rate # Risikofreier Zinssatz
self.q = dividend # Dividenden-/Staking-Yield für Krypto
def dupire_local_vol(self, strikes: np.ndarray, maturities: np.ndarray,
call_prices: np.ndarray) -> np.ndarray:
"""
Berechnet die lokale Volatilitätsfläche mittels Dupire-Gleichung
σ²(K,T) = [∂C/∂T + (r-q)K·∂C/∂K + qC] / [½K²·∂²C/∂K²]
Args:
strikes: Ausübungspreise (Array)
maturities: Laufzeiten (Array)
call_prices: Marktpreise der Calls (Matrix: rows=strikes, cols=maturities)
"""
n_strikes = len(strikes)
n_mats = len(maturities)
local_vol = np.zeros((n_strikes, n_mats))
# Analytische Gradienten via finite differences
dK = np.gradient(strikes)
dT = np.gradient(maturities)
for i, T in enumerate(maturities):
for j, K in enumerate(strikes):
if j == 0 or j == n_strikes - 1 or i == 0:
local_vol[j, i] = np.nan
continue
# Partielle Ableitungen zweiter Ordnung
d2C_dK2 = (call_prices[j+1, i] - 2*call_prices[j, i] +
call_prices[j-1, i]) / (dK[j]**2)
# Partielle Ableitung erster Ordnung
dC_dK = (call_prices[j+1, i] - call_prices[j-1, i]) / (2*dK[j])
# Zeitliche Ableitung
if i > 0:
dC_dT = (call_prices[j, i] - call_prices[j, i-1]) / dT[i]
else:
dC_dT = 0.0
# Vermeidung Division durch Null
if abs(d2C_dK2) < 1e-10:
local_vol[j, i] = local_vol[j-1, i] if j > 0 else 0.5
continue
# Dupire-Formel
numerator = dC_dT + (self.r - self.q) * K * dC_dK + self.q * call_prices[j, i]
denominator = 0.5 * (K ** 2) * d2C_dK2
if denominator > 0:
local_vol[j, i] = np.sqrt(numerator / denominator)
else:
local_vol[j, i] = np.nan
return local_vol
def price_european_pde(self, K: float, T: float, is_call: bool = True,
n_space: int = 500, n_time: int = 200) -> float:
"""
Finite-Difference PDE-Löser für europäische Optionen unter lokaler Volatilität
Crank-Nicolson Schema mit Richardson-Extrapolation
Returns: Optionspreis
"""
S_max = 3 * K
dS = S_max / n_space
dt = T / n_time
# Volatilitäts-Gitter (vereinfacht: konstante lokale Vol)
sigma = self._get_local_vol_at_maturity(T)
# Preisgitter initialisieren
V = np.zeros((n_space + 1, n_time + 1))
# Randbedingungen
if is_call:
V[:, -1] = np.maximum(np.linspace(0, S_max, n_space + 1) - K, 0)
else:
V[:, -1] = np.maximum(K - np.linspace(0, S_max, n_space + 1), 0)
# Crank-Nicolson Iteration
for n in range(n_time - 1, -1, -1):
for i in range(1, n_space):
S = i * dS
# Koeffizienten
a = 0.25 * dt * (sigma**2 * S**2 / dS**2 -
(self.r - self.q) * S / dS)
b = -0.5 * dt * (sigma**2 * S**2 / dS**2 + self.r)
c = 0.25 * dt * (sigma**2 * S**2 / dS**2 +
(self.r - self.q) * S / dS)
V[i, n] = a * V[i-1, n+1] + (1 + b) * V[i, n+1] + c * V[i+1, n+1]
# Lineare Interpolation für finalen Preis
idx = int(self.S / dS)
return np.interp(self.S, np.linspace(0, S_max, n_space + 1), V[:, 0])
1.2 SABR-Modell (Stochastic Alpha Beta Rho)
Das SABR-Modell parametert die Volatilitätsdynamik direkt im risikoneutralen Maß und modelliert vier stochastische Prozesse simultan:
"""
SABR-Modell Implementierung für Krypto-Optionen
Stochastic Alpha, Beta, Rho, Sigma
"""
from dataclasses import dataclass
from typing import Tuple, Optional
import numpy as np
from scipy.stats import norm
from scipy.optimize import minimize, differential_evolution
@dataclass
class SAB