Live results do not match the backtest (3 bots)

Started by Frank Dzaebel on Dec 4, 2025 at 2:03 AM
767 views 3 replies
Posted Dec 4, 2025 at 2:03 AM
Hi all,

I am using this new bot service from the beginning and overall I am pleased with the results. Tom did a great job and worked hard on the bots. I am trading with all bots except of Goldilocks.

Overall I must say that my live results do almost never look like the backtest on the Aeromir website. E.g. yesterday (12/4/25) I had two winners with Breakout Guardian and Low Volume Hunter and the backtest shows two losses.

Well, hope Tom will read this and create bugfixes.

Best

Frank
Posted Dec 5, 2025 at 6:34 AM
Hi Frank,

i had MES winner and MNQ was an loser yesterday.. The results are different.

cheers
Gerd
Posted Dec 6, 2025 at 1:22 AM

Why Your Live Results May Differ From Backtests (And Why That's Normal)

If you've noticed that yesterday's live trade didn't match what the backtest shows for the same day, you're not alone — and nothing is broken. This is completely normal in algorithmic trading.

The key insight: Backtests show the statistical edge of a strategy over hundreds of trades. They're not meant to predict individual trade outcomes. What matters is whether your live performance tracks the backtest's average metrics (win rate, profit factor, average win/loss) over a meaningful sample — typically 50-100+ trades.


The Historical Data on the Website

The historical results shown on the Aeromir website are updated day-by-day as trades occur. However, there are a few things to keep in mind:

The strategy code has evolved. Over the past several months, I've made improvements and refinements to the strategies — better exit logic, refined filters, parameter adjustments, etc. The historical backtest data reflects whatever version of the code was running at that time. So if you run a fresh backtest today with the current version, it won't match the historical record exactly because the strategies themselves have improved.

This is actually a good thing — it means you're running better code than what generated some of those older results.


Why Individual Trades Differ

Data Feed Differences

Your broker's live data feed (Rithmic, Tradovate, CQG, etc.) is not identical to the historical data used in backtests. Historical data is often cleaned, aggregated, or timestamped slightly differently. Even a fraction-of-a-second difference in how ticks are recorded can cause:

  • A bar's high or low to be slightly different
  • A breakout level to trigger in one dataset but not the other
  • Entry signals to fire on different bars

Fill Price Variations

Backtests assume you get filled at your exact stop or limit price (or with a fixed slippage setting). In live trading, actual slippage varies based on:

  • Time of day (the open is sloppier than midday)
  • Volatility at that exact moment
  • Your broker's order routing
  • Market depth at your price level

A 1-tick difference on MES is $1.25 per contract — small, but enough to turn a scratch into a small winner or loser.

Network Latency

When your strategy calls EnterLong() in a backtest, the order fills instantly. In live trading, your order travels to NinjaTrader's servers, then to your broker, then to the exchange — and back. In fast-moving markets, price can move during that round trip.

Bar Building Timing

If you're running a strategy at 3:00 AM vs. 8:30 AM, the exact moment your platform considers a bar "closed" may differ slightly from the historical data, especially around session boundaries.


What If You Got a Trade That I Didn't (Or Vice Versa)?

This can happen, and it's usually caused by the same factors:

Data feed variations. Your broker's data feed may show a bar high/low or close that's slightly different from mine. If an entry condition is right on the edge — say, price just barely breaks above the lookback high — one data feed might show a valid breakout while another doesn't. A fraction of a tick can make the difference.

Timing of bar close. Even if we're both running on 5-minute bars, the exact millisecond your platform considers a bar "closed" may differ from mine. A fast-moving market can cover several ticks in that window.

Button states. All Aeromir strategies have on-chart buttons to enable/disable long and short trades. If you toggled one of these (even accidentally), you might take a trade I skipped, or vice versa.

Strategy start time. If you enabled the strategy mid-session while I had mine running from the open, our platforms may have different bar counts or indicator calculations for that day.

Different instruments. If you're running on MES and I'm tracking on ES (or vice versa), the price data isn't identical — micro contracts can have slightly different prints due to lower liquidity.


Code Review

I had Claude.ai perform a detailed code review of all four strategies (Goldilocks, Low Volume Hunter, Breakout Guardian, and Direction Momentum) specifically looking for anything that might cause backtest-to-live discrepancies. The findings:

  • Tick Replay is not required for any Aeromir strategy
  • All strategies process entry signals on bar close (deterministic behavior)
  • No code changes are needed

Settings to Verify

SettingRecommendation
Tick ReplayNot required for any Aeromir strategy
Calculate on bar closeAll Aeromir strategies use bar-close signals (default)
Session templateUse exchange defaults (CME US Index Futures, etc.)
Historical data providerSame provider you trade through, if possible

The Bottom Line

  • Don't expect yesterday's backtest to match yesterday's live trade
  • Do expect your results to approximate backtest averages over 50+ trades
  • Track your metrics — if your win rate and profit factor are in the ballpark after a reasonable sample size, the strategy is performing as designed

If you're seeing dramatically different results over a meaningful sample (not just a day or two), post your settings and trade log and we'll help troubleshoot.

Posted Dec 17, 2025 at 8:25 AM
Tom Nunamaker said:

Why Your Live Results May Differ From Backtests (And Why That's Normal)

If you've noticed that yesterday's live trade didn't match what the backtest shows for the same day, you're not alone — and nothing is broken. This is completely normal in algorithmic trading.

The key insight: Backtests show the statistical edge of a strategy over hundreds of trades. They're not meant to predict individual trade outcomes. What matters is whether your live performance tracks the backtest's average metrics (win rate, profit factor, average win/loss) over a meaningful sample — typically 50-100+ trades.


The Historical Data on the Website

The historical results shown on the Aeromir website are updated day-by-day as trades occur. However, there are a few things to keep in mind:

The strategy code has evolved. Over the past several months, I've made improvements and refinements to the strategies — better exit logic, refined filters, parameter adjustments, etc. The historical backtest data reflects whatever version of the code was running at that time. So if you run a fresh backtest today with the current version, it won't match the historical record exactly because the strategies themselves have improved.

This is actually a good thing — it means you're running better code than what generated some of those older results.


Why Individual Trades Differ

Data Feed Differences

Your broker's live data feed (Rithmic, Tradovate, CQG, etc.) is not identical to the historical data used in backtests. Historical data is often cleaned, aggregated, or timestamped slightly differently. Even a fraction-of-a-second difference in how ticks are recorded can cause:

  • A bar's high or low to be slightly different
  • A breakout level to trigger in one dataset but not the other
  • Entry signals to fire on different bars

Fill Price Variations

Backtests assume you get filled at your exact stop or limit price (or with a fixed slippage setting). In live trading, actual slippage varies based on:

  • Time of day (the open is sloppier than midday)
  • Volatility at that exact moment
  • Your broker's order routing
  • Market depth at your price level

A 1-tick difference on MES is $1.25 per contract — small, but enough to turn a scratch into a small winner or loser.

Network Latency

When your strategy calls EnterLong() in a backtest, the order fills instantly. In live trading, your order travels to NinjaTrader's servers, then to your broker, then to the exchange — and back. In fast-moving markets, price can move during that round trip.

Bar Building Timing

If you're running a strategy at 3:00 AM vs. 8:30 AM, the exact moment your platform considers a bar "closed" may differ slightly from the historical data, especially around session boundaries.


What If You Got a Trade That I Didn't (Or Vice Versa)?

This can happen, and it's usually caused by the same factors:

Data feed variations. Your broker's data feed may show a bar high/low or close that's slightly different from mine. If an entry condition is right on the edge — say, price just barely breaks above the lookback high — one data feed might show a valid breakout while another doesn't. A fraction of a tick can make the difference.

Timing of bar close. Even if we're both running on 5-minute bars, the exact millisecond your platform considers a bar "closed" may differ from mine. A fast-moving market can cover several ticks in that window.

Button states. All Aeromir strategies have on-chart buttons to enable/disable long and short trades. If you toggled one of these (even accidentally), you might take a trade I skipped, or vice versa.

Strategy start time. If you enabled the strategy mid-session while I had mine running from the open, our platforms may have different bar counts or indicator calculations for that day.

Different instruments. If you're running on MES and I'm tracking on ES (or vice versa), the price data isn't identical — micro contracts can have slightly different prints due to lower liquidity.


Code Review

I had Claude.ai perform a detailed code review of all four strategies (Goldilocks, Low Volume Hunter, Breakout Guardian, and Direction Momentum) specifically looking for anything that might cause backtest-to-live discrepancies. The findings:

  • Tick Replay is not required for any Aeromir strategy
  • All strategies process entry signals on bar close (deterministic behavior)
  • No code changes are needed

Settings to Verify

SettingRecommendation
Tick ReplayNot required for any Aeromir strategy
Calculate on bar closeAll Aeromir strategies use bar-close signals (default)
Session templateUse exchange defaults (CME US Index Futures, etc.)
Historical data providerSame provider you trade through, if possible

The Bottom Line

  • Don't expect yesterday's backtest to match yesterday's live trade
  • Do expect your results to approximate backtest averages over 50+ trades
  • Track your metrics — if your win rate and profit factor are in the ballpark after a reasonable sample size, the strategy is performing as designed

If you're seeing dramatically different results over a meaningful sample (not just a day or two), post your settings and trade log and we'll help troubleshoot.

Thanks for this detail Tom. Can anyone help me to find where to i can check the "Settings to Verify" in the above post. Checked the Strategy parameters as well as Tools/Settings in NT but am not seeing these. Thanks

Want to join the discussion?

Login or create an account to reply to this thread.