Skip to content

data_updater_v2.data_clients.bars

bars.py — the one bar shape every client’s prices come back in, whoever served them.

The raw price tables’ column set (nc-data models/core_data/prices.py): one row per bar, keyed (symbol, date) daily and (symbol, date, bar_interval) intraday.

symbol the ticker as the vendor serves it
date the bar's START as a naive UTC datetime (the key)
utc_date · utc_time that instant's UTC date and time of day
est_date · est_time the same instant on the US/Eastern wall clock (EST or EDT)
bar_interval intraday only: 1min, 5min, ...
open · high · low · close as traded (unadjusted)
volume shares for stocks and ETFs (as traded: FMP raw minutes and
EODHD daily volume are put back on that scale), contracts
for commodities, the vendor's number for indices, DOLLARS
(the quote currency) for crypto; None where the vendor's
number cannot be trusted (a minute day FMP mis-adjusted,
EODHD crypto minutes)
coin_volume crypto only: the base currency's units (BTC for BTCUSD)

A DAILY bar carries day identity, not an instant: date is the day at 00:00, utc_date = est_date = the day, both times 00:00. The day is the venue’s: the ET session date for listings, the UTC day for crypto (FMP’s crypto daily closes on the UTC day: its close matches Bitstamp’s last UTC minute to ~1 bp, the ET day’s by 17-44 bp; probed 2026-10-04).

Crypto volume both ways, from whichever unit the source served: FMP serves dollars (composite, all venues: BTC ~$37B a day) and Bitstamp coins (one venue: ~1,900 BTC a day). The other unit is derived over the bar’s own price: the daily VWAP where the vendor gives one, else the bar’s typical price (high + low + close) / 3. Within a source the two agree; across sources they never will (composite vs one venue), so a row’s source decides which is served.

Functions

daily_bar

daily_bar(symbol: str, day: dt.date | str, open_: Any, high: Any, low: Any, close: Any, volume: Any, **extra: Any) -> dict[str, Any]

One daily bar with day identity. extra carries coin_volume for crypto.

finished

finished(bars: list[dict[str, Any]], interval: str) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]

Intraday bars whose span has ended: (kept, the bar still forming taken out).

in_window

in_window(bars: list[dict[str, Any]], lo: dt.date | None, hi: dt.date | None, field: str) -> list[dict[str, Any]]

The bars whose day (field: utc_date or est_date) lies in [lo, hi]: what was asked (FMP’s /api/v3 answers an inverted window with history; a chunked walk returns whole days past the ask). Not a drop: rows outside the ask are not the answer.

intraday_bar

intraday_bar(symbol: str, start: dt.datetime, interval: str, open_: Any, high: Any, low: Any, close: Any, volume: Any, **extra: Any) -> dict[str, Any]

One intraday bar from its START instant (timezone-aware: FMP’s Eastern wall clock or Bitstamp’s UTC epoch, converted before this). extra carries coin_volume.

ny_now

ny_now() -> dt.datetime

Now on New York’s clock (a sensor’s window is New York hours).

ny_today

ny_today() -> dt.date

Today in New York: the day a split, a payout, a listing or the calendar is judged by, whatever zone the machine runs in (a container runs on UTC, a day ahead from 20:00 ET).

on_the_minute

on_the_minute(bars: list[dict[str, Any]]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]

Intraday bars stamped on the minute: a lone stamp off the minute (11:57:04) moved to its minute (the closest clean one: the vendor’s tick, not a lost minute); one whose minute is already served taken out as its duplicate (^DJI 2023-12-27 twice, FMP).

one_each

one_each(bars: list[dict[str, Any]]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]

One bar per instant (a daily bar’s instant is its day): the first served is kept, a second for the same instant taken out.

priced

priced(bars: list[dict[str, Any]]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]

The bars with every price (open, high, low, close): a row the vendor served without one is no bar — taken out, named — before anything reads its prices.

process_intraday_bars

process_intraday_bars(bars: list[dict[str, Any]], interval: str, lo: dt.date, hi: dt.date, field: str) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]

One symbol’s intraday bars (EODHD’s, Bitstamp’s) processed (each row already in the bar shape, zero volume kept at zero): the family’s days asked, stamps on the minute, one bar per instant, the bar still forming out, a row with no price out. Returns (bars, dropped).

sessions_between

sessions_between(lo: dt.date, hi: dt.date) -> list[dt.date]

NYSE’s sessions in [lo, hi] (mcal): none in a weekend or a holiday.

settled

settled(bars: list[dict[str, Any]], family: str) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]

The daily bars of finished days only, for a family (crypto, or a listing family: equity, etf, index, commodity): (kept, the day still trading taken out). Vendors serve the day still trading (mid-session 2026-10-05: FMP’s SPY row with 15.4M of the day’s volume, FMP’s and EODHD’s BTC UTC day so far, Bitstamp’s current candle). Crypto’s day ends at 00:00 UTC; a listing’s at that day’s NYSE close (mcal) — commodities and indices go by the NYSE close too. A finished day with volume 0 stays, at 0 (FMP’s BTC days before 2016-01-02 carry real prices and no volume: Sam, 2026-10-08).

typical

typical(high: Any, low: Any, close: Any) -> float | None

The bar’s typical price, (high + low + close) / 3, or None when a leg is missing.

utc_today

utc_today() -> dt.date

Today’s UTC date: crypto’s day, and the latest day any family can have a bar on.