Fin juin, le corpus de parité PineForge était passé de 167 à 252 stratégies de référence. Trois bugs qu’aucune d’elles ne déclenchait ont fait surface dans des scripts partagés par la communauté : une liquidation sur appel de marge non modélisée, un contrôle de solvabilité aveugle au taux de change et un trailing stop qui ne s’armait jamais, sans le moindre avertissement.
Les chiffres de cet article ont été mesurés le 29 juin 2026 et sont conservés tels quels. Pour les résultats actuels, consultez notre protocole de mesure de la parité.
Lors de notre dernier tour d’horizon, en mai, le corpus de parité comptait 167 stratégies de référence, dont 165 en parité stricte trade pour trade avec TradingView. Il a continué de grandir : fin juin, il comptait 252 stratégies, dont 251 au niveau de parité « excellent » (99,6 %), une anomalie documentée, zéro échec.
Le chiffre en gros titre, c’est la partie ennuyeuse. Le plus intéressant, c’est ce que le corpus n’exerçait pas : trois comportements du courtier de TradingView que nous ne modélisions pas, chacun découvert parce qu’un script partagé par la communauté est passé par un chemin de code qu’aucune des 252 stratégies n’empruntait. Ce billet en passe trois en revue.
Où en était le corpus au 2026-06-29
corpus/validation_report.md (2026-06-29)
Total probes: 252
Excellent: 251 (99.6%)
Anomaly: 1
Strong/Moderate/Weak/Minimal/Missing: 0
TV trades: 389,590
Engine trades: 389,688
Matched: 389,468
Sur l’ensemble du corpus, le moteur a émis 98 trades de plus que TradingView, soit un écart de 0,025 % sur 389 590 trades de référence. C’était l’agrégat ; stratégie par stratégie, l’unique anomalie décrite plus bas n’en expliquait qu’un seul. Le reste venait de 23 stratégies pourtant notées « excellent » selon la grille de ce rapport, laquelle tolérait un écart de nombre de trades inférieur à 1 % : la plupart ne différaient que d’un ou deux trades, et quatre d’entre elles en concentraient 90 sur 98.
Les six sondes les plus récentes formaient alors une catégorie drawing, ajoutée quand nous avons livré un runtime capable de lire les objets de dessin Pine (line.get_price, géométrie des label et des box) comme des données exploitables pendant le backtest, et pas seulement comme des annotations de graphique. Les stratégies qui utilisent une ligne tracée comme état de calcul (une ligne de tendance ancrée à la main et utilisée comme support dynamique, par exemple) ont besoin que le moteur continue de fournir la géométrie d’objets que le script a déjà supprimés, comme le fait TradingView. Les six ont obtenu le niveau « excellent ».
L’unique anomalie, sans détour
Nous n’avons pas écarté la seule stratégie qui ne concordait pas. anomaly-equity-mirror-strategy-equity-01 se situe exactement à la limite de 1× l’equity pour l’admission en marge. Notre analyse de l’époque, que les notes du corpus créditent d’un niveau de confiance de 95 % ou plus, concluait que l’émulateur de courtier de TradingView n’était pas monotone précisément à cette limite : il admettait certaines entrées au-delà de l’equity et en rejetait d’autres en deçà, de façon incohérente d’une barre à l’autre. Notre moteur est déterministe : même equity, même décision d’admission, à chaque fois. C’est correct au regard de la sémantique de marge documentée de Pine et, selon cette analyse, ce n’était pas ce que faisait le courtier de TradingView à cette limite précise. Pour reproduire son comportement, il nous aurait fallu introduire notre propre non-déterminisme ; nous ne l’avons donc pas fait. L’écart était documenté, pas caché, et c’était le seul sur 252. (Depuis, la mesure de référence établie par les mainteneurs le 2026-09-29 a attribué le niveau « excellent » à cette sonde, et le README du corpus indique que ce diagnostic est en cours de réexamen.)
Premier bug : la position que TV aurait liquidée d’office
Le courtier de TradingView n’attend pas que la logique de votre stratégie décide de sortir d’une position qui a crevé son exigence de marge : il liquide. Si l’equity d’une position à effet de levier ou vendeuse baisse au point que la marge requise dépasse l’equity du compte, TradingView procède à la liquidation dès la barre où cela se produit, au prix le plus défavorable de cette barre pour la position, en clôturant quatre fois la quantité nécessaire pour rétablir la marge (dans la limite de la position entière), que les conditions de strategy.exit() soient remplies ou non.
Le moteur ne modélisait pas ce comportement. Il conservait la position et laissait la logique de la stratégie la clôturer tôt ou tard, ce qui, sur une stratégie sans stop serré, pouvait représenter des dizaines de barres pour une position que TradingView avait déjà liquidée. Sur 24 scripts partagés par la communauté qui laissaient courir des positions à effet de levier ou vendeuses jusqu’à l’appel de marge, la liste de trades de TradingView comportait des sorties « Margin call » que le moteur ne produisait jamais.
Le correctif ajoute une liquidation forcée lorsque l’equity du compte passe sous l’exigence de marge : il calcule le prix de liquidation comme le fait le courtier de TradingView, puis arrondit la quantité liquidée au pas de lot du symbole. TradingView ne liquide pas de fractions de lot plus petites que ce pas, et nous non plus désormais, à condition que le backtest le fournisse.
C’est surtout important si vous backtestez des stratégies à effet de levier ou short sur des contrats perpétuels. Si votre courbe d’equity paraissait trop lisse pendant un drawdown, c’était vraisemblablement la raison.
Deuxième bug : le contrôle de solvabilité aveugle au taux de change
Une stratégie Pine peut déclarer une devise de compte différente de la devise de cotation du symbole : currency.INR pour trader une paire en USDT, par exemple. Avant de vérifier que vous avez les fonds pour passer un ordre, le courtier de TradingView convertit la valeur notionnelle de l’ordre dans la devise du compte au taux de change en vigueur, puis la compare à l’equity dans cette même devise.
Le garde-fou de solvabilité du moteur sautait cette conversion. Il comparait directement le notionnel en USDT à une equity libellée en INR, comme si le taux de change était de 1:1 : une stratégie déclarant currency.INR paraissait donc des dizaines de fois plus facile à financer qu’elle n’aurait dû (un USDT vaut plusieurs dizaines de roupies). Sur les scripts concernés, le moteur émettait environ deux fois plus de trades que TradingView, en admettant des entrées que le courtier de TradingView rejetait faute de fonds suffisants.
Le correctif applique le taux de change de la devise du compte à la marge requise avant le contrôle de solvabilité, au même point du pipeline d’ordres que TradingView, avec un taux fourni par le backtest (le moteur utilise 1:1 par défaut). Si vous avez backtesté avec une devise de compte autre que l’USD sur un symbole coté en USD ou en USDT, c’est ce bug qui gonflait discrètement votre nombre de trades.
Troisième bug : le trailing stop qui ne s’armait jamais
C’est celui que nous aurions le plus aimé qu’un utilisateur repère avant nous, parce qu’il échoue en silence. strategy.exit() propose deux façons de définir un trailing stop : trail_points, une distance relative au prix d’entrée, et trail_price, un prix d’activation absolu.
// armed correctly today; trail_price-only calls used to never arm at all
strategy.exit("TS", from_entry = "Long", trail_price = close * 1.05, trail_offset = 10)
La condition d’armement du moteur ne vérifiait que trail_points. Une sortie trailing définie uniquement par trail_price compilait sans erreur, s’exécutait sans erreur, et ne s’armait jamais : la position restait là, sans trailing stop actif, en silence, pendant tout le backtest. Pas d’exception, pas de ligne de log, pas de trade. La stratégie avait l’air protégée. Elle ne l’était pas.
Nous l’avons trouvé parce qu’un script partagé par la communauté, qui définit ses trailing stops avec trail_price seul, ne concordait que sur la moitié des trades de TradingView ; avec le correctif, la concordance est montée à 99,7 %. Aucune sonde du corpus ouvert n’utilisait trail_price : les chiffres du corpus ne pouvaient donc pas révéler l’écart. C’est précisément pour ce genre de trou qu’existe la catégorie validation, comme l’explique le billet sur la composition du corpus : des stratégies étroites et synthétiques, ni rentables ni réalistes, construites pour exercer une seule fonctionnalité Pine de façon isolée, afin qu’une régression de ce genre ne puisse pas se cacher derrière « les chiffres globaux avaient l’air bons ».
Le correctif arme le trailing stop dès que trail_points ou trail_price est présent. Si vous avez déjà écrit une stratégie Pine avec trail_price et que la courbe d’equity ressemblait étrangement à celle d’une stratégie sans aucun trailing stop, c’est qu’il n’y en avait effectivement pas, sur toutes les releases du moteur antérieures à la v0.10.14 (2026-07-02), la première à intégrer le correctif.
Pourquoi c’est tout l’intérêt d’un corpus
Aucun de ces trois bugs n’a été trouvé en revue de code. Ils l’ont été parce qu’une stratégie de la bonne forme est passée dans le moteur et a produit un chiffre qui ne concordait pas avec celui de TradingView. C’est toute la raison d’être d’un corpus versionné et tenu à part, de 167 stratégies, puis 252, et ce n’est pas fini, plutôt que d’une poignée de smoke tests, et ce qui nous pousse à soumettre aussi au même diff des scripts partagés par la communauté, d’où sont sortis ces trois bugs : un chiffre global impeccable peut masquer un bug qui change ce qu’une stratégie a gagné ou perdu, et la seule façon d’attraper ce genre de bug, c’est de faire passer toujours plus de formes de stratégies dans le même diff, face à la même vérité terrain.
Nous continuerons d’ajouter des sondes à mesure que nous trouverons des trous, et de publier les chiffres tels qu’ils sont, les bons comme l’unique anomalie.
Pour aller plus loin
- Parcourir la galerie : les 312 stratégies actuelles du corpus ouvert, chacune avec sa propre page qui détaille son résultat de parité et ses nombres de trades.
- Lire comment nous avons trouvé un bug de marge similaire — un autre bug, une autre limite, la même méthode : isoler, comparer, corriger.
- Backtester depuis Claude ou Cursor : le serveur MCP hébergé gratuit, ou le serveur Docker local sur vos propres données OHLCV.
- Comment nous mesurons la parité : les résultats actuels et leurs sources.