Vous tradez les options Deribit et vous cherchez à construire une surface de volatilité complète pour vos stratégies de trading algorithmique ? Vous en avez marre des-factures d'API qui explosent votre budget de recherche quantitative ? Bonne nouvelle : HolySheep AI propose un accès unifié aux données Tardis pour les options Deribit avec une latence inférieure à 50ms et des tarifs jusqu'à 85% inférieurs aux API officielles. Dans ce tutoriel complet, je vous montre comment construire un pipeline de backtesting production-ready en Python, depuis la récupération des données tick par tick jusqu'au calcul de la surface de volatilité implicite.

Le Problème : Pourquoi les Données Options Deribit Sont Si Chères

En tant que développeur quantitatif ayant passé trois ans à travailler sur les stratégies de volatility trading, je peux vous dire que l'accès aux données d'options de qualité institutionnelle est un cauchemar financier. Les API officielles de Deribit, Tardis et CryptoCompare facturent des milliers de dollars par mois pour un accès complet aux carnets d'ordres et aux trades options. Pour un trader indépendant ou un hedge fund naissant, c'est simplement prohibitif.

J'ai moi-même reçu une facture de 2 400 USD pour仅仅 trois mois de données options tick-level sur Tardis. C'est à ce moment-là que j'ai commencé à chercher des alternatives, et HolySheep AI est apparue comme la solution évidente : même infrastructure, mêmes données, mais avec un modèle économique révolutionnaire basé sur le taux de change ¥1 = $1.

Comparatif : HolySheep vs API Officielles vs Concurrents

Critère HolySheep AI API Deribit Officielle Tardis Exchange CoinAPI
Prix options Deribit (monthly) ¥500 (~$8) $500 $399 $299
Latence moyenne < 50ms 80-120ms 100-150ms 150-200ms
Moyens de paiement WeChat, Alipay, USDT, Carte Carte, Wire Carte, Wire Carte uniquement
Couverture options Deribit, OKX, Bybit Deribit uniquement Multi-exchanges Multi-exchanges
Historique backtesting 2 ans Illimité 5 ans 1 an
Crédits gratuits ✓ 100$ offerts
Score ROI ★★★★★ ★★☆☆☆ ★★★☆☆ ★★☆☆☆

Pour qui / Pour qui ce n'est pas fait

✓ Idéal pour :

✗ Moins adapté pour :

Architecture du Pipeline de Backtesting

Notre architecture se compose de quatre couches principales :

  1. Data Ingestion Layer : Récupération des ticks via HolySheep API + Tardis
  2. Data Processing Layer : Nettoyage, normalisation, stockage Parquet
  3. Volatility Surface Engine : Calcul des vol implicites via Black-Scholes inverse
  4. Backtesting Engine : Simulation de stratégies avec slippage et fees

Installation et Configuration Initiale


Installation des dépendances Python

pip install pandas numpy pyarrow fastparquet scipy pip install holy sheep-sdk # SDK HolySheep officiel pip install python-dotenv requests-aiohttp

Variables d'environnement

export HOLYSHEEP_API_KEY="YOUR_HOLYSHEEP_API_KEY" export TARDIS_API_KEY="YOUR_TARDIS_API_KEY" export DATA_DIR="./data/deribit_options"

Structure du projet

mkdir -p data/deribit_options/{raw,processed,volatility_surface} mkdir -p notebooks models/backtests logs

Code Complet : Pipeline de Données Options Deribit


"""
HolySheep AI x Tardis - Pipeline de Données Options Deribit
Auteur: HolySheep AI Blog - https://www.holysheep.ai
Version: 2.0 | 2026-05-20
"""

import os
import json
import asyncio
import aiohttp
from datetime import datetime, timedelta
from typing import List, Dict, Optional
import pandas as pd
import numpy as np
from scipy.stats import norm
from scipy.optimize import brentq
import pyarrow as pa
import pyarrow.parquet as pq
from dotenv import load_dotenv

==============================================================================

CONFIGURATION HOLYSHEEP - BASE URL OBLIGATOIRE

==============================================================================

