VALYNOXSTRATEGY RESEARCH TECHNOLOGY
AlphaPrimeAlphaPrime
ACADEMY / DATA

Backtest data quality: gaps, bad ticks, time zones and rolls

Missing bars, bad prints, shifted timestamps and badly joined contract rolls each change which trades a backtest takes and at what price. Check bar counts, spikes, session times and roll dates before you import data, not after the research.

By · Published · updated · Editorial policy

Contents
  1. What can be wrong in historical bar data?
  2. How do missing bars and holidays change a backtest?
  3. What do bad prints and spikes do to results?
  4. How do time zones and daylight saving shift your bars?
  5. How should continuous futures contracts be rolled and adjusted?
  6. Why fix the data before a strategy search?
  7. What should you check before importing data?
  8. Frequently asked questions

What can be wrong in historical bar data?

Historical bar data can have four main faults: missing bars, bad prints, shifted timestamps and badly joined contract rolls. Each one changes which trades a backtest takes and at what price. A strategy search tends to reward the errors that flatter results. Check bar counts, price spikes, session times and roll dates before you import the data.

A price bar is one row of data that holds the open, high, low, close and volume of a market for a fixed period, such as five minutes or one day. A backtest reads these rows one by one and decides on each bar whether to trade. If a row is missing, wrong or in the wrong place, the backtest trades in a market that never existed.

Think of planning a drive with a map that has a few roads missing and one bridge drawn where there is none. The route planner cannot tell that the bridge is fake. It uses the bridge because it is the shortest way. A strategy search treats a fake price the same way.

ProblemWhat you see in the dataWhat it does to the backtest
Missing barsFewer bars than the session should haveIndicators cover more real time than their settings suggest, session exits move, and fake gaps appear
Bad printsOne bar with a high or low far from the othersOrder fills that could not have happened, and inflated volatility readings
Time zone shiftsThe session open moves by an hour on some datesTime-of-day rules trade a different part of the session
Roll joinsA price jump on the day the contract changesProfit or loss that no trader earned, and false signals

How do missing bars and holidays change a backtest?

Missing bars stretch indicators over more real time and move session-based exits, so the backtest no longer matches the market you would have traded. A missing bar is a period that should have a bar in the data but does not.

Not every gap is an error. Three kinds of gap look alike in the file:

  • Exchange holidays and shortened sessions. The market was closed or closed early. These gaps are correct and should stay.
  • Quiet periods in thin markets. Some data sources print no bar when no trade happened. The market was open, but nothing traded.
  • Data outages. The market traded, but the data source or your own recording missed it. These gaps are the errors.

An outage changes results in three ways. A 20-bar moving average that spans an outage covers more hours than its settings suggest. A rule that exits on the last bar of the session exits early if the last bars are missing. And when bars return after the outage, the price jump looks like a real gap, so gap-based strategies trade it.

To find outages, work out how many bars a full session should have and count the bars on each day. For example, the TAIEX futures day session runs from 08:45 to 13:45 Taiwan time. That is 60 five-minute bars if each bar covers a full five minutes. List every day below the expected count, then match the list against the exchange holiday calendar. What remains is your outage list. The guide to market holidays in backtests explains how holiday gaps and reopenings affect signals.

What do bad prints and spikes do to results?

A single bad print can create a trade that could never have filled, and a strategy search will often rank that trade near the top. A bad print is a recorded trade price far away from where the market really traded. Typical causes are a feed error, a trade the exchange later cancelled, or a mistake in a source file.

On a bar chart, a bad print usually shows as one long wick. A wick is the thin line above or below the bar body that marks the high or the low. Limit orders and stop orders are the most exposed, because the backtest fills them as soon as the bar's high or low touches the order price.

Hypothetical example

An index future trades near 18,000 points. A mean-reversion strategy places a buy limit order 150 points below the market, at 17,850. One five-minute bar has a bad print of 17,600 as its low, while every real trade in that bar was between 17,990 and 18,010. The backtest fills the buy at 17,850. The bar closes at 18,000, and the strategy exits on the next bar near 18,000. The backtest records a gain of 150 points on a trade that no broker could have filled. If the strategy has only 40 trades in total, this one fake trade can be a large part of its whole result.

One bad print fills a limit order: eight hypothetical five-minute bars trade near 18k points, one bar has a false wick down to 17.6k that crosses a buy limit at 17.85k, and the backtest records a fill that real prices never reached A bad print fills the order Hypothetical 5-minute bars Real ~18k Buy limit 17.85k Bad print 17.6k Backtest books a fake +150 points. So: check wicks on top winners.
The hypothetical example above: one bad print touches a limit order that real prices never reached, and the backtest records a trade.

