pub struct OhlcvBar {
pub symbol: String,
pub timeframe: Timeframe,
pub bar_start_ms: u64,
pub open: Decimal,
pub high: Decimal,
pub low: Decimal,
pub close: Decimal,
pub volume: Decimal,
pub trade_count: u64,
pub is_complete: bool,
pub is_gap_fill: bool,
pub vwap: Option<Decimal>,
}Expand description
A completed or partial OHLCV bar.
Fields§
§symbol: StringInstrument symbol (e.g. "BTC-USD").
timeframe: TimeframeTimeframe of this bar.
bar_start_ms: u64UTC millisecond timestamp of the bar’s open boundary.
open: DecimalOpening price (first tick’s price in the bar window).
high: DecimalHighest price seen in the bar window.
low: DecimalLowest price seen in the bar window.
close: DecimalClosing price (most recent tick’s price in the bar window).
volume: DecimalTotal traded volume in this bar.
trade_count: u64Number of ticks contributing to this bar.
is_complete: booltrue once the bar’s time window has been closed by a tick in a later window.
is_gap_fill: booltrue if this bar was synthesized to fill a gap — no real ticks were received
during its window. Gap-fill bars have trade_count == 0 and all OHLC fields set
to the last known close price. Callers may use this flag to filter synthetic bars
out of indicator calculations or storage.
vwap: Option<Decimal>Volume-weighted average price for this bar. None for gap-fill bars.
Implementations§
Source§impl OhlcvBar
impl OhlcvBar
Sourcepub fn body(&self) -> Decimal
pub fn body(&self) -> Decimal
Candle body size: (close - open).abs().
Direction-independent; use close > open to determine bullish/bearish.
Sourcepub fn body_high(&self) -> Decimal
pub fn body_high(&self) -> Decimal
Higher of open and close: max(open, close).
The top of the candle body, regardless of direction.
Sourcepub fn body_low(&self) -> Decimal
pub fn body_low(&self) -> Decimal
Lower of open and close: min(open, close).
The bottom of the candle body, regardless of direction.
Sourcepub fn is_bullish(&self) -> bool
pub fn is_bullish(&self) -> bool
Returns true if this is a bullish bar (close > open).
Sourcepub fn is_bearish(&self) -> bool
pub fn is_bearish(&self) -> bool
Returns true if this is a bearish bar (close < open).
Sourcepub fn has_upper_wick(&self) -> bool
pub fn has_upper_wick(&self) -> bool
Returns true if the bar has a non-zero upper wick (high > max(open, close)).
Sourcepub fn has_lower_wick(&self) -> bool
pub fn has_lower_wick(&self) -> bool
Returns true if the bar has a non-zero lower wick (min(open, close) > low).
Sourcepub fn body_direction(&self) -> BarDirection
pub fn body_direction(&self) -> BarDirection
Directional classification of the bar body.
Returns BarDirection::Bullish when close > open, BarDirection::Bearish
when close < open, and BarDirection::Neutral when they are equal.
Sourcepub fn is_doji(&self, epsilon: Decimal) -> bool
pub fn is_doji(&self, epsilon: Decimal) -> bool
Returns true if the bar body is a doji (indecision candle).
A doji has |close - open| <= epsilon. Use a small positive epsilon
such as dec!(0.01) to account for rounding in price data.
Sourcepub fn wick_upper(&self) -> Decimal
pub fn wick_upper(&self) -> Decimal
Upper wick (shadow) length: high - max(open, close).
The upper wick is the portion of the candle above the body.
Sourcepub fn wick_lower(&self) -> Decimal
pub fn wick_lower(&self) -> Decimal
Lower wick (shadow) length: min(open, close) - low.
The lower wick is the portion of the candle below the body.
Sourcepub fn price_change(&self) -> Decimal
pub fn price_change(&self) -> Decimal
Signed price change: close - open.
Positive for bullish bars, negative for bearish bars, zero for doji.
Unlike body, this preserves direction.
Sourcepub fn typical_price(&self) -> Decimal
pub fn typical_price(&self) -> Decimal
Typical price: (high + low + close) / 3.
Commonly used as the basis for VWAP and commodity channel index (CCI) calculations.
Sourcepub fn close_location_value(&self) -> Option<f64>
pub fn close_location_value(&self) -> Option<f64>
Close Location Value (CLV): where the close sits within the bar’s range.
Formula: (close - low - (high - close)) / range.
Returns None if the range is zero (e.g. a single-price bar). Values
are in [-1.0, 1.0]: +1.0 means the close is at the high, -1.0 at
the low, and 0.0 means the close is exactly mid-range.
Sourcepub fn median_price(&self) -> Decimal
pub fn median_price(&self) -> Decimal
Median price: (high + low) / 2.
The midpoint of the bar’s price range, independent of open and close.
Sourcepub fn weighted_close(&self) -> Decimal
pub fn weighted_close(&self) -> Decimal
Weighted close price: (high + low + close × 2) / 4.
Gives extra weight to the closing price over the high and low extremes. Commonly used as the basis for certain momentum and volatility indicators.
Sourcepub fn price_change_pct(&self) -> Option<f64>
pub fn price_change_pct(&self) -> Option<f64>
Percentage price change: (close − open) / open × 100.
Returns None if open is zero. Positive values indicate a bullish bar;
negative values indicate a bearish bar.
Sourcepub fn body_ratio(&self) -> Option<f64>
pub fn body_ratio(&self) -> Option<f64>
Body ratio: body / range.
The fraction of the total price range that is body (rather than wicks).
Ranges from 0.0 (pure wicks / doji) to 1.0 (no wicks at all).
Returns None if the bar’s range is zero (all prices identical).
Sourcepub fn true_range(&self, prev_close: Decimal) -> Decimal
pub fn true_range(&self, prev_close: Decimal) -> Decimal
True range: max(high − low, |high − prev_close|, |low − prev_close|).
The standard ATR (Average True Range) input. Accounts for overnight gaps by including the distance from the previous close to today’s high and low.
Sourcepub fn inside_bar(&self, prev: &OhlcvBar) -> bool
👎Deprecated since 2.2.0: Use is_inside_bar instead
pub fn inside_bar(&self, prev: &OhlcvBar) -> bool
Use is_inside_bar instead
Returns true if this bar is an inside bar relative to prev.
An inside bar has high < prev.high and low > prev.low — its full
range is contained within the prior bar’s range. Used in price action
trading as a consolidation signal.
Sourcepub fn outside_bar(&self, prev: &OhlcvBar) -> bool
pub fn outside_bar(&self, prev: &OhlcvBar) -> bool
Returns true if this bar is an outside bar relative to prev.
An outside bar has high > prev.high and low < prev.low — it fully
engulfs the prior bar’s range. Also called a key reversal day.
Sourcepub fn wick_ratio(&self) -> Option<f64>
pub fn wick_ratio(&self) -> Option<f64>
Returns the ratio of total wick length to bar range: (upper_wick + lower_wick) / range.
A value near 1 indicates a bar that is mostly wicks with little body.
Returns None when the bar has zero range (high == low).
Sourcepub fn is_hammer(&self) -> bool
pub fn is_hammer(&self) -> bool
Returns true if this bar has a classic hammer shape.
A hammer has:
- A small body (≤ 30% of range)
- A long lower wick (≥ 60% of range)
- A tiny upper wick (≤ 10% of range)
Returns false if the bar’s range is zero.
Sourcepub fn is_shooting_star(&self) -> bool
pub fn is_shooting_star(&self) -> bool
Returns true if this bar has a classic shooting-star shape.
A shooting star has:
- A small body (≤ 30% of range)
- A long upper wick (≥ 60% of range)
- A tiny lower wick (≤ 10% of range)
This is the inverse of a hammer — it signals a potential reversal at
the top of an uptrend. Returns false if the bar’s range is zero.
Sourcepub fn gap_from(&self, prev: &OhlcvBar) -> Decimal
pub fn gap_from(&self, prev: &OhlcvBar) -> Decimal
Gap from the previous bar: self.open − prev.close.
Positive values indicate a gap-up; negative values indicate a gap-down. Zero means the bar opened exactly at the previous close (no gap).
Sourcepub fn is_gap_up(&self, prev: &OhlcvBar) -> bool
pub fn is_gap_up(&self, prev: &OhlcvBar) -> bool
Returns true if this bar opened above the previous bar’s close.
Sourcepub fn is_gap_down(&self, prev: &OhlcvBar) -> bool
pub fn is_gap_down(&self, prev: &OhlcvBar) -> bool
Returns true if this bar opened below the previous bar’s close.
Sourcepub fn bar_midpoint(&self) -> Decimal
pub fn bar_midpoint(&self) -> Decimal
Body midpoint: (open + close) / 2.
The arithmetic center of the candle body, regardless of direction. Useful as a proxy for the “fair value” of the period.
Sourcepub fn body_to_range_ratio(&self) -> Option<Decimal>
pub fn body_to_range_ratio(&self) -> Option<Decimal>
Body as a fraction of total range: body / range.
Returns None when range is zero (all OHLC prices identical).
Sourcepub fn is_long_upper_wick(&self) -> bool
pub fn is_long_upper_wick(&self) -> bool
Returns true if the upper wick is longer than the candle body.
Indicates a bearish rejection at the high (supply above current price).
Sourcepub fn is_long_lower_wick(&self) -> bool
pub fn is_long_lower_wick(&self) -> bool
Returns true if the lower wick is longer than the candle body.
Indicates a bullish rejection at the low (demand below current price).
Sourcepub fn price_change_abs(&self) -> Decimal
👎Deprecated since 2.2.0: Use body() instead
pub fn price_change_abs(&self) -> Decimal
Use body() instead
Absolute price change over the bar: |close − open|.
Alias for body.
Sourcepub fn upper_shadow(&self) -> Decimal
pub fn upper_shadow(&self) -> Decimal
Upper shadow length — alias for wick_upper.
Returns high − max(open, close).
Sourcepub fn lower_shadow(&self) -> Decimal
pub fn lower_shadow(&self) -> Decimal
Lower shadow length — alias for wick_lower.
Returns min(open, close) − low.
Sourcepub fn is_spinning_top(&self, body_pct: Decimal) -> bool
pub fn is_spinning_top(&self, body_pct: Decimal) -> bool
Returns true if this bar has a spinning-top pattern.
A spinning top has a small body (≤ body_pct of range) with significant
wicks on both sides (each wick strictly greater than the body). Signals
market indecision — neither buyers nor sellers controlled the period.
body_pct is a fraction in [0.0, 1.0], e.g. dec!(0.3) for 30%.
Returns false if the bar’s range is zero.
Sourcepub fn hlc3(&self) -> Decimal
pub fn hlc3(&self) -> Decimal
HLC3: (high + low + close) / 3 — alias for typical_price.
Sourcepub fn ohlc4(&self) -> Decimal
pub fn ohlc4(&self) -> Decimal
OHLC4: (open + high + low + close) / 4.
Gives equal weight to all four price points. Sometimes used as a smoother proxy than typical price because it incorporates the open.
Sourcepub fn is_marubozu(&self) -> bool
pub fn is_marubozu(&self) -> bool
Returns true if this bar is a marubozu — no upper or lower wicks.
A marubozu has open == low and close == high (bullish) or
open == high and close == low (bearish). It signals strong
one-directional momentum with no intrabar rejection.
A zero-range bar (all prices equal) is considered a marubozu.
Sourcepub fn is_engulfing(&self, prev: &OhlcvBar) -> bool
pub fn is_engulfing(&self, prev: &OhlcvBar) -> bool
Returns true if this bar’s body engulfs prev’s body.
Engulfing requires: self.open < prev.open.min(prev.close) and
self.close > prev.open.max(prev.close) (or vice versa for bearish).
Specifically, self.body_low < prev.body_low and
self.body_high > prev.body_high.
Does NOT require opposite directions — use in combination with
is_bullish / is_bearish if
classic engulfing patterns are needed.
Sourcepub fn is_harami(&self, prev: &OhlcvBar) -> bool
pub fn is_harami(&self, prev: &OhlcvBar) -> bool
Returns true if this bar is a harami: its body is entirely contained
within the previous bar’s body.
A harami is the opposite of an engulfing pattern. Neither bar needs to be bullish or bearish — only the body ranges are compared.
Sourcepub fn tail_length(&self) -> Decimal
pub fn tail_length(&self) -> Decimal
The longer of the upper and lower wicks.
Returns the maximum of wick_upper() and wick_lower(). Useful for
identifying long-tailed candles regardless of direction.
Sourcepub fn is_inside_bar(&self, prev: &OhlcvBar) -> bool
pub fn is_inside_bar(&self, prev: &OhlcvBar) -> bool
Returns true if this bar is an inside bar: both high and low are
strictly within the previous bar’s range.
Unlike is_harami, which compares body ranges,
this method compares the full high-low range including wicks.
Sourcepub fn gap_up(&self, prev: &OhlcvBar) -> bool
pub fn gap_up(&self, prev: &OhlcvBar) -> bool
Returns true if this bar opened above the previous bar’s high (gap up).
Sourcepub fn gap_down(&self, prev: &OhlcvBar) -> bool
pub fn gap_down(&self, prev: &OhlcvBar) -> bool
Returns true if this bar opened below the previous bar’s low (gap down).
Sourcepub fn body_size(&self) -> Decimal
👎Deprecated since 2.2.0: Use body() instead
pub fn body_size(&self) -> Decimal
Use body() instead
Absolute size of the candle body: |close - open|.
Alias for body.
Sourcepub fn volume_delta(&self, prev: &OhlcvBar) -> Decimal
pub fn volume_delta(&self, prev: &OhlcvBar) -> Decimal
Volume change vs the previous bar: self.volume - prev.volume.
Sourcepub fn is_consolidating(&self, prev: &OhlcvBar) -> bool
pub fn is_consolidating(&self, prev: &OhlcvBar) -> bool
Returns true if this bar’s range is less than 50% of the previous bar’s range.
Indicates price consolidation / compression.
Sourcepub fn mean_volume(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn mean_volume(bars: &[OhlcvBar]) -> Option<Decimal>
Mean volume across a slice of bars.
Returns None if the slice is empty.
Sourcepub fn vwap_deviation(&self) -> Option<f64>
pub fn vwap_deviation(&self) -> Option<f64>
Absolute deviation of close price from VWAP as a fraction of VWAP: |close - vwap| / vwap.
Returns None if vwap is not set or is zero.
Sourcepub fn relative_volume(&self, avg_volume: Decimal) -> Option<f64>
pub fn relative_volume(&self, avg_volume: Decimal) -> Option<f64>
Volume as a ratio of avg_volume.
Returns None if avg_volume is zero.
Sourcepub fn intraday_reversal(&self, prev: &OhlcvBar) -> bool
pub fn intraday_reversal(&self, prev: &OhlcvBar) -> bool
Returns true if this bar opens in the direction of the prior bar’s move
but closes against it (an intraday reversal signal).
Specifically: prev was bullish (close > open), this bar opens near/above prev close, and closes below prev open — or vice versa for a bearish reversal.
Sourcepub fn range_pct(&self) -> Option<f64>
pub fn range_pct(&self) -> Option<f64>
High-low range as a percentage of the open price: (high - low) / open * 100.
Returns None if open is zero.
Sourcepub fn is_outside_bar(&self, prev: &OhlcvBar) -> bool
👎Deprecated since 2.2.0: Use outside_bar() instead
pub fn is_outside_bar(&self, prev: &OhlcvBar) -> bool
Use outside_bar() instead
Returns true if this bar is an outside bar (engulfs prev’s range).
An outside bar has a higher high AND lower low than the previous bar.
Alias for outside_bar.
Sourcepub fn high_low_midpoint(&self) -> Decimal
pub fn high_low_midpoint(&self) -> Decimal
Midpoint of the high-low range: (high + low) / 2.
Alias for median_price.
Sourcepub fn high_close_ratio(&self) -> Option<f64>
pub fn high_close_ratio(&self) -> Option<f64>
Ratio of close to high: close / high as f64.
Returns None if high is zero. A value near 1.0 means the bar closed
near its high (bullish strength); near 0.0 means it closed far below.
Sourcepub fn lower_shadow_pct(&self) -> Option<f64>
pub fn lower_shadow_pct(&self) -> Option<f64>
Lower shadow as a fraction of the full bar range: lower_shadow / range.
Returns None if the bar’s range is zero.
Sourcepub fn open_close_ratio(&self) -> Option<f64>
pub fn open_close_ratio(&self) -> Option<f64>
Ratio of close to open: close / open as f64.
Returns None if open is zero. Values above 1.0 indicate a bullish bar.
Sourcepub fn is_wide_range_bar(&self, threshold: Decimal) -> bool
pub fn is_wide_range_bar(&self, threshold: Decimal) -> bool
Returns true if this bar’s range (high - low) exceeds threshold.
Sourcepub fn close_to_low_ratio(&self) -> Option<f64>
pub fn close_to_low_ratio(&self) -> Option<f64>
Position of close within the bar’s high-low range: (close - low) / (high - low).
Returns None if the bar’s range is zero. Result is in [0.0, 1.0]:
0.0→ closed at the low (bearish)1.0→ closed at the high (bullish)
Sourcepub fn volume_per_trade(&self) -> Option<Decimal>
pub fn volume_per_trade(&self) -> Option<Decimal>
Average volume per trade: volume / trade_count.
Returns None if trade_count is zero.
Sourcepub fn price_range_overlap(&self, other: &OhlcvBar) -> bool
pub fn price_range_overlap(&self, other: &OhlcvBar) -> bool
Returns true if this bar’s high-low range overlaps with other’s range.
Two ranges overlap when neither is entirely above or below the other.
Sourcepub fn bar_height_pct(&self) -> Option<f64>
pub fn bar_height_pct(&self) -> Option<f64>
Bar height as a fraction of the open price: (high - low) / open.
Returns None if open is zero. Useful for comparing volatility across
instruments trading at different price levels.
Sourcepub fn bar_type(&self) -> &'static str
pub fn bar_type(&self) -> &'static str
Classifies this bar as "bullish", "bearish", or "doji".
A doji is a bar whose body is zero (open equals close). Otherwise the direction is determined by whether close is above or below open.
Sourcepub fn body_pct(&self) -> Option<Decimal>
pub fn body_pct(&self) -> Option<Decimal>
Body as a percentage of the total high-low range.
Returns None when the range is zero (all four prices equal).
A 100% body means no wicks (marubozu); near 0% means a doji.
Sourcepub fn is_bullish_hammer(&self) -> bool
pub fn is_bullish_hammer(&self) -> bool
Returns true if this bar is a bullish hammer: a long lower wick,
small body near the top of the range, and little or no upper wick.
Specifically: the lower wick is at least twice the body, and the upper wick is no more than the body.
Sourcepub fn upper_wick_pct(&self) -> Option<Decimal>
pub fn upper_wick_pct(&self) -> Option<Decimal>
Upper wick as a percentage of the total range (0–100).
Returns None when the range is zero.
Sourcepub fn lower_wick_pct(&self) -> Option<Decimal>
pub fn lower_wick_pct(&self) -> Option<Decimal>
Lower wick as a percentage of the total range (0–100).
Returns None when the range is zero.
Sourcepub fn is_bearish_engulfing(&self, prev: &OhlcvBar) -> bool
pub fn is_bearish_engulfing(&self, prev: &OhlcvBar) -> bool
Returns true if this bar is a bearish engulfing candle relative to prev.
A bearish engulfing has: current bar bearish, body entirely engulfs prev body.
Sourcepub fn is_bullish_engulfing(&self, prev: &OhlcvBar) -> bool
pub fn is_bullish_engulfing(&self, prev: &OhlcvBar) -> bool
Returns true if this bar is a bullish engulfing candle relative to prev.
A bullish engulfing has: current bar bullish, body entirely engulfs prev body.
Sourcepub fn close_gap(&self, prev: &OhlcvBar) -> Decimal
👎Deprecated since 2.2.0: Use gap_from() instead
pub fn close_gap(&self, prev: &OhlcvBar) -> Decimal
Use gap_from() instead
Gap between this bar’s open and the previous bar’s close: self.open - prev.close.
A positive value indicates an upward gap; negative indicates a downward gap.
Alias for gap_from.
Sourcepub fn close_above_midpoint(&self) -> bool
pub fn close_above_midpoint(&self) -> bool
Returns true if the close price is strictly above the bar’s midpoint (high + low) / 2.
Sourcepub fn close_momentum(&self, prev: &OhlcvBar) -> Decimal
pub fn close_momentum(&self, prev: &OhlcvBar) -> Decimal
Price momentum: self.close - prev.close.
Positive → price increased; negative → decreased.
Sourcepub fn bar_range(&self) -> Decimal
👎Deprecated since 2.2.0: Use range() instead
pub fn bar_range(&self) -> Decimal
Use range() instead
Full high-low range of the bar: high - low.
Alias for range.
Sourcepub fn bar_duration_ms(&self) -> u64
pub fn bar_duration_ms(&self) -> u64
Duration of this bar’s timeframe in milliseconds.
Sourcepub fn is_gravestone_doji(&self, epsilon: Decimal) -> bool
pub fn is_gravestone_doji(&self, epsilon: Decimal) -> bool
Returns true if this bar resembles a gravestone doji.
A gravestone doji has open ≈ close ≈ low (body within epsilon of
zero and close within epsilon of the low), with a long upper wick.
Sourcepub fn is_dragonfly_doji(&self, epsilon: Decimal) -> bool
pub fn is_dragonfly_doji(&self, epsilon: Decimal) -> bool
Returns true if this bar resembles a dragonfly doji.
A dragonfly doji has open ≈ close ≈ high (body within epsilon of
zero and close within epsilon of the high), with a long lower wick.
Sourcepub fn is_flat(&self) -> bool
pub fn is_flat(&self) -> bool
Returns true if this bar is completely flat (open == close == high == low).
For a valid OHLCV bar, range() == 0 is sufficient: since low ≤ open, close ≤ high,
high == low forces all four prices equal.
Sourcepub fn true_range_with_prev(&self, prev_close: Decimal) -> Decimal
👎Deprecated since 2.2.0: Use true_range() instead
pub fn true_range_with_prev(&self, prev_close: Decimal) -> Decimal
Use true_range() instead
True range: max(high - low, |high - prev_close|, |low - prev_close|).
Alias for true_range.
Sourcepub fn close_to_high_ratio(&self) -> Option<f64>
👎Deprecated since 2.2.0: Use high_close_ratio() instead
pub fn close_to_high_ratio(&self) -> Option<f64>
Use high_close_ratio() instead
Returns the ratio of close to high, or None if high is zero.
Alias for high_close_ratio.
Sourcepub fn close_open_ratio(&self) -> Option<f64>
👎Deprecated since 2.2.0: Use open_close_ratio() instead
pub fn close_open_ratio(&self) -> Option<f64>
Use open_close_ratio() instead
Returns the ratio of close to open, or None if open is zero.
Alias for open_close_ratio.
Sourcepub fn price_at_pct(&self, pct: f64) -> Decimal
pub fn price_at_pct(&self, pct: f64) -> Decimal
Interpolates a price within the bar’s high-low range.
pct = 0.0 returns low; pct = 1.0 returns high.
Values outside [0.0, 1.0] are clamped to that interval.
Sourcepub fn average_true_range(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn average_true_range(bars: &[OhlcvBar]) -> Option<Decimal>
Average true range (ATR) across a slice of consecutive bars.
Computes the mean of true_range for bars [1..],
using each bar’s predecessor as the previous close. Returns None if
the slice has fewer than 2 bars.
Sourcepub fn average_body(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn average_body(bars: &[OhlcvBar]) -> Option<Decimal>
Average body size across a slice of bars: mean of body for each bar.
Returns None if the slice is empty.
Sourcepub fn highest_high(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn highest_high(bars: &[OhlcvBar]) -> Option<Decimal>
Maximum high across a slice of bars.
Returns None if the slice is empty. Useful for computing resistance
levels, swing highs, and ATH/period-high comparisons.
Sourcepub fn lowest_low(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn lowest_low(bars: &[OhlcvBar]) -> Option<Decimal>
Minimum low across a slice of bars.
Returns None if the slice is empty. Useful for computing support
levels, swing lows, and ATL/period-low comparisons.
Sourcepub fn highest_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn highest_close(bars: &[OhlcvBar]) -> Option<Decimal>
Maximum close across a slice of bars.
Returns None if the slice is empty. Useful for identifying the
highest closing price within a lookback window.
Sourcepub fn lowest_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn lowest_close(bars: &[OhlcvBar]) -> Option<Decimal>
Minimum close across a slice of bars.
Returns None if the slice is empty. Useful for identifying the
lowest closing price within a lookback window.
Sourcepub fn close_range(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn close_range(bars: &[OhlcvBar]) -> Option<Decimal>
Close price range: highest_close − lowest_close across a slice.
Returns None if the slice is empty.
Sourcepub fn momentum(bars: &[OhlcvBar], n: usize) -> Option<f64>
pub fn momentum(bars: &[OhlcvBar], n: usize) -> Option<f64>
N-period price momentum: (close[last] / close[last - n]) − 1.
Returns None if the slice has fewer than n + 1 bars or if
close[last - n] is zero.
Sourcepub fn sum_volume(bars: &[OhlcvBar]) -> Decimal
pub fn sum_volume(bars: &[OhlcvBar]) -> Decimal
Total traded volume across a slice of bars.
Returns Decimal::ZERO for an empty slice. Complements
mean_volume when the sum rather than the average
is needed.
Sourcepub fn bullish_count(bars: &[OhlcvBar]) -> usize
pub fn bullish_count(bars: &[OhlcvBar]) -> usize
Count of bullish bars (close > open) in a slice.
Sourcepub fn bearish_count(bars: &[OhlcvBar]) -> usize
pub fn bearish_count(bars: &[OhlcvBar]) -> usize
Count of bearish bars (close < open) in a slice.
Sourcepub fn bullish_streak(bars: &[OhlcvBar]) -> usize
pub fn bullish_streak(bars: &[OhlcvBar]) -> usize
Length of the current bullish streak at the end of bars.
Counts consecutive bullish bars (close > open) from the tail of the
slice. Returns 0 if the last bar is not bullish or the slice is empty.
Sourcepub fn bearish_streak(bars: &[OhlcvBar]) -> usize
pub fn bearish_streak(bars: &[OhlcvBar]) -> usize
Length of the current bearish streak at the end of bars.
Counts consecutive bearish bars (close < open) from the tail of the
slice. Returns 0 if the last bar is not bearish or the slice is empty.
Sourcepub fn win_rate(bars: &[OhlcvBar]) -> Option<f64>
pub fn win_rate(bars: &[OhlcvBar]) -> Option<f64>
Fraction of bullish bars in a slice: bullish_count / total.
Returns None if the slice is empty. Result is in [0.0, 1.0].
Sourcepub fn max_drawdown(bars: &[OhlcvBar]) -> Option<f64>
pub fn max_drawdown(bars: &[OhlcvBar]) -> Option<f64>
Maximum drawdown of close prices across a slice of bars.
Computed as the largest percentage decline from a running close peak:
max_drawdown = max over i of (peak_close_before_i - close_i) / peak_close_before_i.
Returns None if the slice has fewer than 2 bars or if all closes are zero.
Result is in [0.0, ∞) — a value of 0.05 means a 5% drawdown.
Sourcepub fn linear_regression_slope(bars: &[OhlcvBar]) -> Option<f64>
pub fn linear_regression_slope(bars: &[OhlcvBar]) -> Option<f64>
Ordinary least-squares slope of close prices across a slice of bars.
Fits the line close[i] = slope × i + intercept using simple linear
regression, where i is the bar index (0-based). A positive slope
indicates an upward trend; negative indicates a downtrend.
Returns None if the slice has fewer than 2 bars or if the closes
cannot be converted to f64.
Sourcepub fn volume_slope(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_slope(bars: &[OhlcvBar]) -> Option<f64>
OLS linear regression slope of bar volumes over bar index.
Positive means volume is trending up; negative means trending down.
Returns None for fewer than 2 bars or if volumes can’t be converted to f64.
Sourcepub fn mean_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn mean_close(bars: &[OhlcvBar]) -> Option<Decimal>
Arithmetic mean of close prices across a slice of bars.
Returns None if the slice is empty.
Sourcepub fn close_std_dev(bars: &[OhlcvBar]) -> Option<f64>
pub fn close_std_dev(bars: &[OhlcvBar]) -> Option<f64>
Population standard deviation of close prices across a slice of bars.
Returns None if the slice has fewer than 2 bars or if closes cannot
be converted to f64.
Sourcepub fn price_efficiency_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn price_efficiency_ratio(bars: &[OhlcvBar]) -> Option<f64>
Elder’s efficiency ratio: |close[last] − close[first]| / Σ|range(bar)|.
Measures how directionally efficient price movement is across the slice.
A value close to 1 means price moved cleanly; near 0 means choppy.
Returns None if the slice has fewer than 2 bars or total range is zero.
Sourcepub fn mean_clv(bars: &[OhlcvBar]) -> Option<f64>
pub fn mean_clv(bars: &[OhlcvBar]) -> Option<f64>
Mean CLV across a slice of bars; None for an empty slice or
if any CLV cannot be computed.
Sourcepub fn mean_range(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn mean_range(bars: &[OhlcvBar]) -> Option<Decimal>
Mean of the high-low range (H − L) across the slice.
Returns None if the slice is empty.
Sourcepub fn close_z_score(bars: &[OhlcvBar], value: Decimal) -> Option<f64>
pub fn close_z_score(bars: &[OhlcvBar], value: Decimal) -> Option<f64>
Z-score of value relative to the close price series.
Returns None if the slice has fewer than 2 bars or the standard
deviation is zero.
Sourcepub fn bollinger_band_width(bars: &[OhlcvBar]) -> Option<f64>
pub fn bollinger_band_width(bars: &[OhlcvBar]) -> Option<f64>
Normalised Bollinger Band width: 2 × close_std_dev / mean_close.
Returns None if mean_close is zero or the slice is too small.
Sourcepub fn up_down_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn up_down_ratio(bars: &[OhlcvBar]) -> Option<f64>
Ratio of bullish bars to bearish bars in the slice.
Returns None if there are no bearish bars.
Sourcepub fn volume_weighted_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn volume_weighted_close(bars: &[OhlcvBar]) -> Option<Decimal>
Volume-weighted average close price across the slice.
Returns None if the slice is empty or total volume is zero.
Sourcepub fn rolling_return(bars: &[OhlcvBar]) -> Option<f64>
pub fn rolling_return(bars: &[OhlcvBar]) -> Option<f64>
Percentage change in close price from the first bar to the last.
Returns None if the slice has fewer than 2 bars or the first
close is zero.
Sourcepub fn average_high(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn average_high(bars: &[OhlcvBar]) -> Option<Decimal>
Mean of the high prices across the slice.
Returns None if the slice is empty.
Sourcepub fn average_low(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn average_low(bars: &[OhlcvBar]) -> Option<Decimal>
Mean of the low prices across the slice.
Returns None if the slice is empty.
Sourcepub fn min_body(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn min_body(bars: &[OhlcvBar]) -> Option<Decimal>
Minimum bar body size (|close − open|) across the slice.
Returns None if the slice is empty.
Sourcepub fn max_body(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn max_body(bars: &[OhlcvBar]) -> Option<Decimal>
Maximum bar body size (|close − open|) across the slice.
Returns None if the slice is empty.
Sourcepub fn atr_pct(bars: &[OhlcvBar]) -> Option<f64>
pub fn atr_pct(bars: &[OhlcvBar]) -> Option<f64>
Average True Range expressed as a fraction of the mean close price.
Returns None if the slice has fewer than 2 bars or mean close is zero.
Sourcepub fn breakout_count(bars: &[OhlcvBar]) -> usize
pub fn breakout_count(bars: &[OhlcvBar]) -> usize
Count of bars (from index 1 onward) whose close strictly exceeds the previous bar’s high — i.e., upside breakout bars.
Sourcepub fn doji_count(bars: &[OhlcvBar], epsilon: Decimal) -> usize
pub fn doji_count(bars: &[OhlcvBar], epsilon: Decimal) -> usize
Count of doji bars (|close − open| ≤ epsilon) in the slice.
Sourcepub fn channel_width(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn channel_width(bars: &[OhlcvBar]) -> Option<Decimal>
Full channel width: highest_high − lowest_low across the slice.
Returns None if the slice is empty.
Sourcepub fn sma(bars: &[OhlcvBar], n: usize) -> Option<Decimal>
pub fn sma(bars: &[OhlcvBar], n: usize) -> Option<Decimal>
Simple moving average of the last n close prices.
Returns None if n is zero or the slice has fewer than n bars.
Sourcepub fn mean_wick_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn mean_wick_ratio(bars: &[OhlcvBar]) -> Option<f64>
Mean wick ratio (upper_wick + lower_wick) / range across the slice.
Bars where range is zero are excluded. Returns None if the slice is
empty or all bars have zero range.
Sourcepub fn bullish_volume(bars: &[OhlcvBar]) -> Decimal
pub fn bullish_volume(bars: &[OhlcvBar]) -> Decimal
Total volume of all bullish (close ≥ open) bars in the slice.
Sourcepub fn bearish_volume(bars: &[OhlcvBar]) -> Decimal
pub fn bearish_volume(bars: &[OhlcvBar]) -> Decimal
Total volume of all bearish (close < open) bars in the slice.
Sourcepub fn close_above_mid_count(bars: &[OhlcvBar]) -> usize
pub fn close_above_mid_count(bars: &[OhlcvBar]) -> usize
Count of bars where close is strictly above the bar midpoint ((high + low) / 2).
Sourcepub fn ema(bars: &[OhlcvBar], alpha: f64) -> Option<f64>
pub fn ema(bars: &[OhlcvBar], alpha: f64) -> Option<f64>
Exponential moving average of close prices over the slice.
alpha is the smoothing factor in (0.0, 1.0]; higher values weight
recent bars more. Processes bars in order (oldest to newest).
Returns None if the slice is empty.
Sourcepub fn highest_open(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn highest_open(bars: &[OhlcvBar]) -> Option<Decimal>
Maximum open price across the slice.
Returns None if the slice is empty.
Sourcepub fn lowest_open(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn lowest_open(bars: &[OhlcvBar]) -> Option<Decimal>
Minimum open price across the slice.
Returns None if the slice is empty.
Sourcepub fn rising_close_count(bars: &[OhlcvBar]) -> usize
pub fn rising_close_count(bars: &[OhlcvBar]) -> usize
Count of bars (from index 1 onward) where close is strictly greater than the previous bar’s close.
Sourcepub fn mean_body_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn mean_body_ratio(bars: &[OhlcvBar]) -> Option<f64>
Mean body-to-range ratio across the slice.
Bars with zero range are excluded.
Returns None if the slice is empty or all bars have zero range.
Sourcepub fn volume_std_dev(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_std_dev(bars: &[OhlcvBar]) -> Option<f64>
Sample standard deviation of bar volumes across the slice.
Returns None if the slice has fewer than 2 bars.
Sourcepub fn max_volume_bar(bars: &[OhlcvBar]) -> Option<&OhlcvBar>
pub fn max_volume_bar(bars: &[OhlcvBar]) -> Option<&OhlcvBar>
Bar with the highest volume in the slice.
Returns None if the slice is empty.
Sourcepub fn min_volume_bar(bars: &[OhlcvBar]) -> Option<&OhlcvBar>
pub fn min_volume_bar(bars: &[OhlcvBar]) -> Option<&OhlcvBar>
Bar with the lowest volume in the slice.
Returns None if the slice is empty.
Sourcepub fn gap_sum(bars: &[OhlcvBar]) -> Decimal
pub fn gap_sum(bars: &[OhlcvBar]) -> Decimal
Sum of gap-open amounts: Σ (open[n] − close[n−1]) for n ≥ 1.
A positive value indicates upward gaps dominate; negative means downward.
Sourcepub fn three_white_soldiers(bars: &[OhlcvBar]) -> bool
pub fn three_white_soldiers(bars: &[OhlcvBar]) -> bool
Returns true if the last three bars form a “three white soldiers” pattern:
three consecutive bullish (close > open) bars, each closing above the prior bar’s close.
Sourcepub fn three_black_crows(bars: &[OhlcvBar]) -> bool
pub fn three_black_crows(bars: &[OhlcvBar]) -> bool
Returns true if the last three bars form a “three black crows” pattern:
three consecutive bearish (close < open) bars, each closing below the prior bar’s close.
Sourcepub fn is_gap_bar(bar: &OhlcvBar, prev_close: Decimal) -> bool
pub fn is_gap_bar(bar: &OhlcvBar, prev_close: Decimal) -> bool
Returns true if the bar opened with a gap relative to prev_close
(i.e. open != prev_close).
Sourcepub fn gap_bars_count(bars: &[OhlcvBar]) -> usize
pub fn gap_bars_count(bars: &[OhlcvBar]) -> usize
Counts consecutive-pair windows where a gap exists (open != prior close).
Sourcepub fn bar_efficiency(bar: &OhlcvBar) -> Option<f64>
pub fn bar_efficiency(bar: &OhlcvBar) -> Option<f64>
Bar efficiency: ratio of net price move to total range.
(close - open).abs() / (high - low). Returns None for a zero-range bar.
Sourcepub fn wicks_sum(bars: &[OhlcvBar]) -> Decimal
pub fn wicks_sum(bars: &[OhlcvBar]) -> Decimal
Sum of upper and lower wick lengths for each bar.
Upper wick = high - close.max(open), lower wick = close.min(open) - low.
Sourcepub fn avg_close_to_high(bars: &[OhlcvBar]) -> Option<f64>
pub fn avg_close_to_high(bars: &[OhlcvBar]) -> Option<f64>
Mean of (high - close) across all bars — average distance from close to high.
Returns None for an empty slice.
Sourcepub fn avg_range(bars: &[OhlcvBar]) -> Option<f64>
pub fn avg_range(bars: &[OhlcvBar]) -> Option<f64>
Mean of (high - low) across all bars.
Returns None for an empty slice.
Sourcepub fn max_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn max_close(bars: &[OhlcvBar]) -> Option<Decimal>
Maximum close price in the slice.
Returns None for an empty slice.
Sourcepub fn min_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn min_close(bars: &[OhlcvBar]) -> Option<Decimal>
Minimum close price in the slice.
Returns None for an empty slice.
Sourcepub fn trend_strength(bars: &[OhlcvBar]) -> Option<f64>
pub fn trend_strength(bars: &[OhlcvBar]) -> Option<f64>
Trend strength: fraction of consecutive close-to-close moves that are upward.
Returns None if fewer than 2 bars.
Sourcepub fn net_change(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn net_change(bars: &[OhlcvBar]) -> Option<Decimal>
Net price change: close - open for the last bar.
Returns None for an empty slice.
Sourcepub fn open_to_close_pct(bars: &[OhlcvBar]) -> Option<f64>
pub fn open_to_close_pct(bars: &[OhlcvBar]) -> Option<f64>
Percentage change from open to close for the last bar: (close - open) / open * 100.
Returns None for an empty slice or zero open.
Sourcepub fn high_to_low_pct(bars: &[OhlcvBar]) -> Option<f64>
pub fn high_to_low_pct(bars: &[OhlcvBar]) -> Option<f64>
Percentage of high-to-low range relative to high: (high - low) / high * 100.
Returns None for an empty slice or zero high.
Sourcepub fn consecutive_highs(bars: &[OhlcvBar]) -> usize
pub fn consecutive_highs(bars: &[OhlcvBar]) -> usize
Count of consecutive bars (from the end) where high is strictly higher than the prior high.
Sourcepub fn consecutive_lows(bars: &[OhlcvBar]) -> usize
pub fn consecutive_lows(bars: &[OhlcvBar]) -> usize
Count of consecutive bars (from the end) where low is strictly lower than the prior low.
Sourcepub fn volume_change_pct(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_change_pct(bars: &[OhlcvBar]) -> Option<f64>
Percentage change in volume from one bar to the next (last bar vs prior bar).
Returns None if fewer than 2 bars or prior volume is zero.
Sourcepub fn open_gap_pct(bars: &[OhlcvBar]) -> Option<f64>
pub fn open_gap_pct(bars: &[OhlcvBar]) -> Option<f64>
Gap percentage between consecutive bars: (bar.open - prev.close) / prev.close * 100.
Returns None if fewer than 2 bars or previous close is zero.
Sourcepub fn volume_cumulative(bars: &[OhlcvBar]) -> Decimal
pub fn volume_cumulative(bars: &[OhlcvBar]) -> Decimal
Cumulative volume across all bars.
Sourcepub fn price_position(bars: &[OhlcvBar]) -> Option<f64>
pub fn price_position(bars: &[OhlcvBar]) -> Option<f64>
Position of the last bar’s close within the overall high-low range of all bars.
Returns (close - lowest_low) / (highest_high - lowest_low).
Returns None if the slice is empty or range is zero.
Sourcepub fn is_trending_up(bars: &[OhlcvBar], n: usize) -> bool
pub fn is_trending_up(bars: &[OhlcvBar], n: usize) -> bool
Returns true if the last n closes form a strict uptrend.
Each close must be strictly greater than the previous. Returns false
if n < 2 or the slice has fewer than n bars.
Sourcepub fn is_trending_down(bars: &[OhlcvBar], n: usize) -> bool
pub fn is_trending_down(bars: &[OhlcvBar], n: usize) -> bool
Returns true if the last n closes form a strict downtrend.
Each close must be strictly less than the previous. Returns false
if n < 2 or the slice has fewer than n bars.
Sourcepub fn volume_acceleration(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_acceleration(bars: &[OhlcvBar]) -> Option<f64>
Percentage change in volume between the last two bars.
Returns None if fewer than 2 bars or if the previous bar’s volume is
zero.
Sourcepub fn wick_body_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn wick_body_ratio(bars: &[OhlcvBar]) -> Option<f64>
Mean ratio of total wick length to body size across all bars.
For each bar: (upper_wick + lower_wick) / body. Bars with a zero body
are skipped. Returns None if no valid bars exist.
Sourcepub fn close_above_open_count(bars: &[OhlcvBar]) -> usize
pub fn close_above_open_count(bars: &[OhlcvBar]) -> usize
Count of bars where close > open (bullish bars).
Sourcepub fn volume_price_correlation(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_price_correlation(bars: &[OhlcvBar]) -> Option<f64>
Pearson correlation between per-bar volume and close price.
Returns None if fewer than 2 bars or if either series has zero
variance.
Sourcepub fn body_consistency(bars: &[OhlcvBar]) -> Option<f64>
pub fn body_consistency(bars: &[OhlcvBar]) -> Option<f64>
Fraction of bars where body size exceeds 50% of the bar’s total range.
Returns None if the slice is empty or all bars have zero range.
Sourcepub fn close_volatility_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn close_volatility_ratio(bars: &[OhlcvBar]) -> Option<f64>
Coefficient of variation of close prices: std_dev(close) / mean(close).
A dimensionless measure of close price dispersion. Returns None if
fewer than 2 bars or if mean close is zero.
Sourcepub fn close_momentum_score(bars: &[OhlcvBar]) -> Option<f64>
pub fn close_momentum_score(bars: &[OhlcvBar]) -> Option<f64>
Rolling close momentum score: fraction of bars where close is above the simple average close of the window.
Returns None if the slice is empty or the mean cannot be computed.
Sourcepub fn range_expansion_count(bars: &[OhlcvBar]) -> usize
pub fn range_expansion_count(bars: &[OhlcvBar]) -> usize
Count of bars where the range (high - low) exceeds the preceding bar’s range (i.e., the bar “expands” relative to the prior bar).
Returns 0 if fewer than 2 bars.
Sourcepub fn gap_count(bars: &[OhlcvBar]) -> usize
pub fn gap_count(bars: &[OhlcvBar]) -> usize
Count of bars where the open gaps away from the previous bar’s close
(absolute gap > zero, i.e., open != prev_close).
Sourcepub fn avg_wick_size(bars: &[OhlcvBar]) -> Option<f64>
pub fn avg_wick_size(bars: &[OhlcvBar]) -> Option<f64>
Mean total wick size (upper + lower wick) across all bars.
Returns None if the slice is empty.
Sourcepub fn mean_volume_ratio(bars: &[OhlcvBar]) -> Vec<Option<f64>>
pub fn mean_volume_ratio(bars: &[OhlcvBar]) -> Vec<Option<f64>>
Ratio of each bar’s volume to the mean volume of the window.
Returns a Vec of Option<f64> — None entries indicate bars where
the mean cannot be computed (e.g., empty slice) or the conversion
failed. Returns an empty Vec for an empty slice.
Sourcepub fn close_above_high_ma(bars: &[OhlcvBar], n: usize) -> usize
pub fn close_above_high_ma(bars: &[OhlcvBar], n: usize) -> usize
Count of bars where close > n-bar simple moving average of highs.
Returns 0 if n < 1 or the slice has fewer than n bars.
Sourcepub fn price_compression_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn price_compression_ratio(bars: &[OhlcvBar]) -> Option<f64>
Price compression ratio: mean_body / mean_range.
A value near 1 indicates full-body candles (strong directional moves);
near 0 indicates indecision or doji-heavy periods. Returns None if
the slice is empty or mean range is zero.
Sourcepub fn open_close_spread(bars: &[OhlcvBar]) -> Option<f64>
pub fn open_close_spread(bars: &[OhlcvBar]) -> Option<f64>
Mean absolute difference between open and close across all bars.
Returns None if the slice is empty.
Sourcepub fn max_consecutive_gains(bars: &[OhlcvBar]) -> usize
pub fn max_consecutive_gains(bars: &[OhlcvBar]) -> usize
Longest run of consecutive bars with strictly rising closes.
Sourcepub fn max_consecutive_losses(bars: &[OhlcvBar]) -> usize
pub fn max_consecutive_losses(bars: &[OhlcvBar]) -> usize
Longest run of consecutive bars with strictly falling closes.
Sourcepub fn price_path_length(bars: &[OhlcvBar]) -> Option<f64>
pub fn price_path_length(bars: &[OhlcvBar]) -> Option<f64>
Total path length of close prices: sum of absolute consecutive changes.
Measures how much the close price “travels” over the window. A high
value relative to the net change indicates choppy price action.
Returns None if fewer than 2 bars.
Sourcepub fn close_reversion_count(bars: &[OhlcvBar]) -> usize
pub fn close_reversion_count(bars: &[OhlcvBar]) -> usize
Count of bars where the close reverts toward the window mean (i.e., the bar’s close is between the previous close and the window mean close).
Returns 0 if fewer than 2 bars or no mean can be computed.
Sourcepub fn atr_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn atr_ratio(bars: &[OhlcvBar]) -> Option<f64>
ATR as a fraction of the mean close price.
ATR / mean_close * 100. A dimensionless volatility measure. Returns
None if fewer than 2 bars or if mean close is zero.
Sourcepub fn volume_trend_strength(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_trend_strength(bars: &[OhlcvBar]) -> Option<f64>
Pearson correlation between bar index and volume — a measure of whether volume is trending up or down over the window.
Returns None if fewer than 2 bars or if either series has zero variance.
Sourcepub fn high_close_spread(bars: &[OhlcvBar]) -> Option<f64>
pub fn high_close_spread(bars: &[OhlcvBar]) -> Option<f64>
Mean spread between high and close across all bars.
mean(high - close). Always ≥ 0 since high ≥ close by definition.
Returns None if the slice is empty.
Sourcepub fn open_range(bars: &[OhlcvBar]) -> Option<f64>
pub fn open_range(bars: &[OhlcvBar]) -> Option<f64>
Mean open-to-first-close range for the session opening bar.
Defined as the absolute distance |close - open| averaged over all
bars. Equivalent to [open_close_spread] but named for discoverability.
Returns None if the slice is empty.
Sourcepub fn normalized_close(bars: &[OhlcvBar]) -> Option<f64>
pub fn normalized_close(bars: &[OhlcvBar]) -> Option<f64>
Normalised close: last close as a fraction of the window’s close range.
(last_close - min_close) / (max_close - min_close). Returns None
if fewer than 2 bars or the close range is zero.
Sourcepub fn price_channel_position(bars: &[OhlcvBar]) -> Option<f64>
pub fn price_channel_position(bars: &[OhlcvBar]) -> Option<f64>
Price channel position: where the last close falls in the
[lowest_low, highest_high] range.
(last_close - lowest_low) / (highest_high - lowest_low). Returns
None if the slice is empty or the range is zero.
Sourcepub fn candle_score(bars: &[OhlcvBar]) -> Option<f64>
pub fn candle_score(bars: &[OhlcvBar]) -> Option<f64>
Composite candle score: fraction of bars that are bullish, have a body above 50% of range, and close above the midpoint of the bar.
Returns None if the slice is empty.
Sourcepub fn bar_speed(bars: &[OhlcvBar]) -> Option<f64>
pub fn bar_speed(bars: &[OhlcvBar]) -> Option<f64>
Mean number of ticks per millisecond of bar duration.
tick_count / bar_duration_ms. Returns None if the slice is empty
or the total duration across bars is zero.
Sourcepub fn higher_highs_count(bars: &[OhlcvBar]) -> usize
pub fn higher_highs_count(bars: &[OhlcvBar]) -> usize
Count of bars where the high is strictly greater than the previous bar’s high.
Returns 0 if fewer than 2 bars.
Sourcepub fn lower_lows_count(bars: &[OhlcvBar]) -> usize
pub fn lower_lows_count(bars: &[OhlcvBar]) -> usize
Count of bars where the low is strictly less than the previous bar’s low.
Returns 0 if fewer than 2 bars.
Sourcepub fn close_minus_open_pct(bars: &[OhlcvBar]) -> Option<f64>
pub fn close_minus_open_pct(bars: &[OhlcvBar]) -> Option<f64>
Mean (close - open) / open * 100 across all bars.
Bars with zero open are skipped. Returns None if no valid bars.
Sourcepub fn volume_per_range(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_per_range(bars: &[OhlcvBar]) -> Option<f64>
Mean volume per unit of bar range.
volume / (high - low). Bars with zero range are skipped. Returns
None if the slice is empty or all bars have zero range.
Sourcepub fn body_fraction(bars: &[OhlcvBar]) -> Option<f64>
pub fn body_fraction(bars: &[OhlcvBar]) -> Option<f64>
Average body size (|close − open|) as a fraction of total bar range.
Returns None if all bars have zero range or the slice is empty.
Sourcepub fn bullish_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn bullish_ratio(bars: &[OhlcvBar]) -> Option<f64>
Fraction of bars that are bullish (close strictly greater than open).
Returns None if the slice is empty.
Sourcepub fn peak_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn peak_close(bars: &[OhlcvBar]) -> Option<Decimal>
Maximum (highest) close price across all bars.
Returns None if the slice is empty.
Sourcepub fn trough_close(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn trough_close(bars: &[OhlcvBar]) -> Option<Decimal>
Minimum (lowest) close price across all bars.
Returns None if the slice is empty.
Sourcepub fn up_volume_fraction(bars: &[OhlcvBar]) -> Option<f64>
pub fn up_volume_fraction(bars: &[OhlcvBar]) -> Option<f64>
Fraction of total volume that occurred on up-bars (close > open).
Returns None if total volume is zero or the slice is empty.
Sourcepub fn tail_upper_fraction(bars: &[OhlcvBar]) -> Option<f64>
pub fn tail_upper_fraction(bars: &[OhlcvBar]) -> Option<f64>
Average upper wick as a fraction of total bar range.
Upper wick = high − max(open, close). Returns None if all bars have
zero range or the slice is empty.
Sourcepub fn tail_lower_fraction(bars: &[OhlcvBar]) -> Option<f64>
pub fn tail_lower_fraction(bars: &[OhlcvBar]) -> Option<f64>
Average lower wick as a fraction of total bar range.
Lower wick = min(open, close) − low. Returns None if all bars have
zero range or the slice is empty.
Sourcepub fn range_std_dev(bars: &[OhlcvBar]) -> Option<f64>
pub fn range_std_dev(bars: &[OhlcvBar]) -> Option<f64>
Standard deviation of bar ranges (high − low).
Measures consistency of bar volatility. Returns None if fewer than 2
bars are provided.
Sourcepub fn close_to_range_position(bars: &[OhlcvBar]) -> Option<f64>
pub fn close_to_range_position(bars: &[OhlcvBar]) -> Option<f64>
Mean of (close − low) / range across bars — where the close lands
inside each bar’s high-low range.
Returns None if the slice is empty or every bar has zero range.
A value near 1.0 means closes are consistently near the high (bullish);
near 0.0 means closes hug the low (bearish).
Sourcepub fn volume_oscillator(
bars: &[OhlcvBar],
short_n: usize,
long_n: usize,
) -> Option<f64>
pub fn volume_oscillator( bars: &[OhlcvBar], short_n: usize, long_n: usize, ) -> Option<f64>
Volume oscillator: (short_avg_vol − long_avg_vol) / long_avg_vol.
short_n bars are used for the short average and long_n for the long.
Returns None if long_n > bars.len(), short_n == 0, long_n == 0,
short_n >= long_n, or the long average is zero.
A positive result means recent volume is above the longer-term average (expanding volume); negative means volume is contracting.
Sourcepub fn direction_reversal_count(bars: &[OhlcvBar]) -> usize
pub fn direction_reversal_count(bars: &[OhlcvBar]) -> usize
Count of consecutive direction changes: how many times the bar sentiment (bullish / bearish) flips from one bar to the next.
Doji bars (open == close) count as a continuation of the previous direction. Returns 0 for slices shorter than 2.
Sourcepub fn upper_wick_dominance_fraction(bars: &[OhlcvBar]) -> Option<f64>
pub fn upper_wick_dominance_fraction(bars: &[OhlcvBar]) -> Option<f64>
Fraction of bars where the upper wick is strictly longer than the lower wick.
Returns None for an empty slice.
Sourcepub fn avg_open_to_high_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn avg_open_to_high_ratio(bars: &[OhlcvBar]) -> Option<f64>
Mean of (high − open) / range across bars — average fraction of the
bar the price moved up from the open.
Returns None if the slice is empty or every bar has zero range.
Sourcepub fn volume_weighted_range(bars: &[OhlcvBar]) -> Option<f64>
pub fn volume_weighted_range(bars: &[OhlcvBar]) -> Option<f64>
Volume-weighted average of bar range: sum(range × volume) / sum(volume).
Returns None when the slice is empty or total volume is zero.
Sourcepub fn bar_strength_index(bars: &[OhlcvBar]) -> Option<f64>
pub fn bar_strength_index(bars: &[OhlcvBar]) -> Option<f64>
Bar strength index: mean close-location value (CLV) across the slice.
CLV for each bar is (close − low − (high − close)) / range, which
is +1 when close == high and −1 when close == low. Bars with zero
range are excluded.
Returns None when no bars have non-zero range.
Sourcepub fn shadow_to_body_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn shadow_to_body_ratio(bars: &[OhlcvBar]) -> Option<f64>
Ratio of total wick length to total body size across the slice.
Computes sum(upper_wick + lower_wick) / sum(body) where body is
|close − open|. Returns None when total body is zero (all doji
or empty slice).
Sourcepub fn first_last_close_pct(bars: &[OhlcvBar]) -> Option<f64>
pub fn first_last_close_pct(bars: &[OhlcvBar]) -> Option<f64>
Percentage change from the first bar’s close to the last bar’s close.
Computed as (last.close − first.close) / first.close × 100.
Returns None when the slice is empty or the first close is zero.
Sourcepub fn open_to_close_volatility(bars: &[OhlcvBar]) -> Option<f64>
pub fn open_to_close_volatility(bars: &[OhlcvBar]) -> Option<f64>
Standard deviation of per-bar (close − open) / open returns.
Measures intrabar volatility consistency. Returns None when fewer
than 2 bars are provided or every open is zero.
Sourcepub fn close_recovery_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn close_recovery_ratio(bars: &[OhlcvBar]) -> Option<f64>
Mean of (close − low) / range across bars.
Indicates where each close lands within its bar’s high-low range.
Near 1.0 means closes consistently hug the high (bullish);
near 0.0 means closes hug the low (bearish). Bars with zero range
are excluded. Returns None if no bars have non-zero range.
Sourcepub fn median_range(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn median_range(bars: &[OhlcvBar]) -> Option<Decimal>
Median bar range (high − low) across the slice.
Robust to outlier bars with unusually wide or narrow ranges.
Returns None for an empty slice.
Sourcepub fn mean_typical_price(bars: &[OhlcvBar]) -> Option<Decimal>
pub fn mean_typical_price(bars: &[OhlcvBar]) -> Option<Decimal>
Mean typical price (high + low + close) / 3 across the slice.
The typical price is a common single-value summary of a bar used
in pivot-point and money-flow calculations. Returns None if empty.
Sourcepub fn directional_volume_ratio(bars: &[OhlcvBar]) -> Option<f64>
pub fn directional_volume_ratio(bars: &[OhlcvBar]) -> Option<f64>
Ratio of bullish-bar volume to the sum of bullish and bearish volumes.
A value near 1.0 means almost all volume is in up-bars; near 0.0
means down-bars dominate. Returns None when both are zero (e.g.,
all flat/neutral bars).
Sourcepub fn inside_bar_fraction(bars: &[OhlcvBar]) -> Option<f64>
pub fn inside_bar_fraction(bars: &[OhlcvBar]) -> Option<f64>
Fraction of bars (from the second onward) that are inside bars.
An inside bar has a high ≤ previous high and low ≥ previous low.
Returns None if the slice has fewer than 2 bars.
Sourcepub fn body_momentum(bars: &[OhlcvBar]) -> Decimal
pub fn body_momentum(bars: &[OhlcvBar]) -> Decimal
Net body momentum: sum of signed body sizes across all bars.
Bullish bars contribute +(close − open); bearish bars contribute
−(open − close); flat bars contribute 0. A positive total
indicates the bars collectively closed higher than they opened.
Sourcepub fn avg_trade_count(bars: &[OhlcvBar]) -> Option<f64>
pub fn avg_trade_count(bars: &[OhlcvBar]) -> Option<f64>
Mean trade_count (ticks per bar) across the slice.
Returns None if the slice is empty.
Sourcepub fn max_trade_count(bars: &[OhlcvBar]) -> Option<u64>
pub fn max_trade_count(bars: &[OhlcvBar]) -> Option<u64>
Maximum trade_count seen across the slice.
Returns None if the slice is empty.