Market Connect-Exec : Une librairie Python pour l'exécution multi-broker et les données de marché

Documentation Outils

marketconnect-exec est une librairie Python pour les traders quantitatifs et gérants de portefeuille. Elle fournit une interface unifiée vers Deribit et Interactive Brokers — couvrant la gestion des ordres, les positions, les données de compte, les données de marché et l'analytique dérivés via une API unique et cohérente.

Bannière Market Connect exec
Antoine Perrin Profile Picture

Antoine

CEO - CodeMarketLabs

2026-03-14

marketconnect-exec : Une librairie Python pour l'exécution multi-broker et les données de marché

marketconnect-exec est une librairie Python conçue pour les traders quantitatifs et gérants de portefeuille qui ont besoin d'une interface propre et unifiée pour interagir avec plusieurs brokers depuis une même base de code. Construite autour d'un pattern d'adaptateur abstrait, elle supporte actuellement Deribit et Interactive Brokers (IBKR) — couvrant le workflow de trading complet : connexion, placement et gestion des ordres, récupération des positions et données de compte, données de marché, et analytique dérivés. Un routeur central et une couche d'exécution dispatche chaque appel vers le bon broker automatiquement, de sorte que le code de votre stratégie reste agnostique au broker.

Ce que la librairie apporte

  • Pattern adaptateur abstrait : ajoutez un nouveau broker en implémentant une seule classe, rien d'autre ne change.
  • Gestion des ordres unifiée : placement, annulation et suivi avec des enums normalisés sur tous les brokers.
  • Positions & données de compte : positions du portefeuille, solde cash, marge et opérations historiques.
  • Données de marché : OHLC historique, prix de clôture, cotations en direct, profondeur du carnet d'ordres et dernières transactions.
  • Analytique dérivés : volatilité implicite, surface de volatilité avec filtrage avancé, et chaînes de futures.
  • Mapping des champs broker : types d'ordres, sens et time-in-force traduits automatiquement par broker.

1. Architecture : Router & Pattern Adaptateur

La librairie s'articule autour de deux abstractions centrales. AbstractBroker définit le contrat complet que chaque broker doit implémenter — connexion, gestion des ordres, positions, données de marché et dérivés. APIRouter est un registre léger qui stocke les instances d'adaptateurs et dispatche les appels par nom. La classe Execution encapsule le routeur et expose l'API publique que votre code de stratégie utilise. Ce découpage signifie que vous pouvez remplacer ou ajouter un broker sans toucher à aucune logique de stratégie.

python
from marketconnect_exec.core.router import APIRouter
from marketconnect_exec.core.execution import Execution
from marketconnect_exec.brokers.deribit.adapter import DeribitAdapter
from marketconnect_exec.brokers.ibkr.adapter import IBKRAdapter

# --- Enregistrement des adaptateurs broker ---
router = APIRouter()

# Deribit — dérivés crypto
router.register_broker(DeribitAdapter(
    client_id="YOUR_API_KEY",
    client_secret="YOUR_API_SECRET"
))

# Interactive Brokers — actions, ETFs, options
router.register_broker(IBKRAdapter(
    host="127.0.0.1",
    port=7497,          # 7497 = paper trading, 7496 = live
    client_id=1
))

# Connexion de tous les brokers enregistrés en un seul appel
router.connect_all_brokers()

# Couche d'exécution — point d'entrée unique pour toutes les opérations
exec = Execution(router)

# Vérification de l'état de connexion sur un adaptateur
adapter = router.get_broker_adapter("deribit")
print(adapter.is_connected)   # True

# Déconnexion propre
router.disconnect_all_brokers()
L'infrastructure de trading algorithmique rendue possible par marketconnect-exec
L'infrastructure de trading algorithmique rendue possible par marketconnect-exec

2. Types Statiques : Ordres, Brokers & Time-in-Force

Tous les paramètres sont typés avec des enums définis dans le module static. OrderSide, OrderType, TimeInForce et BrokerName sont utilisés de façon cohérente dans chaque fonction — pas de chaînes brutes. La classe Mapping gère la traduction de ces enums universels vers les valeurs spécifiques à chaque broker (par ex. OrderType.LIMIT devient 'LMT' pour IBKR et 'limit' pour Deribit). OrderTicket est le dataclass normalisé retourné par chaque placement d'ordre, quel que soit le broker.