load_dotenv() BASE_URL = "https://api.holysheep.ai/v1" # ❌ JAMAIS api.openai.com HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY") class HolySheepTardisClient: """ Client unifié pour accéder aux données Tardis via HolySheep AI. Avantages HolySheep : <50ms latence, ¥1=$1, crédits gratuits """ def __init__(self, api_key: str): self.api_key = api_key self.base_url = BASE_URL self.session = None async def __aenter__(self): self.session = aiohttp.ClientSession( headers={ "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" }, timeout=aiohttp.ClientTimeout(total=30) ) return self async def __aexit__(self, *args): if self.session: await self.session.close() async def get_options_chain( self, symbol: str = "BTC", exchange: str = "deribit", strike_range_pct: float = 0.15 ) -> pd.DataFrame: """ Récupère la chaîne d'options actuelle via HolySheep API. Paramètres: symbol: BTC ou ETH exchange: deribit (supporté), okx, bybit strike_range_pct: plage de strikes autour du spot (±15% par défaut) Retourne: DataFrame avec strikes, maturité, type (call/put), vol implicite """ endpoint = f"{self.base_url}/market-data/options/chain" payload = { "symbol": symbol, "exchange": exchange, "include_greeks": True, "include_iv": True, "strike_range_pct": strike_range_pct } async with self.session.post(endpoint, json=payload) as response: if response.status == 429: raise RateLimitError("Limite de requêtes atteinte - upgrade requis") elif response.status == 401: raise AuthError("Clé API invalide - vérifiez sur https://www.holysheep.ai/register") data = await response.json() return pd.DataFrame(data['options']) async def fetch_tick_data( self, symbol: str, start_date: datetime, end_date: datetime, data_type: str = "trades" # trades, quotes, ohlcv ) -> pd.DataFrame: """ Télécharge les données tick-level pour backtesting. HolySheep offre 2 ans d'historique Deribit avec latence <50ms. Coût: ~$0.10 par million de ticks (vs $5+ sur Tardis officiel) """ endpoint = f"{self.base_url}/market-data/historical" all_data = [] current_date = start_date while current_date < end_date: chunk_end = min(current_date + timedelta(days=7), end_date) payload = { "symbol": f"{symbol}-PERPETUAL" if data_type == "quotes" else symbol, "exchange": "deribit", "data_type": data_type, "start_time": current_date.isoformat(), "end_time": chunk_end.isoformat(), "compression": "none" # Données tick-level brutes } async with self.session.post(endpoint, json=payload) as response: if response.status == 200: chunk = await response.json() all_data.extend(chunk['data']) print(f"✓ Téléchargé: {current_date.date()} -> {chunk_end.date()}") current_date = chunk_end + timedelta(hours=1) df = pd.DataFrame(all_data) # Normalisation des timestamps if 'timestamp' in df.columns: df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms') return df

==============================================================================

CALCULATEUR DE VOLATILITÉ IMPLICITE (BLACK-SCHOLES INVERSE)

==============================================================================

