Eugen Soloviov

Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Articles

L'honnete resultat negatif : des dizaines de milliers de backtests, cinq majors, aucun edge robuste

L'honnete resultat negatif : des dizaines de milliers de backtests, cinq majors, aucun edge robuste

L'aboutissement de l'arc recherche-et-surapprentissage, et il se termine sur un resultat negatif — le bon. Une recherche mono-actif en double timeframe sur ETHUSDT a trouve une configuration valant +16,35 % en out-of-sample et +2,62 % sur un holdout intact ; le Deflated Sharpe Ratio, tenant compte des ~37 000 essais, l'a deflate a 0,00. Une passe cross-instrument sur cinq majors (ETH/BTC/SOL/BNB/XRP, ~1,18 M de barres 1m chacun), avec selection par la mediane out-of-sample, l'acheve pour de bon : DSR dual 0,24 / PBO 0,264, DSR triple 0,14 / PBO 0,327 — les deux echouent aux seuils. Le champion est profitable sur 1 des 5 symboles et negatif sur les autres. Voila a quoi sert l'appareillage anti-surapprentissage : vous empecher de deployer le meilleur du bruit en le prenant pour de l'alpha.

Prouver l'absence de look-ahead dans les backtests multi-timeframe : perturber le futur pour prouver que le passé ne peut pas le voir

Prouver l'absence de look-ahead dans les backtests multi-timeframe : perturber le futur pour prouver que le passé ne peut pas le voir

Les backtests multi-timeframe laissent fuiter le futur à travers une bougie de timeframe supérieur en cours de formation, dont la clôture finale n'existe pas encore. On ne peut pas se contenter d'une revue de code pour en avoir la certitude — il faut le tester. Nous reproduisons exactement la règle de bougie clôturée du bot live, puis prouvons l'absence de fuite avec une sonde à futur perturbé : on perturbe chaque bougie future et on vérifie que chaque signal et chaque trade passés restent identiques bit à bit. 25/25 tests de parité, et la sonde a du mordant.

Quand le GPU devient rentable : la roofline du sweep de paramètres, où un 167x d'affiche est en réalité 27x d'algorithme fois 6.2x de matériel

Quand le GPU devient rentable : la roofline du sweep de paramètres, où un 167x d'affiche est en réalité 27x d'algorithme fois 6.2x de matériel

L'avance du GPU sur le CPU grandit avec la taille de batch — de 54.5x à un combo par appel jusqu'à 359.6x à 61 sur notre précalcul d'indicateurs multi-timeframe — parce qu'un petit sweep ne peut pas amortir le surcoût de lancement des kernels et de transfert. Nous décomposons un 167x d'affiche en un gain algorithmique de 27x qui profite aussi au CPU et un gain matériel de 6.2x, montrons que la vraie avance GPU contre meilleur CPU n'est que de 3.2x en single-timeframe et de 6.2x en multi, et donnons un guide de décision sur la largeur qu'un sweep doit atteindre avant qu'un GPU mérite l'investissement.

Le piège de précision GPU : comment un backtest fp32 sur Apple Metal renvoie silencieusement des résultats aberrants

Le piège de précision GPU : comment un backtest fp32 sur Apple Metal renvoie silencieusement des résultats aberrants

Le GPU Metal d'Apple n'a pas de float64. Portez naïvement un backtest vectorisé dessus, et la tentante WMA en somme cumulée déborde en fp32 — erreur relative maximale de 211× — tout en continuant de tourner et de renvoyer des chiffres d'apparence plausible. Le correctif n'est pas plus de précision : c'est une formulation différente — une convolution directe par fenêtre glissante, fiable en fp32 jusqu'à 8×10⁻⁷ et 55.9× plus rapide que numba mono-thread. Le piège, l'arithmétique, et comment prouver qu'on n'y est pas tombé.

La porte de fidélité : le backtesting du grossier au fin vous trompe plus vite, à moins que le proxy bon marché ne classe comme l'évaluation coûteuse

La porte de fidélité : le backtesting du grossier au fin vous trompe plus vite, à moins que le proxy bon marché ne classe comme l'évaluation coûteuse

La recherche en drill-down / multi-fidélité (ASHA, élimination successive, Hyperband) filtre à bas coût des milliers de configurations et ne promeut que les survivants vers l'évaluation complète, coûteuse. C'est une véritable accélération — mais elle s'effondre silencieusement si le classement à basse fidélité contredit celui à haute fidélité. Nous avons mesuré la corrélation de rang par fold : à un seul fold, le ρ de Spearman peut valoir 0.03 (un classement presque aléatoire), puis grimper à 0.43, 0.67, 0.78, 0.91 à mesure que les folds s'accumulent. Le correctif est une porte obligatoire unique — mesurer d'abord ρ(bon marché, complet), puis relever automatiquement la fidélité minimale jusqu'au premier palier où ρ ≥ 0.5.

Recherche aléatoire vs recherche intelligente : le point de bascule, c'est le coût d'évaluation, pas l'algorithme

Recherche aléatoire vs recherche intelligente : le point de bascule, c'est le coût d'évaluation, pas l'algorithme

