Skip to main content

Sink

Struct Sink 

Source
pub struct Sink { /* private fields */ }
Expand description

Live updates for one subscription. Cheap to clone and usable from any thread; pushes never wait for the chart to catch up.

use chrono::Utc;
use egui_charts::data::{Datafeed, HistoryPage, HistoryRequest, Reply, Subscription};
use egui_charts::model::{OrderBook, OrderBookLevel, Tick, OrderSide};

struct Exchange;

impl Datafeed for Exchange {
    fn history(&self, _: HistoryRequest, reply: Reply<HistoryPage>) {
        reply.send(Ok(HistoryPage::default()));
    }

    /// A real feed pushes from its connection's thread or task.
    fn subscribe(&self, subscription: Subscription) {
        let sink = subscription.sink;
        let level = |price, size| OrderBookLevel { price, size, order_cnt: None };
        let symbol = subscription.symbol;
        let book = |bids, asks| OrderBook { ts: Utc::now(), symbol: symbol.clone(), bids, asks };

        sink.push_depth_snapshot(7, book(vec![level(99.75, 3.0)], vec![level(100.0, 2.0)]));
        let side = Some(OrderSide::Buy);
        sink.push_tick(Tick::new(Utc::now(), 100.0, 2.0, side).with_id(41_207));
        // The buy took the whole offer at 100.
        sink.push_depth_delta(8, &book(vec![], vec![level(100.0, 0.0)]));
    }
}

Pending bars are capped at 100,000 slots independently of raw trades. Overflow discards the oldest slots and reports FeedError::InvalidData on the next drain; the host reloads history to recover the missing bars.

Implementations§

Source§

impl Sink

Source

pub fn reset_replay(&self, time: DateTime<Utc>)

Starts a new replay position on this subscription. The next chart drain clears prior bars, trades, depth, quote and sampled history before applying subsequent pushes. Resets trade ids and partial event bars too, so rewinding cannot double-count or retain future state. Hosts coordinate outstanding history replies and call this on every symbol’s sink before dispatching ReplayClock::seek. Keep using the same subscription and sampler grid.

Source

pub fn push_bar(&self, bar: Bar)

A bar of the subscribed timeframe, stamped with its open or any instant inside it: replaces the bar it shares a slot with, appends a newer one, corrects an older one. A bar of a day or longer is stamped inside its calendar period, as HistoryPage::bars describes. A bar stamped too far ahead of the feed’s current time is rejected, as Sink::set_server_time describes.

Source

pub fn push_tick(&self, tick: Tick)

A trade, folded into the bar of its slot and kept for order flow, the oldest trades making room for new ones. Its size is added to that bar’s volume, also when the bar came from a history page. Trades that arrive before history extend only the page’s newest bar, which must count only trades the stream did not send, or the feed must hold those trades until the page is answered. Completed page bars replace bars built from ticks. A feed that cannot tell pushes bars instead. Trades older than the last accepted execution or forming bar are dropped, and so is a trade whose id is among those of the last trades the subscription folded, as many as its trade store holds. A trade stamped too far ahead of the feed’s current time is rejected, as Sink::set_server_time describes. Repeated ids can complete missing aggressor and resting order ids without adding volume.

Trade-based intervals start at the first accepted execution of the subscription. Replay the retained executions on resubscription to rebuild a partial bar. Count bars use the first trade’s time; if that would duplicate a bar time, it advances by one nanosecond. Original execution times remain unchanged. Volume and delta fills split exactly at the threshold; range bars need the instrument tick size and close at the first real fill reaching it. A fill producing more than 100,000 bars is rejected atomically. A pushed trade-based bar must be complete: the next trade starts a fresh bar. History pages should contain complete trade-based bars only.

Source

pub fn advance_time(&self, now: DateTime<Utc>)

Advances a time-based stream through now, opening an empty forming candle at the current clock boundary when there has been no execution. Empty candles have zero volume and carry the close of the newest bar before them that is not whitespace, whether this stream or a history page delivered it, before or after the heartbeat; their first trade sets the real open, high and low. Count bars never advance without trades. A clock with a session opens a candle only inside the windows the subscription selected: a heartbeat outside them only advances the stream’s time, and the first one inside the next session opens that session’s slot at the last close. Call from a trusted feed heartbeat, after seeding a bar or execution; invalid or future clock values obey the same rule as trade timestamps. Heartbeats also close due depth-history periods, including on count intervals.

Source

pub fn push_depth_snapshot(&self, sequence: u64, book: OrderBook)