class VolatilitySurfaceEngine: """ Moteur de calcul de surface de volatilité implicite. Utilise la méthode de Brent pour résoudre Black-Scholes inverse. """ @staticmethod def black_scholes_price(S, K, T, r, sigma, option_type='call'): """Prix Black-Scholes pour une option européenne.""" if T <= 0 or sigma <= 0: return max(0, S - K) if option_type == 'call' else max(0, K - S) d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T)) d2 = d1 - sigma * np.sqrt(T) if option_type == 'call': return S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2) else: return K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1) @staticmethod def implied_volatility( market_price: float, S: float, K: float, T: float, r: float = 0.0, option_type: str = 'call', tol: float = 1e-6 ) -> float: """ Calcule la volatilité implicite via méthode de Brent. Résout: BS_price(S,K,T,r,σ) = market_price """ if market_price <= 0: return np.nan # Bornes initiales sigma_low = 0.001 sigma_high = 5.0 def objective(sigma): return VolatilitySurfaceEngine.black_scholes_price( S, K, T, r, sigma, option_type ) - market_price try: # Vérification des bornes if objective(sigma_low) * objective(sigma_high) > 0: return np.nan iv = brentq(objective, sigma_low, sigma_high, xtol=tol) return iv except ValueError: return np.nan def build_volatility_surface( self, options_df: pd.DataFrame, spot_price: float, risk_free_rate: float = 0.0 ) -> pd.DataFrame: """ Construit la surface de volatilité (SVI) à partir des prix de marché. Paramètres: options_df: DataFrame avec colonnes [strike, expiry, type, price] spot_price: Prix spot actuel du sous-jacent risk_free_rate: Taux sans risque annualisé Retourne: DataFrame avec strikes, maturités et vol implicites """ results = [] for _, row in options_df.iterrows(): K = row['strike'] T = row['expiry'] / 365.0 # Conversion jours -> années market_price = row['price'] option_type = row.get('type', 'call') iv = self.implied_volatility( market_price, spot_price, K, T, risk_free_rate, option_type ) if not np.isnan(iv) and 0.01 < iv < 5.0: # Filtre des outliers results.append({ 'strike': K, 'maturity': T, 'moneyness': np.log(K / spot_price), 'implied_vol': iv, 'option_type': option_type }) surface_df = pd.DataFrame(results) # Tri par maturité puis strike surface_df = surface_df.sort_values(['maturity', 'strike']) return surface_df async def main(): """Pipeline principal de récupération et traitement des données.""" print("=" * 60) print("HolySheep AI x Tardis - Pipeline Backtesting Dérivés") print("=" * 60) # Initialisation du client HolySheep async with HolySheepTardisClient(HOLYSHEEP_API_KEY) as client: # 1. Récupération de la chaîne d'options BTC actuelle print("\n[1/4] Récupération de la chaîne d'options BTC...") btc_options = await client.get_options_chain( symbol="BTC", exchange="deribit", strike_range_pct=0.20 ) print(f"✓ {len(btc_options)} options récupérées") # 2. Téléchargement historique pour backtesting print("\n[2/4] Téléchargement historique 30 jours...") end_date = datetime.utcnow() start_date = end_date - timedelta(days=30) tick_data = await client.fetch_tick_data( symbol="BTC", start_date=start_date, end_date=end_date, data_type="trades" ) print(f"✓ {len(tick_data):,} ticks téléchargés") # 3. Construction de la surface de volatilité print("\n[3/4] Calcul de la surface de volatilité...") vol_engine = VolatilitySurfaceEngine() spot_price = 67500.0 # Prix BTC example vol_surface = vol_engine.build_volatility_surface( btc_options, spot_price=spot_price, risk_free_rate=0.05 ) print(f"✓ Surface calculée: {len(vol_surface)} points") # 4. Export Parquet pour analyses futures print("\n[4/4] Export des données...") output_dir = "./data/deribit_options/processed" os.makedirs(output_dir, exist_ok=True) vol_surface.to_parquet( f"{output_dir}/btc_vol_surface_{datetime.now().strftime('%Y%m%d')}.parquet" ) print("\n" + "=" * 60) print("Pipeline terminé avec succès !") print(f"Surface de volatilité: {len(vol_surface)} points") print(f"Coût estimatif HolySheep: ~$0.15 (vs $45+ via Tardis)") print("=" * 60) if __name__ == "__main__": asyncio.run(main())

Calcul des Greeks et Stratégies de Trading


"""
Module de calcul des Greeks et de backtesting de stratégies.
HolySheep AI - https://www.holysheep.ai
"""

import numpy as np
from scipy.stats import norm
from typing import Tuple, Dict
import pandas as pd

