Diagnose and repair missing stock price bars
Repair missing stock bars by first deciding whether a bar should exist. Compare the downloaded keys with the appropriate market calendar, the security’s listing interval and verified security-status evidence. Separate closed days, pre-listing periods, suspensions, unresolved absences and supported acquisition failures. Only the last category belongs automatically in the targeted refetch queue.
This guide executes that classification and repairs one synthetic gap. It preserves dates with no justified observation instead of filling every weekday with the previous close. CoTrading’s corresponding repair workflow remains planned or unverified. The fixture receives its status evidence explicitly and does not query a real halt archive or infer a suspension from an empty provider response.
Build the expected-session reference carefully
Use a market-specific calendar and timezone for the requested interval. The NYSE calendar is an official example of holidays and session schedules; it is not a universal calendar for every security or market. Early closes still need their declared session treatment, while holidays should not generate an invented daily price.
Add the security’s valid listing interval, including identifier changes if they affect the requested line. A market can trade before a newly listed company exists or after its listing ends. Those dates are outside this security’s requested history even though the exchange is open.
Preserve the origin and effective dates of these inputs. A present-day list of active stocks cannot establish a historical listing interval. If the interval is unknown, classify the uncertainty rather than assuming the stock existed for every requested session. The synthetic example supplies those boundaries, so its calculation does not solve historical security-master acquisition.
Keep suspension evidence separate from calendar evidence
An exchange holiday concerns the market; a suspension concerns a particular security and time interval. A missing bar cannot establish either by itself. Nasdaq Trader’s halt page links current, search and historical halt resources and states the timezone used for displayed halt times. A real review must select the applicable dated evidence rather than treat the current page as proof of an old event.
Also distinguish a full-session absence from an intraday halt. A stock can trade before or after an intraday interruption and still have a valid daily bar. The fixture’s verified_suspended status explicitly means the supplied evidence supports no expected daily observation for that entire session. Extending the method to intraday status intervals needs additional logic.
If no reliable status history is available, leave the cause unknown. Do not infer suspension because price did not change, because volume is zero in another file or because the source request returned no rows. Those observations can motivate investigation but do not replace status evidence.
Classify the synthetic dates
The example covers 16–26 October 2026 with a supplied market-session set. Fictional stock AAA is listed from the 19th through the 23rd. Initial accepted bars exist on the 19th and 23rd. The 20th is supplied as a verified full-session suspension; the 21st is verified active with a recorded failed data request; the 22nd lacks enough evidence to explain its absence.
| Date | Diagnosis | Action |
|---|---|---|
| 16 October | before listing | no bar expected |
| 19 October | observed | retain source |
| 20 October | suspended | preserve status, no invented bar |
| 21 October | download gap | targeted retry |
| 22 October | unknown reason | investigate evidence |
| 23 October | observed | retain source |
| 24–25 October | market closed | no price row |
| 26 October | after listing interval | no bar expected |
This is a constructed diagnostic scenario, not a report about a real issuer. Its status and listing records must not be repurposed as actual market facts. The purpose is to exercise every branch while preserving a compact, inspectable input.
Turn classification into a repair request
if day not in market_sessions:
state = "market_closed"
elif day < listed_from:
state = "before_listing"
elif day > listed_until:
state = "after_listing"
elif status.get(day) == "verified_suspended":
state = "suspended"
elif status.get(day) == "verified_active" and day in failed_requests:
state = "download_gap"
else:
state = "unknown_reason"
The full fixture first retains accepted existing observations where appropriate. The repair queue includes only dates classified download_gap. Each real request should retain stock, date, frequency, basis, source and the evidence that the gap represents an acquisition failure rather than a legitimate absence.
Download the complete example. Use Python 3.12+, the standard library and synthetic inputs; run python R536.py. The source is docs/growth/research/round-5/examples/R536.py.
Actual output retries only 21 October. The mock repair adds close 11 with source synthetic-retry-1. Initial closes 10 on the 19th and 13 on the 23rd remain. The repaired price table therefore has three observations, while 22 October stays unknown and the other nonobserved statuses remain in the diagnostic table.
Check repairs without erasing legitimate absences
The script asserts the exact retry date, final accepted keys, retained original input and source of the repaired row. It also asserts that the suspended, unknown and weekend dates have no manufactured prices. A rectangular table with a row for every calendar day would fail this acceptance policy even if it looked easier to chart.
For real OHLCV repairs, validate the returned row under the same schema, units and session contract as the original table. An error message saved under a requested date is not a repaired bar. A response containing adjacent dates should not be silently substituted for the missing date. Reconcile accepted keys again after each retry.
If the request fails repeatedly, retain the acquisition gap with bounded attempts. If new evidence changes the classification, record the reason separately from the returned price. A suspected download failure that becomes a confirmed suspension is a diagnosis correction, not a price repair.
Test the unresolved-gap counterexample
The 22nd has no bar and no sufficient status evidence. Forward-filling the 19th’s or 21st’s close would create an observation without resolving why it is absent. The example deliberately leaves that date out of the accepted price table and in still_unknown. A missing cause should not be converted into a no-change trading day.
The 20th is different: the fixture has evidence supporting the suspension classification. It receives a resolved status but still no traded bar. Thus diagnosis completeness and price-row completeness are separate concepts. Filling zero volume and a repeated close would blur that distinction and could distort volatility, turnover and execution assumptions.
Deliver repaired prices and retained statuses together
Keep the original history, calendar reference, listing interval, security-status evidence, request-failure log, diagnostic table and accepted replacements. The price table and status table have different row counts by design. A downstream consumer should know which absences are explained and which remain unresolved before applying any return or alignment policy.
Reopen affected dates after new halt evidence, listing-history corrections or provider responses. Preserve prior diagnoses so the reviewer can see whether a newly available row repaired an acquisition failure or contradicted an earlier assumption. Do not silently overwrite a suspension label while inserting a bar.
For multiple stocks, execute the classification per security against the proper market calendar. The same market day can be observed for one company and unresolved for another. Bulk download coverage is a starting point; this process adds security-specific evidence and a targeted repair operation. Its success is supported history with visible remaining boundaries, not a perfectly filled grid of invented OHLCV.
Accept a replacement with evidence and unchanged scope
Each repair item should identify the requested key, the reason it was eligible for refetch and the source of the returned observation. Compare the accepted replacement with that request before merging. A returned row for another date or another price basis cannot close the original gap even if its values look plausible.
Preserve status history when a diagnosis changes. If new evidence shows that the stock was active on a previously suspected suspension date, reopen the missing-bar question. If a recorded download failure is later shown to fall outside the actual listing interval, close the acquisition task with that explanation rather than manufacturing a price.
The consumer should receive separate counts for requested dates, expected security sessions, accepted observations, explained absences and unresolved gaps. Those numbers are not interchangeable. A repaired dataset can have fewer price rows than market sessions without being defective, while a fully rectangular dataset can still contain unsupported synthetic bars. This distinction matters before volatility, turnover or strategy calculations consume the history.
FAQ
Is every missing weekday a download error?
No. Check market sessions, listing intervals and security status before forming a retry request.
Can the previous close be inserted when the cause is unknown?
Not as an observed bar. Any downstream synthetic filling policy must be separate and explicitly labeled.