Data Access

Price series, OHLC columns, TBBO tick fields, composite prices, and time components.

close

Closing price for each bar as a pandas Series.

The most commonly used price input and the default for most indicator calculations. Supports all standard pandas operations.

On TBBO files (when read from Python), close is the per-bar last mid-price after the WASM aggregator builds bars at the active timeframe.

Returns

pandas Series of float64

Example

from quant_charts import close

sma_20 = close.rolling(20).mean()
ema_12 = close.ewm(span=12, adjust=False).mean()
daily_return = close.pct_change()

Output

>>> close.head()
0    100.578931
1    100.436809
2    102.385924
3    105.363522
4    104.579579
dtype: float64

open

Opening price for each bar as a pandas Series.

The opening price of each bar. Useful for gap analysis (comparing current open to previous close) and candlestick pattern detection.

Returns

pandas Series of float64

Example

from quant_charts import open, close
gap = open - close.shift(1)

high

Highest price reached during each bar.

Used for channel indicators, range calculations, true range, and resistance level detection.

Returns

pandas Series of float64

Example

from quant_charts import high, low
bar_range = high - low
highest_20 = high.rolling(20).max()

low

Lowest price reached during each bar.

Used alongside high for volatility measures, channel indicators, and support level detection.

Returns

pandas Series of float64

Example

from quant_charts import high, low
lowest_20 = low.rolling(20).min()

Column resolvers (volume_series / delta_series / vwap_series / df_col_or)

Helpers that resolve volume / delta / VWAP across different parquet shapes via priority chains.

Different parquets ship different columns. Native OHLC files often carry volume / delta / vwap; TBBO-aggregated bars carry bid_vol / ask_vol / tickCount; some older files only have tickCount. Hard-coding column names breaks portability across data files. The four helpers below resolve a single concept (the volume signal, the signed delta signal, etc.) with an explicit fallback chain so your indicator/strategy works on every parquet shape:

All resolvers return numpy arrays of length len(df) (or default for df_col_or). NaN entries are coerced to 0 inside volume_series and delta_series so cumulative sums stay finite.

Declare required_columns=[...] only for columns your math truly needs (typically high/low/close); leave optional columns out and read them via the resolvers so the validator does not reject parquets that lack the optional columns.

Returns

numpy.ndarray of float64

Example

from quant_charts import indicator, plot, volume_series, delta_series, vwap_series, cvd, df_col_or

@indicator(name="Order-Flow Light", overlay=False, required_columns=["close"])
class OrderFlowLight:
    def calculate(self, df):
        vol = volume_series(df)        # works on any parquet shape
        cvd_arr = cvd(delta_series(df))
        vwap = vwap_series(df)         # uses precomputed column or builds session VWAP
        custom = df_col_or(df, "trade_size", "tickCount", default=vol)
        plot(cvd_arr, "CVD", color="#7AA2F7")

volume

Trading volume for each bar.

Total traded volume within each bar. May be zero if volume data is unavailable. Used for VWAP, volume analysis, and liquidity filtering.

On TBBO data (Python execution path) this is the per-bar sum of trade volume aggregated by scripts/strategy_executor.py.

Returns

pandas Series of float64

Example

from quant_charts import close, volume
vwap = (close * volume).cumsum() / volume.cumsum()

Output

>>> volume.head()
0    18702.0
1    10384.0
2    10404.0
3    50943.0
4    57926.0
dtype: float64

delta

Per-bar signed volume delta (buyer minus seller).

Positive when buyers lift the offer, negative when sellers hit the bid. Pair with the cvd() helper for cumulative volume delta.

Returns

pandas Series of float64

Example

from quant_charts import delta, cvd
cumdelta = cvd(delta)

vwap

Session volume-weighted average price.

Available where the parquet provides it (or computed from volume + close otherwise). Pair with vwap_band(vwap, atr, mult) for mean-reversion envelopes.

Returns