python
from marketconnect_exec.static.brokers import BrokerName
from marketconnect_exec.static.orders import OrderSide, OrderType
from marketconnect_exec.static.time_in_force import TimeInForce
from marketconnect_exec.static.mappings import Mapping

# --- Enums disponibles ---
print(list(BrokerName))    # [<BrokerName.DERIBIT: 'deribit'>, <BrokerName.IBKR: 'ibkr'>]
print(list(OrderSide))     # [BUY, SELL]
print(list(OrderType))     # [MARKET, LIMIT, STOP_MARKET, STOP_LIMIT, TRAILING_STOP]
print(list(TimeInForce))   # [GTC, IOC, FOK, GTD]

# --- Mapping : enum universel → chaîne spécifique broker ---
print(Mapping.get_order_type('DERIBIT', OrderType.LIMIT))        # 'limit'
print(Mapping.get_order_type('IBKR',    OrderType.STOP_MARKET))  # 'STP'
print(Mapping.get_time_in_force('IBKR', TimeInForce.GTD))        # 'GTD'
print(Mapping.get_side('DERIBIT', OrderSide.BUY))                # 'buy'
print(Mapping.get_side('IBKR',    OrderSide.SELL))               # 'SELL'

# --- Mapping inverse : chaîne broker → enum universel ---
print(Mapping.get_universal_order_type('IBKR', 'LMT'))            # OrderType.LIMIT
print(Mapping.get_universal_tif('DERIBIT', 'good_til_cancelled'))  # TimeInForce.GTC

# --- OrderTicket : retour normalisé de stage_order ---
# broker_name, order_id, symbol, creation_date,
# order_side, order_type, time_in_force, quantity,
# price, stop_price, trailing_stop_pct, trailing_stop_val, local_id

3. Gestion des Ordres

La méthode stage_order est le point d'entrée principal pour l'exécution. Elle accepte des enums universels et retourne un OrderTicket normalisé avec le nom du broker, l'identifiant de l'ordre, le symbole, l'horodatage de création et tous les paramètres de l'ordre. L'annulation et les requêtes de statut suivent le même schéma — passez l'enum BrokerName et l'order_id retourné par le ticket. Les trois méthodes sont disponibles sur l'objet Execution et routent transparentement vers l'adaptateur correct.

python
from marketconnect_exec.static.brokers import BrokerName
from marketconnect_exec.static.orders import OrderSide, OrderType
from marketconnect_exec.static.time_in_force import TimeInForce

# --- Ordre limite achat sur Deribit ---
ticket = exec.stage_order(
    broker=BrokerName.DERIBIT,
    symbol="BTC-PERPETUAL",
    side=OrderSide.BUY,
    quantity=1.0,
    order_type=OrderType.LIMIT,
    price=65_000.0,
    time_in_force=TimeInForce.GTC
)
print(ticket.order_id)       # ex. '12345678'
print(ticket.broker_name)    # 'deribit'
print(ticket.creation_date)  # objet datetime

# --- Ordre marché vente sur IBKR ---
ibkr_ticket = exec.stage_order(
    broker=BrokerName.IBKR,
    symbol="AAPL",
    side=OrderSide.SELL,
    quantity=100.0,
    order_type=OrderType.MARKET,
    time_in_force=TimeInForce.IOC
)

# --- Stop-limit sur Deribit avec reduce_only ---
stop_ticket = exec.stage_order(
    broker=BrokerName.DERIBIT,
    symbol="ETH-PERPETUAL",
    side=OrderSide.SELL,
    quantity=5.0,
    order_type=OrderType.STOP_LIMIT,
    price=3_000.0,
    stop_price=3_050.0,
    time_in_force=TimeInForce.GTC,
    reduce_only=True
)

# --- Suivi et annulation ---
status = exec.get_order_status(BrokerName.DERIBIT, ticket.order_id, symbol="BTC-PERPETUAL")
print(status)  # dict de statut natif du broker

