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
TWAP vs VWAP vs POV: picking an execution benchmark (and knowing when each lies to you)
TWAP, VWAP and POV are bets on a volume forecast. We dissect each scheduler's hidden assumptions, build crypto intraday volume curves, and run all three head-to-head on replayed L2 data.
Almgren-Chriss Without the Hand-Waving: Optimal Execution You Can Implement in an Afternoon
Full derivation of the Almgren-Chriss optimal execution model: linear impact, the sinh/cosh trajectory, the efficient frontier, and working Python for calibrating eta, gamma, and sigma from Binance L2 and trade data.
The Honest Negative: Tens of Thousands of Backtests, Five Majors, No Robust Edge
The capstone of the search-and-overfit arc, and it ends in a negative result — the correct one. A single-symbol dual-timeframe search on ETHUSDT found a config worth +16.35% out-of-sample and +2.62% on an untouched holdout; the Deflated Sharpe Ratio, accounting for ~37,000 trials, deflated it to 0.00. A cross-instrument pass over five majors (ETH/BTC/SOL/BNB/XRP, ~1.18M 1m bars each), selecting by median out-of-sample, kills it for good: dual DSR 0.24 / PBO 0.264, triple DSR 0.14 / PBO 0.327 — both fail the gates. The champion is profitable on 1 of 5 symbols and negative on the rest. This is what the anti-overfit apparatus is for: to stop you from shipping the best of noise as alpha.
Proving No Look-Ahead in Multi-Timeframe Backtests: Perturb the Future, Prove the Past Can't See It
Multi-timeframe backtests leak the future through a forming higher-timeframe bar whose final close does not exist yet. You cannot code-review your way to confidence — you have to test it. We reproduce the live bot's closed-bar rule exactly, then prove no leakage with a shifted-future probe: perturb every future bar and assert every past signal and trade is bitwise unchanged. 25/25 parity checks, and the probe has teeth.
When the GPU Pays Off: The Parameter-Sweep Roofline, Where a Headline 167x Is Really 27x Algorithm Times 6.2x Hardware
The GPU's lead over CPU grows with batch size — 54.5x at one combo per call up to 359.6x at 61 on our multi-timeframe indicator precompute — because a small sweep cannot amortize kernel-launch and transfer overhead. We decompose a headline 167x into a 27x algorithmic win that also helps the CPU and a 6.2x hardware win, show the true GPU-vs-best-CPU lead is only 3.2x single-timeframe and 6.2x multi, and give a decision guide for how wide a sweep must be before a GPU is worth buying into.
The GPU Precision Trap: How an fp32 Backtest on Apple Metal Silently Returns Garbage
Apple's Metal GPU has no float64. Port a vectorized backtest to it naively and the tempting prefix-sum WMA overflows fp32 — max relative error 211× — yet it still runs and returns plausible-looking numbers. The fix is not more precision; it is a different formulation: a direct windowed convolution, fp32-safe to 8×10⁻⁷ and 55.9× faster than single-thread numba. The trap, the arithmetic, and how to prove you didn't fall in.
The Fidelity Gate: Coarse-to-Fine Backtesting Fools You Faster Unless the Cheap Proxy Ranks Like the Expensive One
Drill-down / multi-fidelity search (ASHA, successive halving, Hyperband) screens thousands of configs cheaply and promotes only survivors to the expensive full evaluation. It is a genuine speedup — but it collapses silently if the low-fidelity ranking disagrees with the high-fidelity one. We measured the fold-rank correlation: at one fold Spearman ρ can be 0.03 (ranks almost randomly), climbing to 0.43, 0.67, 0.78, 0.91 as folds accumulate. The fix is one mandatory gate — measure ρ(cheap, full) first, and auto-raise the minimum fidelity to the first rung where ρ ≥ 0.5.
Random vs Smart Search: The Crossover Is Eval Cost, Not the Algorithm
When one backtest is cheap, dumb scrambled Sobol wins on raw throughput — smart samplers (TPE, CMA-ES, ASHA) pay a Python ask/tell tax that drops them 20x, so they evaluate far fewer points at equal wall-clock and lose. Make each eval expensive (multi-TF + walk-forward folds) and the crossover flips. We measured both regimes, and why fold-rank fidelity (ρ@1 rising 0.03→0.43) is the precondition for pruning to pay off.
The Two-Axis Parameter Space: Why Most of Your Sweep Should Be Nearly Free
Not all parameters cost the same to search. A strategy's parameters split into an expensive axis (indicators — recomputed over the whole series) and a cheap axis (decision thresholds — an O(n) pass over precomputed signals). Because indicators are invariant to thresholds, you compute them once and sweep thousands of threshold configs at ~5,600 cfg/s — roughly 1,600x cheaper than recomputing per config. A re-pricing of the curse of dimensionality.
The Framework Tax: When Your Backtest Library Is Slower Than a Naive Pandas Loop
We benchmarked eight backtest engines on one identical parameter sweep — 150k bars, 80 HMA-cross combos, trade-count parity locked at 2707. Two of the most popular event-driven frameworks came in slower than a hand-written pandas loop, while a vectorized/compiled engine ran the same work ~13,000× faster. A study of the per-bar overhead that popular libraries were never built to amortize.
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
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.