Examples I've caught in my own code:
- Using the current bar's close for a signal, then entering at the same bar's open. Should be: signal on bar close, entry on the next bar.
- Daily high/low used during the day, when only the high/low so far was known.
- Indicators that repaint, like some zigzag or fractal versions, which change past values.
- Session levels in the wrong time zone. An "Asia range" that included an hour of London data because of a DST offset.
- Data cleaning that peeks. Removing outliers based on full-sample statistics.
- Run the strategy bar by bar in a simulated live mode and compare signals with the vectorised backtest. They must match exactly.
- Shift all signals one bar later. If performance collapses, check whether you were relying on information you couldn't have had.
- Print timestamps of all inputs to a signal for a few random trades and check by hand.