pub struct ReplayDriver { /* private fields */ }Expand description
A recording-backed feed and playback driver for every symbol in one session.
Attach the same Arc<ReplayDriver> to each chart with ChartBuilder::with_feed. Call
advance outside egui context locks before drawing, even while paused, to
publish the shared time to quiet symbols. Zero speed pauses; seeking is inclusive. Hosts own
capture, storage and scheduling. Bar aggregation, book gaps and trade deduplication use the
live sink’s rules. A new subscription reconstructs the current position, including when its
interval changes. No history request can return events beyond the playback position.
use egui_charts::data::{MarketEvent, RecordingWriter, ReplayDriver, ReplayEvent};
use egui_charts::model::{Instrument, Tick};
use std::time::Duration;
let time = chrono::Utc::now();
let mut capture = RecordingWriter::new(Vec::new())?;
capture.write(&ReplayEvent::new("A", time, 0,
MarketEvent::Trade(Tick::new(time, 100.0, 2.0, None))))?;
let bytes = capture.finish()?;
let replay = ReplayDriver::load(bytes.as_slice(), vec![Instrument::new("A")])?;
replay.advance(Duration::ZERO)?;
replay.set_speed(0.0)?;
replay.seek(time);Implementations§
Source§impl ReplayDriver
impl ReplayDriver
Sourcepub fn new(
events: Vec<ReplayEvent>,
instruments: Vec<Instrument>,
) -> Result<Self, FeedError>
pub fn new( events: Vec<ReplayEvent>, instruments: Vec<Instrument>, ) -> Result<Self, FeedError>
Validates a complete recording and its host-supplied instrument metadata. Every recorded symbol must have exactly one instrument; its tick size is needed for price-based bars. Playback starts at the first event, with none consumed, at normal speed.
Sourcepub fn load(reader: impl Read, instruments: Vec<Instrument>) -> Result<Self>
pub fn load(reader: impl Read, instruments: Vec<Instrument>) -> Result<Self>
Loads the same stream that super::RecordingWriter writes. Read errors retain their
original kind; malformed recordings and duplicate merge keys report InvalidData.
Sourcepub fn time(&self) -> DateTime<Utc>
pub fn time(&self) -> DateTime<Utc>
The inclusive playback position shared by all subscriptions.
Sourcepub fn time_range(&self) -> Option<(DateTime<Utc>, DateTime<Utc>)>
pub fn time_range(&self) -> Option<(DateTime<Utc>, DateTime<Utc>)>
First and last recorded observation instants, for transport bounds; None when empty.
Sourcepub fn set_speed(&self, speed: f64) -> Result<(), FeedError>
pub fn set_speed(&self, speed: f64) -> Result<(), FeedError>
Sets a finite, non-negative playback multiplier.
Sourcepub fn is_finished(&self) -> bool
pub fn is_finished(&self) -> bool
Whether every event has been published.
Sourcepub fn advance(&self, elapsed: Duration) -> Result<(), FeedError>
pub fn advance(&self, elapsed: Duration) -> Result<(), FeedError>
Advances once by wall-clock elapsed time and routes due events by symbol. Publishes the resulting time to every sink, including quiet symbols and paused frames. Clock errors leave the position and subscriptions unchanged.
Sourcepub fn seek(&self, time: DateTime<Utc>)
pub fn seek(&self, time: DateTime<Utc>)
Reconstructs every active subscription through time, clearing all later state first.
Replays book history from the beginning as well as trades: starting at the latest book
snapshot would lose earlier heatmap columns. No later snapshot or execution is exposed.
Call outside egui context locks, as with live pushes.
Trait Implementations§
Source§impl Datafeed for ReplayDriver
impl Datafeed for ReplayDriver
Source§fn resolve(&self, symbol: &str, reply: Reply<Instrument>)
fn resolve(&self, symbol: &str, reply: Reply<Instrument>)
symbol. The default reports Instrument::new of the symbol.
Fill Instrument::profile_resolutions to suggest the bars volume profile studies and
drawings read.Source§fn history(&self, _: HistoryRequest, reply: Reply<HistoryPage>)
fn history(&self, _: HistoryRequest, reply: Reply<HistoryPage>)
request.count bars of the range [request.since, request.before), the newest ones
when there are more. Either end left None is unbounded: without before the range
reaches the latest bar.Source§fn subscribe(&self, subscription: Subscription)
fn subscribe(&self, subscription: Subscription)
subscription.sink until unsubscribe. The default does
nothing, which gives a history-only chart.Source§fn unsubscribe(&self, id: SubscriptionId)
fn unsubscribe(&self, id: SubscriptionId)
subscribe started. Pushes that arrive afterwards are ignored. The default does
nothing; a producer can then poll Sink::is_active to know when to stop. Read moreSource§fn depth_history(&self, request: DepthRequest, reply: Reply<DepthPage>)
fn depth_history(&self, request: DepthRequest, reply: Reply<DepthPage>)
FeedError::NotSupported; live-only feeds need not implement this method.Source§fn capabilities(&self, reply: Reply<FeedCapabilities>)
fn capabilities(&self, reply: Reply<FeedCapabilities>)
Chart::feed_capabilities (requires widget). The default
answers FeedCapabilities::default, which reports nothing and so restricts nothing.Source§fn resolve_converted(
&self,
symbol: &str,
conversion: &str,
reply: Reply<Instrument>,
)
fn resolve_converted( &self, symbol: &str, conversion: &str, reply: Reply<Instrument>, )
symbol with its prices converted to conversion, the currency or unit the
host chose with Chart::set_conversion (requires widget). Label the
instrument with the converted currency and
unit. The library converts nothing: the default answers
FeedError::NotSupported, which shows no data rather than unconverted data under a
converted choice.Source§fn trades(&self, request: TradeRequest, reply: Reply<TradePage>)
fn trades(&self, request: TradeRequest, reply: Reply<TradePage>)
request.count trades of the range [request.since, request.before), the newest
ones when there are more, so order flow survives a reload and follows the view back in
time. The default answers FeedError::NotSupported.Source§fn options_volume(&self, query: OptionsVolumeQuery, sink: OptionsVolumeSink)
fn options_volume(&self, query: OptionsVolumeQuery, sink: OptionsVolumeSink)
sink.is_active() is false.
The default supplies none; the library never fetches options data itself.Source§fn option_expiries(&self, underlying: &str, reply: Reply<Vec<NaiveDate>>)
fn option_expiries(&self, underlying: &str, reply: Reply<Vec<NaiveDate>>)
underlying, in ascending order with no duplicates.
The default answers FeedError::NotSupported. Both options methods are declared by
FeedService::OptionChain; the host supplies the data.Source§fn option_chain(&self, query: OptionChainQuery, sink: OptionChainSink)
fn option_chain(&self, query: OptionChainQuery, sink: OptionChainSink)
query’s inclusive expiry range.
Without as_of, keep pushing until the sink is inactive.
With it, push one snapshot for that instant or report FeedError::NotSupported.
Unknown figures stay absent. See OptionQuote for units and OptionChainSink::push
for validation. The default reports FeedError::NotSupported to the sink. Read moreSource§fn option_exposure(&self, query: OptionExposureQuery, sink: OptionExposureSink)
fn option_exposure(&self, query: OptionExposureQuery, sink: OptionExposureSink)
as_of, keep pushing until the sink is inactive;
with it, answer once for that instant or report FeedError::NotSupported (the default).
Declared by FeedService::OptionExposure. The host supplies the data and model. Read moreSource§fn metrics(&self, symbol: &str, reply: Reply<Vec<MetricSeries>>)
fn metrics(&self, symbol: &str, reply: Reply<Vec<MetricSeries>>)
symbol, in display order. The default offers none.
The host publishes the values; the library computes no instrument metrics.Source§fn metric_history(&self, request: MetricRequest, reply: Reply<MetricPage>)
fn metric_history(&self, request: MetricRequest, reply: Reply<MetricPage>)
FeedError::NotSupported.Source§fn subscribe_metric(&self, subscription: MetricSubscription)
fn subscribe_metric(&self, subscription: MetricSubscription)
Self::unsubscribe. The default does nothing.Source§fn price_targets(&self, symbol: &str, reply: Reply<PriceTargets>)
fn price_targets(&self, symbol: &str, reply: Reply<PriceTargets>)
symbol. The default answers FeedError::NotSupported,
which leaves the chart without targets and shows no error.Source§fn symbol_details(&self, symbol: &str, reply: Reply<SymbolDetails>)
fn symbol_details(&self, symbol: &str, reply: Reply<SymbolDetails>)
symbol, for the symbol details
panel. The default answers FeedError::NotSupported, and the panel then shows neither.Source§fn news(&self, query: NewsQuery, reply: Reply<Vec<NewsStory>>)
fn news(&self, query: NewsQuery, reply: Reply<Vec<NewsStory>>)
query.limit stories, newest first, for the news and highlights panels. Answer
FeedError::NotSupported (the default) to have the panels say the feed has none.Source§fn calendar(&self, query: CalendarQuery, reply: Reply<Vec<CalendarEvent>>)
fn calendar(&self, query: CalendarQuery, reply: Reply<Vec<CalendarEvent>>)
query’s filters, in time order, for the calendar
panel. Answer FeedError::NotSupported (the default) to have the panel say the feed has
none.Source§fn screen(&self, query: ScreenerQuery, reply: Reply<Vec<ScreenerRow>>)
fn screen(&self, query: ScreenerQuery, reply: Reply<Vec<ScreenerRow>>)
query.limit symbols that meet every filter of query, sorted as it asks, each
with the values of its columns, for the screener. The feed does the screening. Answer
FeedError::InvalidData for a filter it cannot apply, and FeedError::NotSupported
(the default) to have the panel say the feed has none.Source§fn hotlist(&self, query: HotlistQuery, reply: Reply<Vec<HotlistEntry>>)
fn hotlist(&self, query: HotlistQuery, reply: Reply<Vec<HotlistEntry>>)
query.limit symbols of the hotlist query.list, in the list’s order, for the
hotlists panel. Answer FeedError::NotSupported (the default) to have the panel say the
feed has none.Source§fn screen_text(&self, query: ScreenerQuery, reply: Reply<ScreenerTextAnswer>)
fn screen_text(&self, query: ScreenerQuery, reply: Reply<ScreenerTextAnswer>)
screen, for a query whose text describes the screen in words. The
feed interprets the text with the other criteria and answers the rows with an explanation
of how it understood them. Answer FeedError::NotSupported (the default) to have the
panel say the feed takes no descriptions, and FeedError::InvalidData for one it cannot
interpret.Source§fn request_depth_snapshot(&self, id: SubscriptionId)
fn request_depth_snapshot(&self, id: SubscriptionId)
id was lost to a gap, an unusable update or a book deeper
than the limit: push a new snapshot with Sink::push_depth_snapshot, and keep pushing
deltas while it is fetched. The snapshot may be older than the latest delta: the chart
holds the deltas pushed while the book waits and applies those numbered above the
snapshot. Called once per loss: after an unusable snapshot the chart does not ask
again, and the book stays empty until the feed pushes a usable one or the subscription
restarts. The default does nothing, for feeds without depth.Auto Trait Implementations§
impl !Freeze for ReplayDriver
impl RefUnwindSafe for ReplayDriver
impl Send for ReplayDriver
impl Sync for ReplayDriver
impl Unpin for ReplayDriver
impl UnsafeUnpin for ReplayDriver
impl UnwindSafe for ReplayDriver
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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