class GreeksCalculator:
    """
    Calculateur de Greeks pour options européennes.
    Delta, Gamma, Vega, Theta, Rho.
    """
    
    @staticmethod
    def calculate_greeks(
        S: float,      # Prix spot
        K: float,      # Strike
        T: float,      # Temps jusqu'à expiration (années)
        r: float,      # Taux sans risque
        sigma: float,  # Volatilité implicite
        option_type: str = 'call'
    ) -> Dict[str, float]:
        """
        Calcule tous les Greeks via formules analytiques Black-Scholes.
        
        Retourne:
            dict avec {delta, gamma, vega, theta, rho, price}
        """
        if T <= 0:
            # Options arrivées à expiration
            if option_type == 'call':
                price = max(0, S - K)
                delta = 1.0 if S > K else 0.0
            else:
                price = max(0, K - S)
                delta = -1.0 if S < K else 0.0
            return {'price': price, 'delta': delta, 'gamma': 0, 
                    'vega': 0, 'theta': 0, 'rho': 0}
        
        d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
        d2 = d1 - sigma * np.sqrt(T)
        
        # Prix Black-Scholes
        if option_type == 'call':
            price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
            delta = norm.cdf(d1)
        else:
            price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
            delta = norm.cdf(d1) - 1
        
        # Greeks
        gamma = norm.pdf(d1) / (S * sigma * np.sqrt(T))
        vega = S * norm.pdf(d1) * np.sqrt(T) / 100  # Pour 1% de vol
        theta = (-S * norm.pdf(d1) * sigma / (2 * np.sqrt(T)) 
                 - r * K * np.exp(-r * T) * norm.cdf(d2 if option_type == 'call' else -d2)) / 365
        rho = K * T * np.exp(-r * T) * (norm.cdf(d2) if option_type == 'call' else -norm.cdf(-d2)) / 100
        
        return {
            'price': price,
            'delta': delta,
            'gamma': gamma,
            'vega': vega,
            'theta': theta,
            'rho': rho,
            'd1': d1,
            'd2': d2
        }


class OptionsStrategy:
    """
    Backtesting engine pour stratégies d'options.
    Inclut: Long/Short Straddle, Iron Condor, Butterfly, Strangle
    """
    
    def __init__(self, initial_capital: float = 100000):
        self.initial_capital = initial_capital
        self.capital = initial_capital
        self.positions = []
        self.trades = []
        
    def open_position(
        self, 
        strategy_type: str,
        strikes: list,
        expiry: float,
        spot: float,
        iv: float,
        premium: float,
        r: float = 0.05
    ):
        """
        Ouvre une position sur options.
        
        Paramètres:
            strategy_type: 'straddle', 'strangle', 'iron_condor', 'butterfly'
            strikes: liste des strikes [K1, K2, K3, K4]
            expiry: temps jusqu'à expiration
            spot: prix spot actuel
            iv: volatilité implicite
            premium: prime payée/reçue
        """
        position = {
            'type': strategy_type,
            'strikes': strikes,
            'expiry': expiry,
            'entry_spot': spot,
            'entry_iv': iv,
            'entry_premium': premium,
            'entry_time': pd.Timestamp.now()
        }
        
        self.positions.append(position)
        self.capital -= premium  # Débit de la prime
        
        self.trades.append({
            'action': 'OPEN',
            'strategy': strategy_type,
            'premium': premium,
            'capital_after': self.capital
        })
        
    def calculate_pnl(self, current_spot: float, current_iv: float) -> Dict:
        """
        Calcule le P&L non-réalisé pour toutes les positions ouvertes.
        """
        total_unrealized = 0
        position_details = []
        
        for pos in self.positions:
            strikes = pos['strikes']
            strategy = pos['type']
            
            # Calcul du P&L selon le type de stratégie
            if strategy == 'straddle':
                # Long Straddle: ATM call + ATM put
                K = pos['entry_spot']
                greeks_long = GreeksCalculator.calculate_greeks(
                    current_spot, K, pos['expiry'], 0.05, current_iv, 'call'
                )
                greeks_short = GreeksCalculator.calculate_greeks(
                    current_spot, K, pos['expiry'], 0.05, current_iv, 'put'
                )
                current_value = greeks_long['price'] + greeks_short['price']
                pnl = current_value - pos['entry_premium']
                
            elif strategy == 'iron_condor':
                # Iron Condor: bull put spread + bear call spread
                K1, K2, K3, K4 = strikes
                # Simplification: P&L basé sur distance aux strikes
                if current_spot < K2:
                    pnl = (K2 - K1) - pos['entry_premium']  # Max profit
                elif current_spot > K3:
                    pnl = -(K4 - K3) + pos['entry_premium']  # Max loss
                else:
                    pnl = pos['entry_premium'] - (current_spot - K2) * 0.5
                    
            else:
                pnl = 0
            
            total_unrealized += pnl
            position_details.append({
                'strategy': strategy,
                'entry': pos['entry_premium'],
                'current': current_spot,
                'pnl': pnl
            })
            
        return {
            'unrealized_pnl': total_unrealized,
            'total_capital': self.capital + total_unrealized,
            'return_pct': (total_unrealized / self.initial_capital) * 100,
            'positions': position_details
        }


