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?

Voraussetzungen und Grundkonzepte

Bevor wir mit dem代码-Teil beginnen, definieren wir die zentralen Begriffe:

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推理
Google Gemini 2.5 Flash $2.50 ~80ms Nur USD Schnelle Inferenz

Bei einem monatlichen Volumen von 10 Millionen Token für Research-Zwecke:

Geeignet / Nicht geeignet für

✅ Geeignet für:

❌ Nicht geeignet für:

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:

  1. 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.
  2. 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.
  3. Flexibilität: WeChat- und Alipay-Unterstützung removes barriers für chinesische Nutzer, während USD-Zahlungen für internationale Anwender verfügbar bleiben.
  4. 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.
  5. 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':