pub struct NormalizedTick {
pub exchange: Exchange,
pub symbol: String,
pub price: Decimal,
pub quantity: Decimal,
pub side: Option<TradeSide>,
pub trade_id: Option<String>,
pub exchange_ts_ms: Option<u64>,
pub received_at_ms: u64,
}Expand description
Canonical normalized tick — exchange-agnostic.
Fields§
§exchange: ExchangeSource exchange.
symbol: StringInstrument symbol in the canonical form used by this crate.
price: DecimalTrade price (exact decimal, never f64).
quantity: DecimalTrade quantity (exact decimal).
side: Option<TradeSide>Direction of the aggressing order, if available from the exchange.
trade_id: Option<String>Exchange-assigned trade identifier, if available.
exchange_ts_ms: Option<u64>Exchange-side timestamp (ms since Unix epoch), if included in the feed.
received_at_ms: u64Local system-clock timestamp when this tick was received.
Implementations§
Source§impl NormalizedTick
impl NormalizedTick
Sourcepub fn value(&self) -> Decimal
pub fn value(&self) -> Decimal
Notional trade value: price × quantity.
Returns the total value transferred in this trade. Useful for VWAP calculations and volume-weighted aggregations without requiring callers to multiply at every use site.
See also volume_notional, notional_value,
and dollar_value, which are all aliases.
Sourcepub fn age_ms(&self, now_ms: u64) -> u64
pub fn age_ms(&self, now_ms: u64) -> u64
Age of this tick in milliseconds relative to now_ms.
Returns now_ms - received_at_ms, saturating at zero (never negative).
Useful for staleness checks: tick.age_ms(now) > threshold_ms.
See also quote_age_ms, which is an alias.
Sourcepub fn is_stale(&self, now_ms: u64, threshold_ms: u64) -> bool
pub fn is_stale(&self, now_ms: u64, threshold_ms: u64) -> bool
Returns true if this tick is older than threshold_ms relative to now_ms.
Equivalent to self.age_ms(now_ms) > threshold_ms. Use this for filtering
stale ticks before passing them into aggregation pipelines.
Sourcepub fn is_buy(&self) -> bool
pub fn is_buy(&self) -> bool
Returns true if the tick is a buyer-initiated trade.
Returns false if side is Sell or None (side unknown).
Sourcepub fn is_sell(&self) -> bool
pub fn is_sell(&self) -> bool
Returns true if the tick is a seller-initiated trade.
Returns false if side is Buy or None (side unknown).
Sourcepub fn is_neutral(&self) -> bool
pub fn is_neutral(&self) -> bool
Returns true if the trade side is unknown (None).
Many exchanges do not report the aggressor side. This method lets
callers explicitly test for the “no side information” case rather than
relying on both is_buy() and is_sell() returning false.
Sourcepub fn is_large_trade(&self, threshold: Decimal) -> bool
pub fn is_large_trade(&self, threshold: Decimal) -> bool
Returns true if the traded quantity meets or exceeds threshold.
Useful for isolating institutional-size trades (“block trades”) from
the general flow. The threshold is in the same units as quantity.
Sourcepub fn with_side(self, side: TradeSide) -> Self
pub fn with_side(self, side: TradeSide) -> Self
Return a copy of this tick with the trade side set to side.
Useful in tests and feed normalizers that determine the aggressor side after initial tick construction.
Sourcepub fn with_exchange_ts(self, ts_ms: u64) -> Self
pub fn with_exchange_ts(self, ts_ms: u64) -> Self
Return a copy of this tick with the exchange timestamp set to ts_ms.
Useful in tests and feed normalizers to inject an authoritative exchange timestamp after the tick has already been constructed.
Sourcepub fn price_move_from(&self, prev: &NormalizedTick) -> Decimal
pub fn price_move_from(&self, prev: &NormalizedTick) -> Decimal
Signed price movement from prev to this tick: self.price − prev.price.
Positive when price rose, negative when price fell, zero when unchanged. Only meaningful when both ticks share the same symbol and exchange.
Sourcepub fn is_more_recent_than(&self, other: &NormalizedTick) -> bool
pub fn is_more_recent_than(&self, other: &NormalizedTick) -> bool
Returns true if this tick arrived more recently than other.
Compares received_at_ms timestamps. Equal timestamps return false.
Sourcepub fn latency_ms(&self) -> Option<i64>
pub fn latency_ms(&self) -> Option<i64>
Transport latency in milliseconds: received_at_ms − exchange_ts_ms.
Returns None if the exchange timestamp is unavailable. A positive
value indicates how long the tick took to travel from exchange to this
system; negative values suggest clock skew between exchange and consumer.
See also exchange_latency_ms, which is an alias.
Sourcepub fn volume_notional(&self) -> Decimal
pub fn volume_notional(&self) -> Decimal
Notional value of this trade: price × quantity.
Alias for value.
Sourcepub fn has_exchange_ts(&self) -> bool
pub fn has_exchange_ts(&self) -> bool
Returns true if this tick carries an exchange-provided timestamp.
When false, only the local received_at_ms is available. Use
latency_ms to measure round-trip latency when
this returns true.
Sourcepub fn side_str(&self) -> &'static str
pub fn side_str(&self) -> &'static str
Human-readable trade direction: "buy", "sell", or "unknown".
Sourcepub fn is_round_lot(&self) -> bool
pub fn is_round_lot(&self) -> bool
Returns true if the quantity is a whole number (no fractional part).
Useful for detecting atypical fractional order sizes, or as a simple round-lot check in integer-quantity markets.
Sourcepub fn is_same_symbol_as(&self, other: &NormalizedTick) -> bool
pub fn is_same_symbol_as(&self, other: &NormalizedTick) -> bool
Returns true if this tick’s symbol matches other’s symbol exactly.
Sourcepub fn price_distance_from(&self, other: &NormalizedTick) -> Decimal
pub fn price_distance_from(&self, other: &NormalizedTick) -> Decimal
Absolute price difference between this tick and other.
Returns |self.price - other.price|. Useful for computing price drift
between two ticks of the same instrument without caring about direction.
Sourcepub fn exchange_latency_ms(&self) -> Option<i64>
pub fn exchange_latency_ms(&self) -> Option<i64>
Signed latency between the local receipt timestamp and the exchange timestamp, in milliseconds.
Alias for latency_ms.
Sourcepub fn is_notional_large_trade(&self, threshold: Decimal) -> bool
pub fn is_notional_large_trade(&self, threshold: Decimal) -> bool
Returns true if the notional value of this trade (price × quantity)
exceeds threshold.
Unlike is_large_trade (which compares raw
quantity), this method uses the trade’s dollar value, making it useful
for comparing block-trade size across instruments with different prices.
Sourcepub fn is_zero_price(&self) -> bool
pub fn is_zero_price(&self) -> bool
Returns true if this tick’s price is zero.
A zero price typically indicates a malformed or uninitialized tick.
Sourcepub fn is_fresh(&self, now_ms: u64, max_age_ms: u64) -> bool
pub fn is_fresh(&self, now_ms: u64, max_age_ms: u64) -> bool
Returns true if the tick is still fresh relative to now_ms.
“Fresh” means the tick arrived within the last max_age_ms milliseconds.
Returns false when now_ms < ts_ms (clock skew guard).
Sourcepub fn is_above(&self, price: Decimal) -> bool
pub fn is_above(&self, price: Decimal) -> bool
Returns true if this tick’s price is strictly above price.
Sourcepub fn is_below(&self, price: Decimal) -> bool
pub fn is_below(&self, price: Decimal) -> bool
Returns true if this tick’s price is strictly below price.
Sourcepub fn is_aggressive(&self) -> bool
pub fn is_aggressive(&self) -> bool
Returns true if the tick has a definite direction (buy or sell).
Neutral ticks (where side is None) return false.
Sourcepub fn price_diff_from(&self, other: &NormalizedTick) -> Decimal
👎Deprecated since 2.2.0: Use price_move_from instead
pub fn price_diff_from(&self, other: &NormalizedTick) -> Decimal
Use price_move_from instead
Signed price difference: self.price - other.price.
Alias for price_move_from.
Sourcepub fn is_micro_trade(&self, threshold: Decimal) -> bool
pub fn is_micro_trade(&self, threshold: Decimal) -> bool
Returns true if the trade quantity is strictly less than threshold.
The inverse of is_large_trade.
Sourcepub fn is_buying_pressure(&self, midpoint: Decimal) -> bool
pub fn is_buying_pressure(&self, midpoint: Decimal) -> bool
Returns true if this tick occurred above the given midpoint price.
A tick above the midpoint is typically associated with buying pressure.
Sourcepub fn age_secs(&self, now_ms: u64) -> f64
pub fn age_secs(&self, now_ms: u64) -> f64
Age of this tick in seconds: (now_ms - received_at_ms) / 1000.0.
Returns 0.0 if now_ms is before received_at_ms.
Sourcepub fn is_same_exchange_as(&self, other: &NormalizedTick) -> bool
pub fn is_same_exchange_as(&self, other: &NormalizedTick) -> bool
Returns true if this tick originated from the same exchange as other.
Sourcepub fn quote_age_ms(&self, now_ms: u64) -> u64
👎Deprecated since 2.2.0: Use age_ms instead
pub fn quote_age_ms(&self, now_ms: u64) -> u64
Use age_ms instead
Age of this tick in milliseconds: now_ms - received_at_ms.
Alias for age_ms.
Sourcepub fn notional_value(&self) -> Decimal
👎Deprecated since 2.2.0: Use value instead
pub fn notional_value(&self) -> Decimal
Use value instead
Notional value of this tick: price × quantity.
Alias for value.
Sourcepub fn is_high_value_tick(&self, threshold: Decimal) -> bool
👎Deprecated since 2.2.0: Use is_notional_large_trade instead
pub fn is_high_value_tick(&self, threshold: Decimal) -> bool
Use is_notional_large_trade instead
Returns true if the notional value (price × quantity) exceeds threshold.
Alias for is_notional_large_trade.
Sourcepub fn side_as_str(&self) -> Option<&'static str>
pub fn side_as_str(&self) -> Option<&'static str>
Returns the trade side as a string slice: "buy", "sell", or None.
Sourcepub fn is_above_price(&self, reference: Decimal) -> bool
👎Deprecated since 2.2.0: Use is_above instead
pub fn is_above_price(&self, reference: Decimal) -> bool
Use is_above instead
Returns true if this tick’s price is strictly above reference.
Alias for is_above.
Sourcepub fn price_change_from(&self, reference: Decimal) -> Decimal
pub fn price_change_from(&self, reference: Decimal) -> Decimal
Signed price change relative to reference: self.price - reference.
Sourcepub fn is_market_open_tick(
&self,
session_start_ms: u64,
session_end_ms: u64,
) -> bool
pub fn is_market_open_tick( &self, session_start_ms: u64, session_end_ms: u64, ) -> bool
Returns true if this tick’s received_at_ms falls within a trading session window.
Sourcepub fn is_at_price(&self, target: Decimal) -> bool
👎Deprecated since 2.2.0: Use is_at instead
pub fn is_at_price(&self, target: Decimal) -> bool
Use is_at instead
Returns true if this tick’s price exactly equals target.
Alias for is_at.
Sourcepub fn is_below_price(&self, reference: Decimal) -> bool
👎Deprecated since 2.2.0: Use is_below instead
pub fn is_below_price(&self, reference: Decimal) -> bool
Use is_below instead
Returns true if this tick’s price is strictly below reference.
Alias for is_below.
Sourcepub fn is_round_number(&self, step: Decimal) -> bool
pub fn is_round_number(&self, step: Decimal) -> bool
Returns true if this tick’s price is divisible by step with no remainder.
Useful for identifying round-number price levels (e.g., step = 100).
Returns false if step is zero.
Sourcepub fn signed_quantity(&self) -> Decimal
pub fn signed_quantity(&self) -> Decimal
Returns the trade quantity signed by side: +quantity for Buy, -quantity for Sell, 0 for unknown.
Sourcepub fn as_price_level(&self) -> (Decimal, Decimal)
pub fn as_price_level(&self) -> (Decimal, Decimal)
Returns (price, quantity) as a convenient tuple.
Sourcepub fn quantity_above(&self, threshold: Decimal) -> bool
pub fn quantity_above(&self, threshold: Decimal) -> bool
Returns true if this tick’s quantity is strictly above threshold.
Sourcepub fn is_recent(&self, threshold_ms: u64, now_ms: u64) -> bool
👎Deprecated since 2.2.0: Use is_fresh(now_ms, threshold_ms) instead
pub fn is_recent(&self, threshold_ms: u64, now_ms: u64) -> bool
Use is_fresh(now_ms, threshold_ms) instead
Returns true if this tick was received within threshold_ms of now_ms.
Alias for is_fresh(now_ms, threshold_ms).
Sourcepub fn is_buy_side(&self) -> bool
👎Deprecated since 2.2.0: Use is_buy instead
pub fn is_buy_side(&self) -> bool
Use is_buy instead
Returns true if this tick is on the buy side.
Alias for is_buy.
Sourcepub fn is_sell_side(&self) -> bool
👎Deprecated since 2.2.0: Use is_sell instead
pub fn is_sell_side(&self) -> bool
Use is_sell instead
Returns true if this tick is on the sell side.
Alias for is_sell.
Sourcepub fn is_zero_quantity(&self) -> bool
pub fn is_zero_quantity(&self) -> bool
Returns true if this tick’s quantity is zero (may indicate a cancel or correction).
Sourcepub fn is_within_spread(&self, bid: Decimal, ask: Decimal) -> bool
pub fn is_within_spread(&self, bid: Decimal, ask: Decimal) -> bool
Returns true if this tick’s price is strictly between bid and ask.
Sourcepub fn is_away_from_price(&self, reference: Decimal, threshold: Decimal) -> bool
pub fn is_away_from_price(&self, reference: Decimal, threshold: Decimal) -> bool
Returns true if this tick’s price deviates from reference by more than threshold.
Sourcepub fn is_large_tick(&self, threshold: Decimal) -> bool
👎Deprecated since 2.2.0: Use is_large_trade instead
pub fn is_large_tick(&self, threshold: Decimal) -> bool
Use is_large_trade instead
Returns true if this tick’s quantity is strictly above threshold.
Note: unlike is_large_trade which uses >=,
this method uses strict > for backwards compatibility.
Sourcepub fn price_in_range(&self, low: Decimal, high: Decimal) -> bool
pub fn price_in_range(&self, low: Decimal, high: Decimal) -> bool
Returns true if this tick’s price is within [low, high] (inclusive).
Sourcepub fn rounded_price(&self, tick_size: Decimal) -> Decimal
pub fn rounded_price(&self, tick_size: Decimal) -> Decimal
Price rounded down to the nearest multiple of tick_size.
Returns the original price if tick_size is zero.
Sourcepub fn is_large_spread_from(
&self,
other: &NormalizedTick,
threshold: Decimal,
) -> bool
pub fn is_large_spread_from( &self, other: &NormalizedTick, threshold: Decimal, ) -> bool
Returns true if the absolute price difference from other exceeds threshold.
Sourcepub fn volume_notional_f64(&self) -> f64
pub fn volume_notional_f64(&self) -> f64
Notional value of this tick as f64 (price × quantity).
Sourcepub fn price_velocity(
&self,
prev: &NormalizedTick,
dt_ms: u64,
) -> Option<Decimal>
pub fn price_velocity( &self, prev: &NormalizedTick, dt_ms: u64, ) -> Option<Decimal>
Rate of price change relative to a prior tick: (price - prev.price) / dt_ms.
Returns None if dt_ms is zero (same timestamp).
Sourcepub fn is_reversal(&self, prev: &NormalizedTick, min_move: Decimal) -> bool
pub fn is_reversal(&self, prev: &NormalizedTick, min_move: Decimal) -> bool
Returns true if price reversed direction by at least min_move from prev.
A reversal means the direction of (self.price - prev.price) is opposite to
the direction of (prev.price - prev_prev.price), and the magnitude ≥ min_move.
This two-argument form checks: |self.price - prev.price| >= min_move.
Sourcepub fn spread_crossed(
bid_tick: &NormalizedTick,
ask_tick: &NormalizedTick,
) -> bool
pub fn spread_crossed( bid_tick: &NormalizedTick, ask_tick: &NormalizedTick, ) -> bool
Returns true if a trade crossed the spread: bid_tick.price >= ask_tick.price.
A spread-crossed condition indicates an aggressive order consumed the best opposing quote.
Sourcepub fn dollar_value(&self) -> Decimal
pub fn dollar_value(&self) -> Decimal
Dollar (notional) value of this tick: price * quantity.
Alias for value.
Sourcepub fn contract_value(&self, multiplier: Decimal) -> Decimal
pub fn contract_value(&self, multiplier: Decimal) -> Decimal
Contract value using a futures/options multiplier: price * quantity * multiplier.
Sourcepub fn tick_imbalance(ticks: &[NormalizedTick]) -> Option<f64>
pub fn tick_imbalance(ticks: &[NormalizedTick]) -> Option<f64>
Tick imbalance: (buy_qty - sell_qty) / total_qty across a tick slice.
Buy ticks are those with side == Some(TradeSide::Buy).
Returns None if total quantity is zero.
Sourcepub fn quote_midpoint(
bid: &NormalizedTick,
ask: &NormalizedTick,
) -> Option<Decimal>
pub fn quote_midpoint( bid: &NormalizedTick, ask: &NormalizedTick, ) -> Option<Decimal>
Theoretical quote midpoint: (bid.price + ask.price) / 2.
Returns None if either tick has a non-positive price or if the bid
price exceeds the ask price (crossed market).
Sourcepub fn buy_volume(ticks: &[NormalizedTick]) -> Decimal
pub fn buy_volume(ticks: &[NormalizedTick]) -> Decimal
Total quantity across all buy-initiated ticks in a slice.
Filters ticks where side == Some(TradeSide::Buy) and sums their quantities.
Returns Decimal::ZERO for an empty slice or one with no buy ticks.
Sourcepub fn sell_volume(ticks: &[NormalizedTick]) -> Decimal
pub fn sell_volume(ticks: &[NormalizedTick]) -> Decimal
Total quantity across all sell-initiated ticks in a slice.
Filters ticks where side == Some(TradeSide::Sell) and sums their quantities.
Returns Decimal::ZERO for an empty slice or one with no sell ticks.
Sourcepub fn price_range(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn price_range(ticks: &[NormalizedTick]) -> Option<Decimal>
Price range across a slice of ticks: max(price) − min(price).
Returns None if the slice is empty.
Sourcepub fn average_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn average_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Arithmetic mean price across a slice of ticks.
Returns None if the slice is empty.
Sourcepub fn vwap(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn vwap(ticks: &[NormalizedTick]) -> Option<Decimal>
Volume-weighted average price (VWAP) across a slice of ticks.
Computes Σ(price × quantity) / Σ(quantity).
Returns None if the slice is empty or total volume is zero.
Sourcepub fn count_above_price(ticks: &[NormalizedTick], threshold: Decimal) -> usize
pub fn count_above_price(ticks: &[NormalizedTick], threshold: Decimal) -> usize
Count of ticks whose price is strictly above threshold.
Sourcepub fn count_below_price(ticks: &[NormalizedTick], threshold: Decimal) -> usize
pub fn count_below_price(ticks: &[NormalizedTick], threshold: Decimal) -> usize
Count of ticks whose price is strictly below threshold.
Sourcepub fn total_notional(ticks: &[NormalizedTick]) -> Decimal
pub fn total_notional(ticks: &[NormalizedTick]) -> Decimal
Total notional value (Σ price × quantity) across all ticks.
Sourcepub fn buy_notional(ticks: &[NormalizedTick]) -> Decimal
pub fn buy_notional(ticks: &[NormalizedTick]) -> Decimal
Total notional for buy-side ticks (side == Some(TradeSide::Buy)).
Sourcepub fn sell_notional(ticks: &[NormalizedTick]) -> Decimal
pub fn sell_notional(ticks: &[NormalizedTick]) -> Decimal
Total notional for sell-side ticks (side == Some(TradeSide::Sell)).
Sourcepub fn median_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn median_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Median price across a slice of ticks.
Sorts tick prices and returns the middle value (or mean of two middle
values for an even-length slice). Returns None for an empty slice.
Sourcepub fn net_volume(ticks: &[NormalizedTick]) -> Decimal
pub fn net_volume(ticks: &[NormalizedTick]) -> Decimal
Net volume: buy_volume − sell_volume.
Positive means net buying pressure; negative means net selling pressure.
Sourcepub fn average_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn average_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
Average trade quantity: total_volume / tick_count.
Returns None if the slice is empty.
Sourcepub fn max_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn max_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
Maximum single-trade quantity across the slice.
Returns None if the slice is empty.
Sourcepub fn min_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn min_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
Minimum single-trade quantity across the slice.
Returns None if the slice is empty.
Sourcepub fn buy_count(ticks: &[NormalizedTick]) -> usize
pub fn buy_count(ticks: &[NormalizedTick]) -> usize
Number of buy-side ticks in the slice.
Sourcepub fn sell_count(ticks: &[NormalizedTick]) -> usize
pub fn sell_count(ticks: &[NormalizedTick]) -> usize
Number of sell-side ticks in the slice.
Sourcepub fn price_momentum(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_momentum(ticks: &[NormalizedTick]) -> Option<f64>
Percentage price change from the first to the last tick.
Returns None if the slice has fewer than 2 ticks or the first
tick’s price is zero.
Sourcepub fn min_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn min_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Minimum price across the slice.
Returns None if the slice is empty.
Sourcepub fn max_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn max_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Maximum price across the slice.
Returns None if the slice is empty.
Sourcepub fn price_std_dev(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_std_dev(ticks: &[NormalizedTick]) -> Option<f64>
Standard deviation of tick prices across the slice.
Returns None if the slice has fewer than 2 elements.
Sourcepub fn buy_sell_ratio(ticks: &[NormalizedTick]) -> Option<f64>
pub fn buy_sell_ratio(ticks: &[NormalizedTick]) -> Option<f64>
Ratio of buy volume to sell volume.
Returns None if sell volume is zero.
Sourcepub fn largest_trade(ticks: &[NormalizedTick]) -> Option<&NormalizedTick>
pub fn largest_trade(ticks: &[NormalizedTick]) -> Option<&NormalizedTick>
Returns the tick with the highest quantity in the slice.
Returns None if the slice is empty.
Sourcepub fn large_trade_count(ticks: &[NormalizedTick], threshold: Decimal) -> usize
pub fn large_trade_count(ticks: &[NormalizedTick], threshold: Decimal) -> usize
Count of ticks whose quantity strictly exceeds threshold.
Sourcepub fn price_iqr(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn price_iqr(ticks: &[NormalizedTick]) -> Option<Decimal>
Interquartile range (Q3 − Q1) of tick prices.
Returns None if the slice has fewer than 4 elements.
Sourcepub fn fraction_buy(ticks: &[NormalizedTick]) -> Option<f64>
pub fn fraction_buy(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of ticks that are buy-side.
Returns None if the slice is empty.
Sourcepub fn std_quantity(ticks: &[NormalizedTick]) -> Option<f64>
pub fn std_quantity(ticks: &[NormalizedTick]) -> Option<f64>
Standard deviation of trade quantities across the slice.
Returns None if the slice has fewer than 2 elements.
Sourcepub fn buy_pressure(ticks: &[NormalizedTick]) -> Option<f64>
pub fn buy_pressure(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of sided volume that is buy-initiated: buy_vol / (buy_vol + sell_vol).
Returns None if there are no sided ticks.
Sourcepub fn average_notional(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn average_notional(ticks: &[NormalizedTick]) -> Option<Decimal>
Mean notional value (price × quantity) per trade across the slice.
Returns None if the slice is empty.
Sourcepub fn count_neutral(ticks: &[NormalizedTick]) -> usize
pub fn count_neutral(ticks: &[NormalizedTick]) -> usize
Count of ticks with no known side (neither buy nor sell).
Sourcepub fn recent(ticks: &[NormalizedTick], n: usize) -> &[NormalizedTick]
pub fn recent(ticks: &[NormalizedTick], n: usize) -> &[NormalizedTick]
Returns the last n ticks from the slice.
If n >= ticks.len(), returns the full slice.
Sourcepub fn price_linear_slope(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_linear_slope(ticks: &[NormalizedTick]) -> Option<f64>
OLS linear regression slope of price over tick index.
A positive slope indicates prices are rising across the slice.
Returns None if the slice has fewer than 2 ticks.
Sourcepub fn notional_std_dev(ticks: &[NormalizedTick]) -> Option<f64>
pub fn notional_std_dev(ticks: &[NormalizedTick]) -> Option<f64>
Standard deviation of per-trade notional values (price × quantity).
Returns None if the slice has fewer than 2 elements.
Sourcepub fn monotone_up(ticks: &[NormalizedTick]) -> bool
pub fn monotone_up(ticks: &[NormalizedTick]) -> bool
Returns true if prices in the slice are non-decreasing (each ≥ previous).
Returns true for slices with 0 or 1 ticks.
Sourcepub fn monotone_down(ticks: &[NormalizedTick]) -> bool
pub fn monotone_down(ticks: &[NormalizedTick]) -> bool
Returns true if prices in the slice are non-increasing (each ≤ previous).
Returns true for slices with 0 or 1 ticks.
Sourcepub fn volume_at_price(ticks: &[NormalizedTick], price: Decimal) -> Decimal
pub fn volume_at_price(ticks: &[NormalizedTick], price: Decimal) -> Decimal
Total quantity traded at exactly price.
Sourcepub fn last_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn last_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Price of the most recent tick in the slice.
Returns None if the slice is empty.
Sourcepub fn longest_buy_streak(ticks: &[NormalizedTick]) -> usize
pub fn longest_buy_streak(ticks: &[NormalizedTick]) -> usize
Length of the longest consecutive run of buy-sided ticks.
Sourcepub fn longest_sell_streak(ticks: &[NormalizedTick]) -> usize
pub fn longest_sell_streak(ticks: &[NormalizedTick]) -> usize
Length of the longest consecutive run of sell-sided ticks.
Sourcepub fn price_at_max_volume(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn price_at_max_volume(ticks: &[NormalizedTick]) -> Option<Decimal>
Price level with the highest total traded quantity in the slice.
Returns None if the slice is empty.
Sourcepub fn recent_volume(ticks: &[NormalizedTick], n: usize) -> Decimal
pub fn recent_volume(ticks: &[NormalizedTick], n: usize) -> Decimal
Total quantity of the last n ticks.
If n >= ticks.len(), returns total volume of all ticks.
Sourcepub fn first_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn first_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Price of the first tick in the slice.
Returns None if the slice is empty.
Sourcepub fn price_return_pct(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_return_pct(ticks: &[NormalizedTick]) -> Option<f64>
Percentage return from first to last tick price: (last − first) / first.
Returns None if the slice has fewer than 2 ticks or the first price is zero.
Sourcepub fn volume_above_price(ticks: &[NormalizedTick], price: Decimal) -> Decimal
pub fn volume_above_price(ticks: &[NormalizedTick], price: Decimal) -> Decimal
Total quantity traded strictly above price.
Sourcepub fn volume_below_price(ticks: &[NormalizedTick], price: Decimal) -> Decimal
pub fn volume_below_price(ticks: &[NormalizedTick], price: Decimal) -> Decimal
Total quantity traded strictly below price.
Sourcepub fn quantity_weighted_avg_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn quantity_weighted_avg_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Quantity-weighted average price (VWAP) across all ticks.
Returns None if the slice is empty or total quantity is zero.
Sourcepub fn tick_count_above_price(ticks: &[NormalizedTick], price: Decimal) -> usize
pub fn tick_count_above_price(ticks: &[NormalizedTick], price: Decimal) -> usize
Number of ticks with price strictly above price.
Sourcepub fn tick_count_below_price(ticks: &[NormalizedTick], price: Decimal) -> usize
pub fn tick_count_below_price(ticks: &[NormalizedTick], price: Decimal) -> usize
Number of ticks with price strictly below price.
Sourcepub fn price_at_percentile(
ticks: &[NormalizedTick],
percentile: f64,
) -> Option<Decimal>
pub fn price_at_percentile( ticks: &[NormalizedTick], percentile: f64, ) -> Option<Decimal>
Approximate price at the given percentile (0.0–1.0) by sorting tick prices.
Returns None if the slice is empty or percentile is outside [0, 1].
Sourcepub fn unique_price_count(ticks: &[NormalizedTick]) -> usize
pub fn unique_price_count(ticks: &[NormalizedTick]) -> usize
Number of distinct prices in the tick slice.
Sourcepub fn avg_inter_tick_spread(ticks: &[NormalizedTick]) -> Option<f64>
pub fn avg_inter_tick_spread(ticks: &[NormalizedTick]) -> Option<f64>
Average absolute price difference between consecutive ticks.
Returns None if fewer than 2 ticks.
Sourcepub fn largest_sell(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn largest_sell(ticks: &[NormalizedTick]) -> Option<Decimal>
Largest single-trade quantity among sell-side ticks.
Returns None if there are no sell-side ticks.
Sourcepub fn largest_buy(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn largest_buy(ticks: &[NormalizedTick]) -> Option<Decimal>
Largest single-trade quantity among buy-side ticks.
Returns None if there are no buy-side ticks.
Sourcepub fn trade_count(ticks: &[NormalizedTick]) -> usize
pub fn trade_count(ticks: &[NormalizedTick]) -> usize
Total number of ticks in the slice (alias for slice.len()).
Sourcepub fn price_acceleration(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_acceleration(ticks: &[NormalizedTick]) -> Option<f64>
Price acceleration: change in price velocity between consecutive ticks.
Returns the difference of the last two consecutive price changes.
Returns None if fewer than 3 ticks.
Sourcepub fn buy_sell_diff(ticks: &[NormalizedTick]) -> Decimal
pub fn buy_sell_diff(ticks: &[NormalizedTick]) -> Decimal
Net difference between buy volume and sell volume.
Positive means more buying pressure, negative means more selling pressure.
Sourcepub fn is_aggressive_buy(tick: &NormalizedTick, avg_buy_qty: Decimal) -> bool
pub fn is_aggressive_buy(tick: &NormalizedTick, avg_buy_qty: Decimal) -> bool
Returns true if the tick is a buy that exceeds the average buy quantity.
Sourcepub fn is_aggressive_sell(tick: &NormalizedTick, avg_sell_qty: Decimal) -> bool
pub fn is_aggressive_sell(tick: &NormalizedTick, avg_sell_qty: Decimal) -> bool
Returns true if the tick is a sell that exceeds the average sell quantity.
Sourcepub fn notional_volume(ticks: &[NormalizedTick]) -> Decimal
pub fn notional_volume(ticks: &[NormalizedTick]) -> Decimal
Total notional value: sum of price * quantity across all ticks.
Sourcepub fn weighted_side_score(ticks: &[NormalizedTick]) -> Option<f64>
pub fn weighted_side_score(ticks: &[NormalizedTick]) -> Option<f64>
Weighted side score: buy_volume - sell_volume normalized by total volume.
Returns a value in [-1, 1], or None if total volume is zero.
Sourcepub fn time_span_ms(ticks: &[NormalizedTick]) -> Option<u64>
pub fn time_span_ms(ticks: &[NormalizedTick]) -> Option<u64>
Time span in milliseconds between the first and last tick.
Returns None if fewer than 2 ticks.
Sourcepub fn price_above_vwap_count(ticks: &[NormalizedTick]) -> Option<usize>
pub fn price_above_vwap_count(ticks: &[NormalizedTick]) -> Option<usize>
Count of ticks with price above the VWAP of the slice.
Returns None if VWAP cannot be computed (empty or zero total volume).
Sourcepub fn avg_trade_size(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn avg_trade_size(ticks: &[NormalizedTick]) -> Option<Decimal>
Mean quantity per trade across all ticks.
Returns None if the slice is empty.
Sourcepub fn volume_concentration(ticks: &[NormalizedTick]) -> Option<f64>
pub fn volume_concentration(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of total volume contributed by the largest quarter of trades.
Trades are sorted by quantity descending; the top 25% (rounded up) are
summed and divided by total volume. Returns None if total volume is
zero or the slice is empty.
Sourcepub fn trade_imbalance_score(ticks: &[NormalizedTick]) -> Option<f64>
pub fn trade_imbalance_score(ticks: &[NormalizedTick]) -> Option<f64>
Signed trade imbalance: (buy_count − sell_count) / total.
Returns a value in [-1, 1]. Returns None if the slice is empty.
Sourcepub fn buy_avg_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn buy_avg_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Average price of buy-side ticks.
Returns None if there are no buy-side ticks.
Sourcepub fn sell_avg_price(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn sell_avg_price(ticks: &[NormalizedTick]) -> Option<Decimal>
Average price of sell-side ticks.
Returns None if there are no sell-side ticks.
Sourcepub fn price_skewness(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_skewness(ticks: &[NormalizedTick]) -> Option<f64>
Skewness of the price distribution across ticks.
Uses the standard moment-based formula. Returns None if fewer than 3
ticks or if the standard deviation is zero.
Sourcepub fn quantity_skewness(ticks: &[NormalizedTick]) -> Option<f64>
pub fn quantity_skewness(ticks: &[NormalizedTick]) -> Option<f64>
Skewness of the quantity distribution across ticks.
Uses the standard moment-based formula. Returns None if fewer than 3
ticks or if the standard deviation is zero.
Sourcepub fn price_entropy(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_entropy(ticks: &[NormalizedTick]) -> Option<f64>
Shannon entropy of the price distribution across ticks.
Each unique price is treated as a category. Returns None if the
slice is empty or all ticks have the same price (zero entropy is
returned as Some(0.0)).
Sourcepub fn price_kurtosis(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_kurtosis(ticks: &[NormalizedTick]) -> Option<f64>
Excess kurtosis of the price distribution across ticks.
Returns None if fewer than 4 ticks or if the standard deviation is
zero.
Sourcepub fn high_volume_tick_count(
ticks: &[NormalizedTick],
threshold: Decimal,
) -> usize
pub fn high_volume_tick_count( ticks: &[NormalizedTick], threshold: Decimal, ) -> usize
Count of ticks whose quantity exceeds threshold.
Sourcepub fn vwap_spread(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn vwap_spread(ticks: &[NormalizedTick]) -> Option<Decimal>
Difference between the buy-side average price and the sell-side average price (buy_avg - sell_avg).
A positive value means buyers paid more on average than sellers; a
negative value is unusual (market microstructure artifact). Returns
None if either side has no ticks.
Sourcepub fn avg_buy_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn avg_buy_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
Mean quantity of buy-side ticks.
Returns None if there are no buy-side ticks.
Sourcepub fn avg_sell_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn avg_sell_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
Mean quantity of sell-side ticks.
Returns None if there are no sell-side ticks.
Sourcepub fn price_mean_reversion_score(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_mean_reversion_score(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of prices that are below the VWAP (mean-reversion pressure).
Values close to 0.5 suggest equilibrium; values far from 0.5 suggest
directional bias. Returns None if VWAP cannot be computed.
Sourcepub fn largest_price_move(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn largest_price_move(ticks: &[NormalizedTick]) -> Option<Decimal>
Largest absolute price move between consecutive ticks.
Returns None if fewer than 2 ticks.
Sourcepub fn tick_rate(ticks: &[NormalizedTick]) -> Option<f64>
pub fn tick_rate(ticks: &[NormalizedTick]) -> Option<f64>
Number of ticks per millisecond of elapsed time.
Returns None if fewer than 2 ticks or the time span is zero.
Sourcepub fn buy_notional_fraction(ticks: &[NormalizedTick]) -> Option<f64>
pub fn buy_notional_fraction(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of total notional volume that comes from buy-side trades.
Returns None if total notional volume is zero or the slice is empty.
Sourcepub fn price_range_pct(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_range_pct(ticks: &[NormalizedTick]) -> Option<f64>
Price range as a percentage of the minimum price.
(max_price - min_price) / min_price * 100. Returns None if the
slice is empty or the minimum price is zero.
Sourcepub fn buy_side_dominance(ticks: &[NormalizedTick]) -> Option<f64>
pub fn buy_side_dominance(ticks: &[NormalizedTick]) -> Option<f64>
Buy-side dominance: buy_volume / (buy_volume + sell_volume).
Returns a value in [0, 1]. Returns None if both sides are zero.
Sourcepub fn volume_weighted_price_std(ticks: &[NormalizedTick]) -> Option<f64>
pub fn volume_weighted_price_std(ticks: &[NormalizedTick]) -> Option<f64>
Standard deviation of price weighted by quantity.
Uses VWAP as the mean. Returns None if empty or VWAP cannot be
computed.
Sourcepub fn last_n_vwap(ticks: &[NormalizedTick], n: usize) -> Option<Decimal>
pub fn last_n_vwap(ticks: &[NormalizedTick], n: usize) -> Option<Decimal>
VWAP computed over just the last n ticks.
Returns None if n is 0 or the slice has no ticks, or if total
volume of the window is zero.
Sourcepub fn price_autocorrelation(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_autocorrelation(ticks: &[NormalizedTick]) -> Option<f64>
Lag-1 autocorrelation of the price series across ticks.
Uses the Pearson formula on consecutive price pairs. Returns None if
fewer than 3 ticks or if the variance is zero.
Sourcepub fn net_trade_direction(ticks: &[NormalizedTick]) -> i64
pub fn net_trade_direction(ticks: &[NormalizedTick]) -> i64
Net trade direction score: (buy_count - sell_count) as a signed integer.
Sourcepub fn sell_side_notional_fraction(ticks: &[NormalizedTick]) -> Option<f64>
pub fn sell_side_notional_fraction(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of total notional volume that comes from sell-side trades.
Returns None if total notional volume is zero or the slice is empty.
Sourcepub fn price_oscillation_count(ticks: &[NormalizedTick]) -> usize
pub fn price_oscillation_count(ticks: &[NormalizedTick]) -> usize
Count of price direction reversals (sign changes in consecutive moves).
Returns 0 if fewer than 3 ticks.
Sourcepub fn realized_spread(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn realized_spread(ticks: &[NormalizedTick]) -> Option<Decimal>
Realized spread: mean buy price minus mean sell price.
A positive value suggests buys are executed at higher prices than sells
(typical in a two-sided market). Returns None if either side has no
ticks.
Sourcepub fn adverse_selection_score(ticks: &[NormalizedTick]) -> Option<f64>
pub fn adverse_selection_score(ticks: &[NormalizedTick]) -> Option<f64>
Adverse selection score: fraction of large trades that moved the price against the initiator (proxy for informed trading).
A “large” trade is one with quantity above the window median quantity.
Returns None if the slice has fewer than 3 ticks or median is zero.
Sourcepub fn price_impact_per_unit(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_impact_per_unit(ticks: &[NormalizedTick]) -> Option<f64>
Price impact per unit of volume: |price_return| / total_volume.
Returns None if fewer than 2 ticks or total volume is zero.
Sourcepub fn volume_weighted_return(ticks: &[NormalizedTick]) -> Option<f64>
pub fn volume_weighted_return(ticks: &[NormalizedTick]) -> Option<f64>
Volume-weighted return: VWAP of returns weighted by quantity.
Computes (p_i - p_{i-1}) / p_{i-1} for each consecutive pair,
weighted by qty_i, then sums weighted returns. Returns None if
fewer than 2 ticks or total quantity is zero.
Sourcepub fn quantity_concentration(ticks: &[NormalizedTick]) -> Option<f64>
pub fn quantity_concentration(ticks: &[NormalizedTick]) -> Option<f64>
Gini-coefficient-style quantity concentration.
sum_i sum_j |q_i - q_j| / (2 * n^2 * mean_q). Returns None if
the slice is empty or the mean quantity is zero.
Sourcepub fn price_level_volume(ticks: &[NormalizedTick], price: Decimal) -> Decimal
pub fn price_level_volume(ticks: &[NormalizedTick], price: Decimal) -> Decimal
Total volume traded at a specific price level.
Sourcepub fn mid_price_drift(ticks: &[NormalizedTick]) -> Option<f64>
pub fn mid_price_drift(ticks: &[NormalizedTick]) -> Option<f64>
Drift of the mid-price proxy across ticks.
Defined as (last_price - first_price) / time_span_ms. Returns None
if fewer than 2 ticks or the time span is zero.
Sourcepub fn tick_direction_bias(ticks: &[NormalizedTick]) -> Option<f64>
pub fn tick_direction_bias(ticks: &[NormalizedTick]) -> Option<f64>
Tick direction bias: fraction of consecutive moves in the same direction.
Counts windows where price[i+1] moved in the same direction as
price[i] vs price[i-1]. Returns None if fewer than 3 ticks.
Sourcepub fn median_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn median_quantity(ticks: &[NormalizedTick]) -> Option<Decimal>
Median trade quantity across all ticks.
Returns None if the slice is empty.
Sourcepub fn volume_above_vwap(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn volume_above_vwap(ticks: &[NormalizedTick]) -> Option<Decimal>
Total volume from ticks priced strictly above the VWAP of the slice.
Returns None if VWAP cannot be computed (empty or zero total quantity).
Sourcepub fn inter_arrival_variance(ticks: &[NormalizedTick]) -> Option<f64>
pub fn inter_arrival_variance(ticks: &[NormalizedTick]) -> Option<f64>
Variance of inter-tick arrival times in milliseconds.
Returns None if fewer than 3 ticks are provided (need ≥ 2 intervals).
Sourcepub fn spread_efficiency(ticks: &[NormalizedTick]) -> Option<f64>
pub fn spread_efficiency(ticks: &[NormalizedTick]) -> Option<f64>
Price spread efficiency: net price move divided by total path length.
A value of 1.0 means prices moved directly with no reversals; values
near 0.0 indicate heavy oscillation. Returns None if the slice has
fewer than 2 ticks or the path length is zero.
Sourcepub fn buy_sell_size_ratio(ticks: &[NormalizedTick]) -> Option<f64>
pub fn buy_sell_size_ratio(ticks: &[NormalizedTick]) -> Option<f64>
Ratio of average buy quantity to average sell quantity.
Returns None if there are no buy ticks or no sell ticks, or if avg
sell quantity is zero.
Sourcepub fn trade_size_dispersion(ticks: &[NormalizedTick]) -> Option<f64>
pub fn trade_size_dispersion(ticks: &[NormalizedTick]) -> Option<f64>
Standard deviation of trade quantities across all ticks.
Returns None if fewer than 2 ticks are provided.
Sourcepub fn aggressor_fraction(ticks: &[NormalizedTick]) -> Option<f64>
pub fn aggressor_fraction(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of ticks for which the trade side is known (non-None).
Returns None for an empty slice.
A value near 1.0 indicates the feed reliably reports aggressor side; a value near 0.0 means most ticks are neutral.
Sourcepub fn volume_imbalance_ratio(ticks: &[NormalizedTick]) -> Option<f64>
pub fn volume_imbalance_ratio(ticks: &[NormalizedTick]) -> Option<f64>
Signed volume imbalance: (buy_vol − sell_vol) / (buy_vol + sell_vol).
Returns a value in (−1, +1). Positive means net buying pressure,
negative means net selling pressure. Returns None when the total
known-side volume is zero (all ticks are neutral or the slice is empty).
Sourcepub fn price_quantity_covariance(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_quantity_covariance(ticks: &[NormalizedTick]) -> Option<f64>
Covariance between price and quantity across the tick slice.
Returns None if fewer than 2 ticks are provided or if any value
cannot be converted to f64.
A positive covariance indicates that larger trades tend to occur at higher prices; negative means larger trades skew toward lower prices.
Sourcepub fn large_trade_fraction(
ticks: &[NormalizedTick],
threshold: Decimal,
) -> Option<f64>
pub fn large_trade_fraction( ticks: &[NormalizedTick], threshold: Decimal, ) -> Option<f64>
Fraction of ticks whose quantity meets or exceeds threshold.
Returns None for an empty slice. The result is in [0.0, 1.0].
Useful for characterising how “institutional” the flow is.
Sourcepub fn price_level_density(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_level_density(ticks: &[NormalizedTick]) -> Option<f64>
Number of unique price levels per unit of price range.
Computed as unique_price_count / price_range. Returns None when
the slice is empty or the price range is zero (all ticks at one price).
High density implies granular price action; low density implies price jumps between a few discrete levels.
Sourcepub fn notional_buy_sell_ratio(ticks: &[NormalizedTick]) -> Option<f64>
pub fn notional_buy_sell_ratio(ticks: &[NormalizedTick]) -> Option<f64>
Ratio of buy-side notional to sell-side notional.
Returns None when there are no sell-side ticks or sell notional is
zero. A value above 1.0 means buy-side dollar flow dominates.
Sourcepub fn log_return_mean(ticks: &[NormalizedTick]) -> Option<f64>
pub fn log_return_mean(ticks: &[NormalizedTick]) -> Option<f64>
Mean of tick-to-tick log returns: mean(ln(p_i / p_{i-1})).
Returns None if fewer than 2 ticks are provided or if any price
is zero (which would make the log undefined).
Sourcepub fn log_return_std(ticks: &[NormalizedTick]) -> Option<f64>
pub fn log_return_std(ticks: &[NormalizedTick]) -> Option<f64>
Standard deviation of tick-to-tick log returns.
Returns None if fewer than 3 ticks are provided (need at least 2
returns for a meaningful std-dev) or if any price is zero.
Sourcepub fn price_overshoot_ratio(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_overshoot_ratio(ticks: &[NormalizedTick]) -> Option<f64>
Ratio of the maximum price to the last price: max_price / last_price.
Returns None for an empty slice or if the last price is zero.
A value above 1.0 indicates that the price overshot the closing level during the window — useful as an intrabar momentum signal.
Sourcepub fn price_undershoot_ratio(ticks: &[NormalizedTick]) -> Option<f64>
pub fn price_undershoot_ratio(ticks: &[NormalizedTick]) -> Option<f64>
Ratio of the first price to the minimum price: first_price / min_price.
Returns None for an empty slice or if the minimum price is zero.
A value above 1.0 indicates the window opened above its trough, meaning the price undershot the opening level at some point.
Sourcepub fn net_notional(ticks: &[NormalizedTick]) -> Decimal
pub fn net_notional(ticks: &[NormalizedTick]) -> Decimal
Net notional: buy_notional − sell_notional across the slice.
Positive means net buying pressure in dollar terms; negative means
net selling pressure. Returns Decimal::ZERO for empty slices or
slices with no sided ticks.
Sourcepub fn price_reversal_count(ticks: &[NormalizedTick]) -> usize
pub fn price_reversal_count(ticks: &[NormalizedTick]) -> usize
Count of price direction reversals across the slice.
A reversal occurs when consecutive price moves change sign (up→down or down→up), ignoring flat moves. Returns 0 for fewer than 3 ticks.
Sourcepub fn quantity_kurtosis(ticks: &[NormalizedTick]) -> Option<f64>
pub fn quantity_kurtosis(ticks: &[NormalizedTick]) -> Option<f64>
Excess kurtosis of trade quantities across the slice.
kurtosis = (Σ((q − mean)⁴ / n) / std_dev⁴) − 3
Returns None if the slice has fewer than 4 ticks or std dev is zero.
Sourcepub fn largest_notional_trade(
ticks: &[NormalizedTick],
) -> Option<&NormalizedTick>
pub fn largest_notional_trade( ticks: &[NormalizedTick], ) -> Option<&NormalizedTick>
Reference to the tick with the highest notional value (price × quantity).
Unlike largest_trade which ranks by raw quantity,
this method ranks by dollar value, making it suitable for comparing
trades across different price levels.
Returns None if the slice is empty.
Sourcepub fn twap(ticks: &[NormalizedTick]) -> Option<Decimal>
pub fn twap(ticks: &[NormalizedTick]) -> Option<Decimal>
Time-weighted average price (TWAP) using received_at_ms timestamps.
Each price is weighted by the time interval to the next tick. The last
tick carries zero weight (no interval after it). Returns None if
fewer than 2 ticks are provided or the total time span is zero.
Sourcepub fn neutral_fraction(ticks: &[NormalizedTick]) -> Option<f64>
pub fn neutral_fraction(ticks: &[NormalizedTick]) -> Option<f64>
Fraction of ticks whose side is None (no aggressor information).
Returns None for an empty slice.
Complement of aggressor_fraction.
Sourcepub fn log_return_variance(ticks: &[NormalizedTick]) -> Option<f64>
pub fn log_return_variance(ticks: &[NormalizedTick]) -> Option<f64>
Variance of tick-to-tick log returns: var(ln(p_i / p_{i-1})).
Returns None if fewer than 3 ticks or any price is non-positive.
Sourcepub fn volume_at_vwap(ticks: &[NormalizedTick], tolerance: Decimal) -> Decimal
pub fn volume_at_vwap(ticks: &[NormalizedTick], tolerance: Decimal) -> Decimal
Total quantity traded at prices within tolerance of the VWAP.
Returns Decimal::ZERO if the slice is empty, VWAP cannot be computed,
or no ticks fall within the tolerance band.
Trait Implementations§
Source§impl Clone for NormalizedTick
impl Clone for NormalizedTick
Source§fn clone(&self) -> NormalizedTick
fn clone(&self) -> NormalizedTick
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more