algorithmic trading / backtesting / lookahead bias / python / software engineering
What Is Lookahead Bias? Why Your Vectorized Backtest Is Lying
A ten-line vectorized backtest in Python can produce an equity curve that goes straight up and still be wrong. Shift one column by a single day and today's signal can see tomorrow's price. That is lookahead bias, and vectorized code hides it well.
Fees are easy to subtract from a column. The hard part is a rule like "trim twenty percent of any position that's up fifty percent," which depends on when you bought and whether you already trimmed. An event-driven backtester replays the market one bar at a time: each bar wakes up the strategy, the strategy sends an order, and the fill updates the portfolio, so the code can only see the past. Part 1 of a 3-part series on how the NexusTrade engine was built.
Transcript
0:00You want to know if your trading idea makes money, so you write a backtest in ten lines of Python.
0:04You load ten years of prices into a numpy array and compute a moving average over the whole column at once.
0:10When the price is above the average, you're in.
0:13You multiply that by tomorrow's return, add it all up, and the chart goes straight up.
0:17That chart is lying to you.
0:19If you shift one column by a single day, today's signal can see tomorrow's price.
0:24That's called lookahead bias, and vectorized code hides it perfectly.
0:28You can subtract fees from a column.
0:30The hard part is a rule like "trim twenty percent of any position that's up fifty percent."
0:35That depends on when you bought it and whether you already trimmed it, and a column of numbers has no idea what you own.
0:41Real engines replay the market one bar at a time.
0:45Each bar is an event that wakes up your strategy, the strategy sends an order, and the order becomes a fill that updates your portfolio.
0:52Your code can only see the past, because the future hasn't happened yet.
0:56That's an event-driven backtester, and it's how I built mine.
0:59It also gave me a brand new problem.
1:01Follow for part two.
Join the conversation
Loading conversation…