Skip to main content

NormalizedTick

Struct NormalizedTick 

Source
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: Exchange

Source exchange.

§symbol: String

Instrument symbol in the canonical form used by this crate.

§price: Decimal

Trade price (exact decimal, never f64).

§quantity: Decimal

Trade 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: u64

Local system-clock timestamp when this tick was received.

Implementations§

Source§

impl NormalizedTick

Source

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.

Source

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.

Source

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.

Source

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).

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn volume_notional(&self) -> Decimal

Notional value of this trade: price × quantity.

Source

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.

Source

pub fn side_str(&self) -> &'static str

Human-readable trade direction: "buy", "sell", or "unknown".

Source

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.

Source

pub fn is_same_symbol_as(&self, other: &NormalizedTick) -> bool

Returns true if this tick’s symbol matches other’s symbol exactly.

Source

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.

Source

pub fn exchange_latency_ms(&self) -> Option<i64>

Signed latency between the local receipt timestamp and the exchange timestamp, in milliseconds.

Returns ts_ms as i64 - exchange_ts_ms as i64. Positive values mean the tick arrived at the local system after the exchange stamped it (normal network latency). Negative values indicate clock skew between the exchange and local clock. Returns None if exchange_ts_ms is absent.

Source

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.

Source

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.

Source

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).

Source

pub fn is_above(&self, price: Decimal) -> bool

Returns true if this tick’s price is strictly above price.

Source

pub fn is_below(&self, price: Decimal) -> bool

Returns true if this tick’s price is strictly below price.

Source

pub fn is_at(&self, price: Decimal) -> bool

Returns true if this tick’s price equals price.

Source

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.

Source

pub fn price_diff_from(&self, other: &NormalizedTick) -> Decimal

Signed price difference: self.price - other.price.

Positive when this tick’s price is higher than the other’s.

Source

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.

Source

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.

Source

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.

Source

pub fn is_same_exchange_as(&self, other: &NormalizedTick) -> bool

Returns true if this tick originated from the same exchange as other.

Source

pub fn quote_age_ms(&self, now_ms: u64) -> u64

Age of this tick in milliseconds: now_ms - received_at_ms.

Returns 0 if now_ms is before received_at_ms.

Source

pub fn notional_value(&self) -> Decimal

Notional value of this tick: price × quantity.

Source

pub fn is_high_value_tick(&self, threshold: Decimal) -> bool

Returns true if the notional value (price × quantity) exceeds threshold.

Source

pub fn side_as_str(&self) -> Option<&'static str>

Returns the trade side as a string slice: "buy", "sell", or None.

Source

pub fn is_above_price(&self, reference: Decimal) -> bool

Returns true if this tick’s price is strictly above reference.

Source

pub fn price_change_from(&self, reference: Decimal) -> Decimal

Signed price change relative to reference: self.price - reference.

Source

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.

Source

pub fn is_at_price(&self, target: Decimal) -> bool

Returns true if this tick’s price exactly equals target.

Source

pub fn is_below_price(&self, reference: Decimal) -> bool

Returns true if this tick’s price is strictly below reference.

Source

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.

Source

pub fn signed_quantity(&self) -> Decimal

Returns the trade quantity signed by side: +quantity for Buy, -quantity for Sell, 0 for unknown.

Source

pub fn as_price_level(&self) -> (Decimal, Decimal)

Returns (price, quantity) as a convenient tuple.

Source

pub fn quantity_above(&self, threshold: Decimal) -> bool

Returns true if this tick’s quantity is strictly above threshold.

Source

pub fn is_recent(&self, threshold_ms: u64, now_ms: u64) -> bool

Returns true if this tick was received within threshold_ms of now_ms.

Source

pub fn is_buy_side(&self) -> bool

Returns true if this tick is on the buy side.

Returns false if the side is Sell or None.

Source

pub fn is_sell_side(&self) -> bool

Returns true if this tick is on the sell side.

Returns false if the side is Buy or None.

Source

pub fn is_zero_quantity(&self) -> bool

Returns true if this tick’s quantity is zero (may indicate a cancel or correction).

Source

pub fn is_within_spread(&self, bid: Decimal, ask: Decimal) -> bool

Returns true if this tick’s price is strictly between bid and ask.

Source

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.

Source

pub fn is_large_tick(&self, threshold: Decimal) -> bool

Returns true if this tick’s quantity is strictly above threshold.

Source

pub fn price_in_range(&self, low: Decimal, high: Decimal) -> bool

Returns true if this tick’s price is within [low, high] (inclusive).

Source

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.

Source

pub fn is_large_spread_from( &self, other: &NormalizedTick, threshold: Decimal, ) -> bool

Returns true if the absolute price difference from other exceeds threshold.

Source

pub fn volume_notional_f64(&self) -> f64

Notional value of this tick as f64 (price × quantity).

Source

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).

Source

pub fn vwap(ticks: &[NormalizedTick]) -> Option<Decimal>

Volume-weighted average price across a slice of ticks.

Returns None if the slice is empty or total volume is zero.

Source

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.

Source

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.

Source

pub fn dollar_value(&self) -> Decimal

Dollar (notional) value of this tick: price * quantity.

Source

pub fn contract_value(&self, multiplier: Decimal) -> Decimal

Contract value using a futures/options multiplier: price * quantity * multiplier.

Source

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.

Source

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).

Trait Implementations§

Source§

impl Clone for NormalizedTick

Source§

fn clone(&self) -> NormalizedTick

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NormalizedTick

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for NormalizedTick

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for NormalizedTick

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Serialize for NormalizedTick

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,