Bad prints also distort indicators. The Average True Range (ATR) is built from each bar's high and low, so one spike raises it for many bars afterwards. That changes any stop or position size based on ATR. Channel rules that use the highest high or lowest low of a period keep the false value for their whole lookback.

Three scans find most bad prints:

  • Range scan. Flag bars whose high-to-low range is several times the average range of the bars around them. Five times is a reasonable starting point; adjust it for each market.
  • Jump-and-return scan. Flag bars where the close jumps far from the previous close and the next bar returns to the old level. A real fast move can do this too, so treat these bars as bars to inspect, not bars to delete.
  • Consistency scan. The high must be at least as high as the open and the close, and the low at least as low as both. Zero prices are errors.

When a print is confirmed as bad, rebuild that bar from the clean trades. If you only have bars, set its high and low to the higher and lower of its open and close. Write down every change so you can undo it. Leave real fast moves in place; they are information the strategy needs.

How do time zones and daylight saving shift your bars?

If your timestamps follow the wrong clock, any rule tied to a time of day trades a different part of the session on some dates. A time zone is the clock a timestamp is written in, such as exchange local time, UTC or your own local time.

Daylight saving time moves clocks by one hour twice a year, and regions switch on different dates. The United States switches on the second Sunday of March and the first Sunday of November. The European Union switches on the last Sunday of March and the last Sunday of October. Taiwan does not use daylight saving time. So the time difference between Taipei and New York changes by one hour during the year.

A concrete case: the US stock market opens at 09:30 New York time. In Taiwan time, that is 21:30 between the second Sunday of March and the first Sunday of November, and 22:30 for the rest of the year. A rule written as "trade only between 21:30 and 22:30 Taiwan time" covers the first hour after the US open for part of the year and the hour before it for the rest.

The US open moves an hour in Taiwan time: in summer it falls at 21:30 Taiwan time, at the start of a fixed 21:30 to 22:30 window, and in winter at 22:30, at the end of the same window, so the window covers different market hours The US open moves an hour Taiwan time; cyan = fixed rule window Summer US open Winter US open 20:00 21:30 22:30 24:00 Same window, different market hour. So: store bars in exchange time.
The US open at 09:30 New York time falls at different Taiwan clock times in summer and winter, so a fixed Taiwan-time window covers different market hours.

Two more timestamp problems are common:

  • Bar labels. Some sources label a bar with its start time, others with its end time. A bar marked 10:00 can mean 09:55 to 10:00 or 10:00 to 10:05. If you merge two series that use different labels, one of them sees one bar into the future.
  • Double conversion. A file already stored in local time is converted again during import, and every bar shifts by the full time zone difference.

A quick check: chart the average volume for each time of day, with one line per month. In exchange local time, the volume peak at the main open stays at the same clock time all year. If the peak jumps by an hour in March and November, the timestamps are not in exchange time. For how session choice changes bars, see night sessions in futures backtests.

How should continuous futures contracts be rolled and adjusted?

Choose the roll rule and the adjustment method on purpose, because each one changes either the prices or the profits your backtest shows. A continuous contract is a long price series built by joining one futures contract after another as each one nears expiry. The roll is the point where the series switches from the expiring contract to the next one.

Contracts expire on a fixed schedule. ES and NQ have quarterly contracts that expire in March, June, September and December. TAIEX futures have monthly contracts that settle on the third Wednesday of the delivery month. Data sources usually roll a fixed number of days before expiry, or when trading volume moves to the next contract. The TAIEX futures backtest checklist covers the other settings specific to that market.

On the roll day, the two contracts usually trade at different prices. How the series handles that difference is the adjustment method:

MethodWhat it doesWhat stays correctWhat changesSuits rules that
UnadjustedJoins prices as they tradedReal price levelsA jump at every roll, with profit or loss nobody earnedUse fixed price levels and close positions before each roll
Back-adjustedShifts all older prices by the roll gap in pointsPoint moves and point-based profitOlder price levels; very long histories can even fall below zeroUse stops and targets in points or ticks
Ratio-adjustedMultiplies all older prices by one factorPercentage movesPoint distances in older dataUse percentage-based moves

The ratio method uses one number: factor = Pnew ÷ Pold. Pnew is the price of the new contract at the roll, and Pold is the price of the expiring contract at the same moment. Every price before the roll is multiplied by this factor.

Hypothetical example

