egui_charts/data/metrics.rs
1//! Instrument metrics published by a host, independent of its price bars.
2
3use super::{Sink, SubscriptionId};
4use crate::model::Bar;
5use crate::scales::StudyFormat;
6use chrono::{DateTime, Utc};
7
8/// One metric offered for an instrument, identified by a host-owned key.
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct MetricSeries {
11 /// Key used in metric history and subscription requests.
12 pub id: String,
13 /// Display name, such as "Open interest".
14 pub name: String,
15 /// Display unit, such as "contracts", "USD" or "%".
16 pub unit: String,
17 /// Numeric format used in legends, axes and tooltips.
18 pub format: StudyFormat,
19}
20
21/// A metric's value from this instant until the next published point.
22/// Non-finite values are rejected, like invalid price bars.
23#[derive(Clone, Copy, Debug, PartialEq)]
24pub struct MetricPoint {
25 /// UTC instant at which this observation takes effect.
26 pub time: DateTime<Utc>,
27 /// Metric value in the units declared by `MetricSeries`.
28 pub value: f64,
29}
30
31impl From<MetricPoint> for Bar {
32 fn from(point: MetricPoint) -> Self {
33 Self::new(
34 point.time,
35 point.value,
36 point.value,
37 point.value,
38 point.value,
39 0.0,
40 )
41 }
42}
43
44/// Up to `count` metric points strictly before `before`, or the latest when absent.
45/// Include the point in effect before the chart's first bar when paging back.
46#[derive(Clone, Debug, PartialEq, Eq)]
47pub struct MetricRequest {
48 /// Instrument identifier used by the host.
49 pub symbol: String,
50 /// [`MetricSeries::id`] for this instrument.
51 pub metric: String,
52 /// Exclusive upper time bound, or `None` for the latest points.
53 pub before: Option<DateTime<Utc>>,
54 /// Maximum number of points to return.
55 pub count: usize,
56}
57
58/// A page of metric history, in any order. The chart sorts and deduplicates by timestamp.
59/// A live correction of the same timestamp takes precedence over history.
60#[derive(Clone, Debug, Default, PartialEq)]
61pub struct MetricPage {
62 /// Metric observations in this page.
63 pub points: Vec<MetricPoint>,
64 /// Whether this page reaches the beginning of the available history.
65 pub end_of_history: bool,
66}
67
68/// A live metric stream, stopped through [`super::Datafeed::unsubscribe`].
69/// Push with [`Sink::push_metric`]; timestamps are retained without price-bar aggregation.
70#[derive(Clone)]
71pub struct MetricSubscription {
72 /// Identifier used to unsubscribe this metric stream.
73 pub id: SubscriptionId,
74 /// Instrument identifier used by the host.
75 pub symbol: String,
76 /// Host-owned metric identifier for this instrument.
77 pub metric: String,
78 /// Destination for updates; stop publishing when it becomes inactive.
79 pub sink: Sink,
80}
81
82impl Sink {
83 /// Publish or correct a metric point. Its value is held until the next point;
84 /// an inactive subscription ignores pushes, like [`Self::push_bar`].
85 pub fn push_metric(&self, point: MetricPoint) {
86 self.push_bar(point.into());
87 }
88}