Skip to content

Initial Balance (IB) ​

Session-opening high / low established over the first N bars of a session. Tracks the running session high and session low across the first period candles since construction or reset(). Once the period-th candle has been ingested the value is frozen and every subsequent call returns the same locked output until reset() is invoked.

Quick reference ​

ItemValue
FamilyMarket Profile
Input typeCandle (uses high, low)
Output typeInitialBalanceOutput { high, low }
Output rangeunbounded (price-units)
Default parametersperiod = 12 (1-hour IB on 5-minute US equity bars)
Warmup periodperiod
InterpretationSession opening-balance zone; breaks signal trend day

Formula ​

For the first `period` candles since reset:
  high = running max
  low  = running min

After bar `period`:
  high, low locked until reset()

Caller is responsible for invoking reset() at each new session boundary. See crates/wickra-core/src/indicators/initial_balance.rs.

Parameters ​

NameTypeDefaultConstraintDescription
periodusize12> 0Number of bars defining the IB window.

InitialBalance::new returns Error::PeriodZero for period == 0. InitialBalance::classic() returns the 12-bar factory.

Inputs / Outputs ​

Indicator<Input = Candle, Output = InitialBalanceOutput> with two fields (high, low).

  • Python. InitialBalance(period).batch(high, low) returns an (n, 2) array. Note: batch mode is most useful for session- aggregated bars; on continuous data the locked behaviour produces constant output post-warmup.
  • Node. Flat number[] of length n * 2.

Warmup ​

warmup_period() == period. First period - 1 bars return None; bar period emits and locks the value.

Edge cases ​

  • No automatic reset. This is the most important caveat — must reset() at session boundaries manually.
  • Lock-in semantics. Post-warmup output is constant until reset.
  • Reset. Clears the running high/low and the lock.

Examples ​

Rust ​

rust
use wickra::{Candle, InitialBalance, Indicator};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let bars = [
        Candle::new(100.0, 102.0, 99.0, 101.0, 10.0, 0)?,
        Candle::new(101.0, 103.0, 100.0, 102.0, 10.0, 1)?,
        Candle::new(102.0, 104.0, 101.0, 103.0, 10.0, 2)?,
    ];
    let mut ib = InitialBalance::new(3)?;
    for b in bars { let _ = ib.update(b); }
    let v = ib.value().unwrap();
    println!("IB high={}, low={}", v.high, v.low);  // 104, 99
    Ok(())
}

Python ​

python
import numpy as np
import wickra as ta

# 3-bar IB
h = np.array([102.0, 103.0, 104.0, 105.0, 106.0])
l = np.array([ 99.0, 100.0, 101.0, 102.0, 103.0])

ib = ta.InitialBalance(3)
out = ib.batch(h, l)
# After bar 3: IB locked at high=104, low=99
print(out[-1])  # [104.0, 99.0]

Node ​

javascript
const wickra = require('wickra');
const ib = new wickra.InitialBalance(3);
console.log(ib.batch([102, 103, 104, 105, 106], [99, 100, 101, 102, 103]));

Streaming with session reset ​

rust
use wickra::{Candle, InitialBalance, Indicator};

let mut ib = InitialBalance::classic();  // 12-bar IB
let candle_stream: Vec<wickra::Candle> = Vec::new(); // your live OHLCV candle feed
fn is_new_session(_bar: Candle) -> bool { false } // your session-boundary predicate
for bar in candle_stream {
    if is_new_session(bar) {
        ib.reset();
    }
    if let Some(v) = ib.update(bar) {
        // IB high/low — use as breakout reference
    }
}

Interpretation ​

  • IB as breakout reference. Price breaking above IB-high signals an "extension up" — trend-day potential. Breaking below IB-low signals an "extension down".
  • Day-type classification. Market Profile traders use IB extension patterns to classify the day type (normal, trend-day, neutral, etc.).
  • Default 12 bars. 1-hour IB on 5-min bars is the US equity convention. Other markets: 30-min IB (6 bars) for futures, configurable for crypto / FX.

Common pitfalls ​

  • Forgetting reset. Without manual reset on session boundaries, the IB locks forever. Make session-boundary reset explicit in your trading loop.
  • Wrong session definition. US equity RTH = 9:30-16:00 ET. Crypto 24/7 has no natural session; use UTC midnight or any consistent boundary.

References ​

  • J. Peter Steidlmayer's Market Profile work (1980s) — origin of the Initial Balance concept.
  • Jim Dalton, Mind Over Markets (1990) — practitioner treatment.

See also ​