Why is overfitting the enemy of algo-trading strategies, and how to avoid it

Why is overfitting the enemy of algo-trading strategies, and how to avoid it

2 months agoTutorials By Saleh Mir

What is overfitting?

Overfitting occurs when you tailor your strategy to historical market data excessively, capturing noise and random fluctuations as if they were meaningful trends. This leads to the strategy not working as expected when deployed for live trading.

Overfitting is likely the primary reason why people claim that backtesting is ineffective. However, in reality, backtesting does work; you simply need to ensure that you prevent overfitting, which is what this article is about.

Here are some ways to avoid overfitting:

Add noise to your data

Adding noise to your data can help you avoid overfitting. This can be done by adding random noise to your data, which will help prevent your model from being too closely tailored to your training data.

As a researcher, there are various methods for adding noise to your data. One approach is to carefully measure and add noise to your data. However, if you are using the Jesse framework with Python, the easiest way is to backtest your data on the same period on various exchanges.

For example, if your strategy is performing well on the Binance BTC-USDT symbol in 2020-2021, you can backtest it on the same period on exchanges like Bitfinex and Bybit. You could also try different symbols such as BTC-USD or BTC-EUR. The variations between these markets can be seen as natural noise.

If you find that your strategy performs well on all of these markets, you can have more confidence that it is not overfitting to the data. This can help improve the reliability of your strategy.

Use a large dataset

Use a large dataset to backtest your strategy. Keep in mind that this may not be possible for every coin, but it is usually easier to trade coins with a lot of data, such as BTC or ETH.

For example, if you trade the BTC-USD symbol, you have access to data since 2015 or so. However, if you try to backtest an alt-coin released just last year, then you won't have much data to work with.

Remove unnecessary features from your hyperparameters

Only keep the features that are necessary for your strategy. Remember that simple models usually work best. It is also very important that you completely understand your strategy.

So, if you add an enormous number of features to your parameters, chances are you are building a black box that you don't fully understand.

Cross-validation

This is an easy yet effective way to test the performance of your strategy. Simply divide your historical data into two parts: one for training and one for testing. This way, you can see how well your strategy performs on data that it has never seen before.

You can use the first 80% of your data for training and the last 20% for testing. For example, let's say you're trading BTC-USD and you have data since 2017. To ensure that your strategy performs well in recent times, you can use data from 2018 to 2024 to optimize your strategy. If you like the results, you can do a validation backtest on the remaining data from the beginning of 2017 to the end of 2017. If the numbers are still good, you can be more confident that your strategy is not overfitting to the data.

Paper trading

Try it in paper mode to see it in action in real time. Sometimes you'd be surprised how much insight you will gain by simply watching your strategy in action.

And sometimes, no matter how much practice you do, you can never be sure until you see it in action. Especially if you are a beginner, you should definitely paper trade your strategy before going live.

Simplicity is key

As an algotrader, it's important to stick with strategies that you fully understand. This is why it's best to avoid unnecessary complexity in your approach. In fact, many experienced traders swear by the effectiveness of simple strategies.

Remember that the more complex a strategy is, and the less you understand it, the more likely it is to overfit.

Looser hyperparameter values

If your strategy involves using an EMA, it's important to keep in mind that it may work well with a certain period, such as 20, but not as well with a slightly different period, like 22. This could be a sign that your strategy is overfit and may not perform well in different market conditions. While some variation in results is expected, too much of it is not ideal. Remember, market conditions are constantly changing and will never be exactly the same as before. They may appear similar, but there will always be differences to consider.

For example, consider the following code when using Jesse, where the value of fast_ema is set to 50 and slow_ema is set to 200. It can be 50, 51, 52, etc:

def hyperparameters(self):
    return [
        {'name': 'fast_ema', 'type': int, 'min': 50, 'max': 150, 'default': 50},
        {'name': 'slow_ema', 'type': int, 'min': 150, 'max': 250, 'default': 200},
    ]

However, I don't want to allow for that. I need it to be looser, so I could rewrite my code to be like this:

def hyperparameters(self):
    return [
        {'name': 'fast_ema', 'type': int, 'min': 5, 'max': 15, 'default': 5},
        {'name': 'slow_ema', 'type': int, 'min': 15, 'max': 25, 'default': 20},
    ]

As you can see, I divided all the values by 10. Now, in other parts of my strategy, when I'm using it, instead of simply using that value, I will use that value multiplied by 10, like this:

ema_fast = ta.ema(self.candles, self.hp['fast_ema'] * 10)

Not only does this help prevent overfitting, it also significantly increases the speed of my optimization session.

Conclusion

Avoid over-optimizing. You don't need to optimize every detail of your strategy. If you're satisfied with your strategy's performance, focus on execution instead of excessive tweaking to boost metrics before trading. Once you confirm the strategy works as intended, then optimize it further.

Realistic expectations are crucial. Dreaming of turning a small capital into millions through trading isn't practical.

Monte Carlo simulation and similar helpful methods for preventing overfitting will be added to Jesse. Subscribe to my newsletter for updates.

❤️ Like Jesse?

If you like this project, please consider supporting me for free by using my referral links.

It's a win-win, you get free discounts and bonuses, and it helps me to develop more features and content:


Thank you 🙏