paft_aggregates/info.rs
1//! Instrument identity and market snapshot models.
2//!
3//! These types provide both a lightweight and a full-featured view of an
4//! instrument that downstream consumers can use for rendering UIs, building
5//! reports, or persisting aggregated snapshots.
6//!
7//! - `FastInfo` focuses on the most frequently accessed fields for
8//! low-latency use cases.
9//! - `Info` provides an extended, richer view including ranges and
10//! fundamentals.
11
12use chrono::{DateTime, NaiveDate, Utc};
13#[cfg(feature = "dataframe")]
14use df_derive::ToDataFrame;
15use paft_domain::{Exchange, Isin, MarketState, Symbol};
16use paft_fundamentals::{EsgScores, PriceTarget, RecommendationSummary};
17use paft_money::{Currency, Money};
18#[cfg(feature = "dataframe")]
19use paft_utils::dataframe::ToDataFrame;
20use serde::{Deserialize, Serialize};
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
23#[cfg_attr(feature = "dataframe", derive(ToDataFrame))]
24/// Lightweight snapshot of commonly requested fields for an instrument.
25///
26/// Prefer `FastInfo` for list views and latency-sensitive paths. For
27/// extended snapshots, see [`Info`].
28pub struct FastInfo {
29 /// Primary trading symbol/ticker as provided by the data source.
30 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
31 pub symbol: Symbol,
32 /// Human-friendly instrument name.
33 pub name: Option<String>,
34 /// Primary listing exchange, if known.
35 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
36 pub exchange: Option<Exchange>,
37 /// Current market session state (for example: Pre, Regular, Post).
38 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
39 pub market_state: Option<MarketState>,
40 /// Quote currency used for monetary values in this snapshot.
41 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
42 pub currency: Option<Currency>,
43 /// Most recent traded/quoted price.
44 pub last: Option<Money>,
45 /// Previous session's official close price.
46 pub previous_close: Option<Money>,
47 /// Today's trading volume.
48 pub volume: Option<u64>,
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
52#[cfg_attr(feature = "dataframe", derive(ToDataFrame))]
53/// Detailed instrument profile and market snapshot.
54///
55/// Includes identification fields, real-time snapshot metrics, intraday and
56/// 52-week ranges, as well as a subset of fundamentals. All values are
57/// optional to accommodate partially populated data from upstream sources.
58pub struct Info {
59 // Identity
60 /// Primary trading symbol/ticker as provided by the data source.
61 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
62 pub symbol: Symbol,
63 /// Human-friendly instrument name.
64 pub name: Option<String>,
65 /// International Securities Identification Number.
66 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
67 pub isin: Option<Isin>,
68 /// Primary listing exchange, if known.
69 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
70 pub exchange: Option<Exchange>,
71
72 // Market snapshot
73 /// Current market session state (for example: Pre, Regular, Post).
74 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
75 pub market_state: Option<MarketState>,
76 /// Quote currency for all monetary values in this snapshot.
77 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
78 pub currency: Option<Currency>,
79 /// Most recent traded/quoted price.
80 pub last: Option<Money>,
81 /// Opening price for the current session.
82 pub open: Option<Money>,
83 /// Highest traded price observed during the current session.
84 pub high: Option<Money>,
85 /// Lowest traded price observed during the current session.
86 pub low: Option<Money>,
87 /// Previous session's official close price.
88 pub previous_close: Option<Money>,
89
90 // Ranges & volumes
91 /// Intraday low for the current session.
92 pub day_range_low: Option<Money>,
93 /// Intraday high for the current session.
94 pub day_range_high: Option<Money>,
95 /// 52-week low.
96 pub fifty_two_week_low: Option<Money>,
97 /// 52-week high.
98 pub fifty_two_week_high: Option<Money>,
99 /// Today's trading volume.
100 pub volume: Option<u64>,
101 /// Average daily trading volume (commonly 30D or 90D average, depending on source).
102 pub average_volume: Option<u64>,
103
104 // Fundamentals (generic)
105 /// Market capitalization (price × shares outstanding) in the quote currency.
106 pub market_cap: Option<Money>,
107 /// Number of shares currently outstanding.
108 pub shares_outstanding: Option<u64>,
109 /// Earnings per share, trailing twelve months.
110 pub eps_ttm: Option<Money>,
111 /// Price-to-earnings ratio, trailing twelve months.
112 pub pe_ttm: Option<f64>,
113 /// Dividend yield as a fraction (for example: `0.025` = 2.5%).
114 pub dividend_yield: Option<f64>, // 0.025 = 2.5%
115 /// Most recent ex-dividend date.
116 #[cfg_attr(feature = "dataframe", df_derive(as_string))]
117 pub ex_dividend_date: Option<NaiveDate>,
118
119 // Analyst coverage & ESG
120 /// Analyst price target summary.
121 pub price_target: Option<PriceTarget>,
122 /// Latest recommendation summary.
123 pub recommendation_summary: Option<RecommendationSummary>,
124 /// ESG scores (environmental, social, governance).
125 pub esg_scores: Option<EsgScores>,
126
127 // Timestamp of snapshot
128 #[serde(with = "chrono::serde::ts_seconds_option")]
129 /// Timestamp (UTC) when this snapshot was taken.
130 pub as_of: Option<DateTime<Utc>>,
131}