24 septembre 2026 · recherche

Nous avons rejoué une stratégie paper après un redémarrage. Ses ordres avaient changé.

Nous avons rejoué une stratégie paper après un redémarrage. Ses ordres avaient changé.

Nous avons redémarré une stratégie paper au milieu d'une position et obtenu une séquence d'ordres différente de celle produite avant le redémarrage. Mêmes données de marché, même version de stratégie, même solde de compte. Le calcul du signal correspondait. En revanche, la stratégie ne se souvenait pas de la même façon de sa position et de ses ordres en attente.

Nous avons retracé l'écart au fil d'une journée de replay. La leçon à retenir est simple : pour votre logiciel, un redémarrage est un événement de marché. Si vous ne testez pas comment la stratégie reconstitue son état, un backtest propre peut masquer un système paper qui oublie ce qu'il détient.

09:10 — Nous avons choisi une position sans histoire

La stratégie de test négociait un contrat perpétuel liquide : elle entrait en position longue quand une moyenne mobile courte croisait à la hausse une moyenne plus longue, puis sortait au croisement inverse. Nous avons lancé le replay avec une petite position déjà ouverte et un ordre limite reduce-only en attente pour la réduire. La reprise devait donc reconstituer 2 éléments : ce que nous détenions et ce que nous avions déjà demandé à la plateforme d'exécuter.

Au point de contrôle, le compte détenait 0.04 contrat. L'ordre en attente portait sur 0.01. Le processus de la stratégie avait mis ces 2 valeurs en cache, mais son démarrage ne récupérait que la position. Il a considéré que l'ordre en cache n'existait plus.

09:25 — Le premier ordre en double est apparu

Au redémarrage, la stratégie a détecté la position longue existante, exécuté sa logique de signal et soumis un nouvel ordre de réduction de 0.01. La plateforme paper avait alors 2 ordres actifs. Aucun n'était problématique en soi. Ensemble, ils pouvaient vendre 2 fois la quantité prévue s'ils étaient tous les 2 exécutés.

Nous avons d'abord soupçonné la boucle de signal. Ce n'était pas la boucle, mais l'état incomplet. La stratégie demandait : « Quelle est ma position ? », sans jamais demander : « Quels ordres sont encore actifs ? »

État après le redémarrageCe que le processus croyaitCe que détenait le compte
PositionLongue de 0.04Longue de 0.04
Ordres de réduction ouvertsAucun2 ordres de 0.01 chacun
Exposition prévue après une exécutionLongue de 0.03Pourrait tomber à 0.02

10:00 — Nous avons corrigé la reprise, puis découvert un problème de timing

Nous avons modifié le démarrage pour reconstituer l'état à partir des positions et des ordres ouverts du compte avant d'autoriser de nouvelles décisions. Le doublon a disparu. Puis nous avons compliqué la déconnexion : un ordre a été exécuté pendant que la stratégie était hors ligne, et la notification d'exécution est arrivée après la reconnexion.

L'instantané du compte tenait déjà compte de l'exécution. La notification tardive a ensuite réduit une deuxième fois la position locale. Pendant quelques secondes, la stratégie a cru détenir 0.02 contrat alors que le compte en détenait 0.03. Son rééquilibrage suivant s'est fondé sur un manque fictif.

Nous avons ajouté des règles de rapprochement : prendre l'instantané du compte comme point de départ, utiliser les identifiants d'événement pour ignorer les exécutions déjà prises en compte et ne soumettre aucun ordre avant la fin de la synchronisation initiale. Une notification peut arriver en retard ou en double. La reprise doit gérer les 2 cas.

13:40 — Le replay a révélé un écart discret

Nous avons rejoué le même parcours de prix sur l'exécution initiale et celle après redémarrage. Comparer le P&L final n'aurait pas révélé le problème : les 2 versions ont fini avec la même position après le retournement du marché. La comparaison des événements d'ordre, elle, l'a mis au jour.

Nous avons journalisé chaque décision avec l'état qu'elle avait consulté : position, ordres ouverts, identifiant de la dernière exécution traitée, valeur du signal et version de la stratégie. Le premier événement divergent s'est alors expliqué. Une exécution voyait un ordre actif ; l'autre, une liste vide. Plus tard, l'une a appliqué une exécution 2 fois.

Un solde final identique ne prouve pas que le comportement a été identique. Comparez la séquence de décisions et d'ordres, surtout autour des phases de reprise.

16:20 — Ce que nous ferions autrement la prochaine fois

Nous avons passé trop de temps à rejouer les données de prix avant de vérifier les transitions d'état du compte. La prochaine fois, nous injecterions d'abord les cas de panne et garderions le parcours de marché presque plat. L'erreur logicielle serait ainsi facile à repérer, sans qu'un mouvement volatile brouille le diagnostic.

Nous avons aussi appris à enregistrer un instantané de reprise avec la version de la stratégie et le journal des événements. L'échec est ainsi devenu reproductible en quelques minutes, sans dépendre de la mémoire de quelqu'un pour retrouver la séquence exacte de reconnexion.

Une stratégie paper qui ne se comporte correctement que tant que son processus reste actif n'a pas réussi sa répétition générale. Redémarrez-la en pleine position, faites arriver les exécutions en retard et examinez chaque ordre qu'elle envoie ensuite. Le but n'est pas de prouver qu'elle ne tombera jamais en panne. C'est de rendre sa reprise visible avant que le compte paper ne vous donne la même leçon par surprise.

trading paperétat de la stratégiebacktestinggestion des ordresreproductibilité
← Tous les articles