Quand un backtest est bon marché, un Sobol scrambled naïf l'emporte sur le débit brut — les échantillonneurs intelligents (TPE, CMA-ES, ASHA) paient une taxe ask/tell en Python qui les ralentit de 20x, si bien qu'ils évaluent bien moins de points à wall-clock égal et perdent. Rendez chaque évaluation coûteuse (multi-TF + folds walk-forward) et le point de bascule s'inverse. Nous avons mesuré les deux régimes, et pourquoi la fidélité du classement par fold (ρ@1 passant de 0.03 à 0.43) est la condition préalable pour que l'élagage soit rentable.

L'espace de parametres a deux axes : pourquoi la majeure partie de votre balayage devrait etre quasi gratuite

L'espace de parametres a deux axes : pourquoi la majeure partie de votre balayage devrait etre quasi gratuite

Tous les parametres ne coutent pas le meme prix a explorer. Les parametres d'une strategie se scindent en un axe couteux (les indicateurs, recalcules sur toute la serie) et un axe bon marche (les seuils de decision, un balayage en O(n) sur des signaux precalcules). Comme les indicateurs sont invariants aux seuils, on les calcule une seule fois puis on balaye des milliers de configurations de seuils a ~5 600 cfg/s, soit environ 1 600 fois moins cher que de recalculer par configuration. Une remise a plat du prix du fleau de la dimensionnalite.

La taxe du framework : quand votre bibliothèque de backtest est plus lente qu'une boucle pandas naïve

La taxe du framework : quand votre bibliothèque de backtest est plus lente qu'une boucle pandas naïve

Nous avons évalué huit moteurs de backtest sur un même balayage de paramètres identique — 150k barres, 80 combinaisons de croisements HMA, avec une parité du nombre de trades verrouillée à 2707. Deux des frameworks événementiels les plus populaires se sont révélés plus lents qu'une boucle pandas écrite à la main, tandis qu'un moteur vectorisé/compilé exécutait le même travail environ 13 000× plus vite. Une étude du surcoût par barre que les bibliothèques populaires n'ont jamais été conçues pour amortir.

The Probability of Backtest Overfitting: Did Your Search Beat a Coin Flip?

The Probability of Backtest Overfitting: Did Your Search Beat a Coin Flip?

The Deflated Sharpe Ratio prices the winning strategy; PBO prices the search that picked it. Combinatorially Symmetric Cross-Validation runs C(16,8) = 12,870 train/test splits over a 1000x200 performance matrix and asks: does the in-sample winner land in the bottom half out of sample? The catch almost everyone misses — PBO's null is 0.5, not 1. On 200 zero-edge strategies the best in-sample annualized Sharpe of 1.98 collapses to 0.06 out of sample and PBO = 0.476: a coin flip, fully overfit. Plant a real edge (annualized Sharpe 2.38) and PBO drops to 0.001, the in-sample 3.73 surviving to an out-of-sample 2.34. A moving-average grid on a pure random walk has no out-of-sample skill either — PBO 0.463 averaged over 60 matrices, statistically indistinguishable from the null — and on one representative matrix the mirage is vivid: a best in-sample Sharpe of 2.33 collapses to a median out-of-sample -0.22, PBO 0.573, a 63% chance of a loss.

The IPC Tax: Put the Backtest Engine Behind a Socket and Lose 13% — Almost None of It to the Socket

The IPC Tax: Put the Backtest Engine Behind a Socket and Lose 13% — Almost None of It to the Socket

We ported a numba backtest kernel line-for-line to Rust and called it across a process boundary four ways, with an equivalence gate confirming identical PnL to the last trade. Shipping the entire 1.2 MB price series through a Unix socket costs ~2 ms — about 0.1% of the job. JSON-encoding the same payload costs 1348x more than raw bytes, chatty per-combo calls re-ship the data 80 times, and a per-bar call pattern would pay 2.1 s of pure IPC on a 2.0 s job. The boundary is cheap; the tax is in how you cross it.

The Deflated Sharpe Ratio: How Many of Your Backtest 'Winners' Survive Multiple Testing?

The Deflated Sharpe Ratio: How Many of Your Backtest 'Winners' Survive Multiple Testing?

A parameter search is a machine for manufacturing luck. On pure noise — 1,000 strategies with zero true edge — the best annual Sharpe averages 1.63 and the naive significance test flags a discovery 100% of the time. We build controlled ground truth and show that the Deflated Sharpe Ratio, the Harvey-Liu haircut, and White's Reality Check restore honesty: false discoveries drop from 1.000 to 0.001-0.057, genuine edges above the noise ceiling are kept with power ~1 — and one real trap (correlated grids) where the raw DSR over-deflates and the verdict must be read across a whole band of effective-trial estimates, not one.

Objective-Function Design: The Metric You Optimize Secretly Picks Your Strategy

Objective-Function Design: The Metric You Optimize Secretly Picks Your Strategy

To search for the 'best' strategy you must first define 'best' — and that scalar silently chooses the winner. On synthetic data with a known edge (600 seeds, T=2000, 80 thresholds), a naive per-trade Sharpe crowns a lottery: it picks a sub-5%-exposure winner in 56% of seeds and degenerates in 57% — on the starkest seed, 8 trades posting an in-sample Sharpe of 21.09 that collapses to 0.13 out of sample. The honest repair is almost dull: measure on the full timeline, which never degenerates (out-of-sample 1.71). A trade-count (conf_k) shrinkage and an exposure floor can retrofit a per-trade metric, but even fully repaired they only match full-timeline Sharpe (1.70 vs 1.71) — never beat it. Goodhart's law, in a backtest, with controlled ground truth.