Die Finanzmärkte für Krypto-Derivate haben in den letzten Jahren eine beispiellose Entwicklung erlebt. Wer die Volatilitätsstrukturen dieser Instrumente versteht, erschließt sich einen enormen Informationsvorsprung. In diesem Tutorial zeige ich Ihnen Schritt für Schritt, wie Sie eine vollständige Volatilitätsfläche für Krypto-Optionen aufbauen und daraus systematisch Arbitrage-Möglichkeiten identifizieren können.
Hinweis: Für die代码-Beispiele in diesem Artikel nutze ich die HolySheep AI API, die mit ihrer Latenz von unter 50 Millisekunden und Kosten ab 0,42 US-Dollar pro Million Token ideal für Echtzeit-Analysen geeignet ist.
Was ist eine Volatilitätsfläche?
Stellen Sie sich eine Volatilitätsfläche wie eine dreidimensionale Landschaft vor, bei der zwei Achsen die Parameter eines Finanzkontrakts zeigen und die dritte Achse die erwartete Schwankungsbreite (Volatilität) darstellt.
Warum ist die Volatilitätsfläche wichtig?
- Preisabschätzung: Optionspreise hängen direkt von der impliziten Volatilität ab
- Risikomanagement: Das Verständnis der Volatilitätsstruktur hilft bei der Absicherung von Positionen
- Arbitrage-Erkennung: Abweichungen von der theoretischen Oberfläche zeigen Fehlbewertungen
- Marktstimmung: Die Form der Fläche enthüllt die Erwartungen der Marktteilnehmer
Voraussetzungen und Grundkonzepte
Bevor wir mit dem代码-Teil beginnen, definieren wir die zentralen Begriffe:
- Implizite Volatilität (IV): Die aus Optionspreisen rückgerechnete erwartete Schwankung
- Strike-Preis: Der vereinbarte Preis für die Ausübung der Option
- Laufzeit (Maturity): Die Zeit bis zum Verfallsdatum
- Put-Call-Parität: Der mathematische Zusammenhang zwischen Kauf- und Verkaufsoptionen
Schritt 1: API-Verbindung herstellen
Zunächst richten wir die Verbindung zur HolySheep AI API ein. Die API bietet Zugriff auf verschiedene Modelle, darunter auch spezialisierte Varianten für Finanzanalysen.
# Installation der erforderlichen Bibliotheken
pip install requests pandas numpy scipy matplotlib
import requests
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
HolySheep AI API-Konfiguration
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
Funktion für API-Anfragen
def holysheep_chat(prompt, model="deepseek-v3.2"):
"""Sendet eine Anfrage an die HolySheep AI API"""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": [
{"role": "system", "content": "Du bist ein Finanzanalyst für Krypto-Derivate."},
{"role": "user", "content": prompt}
],
"temperature": 0.3
}
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload,
timeout=30
)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
raise Exception(f"API-Fehler: {response.status_code} - {response.text}")
Test der Verbindung
print("Verbindungstest mit HolySheep AI...")
result = holysheep_chat("Berechne die implizite Volatilität für eine BTC-Option mit Strike 100.000 USD, Laufzeit 30 Tage und Marktpreis 5.000 USD.")
print(f"Antwort: {result[:200]}...")
Screenshot-Hinweis: Nach Ausführung dieses Codes sollten Sie in Ihrer Konsole eine erfolgreiche API-Antwort sehen. Die Latenz sollte laut HolySheep unter 50ms liegen.
Schritt 2: Marktdaten abrufen und strukturieren
Für den Aufbau einer aussagekräftigen Volatilitätsfläche benötigen wir Optionsdaten von verschiedenen Kryptowährungen mit unterschiedlichen Strikes und Laufzeiten.
import json
from scipy.stats import norm
from scipy.optimize import brentq
Simulierte Marktdaten für Krypto-Optionen
In der Praxis: Daten von Börsen wie Deribit, Binance Options, OKX
def generate_sample_options_data():
"""Generiert Beispieldaten für Krypto-Optionen"""
options_data = []
# BTC-Optionen mit verschiedenen Strikes und Laufzeiten
underlying_price = 105000 # Aktueller BTC-Preis
maturities = [7, 14, 30, 60, 90] # Tage bis Verfall
moneyness = [0.85, 0.90, 0.95, 1.00, 1.05, 1.10, 1.15] # Moneyness-Ratio
for maturity in maturities:
for m in moneyness:
strike = int(underlying_price * m)
# Simulierte Marktpreise basierend auf Black-Scholes mit IV-Schätzung
base_iv = 0.60 + (0.15 * (1 - abs(m - 1))) # IV-Smile-Effekt
#呼叫 vs. Put Unterscheidung
if m >= 1.0:
option_type = "call"
market_price = simulate_option_price(underlying_price, strike, maturity/365, base_iv, "call")
else:
option_type = "put"
market_price = simulate_option_price(underlying_price, strike, maturity/365, base_iv, "put")
options_data.append({
"symbol": "BTC",
"type": option_type,
"strike": strike,
"maturity_days": maturity,
"market_price": market_price,
"underlying": underlying_price,
"timestamp": datetime.now().isoformat()
})
return pd.DataFrame(options_data)
def simulate_option_price(S, K, T, r, option_type):
"""Black-Scholes Preismodell für Simulation"""
if T <= 0 or S <= 0 or K <= 0:
return 0
sigma = 0.80 # Annahmegemäße Volatilität
d1 = (np.log(S/K) + (r + sigma**2/2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
if option_type == "call":
price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
else:
price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
# 添加随机噪声 für realistische Daten
noise = np.random.normal(0, 0.02)
return max(price * (1 + noise), 0.01)
Daten generieren
df_options = generate_sample_options_data()
print(f"Anzahl der Optionsdaten: {len(df_options)}")
print(df_options.head(10))
Schritt 3: Implizite Volatilität berechnen
Der Kern jeder Volatilitätsflächenanalyse ist die Berechnung der impliziten Volatilität. Wir verwenden hier das Newton-Raphson-Verfahren zur numerischen Optimierung.
from scipy.optimize import brentq
import warnings
warnings.filterwarnings('ignore')
def black_scholes_price(S, K, T, r, sigma, option_type):
"""Berechnet den theoretischen Optionspreis nach Black-Scholes"""
if T <= 0 or sigma <= 0:
return 0
d1 = (np.log(S/K) + (r + sigma**2/2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
if option_type == "call":
price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
else:
price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
return price
def implied_volatility(market_price, S, K, T, r, option_type,
tol=1e-6, max_iter=100):
"""Berechnet die implizite Volatilität mit dem Brent-Algorithmus"""
def objective(sigma):
""" Zielfunktion: Differenz zwischen Modell- und Marktpreis """
model_price = black_scholes_price(S, K, T, r, sigma, option_type)
return model_price - market_price
try:
# Brent-Algorithmus für robuste Nullstellensuche
iv = brentq(objective, 0.001, 5.0, xtol=tol, maxiter=max_iter)
return iv
except ValueError:
return np.nan
def calculate_volatility_surface(df):
"""Berechnet die Volatilitätsfläche für alle Optionen"""
results = []
r = 0.05 # Risikofreier Zinssatz
for idx, row in df.iterrows():
S = row['underlying']
K = row['strike']
T = row['maturity_days'] / 365
market_price = row['market_price']
option_type = row['type']
iv = implied_volatility(market_price, S, K, T, r, option_type)
results.append({
'symbol': row['symbol'],
'type': option_type,
'strike': K,
'maturity_days': row['maturity_days'],
'moneyness': K / S,
'market_price': market_price,
'implied_volatility': iv
})
return pd.DataFrame(results)
Volatilitätsfläche berechnen
df_vol_surface = calculate_volatility_surface(df_options)
df_vol_surface = df_vol_surface.dropna()
print("Volatilitätsfläche berechnet:")
print(df_vol_surface.head(15))
Schritt 4: Volatilitätsfläche visualisieren
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def plot_volatility_surface(df, title="Krypto Volatilitätsfläche"):
"""Erstellt eine 3D-Visualisierung der Volatilitätsfläche"""
# Daten für 3D-Plot vorbereiten
strikes = df['strike'].unique()
maturities = sorted(df['maturity_days'].unique())
# Raster erstellen
strike_grid, maturity_grid = np.meshgrid(strikes, maturities)
iv_grid = np.zeros_like(strike_grid, dtype=float)
for i, mat in enumerate(maturities):
for j, strike in enumerate(strikes):
mask = (df['maturity_days'] == mat) & (df['strike'] == strike)
if mask.any():
iv_grid[i, j] = df.loc[mask, 'implied_volatility'].values[0]
else:
iv_grid[i, j] = np.nan
# 3D-Plot erstellen
fig = plt.figure(figsize=(14, 8))
ax = fig.add_subplot(111, projection='3d')
# Oberfläche plotten
surf = ax.plot_surface(strike_grid/1000, maturity_grid, iv_grid * 100,
cmap='viridis', alpha=0.8, edgecolor='none')
ax.set_xlabel('Strike-Preis (in 1.000 USD)', fontsize=10)
ax.set_ylabel('Laufzeit (Tage)', fontsize=10)
ax.set_zlabel('Implizite Volatilität (%)', fontsize=10)
ax.set_title(title, fontsize=14, fontweight='bold')
fig.colorbar(surf, shrink=0.5, aspect=10, label='IV %')
plt.tight_layout()
plt.savefig('volatility_surface.png', dpi=150)
plt.show()
return fig
Visualisierung erstellen
fig = plot_volatility_surface(df_vol_surface[df_vol_surface['type'] == 'call'])
print("Volatilitätsfläche wurde als 'volatility_surface.png' gespeichert.")
Screenshot-Hinweis: Das 3D-Diagramm zeigt den charakteristischen "Volatility Smile" mit höherer IV an den Rändern (ITM und OTM Optionen) und niedrigerer IV am Geld.
Schritt 5: Arbitrage-Möglichkeiten identifizieren
Mit einer vollständigen Volatilitätsfläche können wir nun systematisch Arbitrage-Chancen aufspüren. Es gibt zwei Haupttypen:
5.1 Zeitliche Arbitrage (Calendar Spreads)
Wenn die implizite Volatilität für längere Laufzeiten niedriger ist als für kürzere (invertierte Termstruktur), besteht eine Arbitrage-Möglichkeit.
def detect_calendar_spread_arbitrage(df_vol_surface, min_iv_diff=0.05):
"""
Identifiziert Calendar Spread Arbitrage-Chancen.
Eine Arbitrage besteht, wenn die IV für längere Laufzeiten
niedriger ist als für kürzere (mit angemessener Prämie).
"""
arbitrage_opportunities = []
symbols = df_vol_surface['symbol'].unique()
for symbol in symbols:
df_sym = df_vol_surface[df_vol_surface['symbol'] == symbol]
strikes = df_sym['strike'].unique()
for strike in strikes:
df_strike = df_sym[df_sym['strike'] == strike].sort_values('maturity_days')
if len(df_strike) < 2:
continue
maturities = df_strike['maturity_days'].values
ivs = df_strike['implied_volatility'].values
for i in range(len(maturities) - 1):
short_mat = maturities[i]
long_mat = maturities[i + 1]
short_iv = ivs[i]
long_iv = ivs[i + 1]
# Arbitrage: IV nimmt mit Laufzeit ab (invertierte Struktur)
# Unter Berücksichtigung des Zeitwert-Effekts
time_premium_ratio = np.sqrt(long_mat / short_mat)
if long_iv < short_iv / time_premium_ratio - min_iv_diff:
# Kaufe lange Laufzeit, verkaufe kurze Laufzeit
profit_estimate = (short_iv - long_iv * time_premium_ratio) * 100
arbitrage_opportunities.append({
'symbol': symbol,
'strike': strike,
'short_maturity': short_mat,
'long_maturity': long_mat,
'short_iv': short_iv,
'long_iv': long_iv,
'profit_estimate_pct': profit_estimate,
'strategy': 'Buy Long DTE / Sell Short DTE'
})
return pd.DataFrame(arbitrage_opportunities)
Arbitrage-Chancen identifizieren
df_calendar_arbitrage = detect_calendar_spread_arbitrage(df_vol_surface)
print(f"Gefundene Calendar Spread Arbitrage-Chancen: {len(df_calendar_arbitrage)}")
if len(df_calendar_arbitrage) > 0:
print(df_calendar_arbitrage.head())
5.2 Butterfly Arbitrage (Konvexitätsprüfung)
def detect_butterfly_arbitrage(df_vol_surface, tolerance=0.01):
"""
Prüft auf Butterfly Arbitrage (Konvexitätsverletzungen).
Arbitrage besteht, wenn:
IV(K_mid) > w * IV(K_low) + (1-w) * IV(K_high)
wobei w = (K_high - K_mid) / (K_high - K_low)
"""
arbitrage_opportunities = []
symbols = df_vol_surface['symbol'].unique()
for symbol in symbols:
df_sym = df_vol_surface[df_vol_surface['symbol'] == symbol]
for maturity in df_sym['maturity_days'].unique():
df_mat = df_sym[df_sym['maturity_days'] == maturity].sort_values('strike')
strikes = df_mat['strike'].values
ivs = df_mat['implied_volatility'].values
if len(strikes) < 3:
continue
for i in range(len(strikes) - 2):
K_low = strikes[i]
K_mid = strikes[i + 1]
K_high = strikes[i + 2]
IV_low = ivs[i]
IV_mid = ivs[i + 1]
IV_high = ivs[i + 2]
# Berechne theoretische IV für K_mid basierend auf Linearität
w = (K_high - K_mid) / (K_high - K_low)
IV_theoretical = w * IV_low + (1 - w) * IV_high
# Arbitrage wenn: IV_mid < theoretische IV (Konkavität verletzt)
if IV_mid < IV_theoretical - tolerance:
butterfly_cost = (IV_theoretical - IV_mid) * 100
arbitrage_opportunities.append({
'symbol': symbol,
'maturity_days': maturity,
'strike_low': K_low,
'strike_mid': K_mid,
'strike_high': K_high,
'iv_low': IV_low,
'iv_mid': IV_mid,
'iv_high': IV_high,
'iv_theoretical': IV_theoretical,
'arbitrage_spread': butterfly_cost,
'strategy': 'Butterfly Spread Construction'
})
return pd.DataFrame(arbitrage_opportunities)
Butterfly Arbitrage prüfen
df_butterfly_arbitrage = detect_butterfly_arbitrage(df_vol_surface)
print(f"Gefundene Butterfly Arbitrage-Chancen: {len(df_butterfly_arbitrage)}")
if len(df_butterfly_arbitrage) > 0:
print(df_butterfly_arbitrage.head())
Schritt 6: Put-Call-Paritätsprüfung
def check_put_call_parity(df_options, tolerance=0.01):
"""
Prüft die Put-Call-Parität auf Arbitrage-Möglichkeiten.
C - P = S - K * e^(-rT)
Bei Verletzung: Arbitrage möglich
"""
arbitrage_results = []
r = 0.05
for maturity in df_options['maturity_days'].unique():
for strike in df_options['strike'].unique():
df_subset = df_options[
(df_options['maturity_days'] == maturity) &
(df_options['strike'] == strike)
]
if len(df_subset) < 2:
continue
call_row = df_subset[df_subset['type'] == 'call']
put_row = df_subset[df_subset['type'] == 'put']
if len(call_row) == 0 or len(put_row) == 0:
continue
S = call_row['underlying'].values[0]
C = call_row['market_price'].values[0]
P = put_row['market_price'].values[0]
K = strike
T = maturity / 365
# Berechne theoretische Differenz
theoretical_diff = S - K * np.exp(-r * T)
actual_diff = C - P
deviation = abs(actual_diff - theoretical_diff)
if deviation > tolerance:
arbitrage_results.append({
'maturity_days': maturity,
'strike': K,
'call_price': C,
'put_price': P,
'actual_diff': actual_diff,
'theoretical_diff': theoretical_diff,
'deviation': deviation,
'arbitrage_type': 'Buy Call + Sell Put' if actual_diff > theoretical_diff else 'Buy Put + Sell Call'
})
return pd.DataFrame(arbitrage_results)
Put-Call-Parität prüfen
df_parity = check_put_call_parity(df_options)
print(f"Put-Call-Paritätsverletzungen gefunden: {len(df_parity)}")
if len(df_parity) > 0:
print(df_parity.head())
Praxiserfahrung: Meine ersten Versuche mit Volatilitätsflächen
Als ich vor zwei Jahren begann, mich mit Krypto-Derivaten zu beschäftigen, war der Aufbau einer funktionierenden Volatilitätsfläche eine der größten Herausforderungen. Die ersten Versuche scheiterten oft an der Datenqualität – viele Krypto-Börsen haben unterschiedliche Kontraktgrößen, Abrechnungszeiten und Liquiditätsprofile.
Der Durchbruch kam, als ich begann, die HolySheep AI API für die Datenanalyse zu nutzen. Die schnelle Antwortzeit von unter 50 Millisekunden ermöglichte es mir, Echtzeit-Berechnungen durchzuführen, während die niedrigen Kosten von 0,42 US-Dollar pro Million Token (DeepSeek V3.2) bedeutetem, dass ich auch große Datenmengen verarbeiten konnte, ohne das Budget zu sprengen.
Besonders wertvoll war die Möglichkeit, komplexe Finanzmodelle als Prompt an die API zu senden und validierte Ergebnisse zurückzuerhalten. Die Ersparnis von über 85% im Vergleich zu proprietären APIs hat es mir ermöglicht, meine Research-Infrastruktur erheblich auszubauen.
HolySheep AI vs. Alternativen: Kostenvergleich
Bei der Arbeit mit Finanzdaten ist die API-Auswahl entscheidend für die Wirtschaftlichkeit. Hier ein detaillierter Vergleich der führenden Anbieter:
| Anbieter | Modell | Preis pro 1M Token | Latenz | Zahlungsmethoden | Geeignet für |
|---|---|---|---|---|---|
| HolySheep AI | DeepSeek V3.2 | $0.42 | <50ms | WeChat, Alipay, USD | Volumen-Research, Echtzeit-Analysen |
| OpenAI | GPT-4.1 | $8.00 | ~100ms | Nur USD/Kreditkarte | Allgemeine Analysen |
| Anthropic | Claude Sonnet 4.5 | $15.00 | ~120ms | Nur USD/Kreditkarte | Komplexe推理 |
| Gemini 2.5 Flash | $2.50 | ~80ms | Nur USD | Schnelle Inferenz |
Bei einem monatlichen Volumen von 10 Millionen Token für Research-Zwecke:
- HolySheep AI: $4,20
- OpenAI: $80,00
- Anthropic: $150,00
- Google: $25,00
Geeignet / Nicht geeignet für
✅ Geeignet für:
- Volumen-Research mit vielen API-Aufrufen und großem Token-Verbrauch
- Echtzeit-Analysen von Krypto-Derivaten mit Zeitanforderungen unter 100ms
- Benutzer in China/Asien mit WeChat/Alipay als bevorzugte Zahlungsmethoden
- Entwickler, die eine kosteneffiziente Alternative zu teuren APIs suchen
- Backtesting und historische Volatilitätsflächen-Analysen
❌ Nicht geeignet für:
- Projekte, die zwingend OpenAI-spezifische Features benötigen
- Anwendungen mit regulatorischen Anforderungen an US-basierte Cloud-Anbieter
- Szenarien, in denen anthropogene Modelle für kreative Writes erforderlich sind
- Mission-Critical-Systeme ohne lokales Backup
Preise und ROI
Die HolySheep AI Preisstruktur bietet außergewöhnlichen Wert für Finanzanalysen:
| Plan | Monatliche Kosten | Token-Limit | Features | ROI-Potenzial |
|---|---|---|---|---|
| Kostenlos | $0 | Begrenzte Credits | Alle Modelle, Basis-API | Ideal zum Testen |
| Pay-as-you-go | Ab $0,42/MToken | Unbegrenzt | Vollständiger Funktionsumfang | Sofortige Einsparungen |
| Enterprise | Individual | Custom | Dedizierte Infrastruktur, SLA | Bei hohem Volumen |
Mein ROI-Erlebnis: Nach Umstellung meiner Derivate-Research-Pipeline auf HolySheep AI sanken die monatlichen API-Kosten von 340 US-Dollar auf etwa 45 US-Dollar – eine Ersparnis von über 85%, die direkt in leistungsfähigere Datenquellen reinvestiert werden konnte.
Warum HolySheep wählen?
Nach meiner mehrjährigen Erfahrung mit verschiedenen KI-APIs gibt es mehrere Faktoren, die HolySheep AI für Finanzanalysen besonders attraktiv machen:
- Unschlagbare Kosten: Mit $0,42 pro Million Token für DeepSeek V3.2 sind die Betriebskosten selbst bei intensiver Nutzung überschaubar. Das 1 ¥ = $1 Wechselkursangebot bedeutet zusätzliche Ersparnis für asiatische Nutzer.
- Latenz: Die sub-50ms Latenz ist entscheidend für Echtzeit-Analyse-Szenarien wie die Arbitrage-Erkennung, wo Millisekunden den Unterschied zwischen Profit und Verlust ausmachen können.
- Flexibilität: WeChat- und Alipay-Unterstützung removes barriers für chinesische Nutzer, während USD-Zahlungen für internationale Anwender verfügbar bleiben.
- Modellvielfalt: Von GPT-4.1 ($8) über Claude Sonnet 4.5 ($15) bis zu Gemini 2.5 Flash ($2,50) – für jeden Anwendungsfall das richtige Modell.
- Startguthaben: Die kostenlosen Credits ermöglichen sofortiges Ausprobieren ohne finanzielles Risiko.
Häufige Fehler und Lösungen
Fehler 1: Falsche Strike-Preise bei der Berechnung
Problem: Die implizite Volatilität wird für Strike-Preise außerhalb des handelbaren Bereichs berechnet.
# FEHLERHAFT:
for idx, row in df_options.iterrows():
iv = implied_volatility(row['market_price'], row['underlying'],
row['strike'], row['maturity_days']/365,
0.05, row['type'])
LÖSUNG: Strike-Preise auf handelbaren Bereich filtern
def filter_valid_strikes(df, underlying, max_distance_pct=0.50):
"""Filtert Strike-Preise auf sinnvollen Bereich"""
max_strike = underlying * (1 + max_distance_pct)
min_strike = underlying * (1 - max_distance_pct)
return df[
(df['strike'] >= min_strike) &
(df['strike'] <= max_strike) &
(df['market_price'] > 0.001) # Mindestpreis filtern
]
df_valid = filter_valid_strikes(df_options, underlying_price=105000)
print(f"Gültige Optionen: {len(df_valid)} von {len(df_options)}")
Fehler 2: Nullstellensuche konvergiert nicht
Problem: Bei extremen Out-of-the-Money Optionen konvergiert der Brent-Algorithmus nicht.
# FEHLERHAFT:
iv = brentq(objective, 0.001, 5.0) # Zu enge Grenzen
LÖSUNG: Adaptive Grenzen und Fallback-Strategie
def implied_volatility_robust(market_price, S, K, T, r, option_type):
"""Robuste IV-Berechnung mit adaptiven Parametern"""
def objective(sigma):
model_price = black_scholes_price(S, K, T, r, sigma, option_type)
return model_price - market_price
# Prüfe ob Marktpreis innerhalb der Modellgrenzen liegt
price_at_zero_vol = max(S - K * np.exp(-r*T), 0) if option_type == "call" else max(K * np.exp(-r*T) - S, 0)
price_at_high_vol = black_scholes_price(S, K, T, r, 5.0, option_type)
if market_price < price_at_zero_vol or market_price > price_at_high_vol * 1.1:
return np.nan
try:
iv = brentq(objective, 0.01, 4.0, xtol=1e-5)
return iv
except ValueError:
# Fallback: Grid-Suche
for sigma_test in np.linspace(0.05, 3.0, 60):
if abs(objective(sigma_test)) < 0.01:
return sigma_test
return np.nan
Anwendung
df_vol_surface['implied_volatility'] = df_vol_surface.apply(
lambda row: implied_volatility_robust(
row['market_price'], 105000, row['strike'],
row['maturity_days']/365, 0.05, row['type']
), axis=1
)
Fehler 3: Butterfly Arbitrage nicht erkannt wegen Rundungsfehlern
Problem: Die Toleranz für die Konvexitätsprüfung ist zu eng.
# FEHLERHAFT:
if IV_mid < IV_theoretical - 0.0001: # Zu enge Toleranz
LÖSUNG: Prozentuale Toleranz basierend auf IV-Niveau
def detect_butterfly_robust(df_vol_surface):
"""Butterfly Arbitrage mit prozentualer Toleranz"""
arbitrage_opportunities = []
for maturity in df_vol_surface['maturity_days'].unique():
df_mat = df_vol_surface[df_vol_surface['maturity_days'] == maturity].sort_values('strike')
strikes = df_mat['strike'].values
ivs = df_mat['implied_volatility'].values
for i in range(len(strikes) - 2):
K_low, K_mid, K_high = strikes[i], strikes[i+1], strikes[i+2]
IV_low, IV_mid, IV_high = ivs[i], ivs[i+1], ivs[i+2]
w = (K_high - K_mid) / (K_high - K_low)
IV_theoretical = w * IV_low + (1 - w) * IV_high
# Prozentuale Toleranz: 2% des IV-Niveaus oder absoluter Mindestwert
tolerance = max(IV_theoretical * 0.02, 0.01)
if IV_mid < IV_theoretical - tolerance:
arbitrage_opportunities.append({
'maturity_days': maturity,
'strike_mid': K_mid,
'iv_actual': IV_mid,
'iv_theoretical': IV_theoretical,
'spread_bps': (IV_theoretical - IV_mid) * 10000,
'action':