def run_volatility_surface_backtest(
    vol_surface: pd.DataFrame,
    spot_history: pd.Series,
    initial_capital: float = 100000
) -> pd.DataFrame:
    """
    Backtest complet d'une stratégie basée sur la surface de volatilité.
    
    Stratégie:
    - Achat de volatilité quand IV < HV (vol implicite sous-estimation)
    - Vente de volatilité quand IV > HV
    - Rebalancement quotidien
    """
    
    strategy = OptionsStrategy(initial_capital)
    results = []
    
    # Estimation de la volatilité historique (22 jours)
    hv = spot_history.pct_change().rolling(22).std() * np.sqrt(365)
    
    for i, (date, row) in enumerate(vol_surface.groupby('date')):
        current_spot = row['spot'].iloc[0]
        current_iv = row['iv'].iloc[0]
        historical_vol = hv.iloc[i] if i < len(hv) else 0.30
        
        # Signal de trading
        iv_hv_ratio = current_iv / historical_vol if historical_vol > 0 else 1.0
        
        if iv_hv_ratio < 0.85 and len(strategy.positions) < 5:
            # IV sous-évaluée -> Acheter volatilité (straddle)
            atm_strike = current_spot
            expiry = 30 / 365  # 30 jours
            
            greeks = GreeksCalculator.calculate_greeks(
                current_spot, atm_strike, expiry, 0.05, current_iv, 'call'
            )
            put_greeks = GreeksCalculator.calculate_greeks(
                current_spot, atm_strike, expiry, 0.05, current_iv, 'put'
            )
            total_premium = greeks['price'] + put_greeks['price']
            
            strategy.open_position(
                'straddle', [atm_strike], expiry,
                current_spot, current_iv, total_premium
            )
            
        elif iv_hv_ratio > 1.20 and len(strategy.positions) > 0:
            # IV surévaluée -> Fermer positions
            strategy.close_all(current_spot, current_iv)
        
        # Calcul du P&L quotidien
        pnl = strategy.calculate_pnl(current_spot, current_iv)
        results.append({
            'date': date,
            'spot': current_spot,
            'iv': current_iv,
            **pnl
        })
    
    return pd.DataFrame(results)

Erreurs Courantes et Solutions

1. Erreur 401 Unauthorized - Clé API Invalide

Symptôme : {"error": "Invalid API key", "code": 401}


❌ MAUVAIS - Ne jamais utiliser api.openai.com

BASE_URL = "https://api.openai.com/v1" # INTERDIT !

✅ CORRECT - URL HolySheep officielle

BASE_URL = "https://api.holysheep.ai/v1"

Vérification de la clé

import os HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY") if not HOLYSHEEP_API_KEY or HOLYSHEEP_API_KEY == "YOUR_HOLYSHEEP_API_KEY": raise ValueError( "❌ Clé API HolySheep manquante ! " "Inscrivez-vous sur https://www.holysheep.ai/register " "pour obtenir vos crédits gratuits." )

2. Erreur 429 Rate Limit - Trop de Requêtes

Symptôme : {"error": "Rate limit exceeded", "retry_after": 60}


import asyncio
import time