The whole order book, numbered sequence, at most 10,000 levels per side: a deeper book is rejected. It replaces the book; the next delta carries sequence + 1. Levels are keyed by the nearest integer tick of the instrument’s tick_size, when it has one, so prices that differ by a rounding error are one level and the latest size pushed for it holds. A crossed book is kept as pushed.

Source

pub fn push_depth_delta(&self, sequence: u64, changes: &OrderBook)

The levels that changed since the update numbered sequence - 1, each with its new size; a size of 0 removes the level. The symbol of changes is ignored. Taken by reference, so a feed can clear and refill one OrderBook for every delta instead of allocating its levels per message. Changes are sorted by price and merged in one pass, with the last entry for each price winning. A delta numbered at or below the last one applied is ignored. After a gap, before the first snapshot, or when a side would exceed 10,000 levels, the book is cleared and the chart calls Datafeed::request_depth_snapshot once; a snapshot pushed before the chart sees the loss cancels the call. Keep pushing deltas while the snapshot is fetched: those pushed while the book waits are held, the oldest dropped beyond 10,000 levels in all, and the snapshot applies the ones numbered above its own sequence.

Source

pub fn push_order_snapshot( &self, sequence: u64, time: DateTime<Utc>, orders: Vec<RestingOrder>, )

Replaces the per-order book, at most 10,000 orders per side, listed in queue order. The next event has sequence + 1; events buffered during resync above the snapshot’s sequence apply afterwards. Gaps and invalid events clear both books and ask the feed for a new snapshot once through Datafeed::request_depth_snapshot. Use either order events or aggregated deltas for a subscription; an aggregated push discards the order queues.

Source

pub fn push_order_event( &self, sequence: u64, time: DateTime<Utc>, event: OrderEvent, )

Applies one order event with consecutive sequencing. Repeated sequences are ignored; while waiting for a snapshot at most 10,000 consecutive events are kept. Unknown cancels, duplicate adds, invalid sizes and oversized executions lose the book. An execution’s optional trade enters the raw trade store and carries the resting order id it filled.

Source

pub fn push_quote(&self, quote: Level1Quote)

Latest best bid and ask. Bursts coalesce to the newest timestamp (last arrival on a tie). Non-finite prices and negative or non-finite sizes are rejected without replacing the pending quote. A crossed quote, its bid above its ask, is kept, as the top of a crossed book (see OrderBook::is_crossed). Times obey the feed-clock rule of Self::set_server_time. The subscription supplies the instrument identity; the sink ignores a quote whose symbol differs from its subscribed symbol.

Source

pub fn set_server_time(&self, now: DateTime<Utc>)

The feed’s current time, from a clock other than the times it pushes, such as its server’s heartbeat or time message: reporting the time of the trade or bar about to be pushed would let a wrong time through. The time runs on with the system clock until the next call; until the first, the system clock stands in.

A bar or trade is rejected when its slot opens more than one slot after the slot of this time and more than a minute after this time, or more than two weeks for bars of a day or longer, which a feed stamps on their trading date. A time in the wrong unit, such as milliseconds read as seconds, therefore cannot make every later trade late, while a system clock a few seconds slow rejects nothing. A replay or simulation calls this before its first push, whenever its clock jumps, and at least once per bar while its clock runs at another speed.

Source

pub fn set_status(&self, status: FeedStatus)

The connection status. The latest one wins.

Source

pub fn report_error(&self, error: FeedError)

An error of the live stream. The latest one wins.

Source

pub fn symbols_changed(&self)

Notifies the host that its symbol search catalog should be refreshed. Coalesces within a frame; the chart exposes arrivals through FeedState::symbol_catalog_revision.

Source

pub fn is_active(&self) -> bool

False once the subscription ended. Pushes are ignored from then on.

Source§

impl Sink

Source

pub fn push_metric(&self, point: MetricPoint)

Publish or correct a metric point. Its value is held until the next point; an inactive subscription ignores pushes, like Self::push_bar.

Trait Implementations§

Source§

impl Clone for Sink

Source§

fn clone(&self) -> Sink

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Sink

§

impl !UnwindSafe for Sink

§

impl Freeze for Sink

§

impl Send for Sink

§

impl Sync for Sink

§

impl Unpin for Sink

§

impl UnsafeUnpin for Sink

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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, 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> MaybeSend for T
where T: Send + Sync + ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

§

impl<T> SerializableAny for T
where T: 'static + Any + Clone + for<'a> Send + Sync,

§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

§

fn simd_from(_simd: S, value: T) -> T

§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

§

fn simd_into(self, simd: S) -> T

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