Il y a trois mois, j'ai passé quatre jours entiers à déboguer une RuntimeWarning: overflow encountered in exp qui corrompait mes calibrations de surface de volatilité implicite. Le problème ? Une interpolation CubiqueSpline standard qui générait des valeurs explosives pour les maturités longues avec des strikes extrêmes. Cette expérience m'a poussé à comparer systématiquement toutes les méthodes d'interpolation disponibles pour la construction de surfaces de volatilité implicite.

Comprendre le Problème de la Surface de Volatilité Implicite

La surface de volatilité implicite est une représentation tridimensionnelle de la volatilité implicite en fonction du strike et de la maturité. Elle est fondamentale pour :

Les 5 Méthodes d'Interpolation Comparées

1. Interpolation Linéaire

L'approche la plus simple et la plus robuste. Elle relie les points de données par des segments linéaires, garantissant la continuité mais pas la dérivabilité.

import numpy as np
from scipy.interpolate import interp1d

Construction d'une courbe de volatilité implicite

strikes = np.array([80, 90, 100, 110, 120]) vols = np.array([0.25, 0.22, 0.20, 0.19, 0.21])

Interpolation linéaire

vol_linear = interp1d(strikes, vols, kind='linear', bounds_error=False, fill_value='extrapolate')

Évaluation en dehors des points known

test_strikes = np.linspace(75, 125, 50) test_vols = vol_linear(test_strikes) print(f"Vol à K=95: {vol_linear(95):.4f}") print(f"Vol à K=115: {vol_linear(115):.4f}")

2. Splines Cubiques (Clamped)

Les splines cubiques offrent une continuité C² (fonction, dérivée première et seconde continues). Cependant, elles peuvent générer des oscillations parasites pour des données financières.

from scipy.interpolate import CubicSpline

Spline cubique avec conditions aux limites

cs = CubicSpline(strikes, vols, bc_type='clamped')

bc_type='clamped': dérivée première = 0 aux extrémités

Alternative: 'natural' pour seconde dérivée = 0

test_vols_spline = cs(test_strikes)

Dérivée du smile ( важный pour le skew )

smile_slope = cs(test_strikes, 1) # Première dérivée print(f"Extrapolation K=130: {cs(130):.4f}") # Peut exploser!

3. Interpolation par Fonctions de Base Radiales (RBF)

Méthode particulièrement adaptée aux surfaces 2D avec une很好的 généralisation. Fonctionne bien même avec des données clairsemées.

from scipy.interpolate import RBFInterpolator

Données 2D: strikes et maturités

strikes_2d = np.array([80, 90, 100, 110, 120] * 3) maturities = np.array([0.25]*5 + [0.5]*5 + [1.0]*5) vols_2d = np.array([0.25, 0.22, 0.20, 0.19, 0.21, # T=0.25 0.24, 0.21, 0.19, 0.18, 0.20, # T=0.5 0.23, 0.20, 0.18, 0.17, 0.19]) # T=1.0 coords = np.column_stack([strikes_2d, maturities])

RBF avec noyau gaussien (_smooth=True pour lisser le bruit)

rbf_interp = RBFInterpolator(coords, vols_2d, kernel='gaussian', smoothing=0.01)

Évaluation sur grille

eval_coords = np.array([[k, t] for k in test_strikes for t in [0.3, 0.6, 0.9]]) surface_vols = rbf_interp(eval_coords)

4. Kriging (Krigeage)

Méthode géostatistique qui offre non seulement l'interpolation mais aussi une estimation de l'incertitude. Particulièrement utile pour le pricing d'options avec ajustements de convexité.

# Implémentation Kriging simplifiée
from scipy.linalg import solve

def kriging_interpolation(x_data, y_data, x_eval, sigma_nugget=0.01):
    """
    Kriging ordinaire avec effet de pépite (nugget)
    pour gérer le bruit de mesure
    """
    n = len(x_data)
    # Matrice de covariance (modèle gaussien)
    def cov(h, l=10):
        return np.exp(-3 * (h/l)**2)
    
    # Construction de la matrice de covariance
    H = np.zeros((n+1, n+1))
    for i in range(n):
        for j in range(n):
            H[i,j] = cov(abs(x_data[i] - x_data[j]))
    H[n,:n] = H[:n,n] = 1
    H[n,n] = 0
    
    # Résolution du système
    y_aug = np.append(y_data, np.mean(y_data))
    
    # Résolution avec gestion des erreurs numériques
    try:
        weights = solve(H, y_aug, assume_a='pos')
    except np.linalg.LinAlgError:
        # Ajout de régularisation numérique
        H += np.eye(n+1) * 1e-8
        weights = solve(H, y_aug)
    
    return weights[:n]

Application aux données de volatilité

weights = kriging_interpolation(strikes, vols, test_strikes)

5. Interpolation Smoothing (SciPy UnivariateSpline)

Combine interpolation et lissage, idéal quand les données contiennent du bruit de marché ou des anomalies temporaires.

from scipy.interpolate import UnivariateSpline

Spline avec lissage automatique

s = nombre de points - sqrt(2) pour lisser le bruit

spline_smooth = UnivariateSpline(strikes, vols, s=len(vols)*0.5)

Évaluation

test_vols_smooth = spline_smooth(test_strikes)

Estimation de la qualité du lissage

residual = np.sum((spline_smooth(strikes) - vols)**2) print(f"Résidu du lissage: {residual:.6f}") print(f"Coefficient de lissage effectif: {spline_smooth.get_smoothing_factor():.4f}")

Benchmarks de Performance et Précision

Ressources connexes

Articles connexes

🔥 Essayez HolySheep AI

Passerelle API IA directe. Claude, GPT-5, Gemini, DeepSeek — une clé, sans VPN.

👉 S'inscrire gratuitement →

MéthodeLatence (ms)