At the roll, the expiring contract trades at 18,000 and the new one at 18,100, a gap of 100 points. Unadjusted, a long position held across the roll shows a gain of 100 points that no trader earned, and a breakout rule may see a new high. Back-adjusted, every earlier price gets 100 points added, so a close of 15,000 a year earlier becomes 15,100. Ratio-adjusted, every earlier price is multiplied by 18,100 ÷ 18,000, about 1.0056, so the same 15,000 becomes about 15,083.

Three ways to join a contract roll with a hypothetical 100-point gap: unadjusted prices show a fake 100-point jump at the roll, back-adjusted prices add 100 points to all older prices, and ratio-adjusted prices multiply older prices by about 1.0056 Three ways to join a roll Hypothetical 100-point roll gap Roll Unadjusted fake +100 Back-adjusted +100 pts Ratio-adjusted × 1.0056 No method keeps everything correct. So: match it to how rules measure.
The same roll handled three ways: unadjusted keeps real prices but adds a jump, while the two adjusted series remove the jump by changing older prices.

In live trading, a roll means selling one contract and buying the next, with commission and slippage on both trades. A continuous series hides those two trades. For strategies that hold positions for weeks, count the roll trades in your cost estimate.

A strategy search finds data errors faster than you do, because a variant that happens to trade at a bad price rises to the top of the ranking. When you test many rule and parameter combinations, some will line up by chance with a spike, a roll jump or a missing hour. Their results look strong for a reason that will never repeat. This is one form of overfitting. Overfitting is when a strategy's rules fit the noise in past data instead of a pattern that repeats. The article on overfitting in strategy generation covers it in depth.

Two signs point to a data error rather than an edge. First, one trade makes a large share of the total profit. Second, the best trades cluster on a few dates. If you see either sign, check those dates in the raw data before anything else.

What should you check before importing data?

Run these checks once for each data file, in this order, and keep a short record of what you found and changed.

  1. Clock and labels. Confirm the time zone of the timestamps and whether each bar is labelled with its start or end time.
  2. Bar counts. Count bars per session, list the short days, and match them against the exchange holiday calendar. The rest are outages.
  3. Duplicates and order. Look for repeated timestamps and rows out of time order, which often appear after files are merged.
  4. Price consistency. Check that every high and low contains the open and the close, and that no prices are zero.
  5. Spikes. Run the range scan and the jump-and-return scan, then inspect each flagged bar.
  6. Rolls. List the largest bar-to-bar jumps. In unadjusted data, they should line up with roll dates. Find out which roll rule and which adjustment method the series uses.
  7. Second source. Compare a sample, such as daily closes for one week in each year, with a second data source.
  8. Version record. Note the file name, source, date range and every change, so any later result can be traced to its data.

Then make the backtest settings match the data you checked: the same session times and the same bar size. In AlphaPrime (Valynox), the research scope of GPU backtesting lets you set the data resolution and the trading sessions, so the research runs on the session you verified.

What this means if you use AlphaPrime: run the checklist on your bar data before you import it, and set the trading sessions to match what you verified. If you correct the data later, keep results from each data version in separate batches and revalidate the strategies you kept, so every comparison uses the same data.

Frequently asked questions

What is a bad tick in futures historical data?

A bad tick is a recorded trade price far from where the market really traded, caused by a feed error, a cancelled trade or a file mistake. It usually shows as one long wick on a bar chart. In a backtest it can fill limit or stop orders that real prices never reached, so it creates trades that could not have happened.

Should I use back-adjusted or ratio-adjusted continuous contract data?

Use back-adjusted data when your rules measure moves in points or ticks, because it keeps point differences correct. Use ratio-adjusted data when your rules measure percentage moves, because it keeps percentage changes correct. Use unadjusted data for rules that compare with fixed price levels, and close positions before each roll.

How do I find missing bars in my historical data?

Work out how many bars a full session should contain at your bar size, then count the bars on each day. List the days below the expected count and remove exchange holidays and known shortened sessions. The days that remain are likely data outages to fill from a second source or to mark in your records.

Does daylight saving time affect futures backtests?

It does when timestamps are in a clock that changes on different dates from the exchange, or when rules use fixed clock times. For example, the US open at 09:30 New York time is 21:30 Taiwan time in summer and 22:30 in winter, because Taiwan does not use daylight saving time. Storing data in exchange local time keeps session opens at the same clock time all year.

What AlphaPrime does here

AlphaPrime's GPU backtesting runs research on the bar data you import, with data resolution, next-bar execution, fees and slippage and trading sessions set in the research scope. The strategy databank keeps results organized with search and sort, classification, batch management and revalidation, so strategies can be rechecked after a data correction.

See plans and pricing