1use serde::{Deserialize, Deserializer, Serialize};
4
5#[allow(dead_code)]
10pub(crate) fn deserialize_optional_f64<'de, D>(
11 deserializer: D,
12) -> std::result::Result<Option<f64>, D::Error>
13where
14 D: Deserializer<'de>,
15{
16 let s: Option<String> = Option::deserialize(deserializer)?;
17 match s.as_deref() {
18 Some("None") | Some(".") | Some("-") | Some("") | None => Ok(None),
19 Some(v) => v.parse::<f64>().ok().map_or(Ok(None), |n| Ok(Some(n))),
20 }
21}
22
23#[allow(dead_code)]
25pub(crate) fn deserialize_f64_from_str<'de, D>(
26 deserializer: D,
27) -> std::result::Result<f64, D::Error>
28where
29 D: Deserializer<'de>,
30{
31 let s = String::deserialize(deserializer)?;
32 Ok(s.parse::<f64>().unwrap_or(0.0))
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum AvInterval {
42 OneMin,
44 FiveMin,
46 FifteenMin,
48 ThirtyMin,
50 SixtyMin,
52 Daily,
54 Weekly,
56 Monthly,
58}
59
60impl AvInterval {
61 pub fn as_str(&self) -> &'static str {
63 match self {
64 Self::OneMin => "1min",
65 Self::FiveMin => "5min",
66 Self::FifteenMin => "15min",
67 Self::ThirtyMin => "30min",
68 Self::SixtyMin => "60min",
69 Self::Daily => "daily",
70 Self::Weekly => "weekly",
71 Self::Monthly => "monthly",
72 }
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub enum SeriesType {
79 Close,
81 Open,
83 High,
85 Low,
87}
88
89impl SeriesType {
90 pub fn as_str(&self) -> &'static str {
92 match self {
93 Self::Close => "close",
94 Self::Open => "open",
95 Self::High => "high",
96 Self::Low => "low",
97 }
98 }
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq)]
103pub enum OutputSize {
104 Compact,
106 Full,
108}
109
110impl OutputSize {
111 pub fn as_str(&self) -> &'static str {
113 match self {
114 Self::Compact => "compact",
115 Self::Full => "full",
116 }
117 }
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
126#[non_exhaustive]
127pub struct TimeSeriesEntry {
128 pub timestamp: String,
130 pub open: f64,
132 pub high: f64,
134 pub low: f64,
136 pub close: f64,
138 pub volume: f64,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize)]
144#[non_exhaustive]
145pub struct AdjustedTimeSeriesEntry {
146 pub timestamp: String,
148 pub open: f64,
150 pub high: f64,
152 pub low: f64,
154 pub close: f64,
156 pub adjusted_close: f64,
158 pub volume: f64,
160 pub dividend_amount: f64,
162 pub split_coefficient: Option<f64>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
168#[non_exhaustive]
169pub struct TimeSeries {
170 pub symbol: String,
172 pub last_refreshed: String,
174 pub entries: Vec<TimeSeriesEntry>,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
180#[non_exhaustive]
181pub struct AdjustedTimeSeries {
182 pub symbol: String,
184 pub last_refreshed: String,
186 pub entries: Vec<AdjustedTimeSeriesEntry>,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize)]
196#[non_exhaustive]
197pub struct GlobalQuote {
198 pub symbol: String,
200 pub open: f64,
202 pub high: f64,
204 pub low: f64,
206 pub price: f64,
208 pub volume: f64,
210 pub latest_trading_day: String,
212 pub previous_close: f64,
214 pub change: f64,
216 pub change_percent: String,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
222#[non_exhaustive]
223pub struct BulkQuote {
224 pub symbol: String,
226 pub open: Option<f64>,
228 pub high: Option<f64>,
230 pub low: Option<f64>,
232 pub price: Option<f64>,
234 pub volume: Option<f64>,
236 pub latest_trading_day: Option<String>,
238 pub previous_close: Option<f64>,
240 pub change: Option<f64>,
242 pub change_percent: Option<String>,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
252#[non_exhaustive]
253pub struct SymbolMatch {
254 pub symbol: String,
256 pub name: String,
258 pub asset_type: String,
260 pub region: String,
262 pub market_open: String,
264 pub market_close: String,
266 pub timezone: String,
268 pub currency: String,
270 pub match_score: f64,
272}
273
274#[derive(Debug, Clone, Serialize, Deserialize)]
280#[non_exhaustive]
281pub struct MarketStatus {
282 pub market_type: String,
284 pub region: String,
286 pub primary_exchanges: String,
288 pub local_open: String,
290 pub local_close: String,
292 pub current_status: String,
294 pub notes: String,
296}
297
298#[derive(Debug, Clone, Serialize, Deserialize)]
304#[non_exhaustive]
305pub struct OptionContract {
306 pub contractid: String,
308 pub symbol: String,
310 pub expiration: String,
312 pub strike: f64,
314 pub option_type: String,
316 pub last: Option<f64>,
318 pub mark: Option<f64>,
320 pub bid: Option<f64>,
322 pub bid_size: Option<f64>,
324 pub ask: Option<f64>,
326 pub ask_size: Option<f64>,
328 pub volume: Option<f64>,
330 pub open_interest: Option<f64>,
332 pub implied_volatility: Option<f64>,
334 pub delta: Option<f64>,
336 pub gamma: Option<f64>,
338 pub theta: Option<f64>,
340 pub vega: Option<f64>,
342 pub rho: Option<f64>,
344}
345
346#[derive(Debug, Clone, Serialize, Deserialize)]
348#[non_exhaustive]
349pub struct OptionsChain {
350 pub symbol: String,
352 pub contracts: Vec<OptionContract>,
354}
355
356#[derive(Debug, Clone, Serialize, Deserialize)]
362#[non_exhaustive]
363pub struct NewsArticle {
364 pub title: String,
366 pub url: String,
368 pub time_published: String,
370 pub source: String,
372 pub summary: String,
374 pub overall_sentiment_score: Option<f64>,
376 pub overall_sentiment_label: Option<String>,
378 pub ticker_sentiment: Vec<TickerSentiment>,
380}
381
382#[derive(Debug, Clone, Serialize, Deserialize)]
384#[non_exhaustive]
385pub struct TickerSentiment {
386 pub ticker: String,
388 pub relevance_score: Option<f64>,
390 pub ticker_sentiment_score: Option<f64>,
392 pub ticker_sentiment_label: Option<String>,
394}
395
396#[derive(Debug, Clone, Serialize, Deserialize)]
398#[non_exhaustive]
399pub struct EarningsCallTranscript {
400 pub symbol: String,
402 pub quarter: String,
404 pub transcript: String,
406}
407
408#[derive(Debug, Clone, Serialize, Deserialize)]
410#[non_exhaustive]
411pub struct TopMoverTicker {
412 pub ticker: String,
414 pub price: String,
416 pub change_amount: String,
418 pub change_percentage: String,
420 pub volume: String,
422}
423
424#[derive(Debug, Clone, Serialize, Deserialize)]
426#[non_exhaustive]
427pub struct TopMovers {
428 pub last_updated: String,
430 pub top_gainers: Vec<TopMoverTicker>,
432 pub top_losers: Vec<TopMoverTicker>,
434 pub most_actively_traded: Vec<TopMoverTicker>,
436}
437
438#[derive(Debug, Clone, Serialize, Deserialize)]
444#[non_exhaustive]
445pub struct CompanyOverview {
446 pub symbol: String,
448 pub asset_type: Option<String>,
450 pub name: Option<String>,
452 pub description: Option<String>,
454 pub exchange: Option<String>,
456 pub currency: Option<String>,
458 pub country: Option<String>,
460 pub sector: Option<String>,
462 pub industry: Option<String>,
464 pub market_capitalization: Option<f64>,
466 pub pe_ratio: Option<f64>,
468 pub peg_ratio: Option<f64>,
470 pub book_value: Option<f64>,
472 pub dividend_per_share: Option<f64>,
474 pub dividend_yield: Option<f64>,
476 pub eps: Option<f64>,
478 pub revenue_per_share_ttm: Option<f64>,
480 pub profit_margin: Option<f64>,
482 pub operating_margin_ttm: Option<f64>,
484 pub return_on_assets_ttm: Option<f64>,
486 pub return_on_equity_ttm: Option<f64>,
488 pub revenue_ttm: Option<f64>,
490 pub gross_profit_ttm: Option<f64>,
492 pub ebitda: Option<f64>,
494 pub week_52_high: Option<f64>,
496 pub week_52_low: Option<f64>,
498 pub moving_average_50day: Option<f64>,
500 pub moving_average_200day: Option<f64>,
502 pub shares_outstanding: Option<f64>,
504 pub beta: Option<f64>,
506 pub forward_pe: Option<f64>,
508 pub price_to_sales_ratio_ttm: Option<f64>,
510 pub price_to_book_ratio: Option<f64>,
512 pub analyst_target_price: Option<f64>,
514 pub analyst_rating_strong_buy: Option<u32>,
516 pub analyst_rating_buy: Option<u32>,
518 pub analyst_rating_hold: Option<u32>,
520 pub analyst_rating_sell: Option<u32>,
522 pub analyst_rating_strong_sell: Option<u32>,
524}
525
526#[derive(Debug, Clone, Serialize, Deserialize)]
528#[non_exhaustive]
529pub struct EtfProfile {
530 pub symbol: String,
532 pub name: Option<String>,
534 pub asset_type: Option<String>,
536 pub net_assets: Option<f64>,
538 pub net_expense_ratio: Option<f64>,
540 pub portfolio_turnover: Option<f64>,
542 pub dividend_yield: Option<f64>,
544 pub inception_date: Option<String>,
546 pub holdings: Vec<EtfHolding>,
548}
549
550#[derive(Debug, Clone, Serialize, Deserialize)]
552#[non_exhaustive]
553pub struct EtfHolding {
554 pub symbol: Option<String>,
556 pub description: Option<String>,
558 pub weight: Option<f64>,
560}
561
562#[derive(Debug, Clone, Serialize, Deserialize)]
564#[non_exhaustive]
565pub struct FinancialReport {
566 pub fiscal_date_ending: String,
568 pub reported_currency: String,
570 #[serde(flatten)]
572 pub fields: std::collections::HashMap<String, serde_json::Value>,
573}
574
575#[derive(Debug, Clone, Serialize, Deserialize)]
577#[non_exhaustive]
578pub struct FinancialStatements {
579 pub symbol: String,
581 pub annual_reports: Vec<FinancialReport>,
583 pub quarterly_reports: Vec<FinancialReport>,
585}
586
587#[derive(Debug, Clone, Serialize, Deserialize)]
589#[non_exhaustive]
590pub struct DividendEvent {
591 pub ex_dividend_date: Option<String>,
593 pub declaration_date: Option<String>,
595 pub record_date: Option<String>,
597 pub payment_date: Option<String>,
599 pub amount: Option<f64>,
601}
602
603#[derive(Debug, Clone, Serialize, Deserialize)]
605#[non_exhaustive]
606pub struct SplitEvent {
607 pub effective_date: Option<String>,
609 pub split_ratio: Option<String>,
611}
612
613#[derive(Debug, Clone, Serialize, Deserialize)]
615#[non_exhaustive]
616pub struct EarningsData {
617 pub fiscal_date_ending: Option<String>,
619 pub reported_date: Option<String>,
621 pub reported_eps: Option<f64>,
623 pub estimated_eps: Option<f64>,
625 pub surprise: Option<f64>,
627 pub surprise_percentage: Option<f64>,
629}
630
631#[derive(Debug, Clone, Serialize, Deserialize)]
633#[non_exhaustive]
634pub struct EarningsHistory {
635 pub symbol: String,
637 pub annual_earnings: Vec<EarningsData>,
639 pub quarterly_earnings: Vec<EarningsData>,
641}
642
643#[derive(Debug, Clone, Serialize, Deserialize)]
645#[non_exhaustive]
646pub struct EarningsCalendarEntry {
647 pub symbol: String,
649 pub name: Option<String>,
651 pub report_date: Option<String>,
653 pub fiscal_date_ending: Option<String>,
655 pub estimate: Option<f64>,
657 pub currency: Option<String>,
659}
660
661#[derive(Debug, Clone, Serialize, Deserialize)]
663#[non_exhaustive]
664pub struct IpoCalendarEntry {
665 pub symbol: Option<String>,
667 pub name: Option<String>,
669 pub ipo_date: Option<String>,
671 pub price_range: Option<String>,
673 pub exchange: Option<String>,
675}
676
677#[derive(Debug, Clone, Serialize, Deserialize)]
679#[non_exhaustive]
680pub struct ListingEntry {
681 pub symbol: String,
683 pub name: Option<String>,
685 pub exchange: Option<String>,
687 pub asset_type: Option<String>,
689 pub ipo_date: Option<String>,
691 pub delisting_date: Option<String>,
693 pub status: Option<String>,
695}
696
697#[derive(Debug, Clone, Serialize, Deserialize)]
703#[non_exhaustive]
704pub struct ExchangeRate {
705 pub from_currency_code: String,
707 pub from_currency_name: String,
709 pub to_currency_code: String,
711 pub to_currency_name: String,
713 pub exchange_rate: f64,
715 pub last_refreshed: String,
717 pub bid_price: f64,
719 pub ask_price: f64,
721}
722
723#[derive(Debug, Clone, Serialize, Deserialize)]
725#[non_exhaustive]
726pub struct ForexEntry {
727 pub timestamp: String,
729 pub open: f64,
731 pub high: f64,
733 pub low: f64,
735 pub close: f64,
737}
738
739#[derive(Debug, Clone, Serialize, Deserialize)]
741#[non_exhaustive]
742pub struct ForexTimeSeries {
743 pub from_symbol: String,
745 pub to_symbol: String,
747 pub last_refreshed: String,
749 pub entries: Vec<ForexEntry>,
751}
752
753#[derive(Debug, Clone, Serialize, Deserialize)]
759#[non_exhaustive]
760pub struct CryptoEntry {
761 pub timestamp: String,
763 pub open: f64,
765 pub high: f64,
767 pub low: f64,
769 pub close: f64,
771 pub volume: f64,
773}
774
775#[derive(Debug, Clone, Serialize, Deserialize)]
777#[non_exhaustive]
778pub struct CryptoTimeSeries {
779 pub symbol: String,
781 pub market: String,
783 pub last_refreshed: String,
785 pub entries: Vec<CryptoEntry>,
787}
788
789#[derive(Debug, Clone, Serialize, Deserialize)]
795#[non_exhaustive]
796pub struct CommodityDataPoint {
797 pub date: String,
799 pub value: Option<f64>,
801}
802
803#[derive(Debug, Clone, Serialize, Deserialize)]
805#[non_exhaustive]
806pub struct CommoditySeries {
807 pub name: String,
809 pub interval: String,
811 pub unit: String,
813 pub data: Vec<CommodityDataPoint>,
815}
816
817#[derive(Debug, Clone, Serialize, Deserialize)]
823#[non_exhaustive]
824pub struct EconomicDataPoint {
825 pub date: String,
827 pub value: Option<f64>,
829}
830
831#[derive(Debug, Clone, Serialize, Deserialize)]
833#[non_exhaustive]
834pub struct EconomicSeries {
835 pub name: String,
837 pub interval: String,
839 pub unit: String,
841 pub data: Vec<EconomicDataPoint>,
843}
844
845#[derive(Debug, Clone, Serialize, Deserialize)]
851#[non_exhaustive]
852pub struct IndicatorDataPoint {
853 pub timestamp: String,
855 pub values: std::collections::HashMap<String, f64>,
858}
859
860#[derive(Debug, Clone, Serialize, Deserialize)]
862#[non_exhaustive]
863pub struct TechnicalIndicator {
864 pub indicator: String,
866 pub symbol: String,
868 pub last_refreshed: String,
870 pub interval: String,
872 pub data: Vec<IndicatorDataPoint>,
874}