finance_query/models/screeners/
quote.rs

1use crate::models::quote::FormattedValue;
2use serde::{Deserialize, Serialize};
3
4/// Quote data from a Yahoo Finance screener
5///
6/// This struct contains the fields returned by Yahoo Finance's predefined
7/// screener endpoint. It includes comprehensive quote data for filtering
8/// and displaying screened stocks/funds.
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10#[cfg_attr(feature = "dataframe", derive(crate::ToDataFrame))]
11#[serde(rename_all = "camelCase")]
12pub struct ScreenerQuote {
13    // Core identification
14    /// Stock symbol (e.g., "NVDA")
15    pub symbol: String,
16    /// Short display name (e.g., "NVIDIA Corporation")
17    pub short_name: String,
18    /// Full company name
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub long_name: Option<String>,
21    /// Display name for UI purposes
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub display_name: Option<String>,
24    /// Type of quote (e.g., "EQUITY", "ETF", "CRYPTOCURRENCY")
25    pub quote_type: String,
26    /// Exchange code (e.g., "NMS" for NASDAQ)
27    pub exchange: String,
28
29    // Price information
30    /// Current regular market price
31    pub regular_market_price: FormattedValue<f64>,
32    /// Change in price from previous close
33    pub regular_market_change: FormattedValue<f64>,
34    /// Percent change from previous close
35    pub regular_market_change_percent: FormattedValue<f64>,
36    /// Regular market open price
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub regular_market_open: Option<FormattedValue<f64>>,
39    /// Day's high price
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub regular_market_day_high: Option<FormattedValue<f64>>,
42    /// Day's low price
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub regular_market_day_low: Option<FormattedValue<f64>>,
45    /// Previous close price
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub regular_market_previous_close: Option<FormattedValue<f64>>,
48    /// Regular market timestamp
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub regular_market_time: Option<FormattedValue<i64>>,
51
52    // Volume & Market Cap
53    /// Regular market volume (may be None for funds)
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub regular_market_volume: Option<FormattedValue<i64>>,
56    /// Average daily volume over 3 months
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub average_daily_volume3_month: Option<FormattedValue<i64>>,
59    /// Average daily volume over 10 days
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub average_daily_volume10_day: Option<FormattedValue<i64>>,
62    /// Market capitalization
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub market_cap: Option<FormattedValue<i64>>,
65    /// Outstanding shares
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub shares_outstanding: Option<FormattedValue<i64>>,
68
69    // 52-Week Range
70    /// 52-week high price
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub fifty_two_week_high: Option<FormattedValue<f64>>,
73    /// 52-week low price
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub fifty_two_week_low: Option<FormattedValue<f64>>,
76    /// Change from 52-week low
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub fifty_two_week_change: Option<FormattedValue<f64>>,
79    /// Percent change from 52-week low
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub fifty_two_week_change_percent: Option<FormattedValue<f64>>,
82
83    // Moving Averages
84    /// 50-day moving average
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub fifty_day_average: Option<FormattedValue<f64>>,
87    /// Change from 50-day average
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub fifty_day_average_change: Option<FormattedValue<f64>>,
90    /// Percent change from 50-day average
91    #[serde(skip_serializing_if = "Option::is_none")]
92    pub fifty_day_average_change_percent: Option<FormattedValue<f64>>,
93    /// 200-day moving average
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub two_hundred_day_average: Option<FormattedValue<f64>>,
96    /// Change from 200-day average
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub two_hundred_day_average_change: Option<FormattedValue<f64>>,
99    /// Percent change from 200-day average
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub two_hundred_day_average_change_percent: Option<FormattedValue<f64>>,
102
103    // Valuation Metrics
104    /// Average analyst rating (e.g., "1.3 - Strong Buy")
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub average_analyst_rating: Option<String>,
107    /// Trailing 12-month P/E ratio
108    #[serde(rename = "trailingPE", skip_serializing_if = "Option::is_none")]
109    pub trailing_pe: Option<FormattedValue<f64>>,
110    /// Forward P/E ratio
111    #[serde(rename = "forwardPE", skip_serializing_if = "Option::is_none")]
112    pub forward_pe: Option<FormattedValue<f64>>,
113    /// Price to book ratio
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub price_to_book: Option<FormattedValue<f64>>,
116    /// Book value per share
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub book_value: Option<FormattedValue<f64>>,
119
120    // Earnings Per Share
121    /// Trailing 12-month EPS
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub eps_trailing_twelve_months: Option<FormattedValue<f64>>,
124    /// Forward EPS
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub eps_forward: Option<FormattedValue<f64>>,
127    /// Current year EPS
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub eps_current_year: Option<FormattedValue<f64>>,
130    /// Price to current year EPS
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub price_eps_current_year: Option<FormattedValue<f64>>,
133
134    // Dividend Information
135    /// Dividend yield
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub dividend_yield: Option<FormattedValue<f64>>,
138    /// Dividend rate
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub dividend_rate: Option<FormattedValue<f64>>,
141    /// Ex-dividend date timestamp
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub dividend_date: Option<FormattedValue<i64>>,
144    /// Trailing annual dividend rate
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub trailing_annual_dividend_rate: Option<FormattedValue<f64>>,
147    /// Trailing annual dividend yield
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub trailing_annual_dividend_yield: Option<FormattedValue<f64>>,
150
151    // Bid/Ask
152    /// Current bid price
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub bid: Option<FormattedValue<f64>>,
155    /// Bid size
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub bid_size: Option<FormattedValue<i64>>,
158    /// Current ask price
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub ask: Option<FormattedValue<f64>>,
161    /// Ask size
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub ask_size: Option<FormattedValue<i64>>,
164
165    // Post/Pre Market (Optional)
166    /// Post-market price
167    #[serde(skip_serializing_if = "Option::is_none")]
168    pub post_market_price: Option<FormattedValue<f64>>,
169    /// Post-market price change
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub post_market_change: Option<FormattedValue<f64>>,
172    /// Post-market percent change
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub post_market_change_percent: Option<FormattedValue<f64>>,
175    /// Post-market timestamp
176    #[serde(skip_serializing_if = "Option::is_none")]
177    pub post_market_time: Option<FormattedValue<i64>>,
178    /// Pre-market price
179    #[serde(skip_serializing_if = "Option::is_none")]
180    pub pre_market_price: Option<FormattedValue<f64>>,
181    /// Pre-market price change
182    #[serde(skip_serializing_if = "Option::is_none")]
183    pub pre_market_change: Option<FormattedValue<f64>>,
184    /// Pre-market percent change
185    #[serde(skip_serializing_if = "Option::is_none")]
186    pub pre_market_change_percent: Option<FormattedValue<f64>>,
187    /// Pre-market timestamp
188    #[serde(skip_serializing_if = "Option::is_none")]
189    pub pre_market_time: Option<FormattedValue<i64>>,
190
191    // Earnings Dates
192    /// Earnings timestamp
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub earnings_timestamp: Option<FormattedValue<i64>>,
195    /// Earnings timestamp start
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub earnings_timestamp_start: Option<FormattedValue<i64>>,
198    /// Earnings timestamp end
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub earnings_timestamp_end: Option<FormattedValue<i64>>,
201
202    // Additional Fields
203    /// Currency code (e.g., "USD")
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub currency: Option<String>,
206}