finance_query/ticker/
polygon.rs1use std::sync::Arc;
16
17use crate::adapters::polygon;
18use crate::error::Result;
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum FinancialPeriod {
23 Annual,
25 Quarterly,
27 Ttm,
29}
30
31impl FinancialPeriod {
32 fn as_str(self) -> &'static str {
33 match self {
34 Self::Annual => "annual",
35 Self::Quarterly => "quarterly",
36 Self::Ttm => "ttm",
37 }
38 }
39}
40
41#[derive(Clone, Debug)]
46pub struct PolygonHandle {
47 symbol: Arc<str>,
48}
49
50impl PolygonHandle {
51 pub(crate) fn new(symbol: Arc<str>) -> Self {
54 Self { symbol }
55 }
56
57 pub fn symbol(&self) -> &str {
59 &self.symbol
60 }
61
62 pub async fn snapshot(&self) -> Result<polygon::SingleSnapshotResponse> {
66 polygon::stock_snapshot(&self.symbol).await
67 }
68
69 pub async fn aggregates(
73 &self,
74 multiplier: u32,
75 timespan: polygon::Timespan,
76 from: &str,
77 to: &str,
78 params: Option<polygon::AggregateParams>,
79 ) -> Result<polygon::AggregateResponse> {
80 polygon::stock_aggregates(&self.symbol, multiplier, timespan, from, to, params).await
81 }
82
83 pub async fn previous_close(
87 &self,
88 adjusted: Option<bool>,
89 ) -> Result<polygon::AggregateResponse> {
90 polygon::stock_previous_close(&self.symbol, adjusted).await
91 }
92
93 pub async fn last_trade(&self) -> Result<polygon::LastTradeResponse> {
97 polygon::stock_last_trade(&self.symbol).await
98 }
99
100 pub async fn news(
105 &self,
106 limit: u32,
107 ) -> Result<polygon::PaginatedResponse<polygon::NewsArticle>> {
108 let limit_str = limit.to_string();
109 polygon::stock_news(&[("ticker", &self.symbol), ("limit", &limit_str)]).await
110 }
111
112 pub async fn dividends(&self) -> Result<polygon::PaginatedResponse<polygon::Dividend>> {
116 polygon::stock_dividends(&[("ticker", &self.symbol)]).await
117 }
118
119 pub async fn splits(&self) -> Result<polygon::PaginatedResponse<polygon::Split>> {
123 polygon::stock_splits(&[("ticker", &self.symbol)]).await
124 }
125
126 pub async fn financials(
130 &self,
131 period: FinancialPeriod,
132 limit: Option<u32>,
133 ) -> Result<polygon::PaginatedResponse<polygon::FinancialResult>> {
134 let mut params: Vec<(&str, &str)> = vec![("period_of_report_type", period.as_str())];
135 let limit_str;
136 if let Some(n) = limit {
137 limit_str = n.to_string();
138 params.push(("limit", &limit_str));
139 }
140 polygon::stock_financials(&self.symbol, ¶ms).await
141 }
142
143 pub async fn details(&self) -> Result<polygon::TickerDetailsResponse> {
147 polygon::ticker_details(&self.symbol).await
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn handle_holds_symbol() {
157 let h = PolygonHandle::new(Arc::from("AAPL"));
158 assert_eq!(h.symbol(), "AAPL");
159 }
160
161 #[test]
162 fn handle_clone_is_cheap_arc_clone() {
163 let h1 = PolygonHandle::new(Arc::from("AAPL"));
164 let h2 = h1.clone();
165 assert_eq!(h1.symbol(), h2.symbol());
166 }
167
168 #[allow(dead_code, clippy::manual_async_fn)]
173 async fn _polygon_method_signatures_compile(h: &super::PolygonHandle) {
174 use crate::adapters::polygon;
175 let _ = h.snapshot().await;
176 let _ = h
177 .aggregates(1, polygon::Timespan::Day, "2024-01-01", "2024-01-31", None)
178 .await;
179 let _ = h.previous_close(None).await;
180 let _ = h.last_trade().await;
181 let _ = h.news(10).await;
182 let _ = h.dividends().await;
183 let _ = h.splits().await;
184 let _ = h.financials(FinancialPeriod::Annual, None).await;
185 let _ = h.details().await;
186 }
187}