Skip to content

Session High/Low ​

Running high and low of the current calendar-day session, re-anchored automatically at each day boundary. Unlike OpeningRange / InitialBalance, the boundary is detected from the candle timestamp — no manual reset().

Quick reference ​

ItemValue
FamilySeasonality & Session
Input typeCandle (uses high, low, timestamp)
Output typeSessionHighLowOutput { high, low }
Output rangeunbounded (price units)
Default parametersutc_offset_minutes = 0 (UTC)
Warmup period1
InterpretationIntraday support/resistance envelope

Formula ​

On a new local day:   high = candle.high, low = candle.low
Within the same day:  high = max(high, candle.high)
                      low  = min(low,  candle.low)

The local day is the wall-clock day of Candle::timestamp shifted by utc_offset_minutes. See crates/wickra-core/src/indicators/session_high_low.rs.

Parameters ​

NameTypeDefaultConstraintSourceDescription
utc_offset_minutesi320nonesession_high_low.rs:39Shifts the instant before deriving the day boundary.

SessionHighLow::new is infallible.

Inputs / Outputs ​

rust
const _: fn(&mut wickra::SessionHighLow, wickra::Candle) -> Option<wickra::SessionHighLowOutput> =
    <wickra::SessionHighLow as wickra::Indicator>::update;
  • Python. update((o,h,l,c,v,ts)) → (high, low) tuple; batch(open, high, low, close, volume, timestamp) → (n, 2) array.
  • Node. update(...) → { high, low }; batch(...) → flat number[] length n*2.
  • WASM. update(...) → { high, low } object (timestamp is a BigInt).

Warmup ​

warmup_period() == 1 — both fields are produced from the first bar.

Edge cases ​

  • Widens within a day. A narrower bar never shrinks the range (test tracks_high_low_within_day).
  • Re-anchors on a new day. The first bar of a new local day defines the new range alone (test re_anchors_on_new_day).
  • Offset shifts the boundary. Two bars that straddle UTC midnight can land on the same local day under a non-zero offset (test utc_offset_shifts_day_boundary).
  • Reset. Clears the day anchor and range (test reset_clears_state).

Examples ​

Rust ​

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

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let hour = 3_600_000;
    let mut shl = SessionHighLow::new(0);
    shl.update(Candle::new(100.0, 105.0, 99.0, 101.0, 1.0, 0)?);
    let v = shl.update(Candle::new(101.0, 108.0, 100.0, 107.0, 1.0, hour)?).unwrap();
    println!("{} {}", v.high, v.low); // 108 99
    Ok(())
}

Python ​

python
import wickra as ta

HOUR = 3_600_000
shl = ta.SessionHighLow(0)
shl.update((100.0, 105.0, 99.0, 101.0, 1.0, 0))
print(shl.update((101.0, 108.0, 100.0, 107.0, 1.0, HOUR)))  # (108.0, 99.0)

Node ​

javascript
const wickra = require('wickra');
const HOUR = 3_600_000;
const shl = new wickra.SessionHighLow(0);
shl.update(100, 105, 99, 101, 1, 0);
console.log(shl.update(101, 108, 100, 107, 1, HOUR)); // { high: 108, low: 99 }

Streaming ​

python
shl = ta.SessionHighLow(60)  # CET
for o, h, l, c, v, ts in candle_feed:
    band = shl.update((o, h, l, c, v, ts))
    # band.high / band.low form the session's developing range

Interpretation ​

  1. Intraday envelope. The session high/low are the most-watched intraday reference levels; breaks frequently trigger stop runs and breakouts.
  2. Mean-reversion bounds. Range-bound days oscillate between the developing session high and low.

Common pitfalls ​

  • Continuous (24/7) instruments. Without a meaningful day boundary the range resets at UTC (or offset) midnight, which may not match the venue's session.
  • Gaps. A gap-open bar instantly sets a fresh range; it does not inherit the prior day's levels.

See also ​