Skip to main content

Module obv

Module obv 

Source
Expand description

§On-Balance Volume (OBV)

Cumulative volume flow signed by close direction:

if close[i] > close[i−1]:  OBV += volume[i]
if close[i] < close[i−1]:  OBV −= volume[i]
if close[i] == close[i−1]: OBV unchanged

First bar: OBV = volume[0] (common convention; signed flow starts on bar 1). Absolute level is arbitrary — desks watch slope and divergence, not a magic OBV number.


§Trading perspective

StoryHabit (classic)
Price up, OBV upVolume confirms trend
Price up, OBV flat/downBearish divergence screen
Price down, OBV upBullish accumulation screen

§vs other volume tools

OBVMFIRVOLVWAP
IdeaCumulative signed volumeBounded oscillator 0–100Volume vs its meanVolume-weighted price
Best forDivergence / confirmationOverbought/oversold w/ volumeSpike detectionIntraday fair value

Prefer MFI when you want RSI-like bounds; OBV when you want unbounded cumulative flow; RVOL for “is this bar loud?”; VWAP for session price, not volume trend.

§Pairs well with

  • Price structure / Donchian or Supertrend — breakout + rising OBV.
  • ADX — strong trend + confirming OBV slope.
  • RSI/WillR — oscillator extreme + OBV not confirming → divergence narrative.

§Engineering

ObvParams (unit pack) → obv / ObvStateobv_solution.
Batch uses ObvState end-to-end. Each push is O(1).

§Word problem

Closes 10 → 11 → 10 with volumes 100, 200, 50. OBV path?

Expect: 100, then 100+200=300, then 300−50=250.

use finance_solution::stocks::ta::{obv, ObvParams};
let c = [10.0, 11.0, 10.0];
let v = [100.0, 200.0, 50.0];
let s = obv(&c, &v, ObvParams::default_pack()).unwrap();
assert!((s.obv[0].unwrap() - 100.0).abs() < 1e-12);
assert!((s.obv[1].unwrap() - 300.0).abs() < 1e-12);
assert!((s.obv[2].unwrap() - 250.0).abs() < 1e-12);

Structs§

ObvParams
OBV has no lookback; pack is a unit for API consistency.
ObvSeries
ObvSolution
ObvState
Incremental OBV. Each push is O(1).
ValidatedObv
Validated pack (always succeeds).

Functions§

obv
obv_solution
Examples