In this video, NeuroTrader walks through the process he uses to develop trading strategies in Python and, crucially, to weed out the ones that only look profitable. The uncomfortable premise: the overwhelming majority of strategies that produce a beautiful backtest curve fall apart the moment they meet real money. A great in-sample backtest, on its own, proves almost nothing.
The problem: overfitting hides in every good-looking backtest
When you optimize a strategy’s parameters against historical data, some combination will always fit that particular slice of the past well — even if the market moves were pure noise. The optimizer is very good at memorizing the past and very bad at telling you whether it found a real edge or just curve-fit random wiggles. The whole point of the process below is to separate genuine structure from luck.
What a permutation test actually does
A Monte Carlo permutation test (MCPT) creates thousands of randomized versions of the price series. Each version keeps the same statistical fingerprint — the distribution of returns, the volatility — but scrambles the order, destroying any real trend, momentum, or pattern the strategy might exploit. You then run (or re-optimize) the strategy on each shuffled series and record how well it does.
That gives you a distribution of results under the null hypothesis of “no real edge.” Compare your strategy’s performance on the real data against that distribution. The p-value is simply the fraction of random runs that did as well or better than reality. A low p-value (say, below 0.05) means it would be rare for pure noise to match your result — evidence the edge is real. A high p-value means your optimizer gets similar numbers from random data, which is a red flag for overfitting.
The four-step process
- In-sample excellence. First, optimize the strategy on in-sample data and confirm it has a genuinely strong, tradable edge there. This is necessary but nowhere near sufficient.
- In-sample permutation test. Re-run the entire optimization on ~1,000 permuted price series and compute a p-value. This asks: could my optimization have produced these results on random data? If yes, the “edge” is really overfitting.
- Walk-forward test. Repeatedly optimize on a rolling window and then trade only the next, unseen out-of-sample window, stitching those out-of-sample segments together. This mimics how you would actually deploy and periodically re-tune a strategy.
- Walk-forward permutation test. Run the whole walk-forward procedure on permuted data many times. The resulting p-value is the strongest evidence on offer that the out-of-sample performance is distinguishable from randomness.
The video demonstrates all of this with concrete Python code, using a Donchian-channel breakout and a tree-based strategy as worked examples. The accompanying code is open source at github.com/neurotrader888/mcpt.
Warnings that are easy to miss
- Selection bias breaks the p-value. If you generate thousands of strategy variants and only permutation-test the single best one, something will pass by chance. Test your process, not a cherry-picked winner.
- Permutation tests don’t model regime change. Shuffling existing moves stresses trade sequencing and structure, not entirely new market conditions. It is one layer of defense, not a guarantee.
- In-sample results alone are meaningless. Treat a pretty backtest as a hypothesis to be attacked, not a result to be trusted.
Summary of the video “How I Develop Trading Strategies | Permutation Tests and Trading Strategy Development with Python” by NeuroTrader. Watch the full walkthrough above for the code and detailed explanations.
Leave a Reply
You must be logged in to post a comment.