pandas Series of float64

Example

from quant_charts import vwap, ta, high, low, close, vwap_band
atr = ta.atr(high, low, close, 14)
upper, lower = vwap_band(vwap, atr, mult=1.5)

bid_vol / ask_vol

Per-bar sum of bid_size / ask_size on TBBO bars.

Aggregated by scripts/strategy_executor.py from raw tick bid_size/ask_size. Pair with imbalance(bid_vol, ask_vol) for an order-book pressure ratio.

Note: the WASM chart aggregator only emits 6 fields per bar; bid_vol/ask_vol live on the strategy-execution DataFrame, not the chart bar.

Returns

pandas Series of float64

Example

from quant_charts import bid_vol, ask_vol, imbalance
imb = imbalance(bid_vol, ask_vol)
buy_pressure = imb > 0.6

bid_price / ask_price / mid_price

TBBO best bid/ask/mid prices per bar.

Available on TBBO files; fall back to close on OHLC-only sources so cross-mode code stays symmetric.

Returns

pandas Series of float64

Example

from quant_charts import bid_price, ask_price, mid_price
spread_pct = (ask_price - bid_price) / mid_price * 100

bid_size / ask_size

TBBO per-tick resting size at best bid / ask.

Tick-mode quantity. Fall back to bid_vol / ask_vol on OHLC-aggregated TBBO bars so imbalance(bid_size, ask_size) works at any execution timeframe.

Returns

pandas Series of float64

Example

from quant_charts import bid_size, ask_size, imbalance
imb = imbalance(bid_size, ask_size)

hl2

Median price: (high + low) / 2

Midpoint of high and low. Less noisy than close alone and often used as a smoothed input for oscillators and moving averages.

Returns

pandas Series of float64

Example

from quant_charts import hl2
smoothed = hl2.rolling(14).mean()

Notes

  • Formula: (high + low) / 2

hlc3

Typical price: (high + low + close) / 3

Incorporates close for more weight toward the final traded price. Commonly used in VWAP-like calculations.

Returns

pandas Series of float64

Example

from quant_charts import hlc3
typical = hlc3.rolling(20).mean()

Notes

  • Formula: (high + low + close) / 3

ohlc4

Average price: (open + high + low + close) / 4

The most balanced representation of each bar's price action, weighting all four components equally.

Returns

pandas Series of float64

Example

from quant_charts import ohlc4
balanced = ohlc4.ewm(span=20).mean()

Notes

  • Formula: (open + high + low + close) / 4

TBBO vs OHLC

Two source-data types. Python only runs on OHLC bars; tick-level TBBO uses Rust.

Quant Charts ingests two parquet shapes:

  • OHLC files (e.g. MNQ_OHLC.parquet): pre-aggregated bars with open/high/low/close/volume and optional delta/vwap. Python strategies and indicators run directly on these.
  • TBBO files (e.g. TBBO_Converted.parquet): tick-level bid/ask/bid_size/ask_size/volume/delta. Python execution uses an in-memory aggregator (scripts/strategy_executor.py) to produce OHLC bars at the active timeframe before calling calculate(self, df). Tick-level access (per-tick bid/ask/microprice) is only available in Rust.

If you need per-tick decisions (microprice, spread compression, large-trade detection at tick granularity), write a Rust .rs file and use the #[strategy] or #[indicator] macro.

Example

# Python (OHLC bar path):
@indicator("VWAP Bands", overlay=True, data_mode='ohlc')
class VwapBands:
    def calculate(self, df):
        plot(df['vwap'], "VWAP")

# Rust (TBBO tick path):
#[indicator(name = "Spread Heatmap", overlay = false)]
pub struct SpreadHeatmap { /* ... */ }

Notes

  • Python data_mode accepts 'ohlc' only. Tick mode for Python was removed.
  • TBBO files still render in the chart via the WASM aggregator (6 fields per bar).
  • On TBBO data, Python strategies see bid_vol/ask_vol columns produced by the bar aggregator.