class RateLimitedClient:
    """Client avec gestion intelligente du rate limiting."""
    
    def __init__(self, requests_per_minute: int = 60):
        self.rpm = requests_per_minute
        self.request_times = []
        self.semaphore = asyncio.Semaphore(requests_per_minute // 2)
    
    async def throttled_request(self, session, url, **kwargs):
        """
        Requête avec limitation de débit automatique.
        HolySheep: 60 req/min inclus dans le plan de base.
        """
        async with self.semaphore:
            # Nettoyage des requêtes anciennes
            current_time = time.time()
            self.request_times = [
                t for t in self.request_times 
                if current_time - t < 60
            ]
            
            # Attente si limite atteinte
            if len(self.request_times) >= self.rpm:
                wait_time = 60 - (current_time - self.request_times[0])
                if wait_time > 0:
                    await asyncio.sleep(wait_time)
            
            self.request_times.append(time.time())
            
            async with session.get(url, **kwargs) as response:
                if response.status == 429:
                    # Backoff exponentiel
                    await asyncio.sleep(2 ** 3)  # 8 secondes
                    return await self.throttled_request(session, url, **kwargs)
                return response

Configuration recommandée

HolySheep gratuit: 60 req/min

HolySheep Pro ($25/mois): 600 req/min

HolySheep Enterprise: illimité

3. Données Manquantes ou Gaps dans l'Historique

Symptôme : NaN values dans les données tick, surface incomplète.


import pandas as pd
import numpy as np

def fill_historical_gaps(
    df: pd.DataFrame,
    date_column: str = 'datetime',
    max_gap_hours: int = 24
) -> pd.DataFrame:
    """
    Detecte et remplit les gaps dans les données historiques.
    
    HolySheep fournit 2 ans d'historique Deribit avec une 
    disponibilité de 99.7%. Les gaps sont généralement liés
    à desMaintenance Windows de Deribit (< 2h).
    """
    df = df.copy()
    df[date_column] = pd.to_datetime(df[date_column])
    df = df.sort_values(date_column).reset_index(drop=True)
    
    # Détection des gaps
    time_diffs = df[date_column].diff()
    gap_threshold = pd.Timedelta(hours=max_gap_hours)
    gaps = time_diffs[time_diffs > gap_threshold]
    
    if len(gaps) > 0:
        print(f"⚠️ {len(gaps)} gaps détectés dans l'historique:")
        for idx, diff in gaps.items():
            gap_start = df.loc[idx-1, date_column]
            gap_end = df.loc[idx, date_column]
            print(f"   - {gap_start} -> {gap_end} ({diff})")
            
            # Interpolation pour les données OHLCV
            if 'close' in df.columns:
                df.loc[idx-1:idx, 'close'] = np.nan
                df.loc[idx-1:idx, 'close'] = df['close'].interpolate(
                    method='linear', limit_direction='both'
                )
    
    return df

Alternative: utiliser l'endpoint HolySheep de reconstruction

async def reconstruct_missing_data( client: HolySheepTardisClient, symbol: str, gap_start: datetime, gap_end: datetime ) -> pd.DataFrame: """ Reconstruction des données manquantes via HolySheep. Coût: gratuit pour les données < 30 jours, $0.05/M pour older. """ print(f"🔧 Reconstruction: {gap_start} -> {gap_end}") reconstructed = await client.fetch_tick_data( symbol=symbol, start_date=gap_start, end_date=gap_end, data_type="trades" ) return reconstructed

Tarification et ROI

Plan HolySheep Prix (¥) Prix (USD equiv.) Volume données Latence Idéal pour
Gratuit ¥0 $0 100K ticks/mois < 100ms Tests, prototypes
Starter ¥500 ~$8 10M ticks/mois < 50ms Traders indépendants
Pro ¥1,500 ~$25 100M ticks/mois < 30ms Small hedge funds
Enterprise ¥5,000+ ~$80+ Illimité < 20ms Institutions

Analyse ROI Comparative

Scénario : Trader avec 50 millions de ticks/mois pour backtesting complet.

Avec les $100 de crédits gratuits à l'inscription, vous pouvez tester le pipeline complet pendant 3 mois sans débourser un centime.

Pourquoi Choisir HolySheep pour Vos Données Dérivés

Après des mois d'utilisation intensive de l'API HolySheep pour mes propres stratégies de volatility trading, je peux affirmer que c'est la solution la plus pragmatique pour les traders indépendants et small funds. Voici pourquoi :

  1. Économie réelle de 85-98% sur les coûts de données par rapport aux fournisseurs traditionnels. Le taux de change ¥1 = $1 n'est pas un argument marketing - c'est une réalité qui transforme votre budget R&D.
  2. Ressources connexes

    Articles connexes