Is that a zero, a null, or a day that never happened?
Three different absences. They look nearly identical on a chart and they mean opposite things, and treating one as another is how a correct dataset produces a wrong answer.
null means "we do not have this"
A null is a statement about the data, not about the market. The spec marks the fields where it is legal: intraday volume is typed integer | null, and OperatingMIC on the exchange list is typed string | null. That is a promise made in advance — your parser must handle it.
/fundamentals/{ticker} uses nulls heavily and correctly. An ETF has no income statement; the fields are null because they do not apply, not because the value is zero.
0 means "we measured, and it was zero"
Sometimes that is a genuine quiet period. More often it means the quantity is not meaningful for the instrument. Two verified examples from earlier in this course:
/eod/US10Y.GBONDreturnsvolume: 0on every row. A computed Treasury yield has no shares changing hands.- The spec's real-time example for
EUR.FOREXshowsvolume: 0— not a quiet FX market, but a decentralised OTC market with no consolidated volume to report.
So zero has a third meaning again: "not an applicable quantity here". Averaging those zeros into a volume statistic produces a number with no referent.
A missing row means "this day does not exist"
Weekends, exchange holidays, halts, and any period before the instrument listed. Nothing is wrong. The row was never supposed to be there.
What each mistake costs
Fill a null with zero and a price series shows a 100% drawdown on a day nothing happened, followed by an infinite return the next day. Every risk metric downstream is now fiction.
Treat a missing row as zero volume and your average is wrong by however many non-trading days sit in the window. A 5-day window containing one exchange holiday returns 4 rows. Sum four volumes, divide by 5, and the average is 20% too low — and nothing anywhere reports an error.
Treat a missing row as a flat price and you have invented trading days the market never had, which quietly suppresses measured volatility.
This is why the earlier /eod/AAPL?from=2026-07-20&to=2026-07-24 example returned exactly 5 rows: that week happened to contain no holiday. The point is not that five is the answer — it is that you have to check rather than assume.
Three defaults worth adopting
- Never fill a null with a number. Propagate it, or drop the row, and record which you did. A null that becomes a zero can never be recovered.
- Count rows against expected trading days, not against calendar days.
- Get the expected trading days from the venue.
/exchange-details/{EXCHANGE_CODE}publishes each exchange's holidays and trading hours. That is a better source than your own calendar, and it is the difference between "the data is missing days" and "the market was shut".
The stale-and-missing lesson in Reading the Market covers the market-side half of this — when a quote is technically present and still not telling you the truth.
Try it now
- Here is July 2026 for
AAPL.US: its row count is in the caption, its first four dates and its last in the table. July 2026 has 23 weekdays. Reconcile the count against them and against the venue's holiday list for the month, the second table. Every difference should have a name.
- Here is the last row of
/eod/US10Y.GBONDfor the week ending 25 September 2026, the series charted below; the other four rows of that week carry the samevolume. Compute the week's average volume, look at the answer, and say out loud what it means.
- Search your code for a fill, a
fillna, a?? 0or aCOALESCE. For each one, decide whether the absence it hides was a null, a zero or a missing row.