price

price(source?)

Get the active price series for the chart.

Returns the appropriate price Series for OHLC bars. Pass "open", "high", "low", "close", "hl2", "hlc3", or "ohlc4" to pick a specific source.

Parameters

  • source (str, default "close"): OHLC source name

Returns

pandas Series

Example

src = price()           # close by default
mid = price("hl2")      # explicit hl2

is_ohlc_mode

is_ohlc_mode()

Returns True if the chart is showing OHLC candles.

Returns

bool

Example

if is_ohlc_mode():
    true_range = high - low

is_tick_mode

is_tick_mode()

Returns True if the chart is showing tick data (TBBO files in tick view).

Python strategies always receive aggregated bars, but indicators that render directly on a tick-mode chart can branch on this. For tick-level computation use a Rust indicator.

Returns

bool

Example

if is_tick_mode():
    spread = price("ask") - price("bid")

is_native_ohlc

is_native_ohlc()

Returns True if the source is native OHLC (real intra-bar variation).

Distinguishes native OHLC files (real open/high/low/close) from tick-derived OHLC (O=H=L=C=mid_price). Use this to gate calculations that need true range.

Returns

bool

Example

if is_native_ohlc():
    tr = high - low
else:
    tr = price().rolling(2).apply(lambda x: abs(x[1] - x[0]))

get_source_data_type

get_source_data_type()

Returns "TBBO", "OHLC", or None.

Returns

Optional[str]

Example

kind = get_source_data_type()
if kind == "TBBO":
    log("running on tick-derived bars")

on_tick

on_tick(func)

Decorator: wrapped function only runs in tick mode.

Returns the decorated function unchanged but short-circuits to None when the chart is in OHLC mode. Use to keep tick-only logic out of OHLC code paths without an explicit if.

Returns

callable

Example

from quant_charts import on_tick

@on_tick
def microprice_drift():
    return (ask_price + bid_price) * 0.5

drift = microprice_drift()  # None in OHLC mode

on_ohlc

on_ohlc(func)

Decorator: wrapped function only runs in OHLC mode.

Returns

callable

Example

@on_ohlc
def true_range():
    return (high - low).rolling(14).mean()

either

either(tick_func, ohlc_func)

Run tick_func() in tick mode, ohlc_func() in OHLC mode.

Convenience for two-implementation indicators where the tick path differs structurally from the OHLC path.

Returns

Any

Example

from quant_charts import either

result = either(
    lambda: (ask_price - bid_price).rolling(20).mean(),
    lambda: (high - low).rolling(20).mean(),
)

hour

Hour of day (0-23) in US/Eastern time.

Lazy proxy that extracts the hour from each bar's timestamp. Works like a numpy array in comparisons.

Important: Futures sessions cross midnight. A "Monday" session starts Sunday 6pm ET.

Returns

TimeSeries (int)

Example

from quant_charts import hour, minute

rth = (hour >= 9) & (hour < 16)
asian = (hour >= 19) | (hour < 1)
market_open = (hour == 9) & (minute == 30)

minute

Minute of hour (0-59).

Lazy proxy that extracts the minute from each bar's timestamp. Converted to US/Eastern time.

Returns

TimeSeries (int)

Example

from quant_charts import hour, minute

first_half = minute < 30
market_open = (hour == 9) & (minute == 30)

second

Second of minute (0-59). Useful for tick-level timing.

Lazy proxy, converted to US/Eastern time.

Returns

TimeSeries (int)

Example

from quant_charts import second
on_the_minute = second == 0

day_of_week

Day of week (0=Monday, 6=Sunday).

US/Eastern time. Remember: futures Sunday session = day_of_week == 6.

Returns

TimeSeries (int)

Example

from quant_charts import day_of_week

is_monday = day_of_week == 0
is_friday = day_of_week == 4
weekday = day_of_week < 5