Tous les articles

Projets4 min de lecture

Pourquoi j'ai construit mon propre moteur de trading

NautilusTrader existe, il est open source, rapide et éprouvé. J'ai quand même choisi d'écrire Orion de zéro. Ce que ça m'apporte, ce que ça me coûte, et quand je conseillerais l'inverse.

Mouvement de montre ouvert, rouages et engrenages apparents

Quand on se lance dans le trading algorithmique, la question arrive vite: pourquoi réécrire un moteur, alors que d'excellents projets open source existent déjà? Le plus abouti est sans doute NautilusTrader: un cœur en Rust, une couche Python pour piloter les stratégies, le même code en backtest et en live, et une vingtaine d'intégrations avec des plateformes de marché.

C'est un très bon projet, que je lis régulièrement pour comparer mes choix. J'ai pourtant décidé de construire Orion moi-même, et j'y travaille depuis plus de six mois. Voici pourquoi.

Un besoin très étroit#

Nautilus est conçu pour être multi-actifs et multi-plateformes: actions, futures, crypto, paris sportifs, marchés de prédiction. C'est sa force, et c'est aussi ce qui le rend généraliste: chaque concept doit fonctionner partout.

Mon besoin est l'inverse. Orion travaille sur un seul type de marché (les contrats à terme du CME), avec un seul format de données (le flux ordre par ordre), et une seule ambition: reconstruire le carnet d'ordres exactement comme la bourse le voit, jusqu'à la position de chaque ordre dans sa file. Pour un besoin aussi étroit, un moteur généraliste apporte surtout des abstractions dont je n'ai pas l'usage.

Des garanties portées par la structure#

C'est la raison principale. Orion repose sur quelques principes que je veux voir tenus par le code lui-même, pas par ma discipline:

  • Impossible de voir le futur. Les événements sont ordonnés sur l'instant où je les reçois, jamais sur l'horodatage de la bourse. Et la couche des stratégies ne dépend pas du carnet brut: regarder dans le futur n'est pas interdit, c'est inexprimable, le code ne compilerait pas.
  • La même chose en backtest et en live. Pas de if backtest dans le code, et rien de ce qui décide ne lit l'horloge du système. Le moteur ne connaît que le flux qu'on lui donne.
  • Un rejeu identique à l'octet près. Rejouer la même séance produit les mêmes résultats, octet pour octet. Une décision ne dépend que des données.
  • Refuser plutôt que deviner. Une donnée incohérente est refusée bruyamment, jamais corrigée en silence.

Avec un framework, on hérite de ses choix. On peut les respecter avec rigueur, mais on ne peut pas faire en sorte que le compilateur les impose à tout le code. Dans Orion, chacune de ces règles est inscrite dans les types, dans le graphe des dépendances entre crates, ou dans un test qui échoue dès qu'on l'enfreint.

Comprendre chaque ligne#

En trading, l'avantage se cache souvent dans des détails: comment la bourse gère la priorité d'un ordre modifié, ce qui arrive à un ordre « iceberg » qui se recharge, comment interpréter un instantané du carnet au milieu de la nuit. Ce sont exactement les endroits où un moteur généraliste doit faire une hypothèse raisonnable pour tout le monde.

Quand mon carnet diffère de la réalité, je veux pouvoir expliquer pourquoi, ligne par ligne. Aujourd'hui, mon carnet reconstruit concorde à 100 % avec un carnet publié indépendamment, sur des millions de comparaisons. Je n'aurais pas cette certitude sur un code dont je ne connais pas chaque recoin.

Rust de bout en bout#

Nautilus permet d'écrire un système entièrement en Rust, mais son centre de gravité reste Python pour les stratégies. Je voulais l'inverse: un seul langage, un seul outillage, un seul système de types du décodage des données jusqu'à l'envoi d'un ordre. Moins de frontières, c'est moins d'endroits où une hypothèse peut se perdre en route.

Apprendre en construisant#

Il y a aussi une raison plus personnelle. Reconstruire un carnet ordre par ordre, simuler une file d'attente, rendre un rejeu déterministe: chacune de ces étapes m'a appris la microstructure des marchés bien plus vite que n'importe quelle lecture. On ne comprend jamais aussi bien un mécanisme qu'en le faisant fonctionner soi-même.

Quand je conseillerais l'inverse#

Construire son propre moteur n'est pas un bon choix par défaut. Je conseillerais un moteur existant comme Nautilus si:

  • vous tradez plusieurs marchés ou plusieurs plateformes, en particulier la crypto, où ses intégrations font gagner des mois;
  • vous voulez aller vite en production et passer votre temps sur les stratégies plutôt que sur l'infrastructure;
  • vous travaillez en équipe, avec des profils plus à l'aise en Python;
  • votre avantage ne dépend pas de la mécanique fine du carnet d'ordres.

Ce que j'en retiens#

  • Un outil généraliste résout le problème de tout le monde. Quand le besoin est très étroit, l'outil sur mesure peut aller plus loin, et plus sûrement.
  • Le vrai gain, ce sont les garanties. Pas la vitesse brute, mais le fait que certaines erreurs soient impossibles à écrire.
  • Le prix est réel: du temps, de la maintenance, et l'obligation de tout vérifier soi-même.
  • Lire les bons projets reste indispensable. Construire seul ne veut pas dire ignorer ce que font les autres.
  • orion
  • rust
  • architecture