A missing candle does not tell you whether the provider failed or the market was closed. First compare the export with a declared time window and the provider’s candle construction rules. This guide includes a local CSV checker that finds empty positions on a fixed time grid, repeated timestamps, conflicting prices and invalid rows. It does not invent quotes. The report helps you decide what to resolve before running a historical strategy test.

What should you establish before counting missing candles?

Record the instrument, provider, price basis and timeframe. Bid, Ask and midpoint candles represent different series; the label EUR/USD alone is insufficient. Compare equivalent bar-opening times. An export labelled by candle closing times will appear shifted against an opening-time export even when both contain valid prices.

The checker accepts the header timestamp,open,high,low,close. Each subsequent row has exactly five comma-separated fields. Write prices with a decimal point and without thousands separators. Quoted fields, additional columns and semicolon-separated exports require conversion first. The checker explicitly rejects these unsupported formats rather than guessing what an export means.

Use a full timestamp such as 2026-10-12T08:00:00Z or 2026-10-12T10:00:00+02:00. These represent the same instant. Seconds are required; up to three fractional-second digits are supported. A time without an offset does not identify the server’s time zone. Adding Z to a local server time changes its meaning rather than converting it to UTC. Check OANDA’s alignment parameters for its candle conventions.

Declare the first and last expected bar openings separately. Both boundaries are included: 08:00 through 08:11 at a one-minute interval means twelve expected timestamps. The grid is anchored at the first boundary and the last must fall exactly on it. This model covers equal elapsed-time intervals. A calendar month, or a local day whose duration changes with daylight saving, cannot be represented by a fixed 1,440-minute assumption.

How do you run the checker and reproduce the example?

Load the prepared CSV, enter an integer interval from 1 to 1,440 minutes and provide both boundaries. Analysis runs in your browser without sending the file’s contents or saving them in persistent storage. The file limit is 2 MiB, with limits of 100,000 rows and 100,000 expected grid positions. Split a longer period into documented, non-overlapping windows.

Prices allow up to 15 significant digits and 48 characters per field. More precise records are invalid, so rounding cannot conceal a conflict.

Check CSV time-grid coverage

The file is analysed locally; the tool neither sends it nor saves it persistently. Format: timestamp,open,high,low,close. Maximum 2 MiB. Timestamps require Z or an explicit offset.

Download clean example · Download diagnostic example

Fictional export: twelve rows do not establish completeness

The practice files are synthetic; they are not broker quotes or account data. Select M1, from 08:00 through 08:11 UTC. The clean file contains twelve different timestamps with no empty positions. The diagnostic file has twelve rows but only eight valid grid positions.

Expected diagnostic-file results
FindingMeaning in this example
4 empty positionsNo valid candle at 08:03, 08:04, 08:10 or 08:11.
2 repeated rowsThe 08:02 and 08:06 timestamps occur again.
1 conflicting-price groupTwo valid 08:06 candles have different OHLC values.
1 invalid rowThe 08:04 high is below its opening price.
1 off-grid row and 1 time reversal08:07:30 is not on M1; 08:08 appears after 08:09.

The longest gaps each contain two expected bar openings. A tie returns the first: 08:03–08:04. This is not a measured outage duration. Conditions in that interval still need to be explained using information outside the file.

Fictional M1 coverage: eight positions out of twelve

Fictional M1 coverage: eight positions out of twelveEmpty positions at 08:03, 08:04, 08:10 and 08:11. Two conflicting candles at 08:06. A labelled legend and text conclusion explain the result.Fictional M1 coverage: eight positions out of twelve✓08:00✓08:01✓08:02×08:03×08:04✓08:05?08:06✓08:07✓08:08✓08:09×08:10×08:11✓ Valid timestamp× No valid record? Price conflict
Conclusion: eight timestamps occupy the grid, but one still has conflicting prices. A total of twelve rows conceals four empty positions.

Which findings need investigation rather than automatic repair?

Coverage counts distinct valid timestamps, not rows. An identical duplicate adds no coverage. Conflicting but valid OHLC records at the same timestamp occupy one grid position and are also flagged as a conflict. Consequently, zero missing positions does not establish usable data. Resolve the price against its source while keeping both versions for comparison; the checker does not choose the higher, newer or more convenient value.

An invalid record contributes no coverage. The checker requires finite prices and checks that the high is no lower than the open, close or low, while the low is no higher than the other prices. Outside-window and off-grid records do not improve the result. All findings are counted, but only twenty examples per group are displayed so a damaged export cannot overwhelm the page.

Compare a weekend gap with the actual product’s session calendar. Investigate a gap inside a declared session using the download log and original source. OANDA’s candlestick documentation defines complete in terms of the candle period having ended; it does not certify a whole export as complete.

Do not fill an empty interval with the last price merely to produce a continuous chart. This creates synthetic candles and can alter indicators and stop execution. Sorting rows does not resolve conflicting OHLC. Preserve the original export and a separate correction record, including the reason and source for each change.

Do complete OHLC bars prove MT5 used recorded ticks?

No. Bars do not describe the entire price sequence. MetaQuotes documents generated ticks when a minute bar exists but its ticks are missing. Complete M1 CSV coverage therefore cannot prove the test used only recorded observations. Inspect the tester log, available tick period and selected model.

Also compare requested and actual test dates. History preparation documentation explains that insufficient history can shift the test start. When exporting with CopyRates, compare requested and returned counts because downloading may still be in progress. Our MT4 and MT5 testing guide addresses platform settings, while strategy testing methodology connects those checks to validation.

What to do tomorrow with the data report?

  1. Save the original export, checker settings and report. Add the instrument, price basis, time zone and session source. This gives another person enough information to repeat the same check instead of comparing unexplained charts with different underlying assumptions.
  2. Investigate the longest gap and every conflicting-price group. Compare source records and the download log. Document a confirmed closed session, or obtain a corrected export when data are missing. Run the same window again and retain the previous report.
  3. Run a short visual strategy test on the accepted interval. Inspect signals around flagged gaps, spread costs and execution order. Continue with data and signal checks in Python if building a separate engine. The report does not predict future returns.