Evolving a neural network trading bot #711
Replies: 2 comments
|
very cool! thanks for posting this here! |
|
Nice experiment. One thing I would watch carefully is keeping the optimization objective and the validation protocol very separate. With direct ANN-weight search, the optimizer can quickly learn quirks of the backtest window, especially on short 1s subperiods. Walk-forward splits, explicit cost/slippage grids, and a very boring baseline usually make the result easier to trust. I maintain a small research-only PyTorch stack for multi-factor/backtest validation, and the public reports there have been a useful reminder of the same thing: after costs, simple baselines are harder to beat than they look. Sharing only as a reference for structuring factor/model/backtest/validation reports, not as a trading-signal repo: https://github.com/initial-d/ml-quant-trading |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I played with direct ANN weights encoding a bit to evolve a NN trading bot.
Currenty there are 3 objectives:Number of positions (to maximize) — encourages bot to do something2025-05-13 UPD: the objectives now are
[returns in each subperiod] ++ [total return].At first, I had pure Python implementation of backtesting engine/code, with PyTorch in
inference_modefor NN. This was slow as hell. I'm backtesting on 1s Binance Spot historic data (candles), and it were taking 30-60 seconds to backtest 100 individuals over just 40-60 minutes of data (usingmultiprocessing.Pool).I decided to rewrite backtesting code and NN implementation (I need only forward pass, no autograd/backprop, so it is very little code) in C++, and leave Python just for
pymooalgorithms. This turned out to be more than 1000 times faster. It takes ~40 seconds to backtest 100 individuals over a month of data (usingmultiprocessing.pool.ThreadPool).Initially I had terrible overfitting: starting backtesting just 1 second (1 candle) later than before were turning almost all "profitable" individuals into non-profitable. Now I split the backtesting period into a few subperiods and try to make the model profitable in EVERY subperiod (I backtest in each subperiod independently, i.e. start with zero RNN state etc.). This seems to help, at least to some degree.
See https://github.com/languagelawyer/genetic_trade
All reactions