exec.cancel_order(BrokerName.DERIBIT, ticket.order_id, symbol="BTC-PERPETUAL")

4. Positions & Données de Compte

Le module positions offre une vue complète de l'état du compte : toutes les positions ouvertes, positions filtrées par devise ou symbole, résumé de compte, solde cash, exigences de marge et opérations historiques. Toutes les méthodes passent par la couche Execution et acceptent un paramètre account optionnel pour les configurations multi-comptes. La méthode get_historical_operations est explicitement non-normalisée — pour IBKR elle nécessite un Flex Query ID pré-configuré passé en kwarg, tandis que pour les brokers crypto elle retourne un journal de transactions universel.

python
from marketconnect_exec.static.brokers import BrokerName
import warnings

# --- Toutes les positions ouvertes ---
positions = exec.get_all_positions(BrokerName.DERIBIT)
for pos in positions:
    print(pos)  # liste de dicts, champs natifs du broker

# --- Filtre par devise ou symboles ---
btc_positions = exec.get_specific_instruments_positions(
    broker=BrokerName.DERIBIT,
    currency="BTC"          # toutes les positions libellées en BTC
)
specific = exec.get_specific_instruments_positions(
    broker=BrokerName.IBKR,
    symbols=["AAPL", "TSLA", "SPY"]   # tickers spécifiques
)

# --- Vue d'ensemble du compte ---
summary = exec.get_account_summary(BrokerName.IBKR)
print(summary)  # liquidation nette, équité, P&L, etc.

cash = exec.get_cash_balance(BrokerName.DERIBIT)
print(cash)     # {'BTC': 0.45, 'ETH': 3.2, 'USDC': 12500.0}

margin = exec.get_account_margin(BrokerName.IBKR)
print(margin)   # marge initiale, marge de maintenance, fonds disponibles

# --- Opérations historiques (non-normalisé — déclenche un UserWarning) ---
with warnings.catch_warnings(record=True) as w:
    # Deribit : retourne le journal de transactions universel
    ops_deribit = exec.get_historical_operations(BrokerName.DERIBIT)

    # IBKR : nécessite un Flex Query pré-configuré
    ops_ibkr = exec.get_historical_operations(
        BrokerName.IBKR,
        query_id="YOUR_FLEX_QUERY_ID"   # configuré dans IBKR Account Management
    )

5. Données de Marché

Le module données de marché couvre la récupération de données historiques et temps-réel via la même interface unifiée. get_histo_ohlc retourne les données chandelier pour un symbole et un timeframe donnés. get_histo_close_price regroupe plusieurs symboles en un seul appel. get_quote retourne le bid/ask/last courant. get_order_book retourne les données de profondeur de marché, et get_last_trades retourne les dernières transactions exécutées. Tous les paramètres datetime utilisent des objets Python natifs.

python
from datetime import datetime
from marketconnect_exec.static.brokers import BrokerName

# --- OHLC historique ---
ohlc = exec.get_histo_ohlc(
    broker=BrokerName.DERIBIT,
    symbol="BTC-PERPETUAL",
    timeframe="1D",                          # chaîne timeframe native du broker
    start=datetime(2024, 1, 1),
    end=datetime(2024, 12, 31)
)
# Retourne dict : {'timestamp': [...], 'open': [...], 'high': [...], 'low': [...], 'close': [...]}

# --- Prix de clôture en batch (utile pour le calcul de NAV de portefeuille) ---
close_prices = exec.get_histo_close_price(
    broker=BrokerName.IBKR,
    symbols=["AAPL", "MSFT", "GOOGL", "SPY"],
    start=datetime(2024, 1, 1),
    end=datetime(2024, 12, 31),
    date_to_skip=[]    # liste de dates à exclure (ex. jours fériés personnalisés)
)
# Retourne dict indexé par symbole : {'AAPL': pd.Series(...), 'MSFT': pd.Series(...)}

# --- Cotation en direct ---
quote = exec.get_quote(BrokerName.DERIBIT, "BTC-PERPETUAL")
print(quote)  # {'bid': 64980.0, 'ask': 65010.0, 'last': 64995.0, 'mark': 65000.0}

