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 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
pub fn inside_bar(&self, prev: &OhlcvBar) -> bool
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 price_change_abs(&self) -> Decimal
pub fn price_change_abs(&self) -> Decimal
Absolute price change over the bar: |close − open|.
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 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
pub fn is_outside_bar(&self, prev: &OhlcvBar) -> bool
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.
Sourcepub fn high_low_midpoint(&self) -> Decimal
pub fn high_low_midpoint(&self) -> Decimal
Midpoint of the high-low range: (high + low) / 2.
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
pub fn close_gap(&self, prev: &OhlcvBar) -> Decimal
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.
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_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).
Sourcepub fn true_range_with_prev(&self, prev_close: Decimal) -> Decimal
pub fn true_range_with_prev(&self, prev_close: Decimal) -> Decimal
True range: max(high - low, |high - prev_close|, |low - prev_close|).
This is the ATR building block. Without a previous close, returns high - low.
Sourcepub fn close_to_high_ratio(&self) -> Option<f64>
pub fn close_to_high_ratio(&self) -> Option<f64>
Returns the ratio of close to high, or None if high is zero.
Sourcepub fn close_open_ratio(&self) -> Option<f64>
pub fn close_open_ratio(&self) -> Option<f64>
Returns the ratio of close to open, or None if open is zero.
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.