# --- Carnet d'ordres ---
book = exec.get_order_book(BrokerName.DERIBIT, "BTC-PERPETUAL", depth=10)
print(book['bids'][:3])   # [[prix, taille], ...] 3 meilleurs bids
print(book['asks'][:3])   # [[prix, taille], ...] 3 meilleures offres

# --- Dernières transactions ---
trades = exec.get_last_trades(BrokerName.DERIBIT, "ETH-PERPETUAL", nb_trades=20)
for t in trades:
    print(t)  # {'timestamp': ..., 'price': ..., 'amount': ..., 'direction': 'buy'|'sell'}
Graphique de l'order book du Bitcoin depuis Deribit API
Graphique de l'order book du Bitcoin depuis Deribit API

6. Analytique Dérivés

Le module dérivés expose trois fonctions de haut niveau. get_implied_vol retourne la volatilité implicite courante pour un instrument donné. get_futures_chain retourne la liste complète des contrats futures actifs avec les données d'expiration et de pricing. get_vol_surface est la plus riche en fonctionnalités : elle construit une surface de volatilité complète avec de nombreuses options de filtrage — par intérêt ouvert, qualité du spread bid-ask, plage de strikes, plage d'expiry, et type de surface (all, call, put, ou OTM uniquement). Un spot et un incrément de strike optionnels permettent un rééchantillonnage de surface à la volée.

python
from marketconnect_exec.static.brokers import BrokerName

# --- Volatilité implicite d'un instrument spécifique ---
iv = exec.get_implied_vol(BrokerName.DERIBIT, "BTC-28MAR25-70000-C")
print(iv)  # {'mark_iv': 0.62, 'bid_iv': 0.60, 'ask_iv': 0.64}

# --- Chaîne de futures ---
futures = exec.get_futures_chain(BrokerName.DERIBIT, "BTC")
for contract in futures:
    print(contract)  # {'symbol': 'BTC-28MAR25', 'expiry': datetime(...), 'mark_price': ...}

# --- Surface de volatilité (complète) ---
vol_surface = exec.get_vol_surface(
    broker=BrokerName.DERIBIT,
    symbol="BTC",
    minimum_contract_open_interest=80,   # filtrer les contrats illiquides
    filter_bid_ask=True,                 # exclure les options sans bid/ask valide
    filter_bid_ask_pct=0.05,             # max (ask_iv - bid_iv) / mid_iv
    strike_range=(50_000, 100_000),      # conserver les strikes entre 50k et 100k
    minimum_days=7,                      # exclure les expirations proches (< 7 jours)
    maximum_days=90,                     # exclure les expirations lointaines (> 90 jours)
    surface_type='otm',                  # puts OTM + calls OTM uniquement
    spot=65_000.0,                       # spot de référence pour le calcul du moneyness
    strike_increment=1_000               # rééchantillonnage de la grille à 1k d'incrément
)

# Chaque entrée de la liste est un dict :
for point in vol_surface[:3]:
    print(point)
    # {'symbol': 'BTC-28MAR25-65000-C', 'strike': 65000,
    #  'expiry_days': 14, 'mark_iv': 0.58, 'delta': 0.51, 'open_interest': 320}
Graphique de la surface de volatilité du Bitcoin depuis Deribit API
Graphique de la surface de volatilité du Bitcoin depuis Deribit API
Graphique de la courbe futures du Bitcoin recupérée depuis Deribit API
Graphique de la courbe futures du Bitcoin recupérée depuis Deribit API

7. Utilitaires & Helpers de Dates

Les modules utils et dates fournissent les fonctions de conversion bas-niveau utilisées en interne dans tous les adaptateurs. datetime_to_timestamp convertit un datetime Python en epoch milliseconde (le format standard de la plupart des REST APIs broker). timestamp_to_datetime et ts_to_datetime (UTC-aware) effectuent la conversion inverse. date_difference_days calcule une différence en jours fractionnaires entre deux datetimes — utile pour les calculs de temps à l'expiration dans le pricing des dérivés.

python
from datetime import datetime, timezone
from marketconnect_exec.static.utils import (
    datetime_to_timestamp,
    timestamp_to_datetime,
    date_difference_days
)
from marketconnect_exec.static.dates import ts_to_datetime

# --- datetime → timestamp milliseconde (pour les paramètres de requête API) ---
start = datetime(2024, 1, 1, 0, 0, 0)
print(datetime_to_timestamp(start))   # 1704067200000

# --- timestamp milliseconde → datetime (naïf, tz locale) ---
print(timestamp_to_datetime(1704067200000))   # 2024-01-01 00:00:00

# --- timestamp milliseconde → datetime UTC-aware (pour les réponses Deribit) ---
print(ts_to_datetime(1704067200000))
# 2024-01-01 00:00:00+00:00

# --- Différence de jours fractionnaires (temps à l'expiration) ---
aujourd_hui = datetime(2025, 3, 14)
expiry = datetime(2025, 3, 28)
print(date_difference_days(aujourd_hui, expiry))   # 14.0

# Usage pratique : calcul du DTE pour chaque contrat de la surface
for contract in futures:
    dte = date_difference_days(datetime.now(), contract['expiry'])
    print(f"{contract['symbol']} : {dte:.1f} jours à l'expiration")

Obtenir marketconnect-exec

marketconnect-exec est disponible en tant que package Python standalone. Que vous gériez une stratégie d'options systématique sur Deribit, un portefeuille actions via Interactive Brokers, ou que vous construisiez un système d'exécution multi-broker, la librairie vous donne une base propre et extensible sans avoir à maintenir du code d'intégration broker-spécifique.

Ce que vous obtenez

  • Code source complet avec fonctions typées, documentées et classe de base abstraite.
  • Couche d'exécution unifiée : une seule API pour Deribit et IBKR, d'autres brokers via une seule classe adaptateur.
  • Support dérivés complet : volatilité implicite, surface de volatilité avec filtrage avancé, chaînes de futures.
  • Enums normalisés et tables de mapping — pas de chaînes brutes broker dans votre code de stratégie.
  • Mises à jour à vie — nouveaux adaptateurs broker et fonctionnalités ajoutés régulièrement.
Comment ajouter un nouveau broker à marketconnect-exec ?

Sous-classez AbstractBroker, implémentez toutes les méthodes abstraites (connect, disconnect, stage_order, get_all_positions, etc.), puis appelez router.register_broker(VotreAdaptateur()). La couche Execution dispatche les appels vers votre adaptateur automatiquement — aucune autre modification n'est nécessaire.

Est-ce que la librairie supporte le paper trading / testnet ?

Oui. Pour Deribit, pointez vos identifiants vers l'endpoint testnet (test.deribit.com). Pour IBKR, connectez-vous au port 7497 (compte paper TWS) au lieu de 7496 (live). L'adaptateur s'initialise avec test = 'LIVE MODE' par défaut — surchargez-le dans votre sous-classe lors de la connexion à un environnement sandbox.

Quelle version de Python est requise ?

Python 3.13 ou supérieur est requis. La librairie utilise la syntaxe moderne des type hints (list[dict] au lieu de List[Dict]) et s'appuie sur des fonctionnalités introduites en Python 3.10+. Installez avec pip install -e . depuis la racine du package.

get_historical_operations est-il normalisé entre les brokers ?

Non — c'est explicitement documenté. Pour Deribit et les autres brokers crypto, il retourne un journal de transactions universel. Pour IBKR, il nécessite un Flex Query configuré dans IBKR Account Management ; passez le query_id en kwarg. Un UserWarning est déclenché à chaque appel de la méthode pour rappeler cette différence.

Puis-je n'utiliser qu'un seul broker sans enregistrer l'autre ?

Oui. N'enregistrez que les adaptateurs dont vous avez besoin. router.register_broker() est appelé une fois par broker et le routeur ne stocke que ce que vous lui donnez. Il n'y a aucune obligation d'enregistrer Deribit et IBKR ensemble — une configuration mono-broker est parfaitement valide.