use std::sync::Arc;
use crate::adapters::polygon;
use crate::error::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FinancialPeriod {
Annual,
Quarterly,
Ttm,
}
impl FinancialPeriod {
fn as_str(self) -> &'static str {
match self {
Self::Annual => "annual",
Self::Quarterly => "quarterly",
Self::Ttm => "ttm",
}
}
}
#[derive(Clone, Debug)]
pub struct PolygonHandle {
symbol: Arc<str>,
}
impl PolygonHandle {
pub(crate) fn new(symbol: Arc<str>) -> Self {
Self { symbol }
}
pub fn symbol(&self) -> &str {
&self.symbol
}
pub async fn snapshot(&self) -> Result<polygon::SingleSnapshotResponse> {
polygon::stock_snapshot(&self.symbol).await
}
pub async fn aggregates(
&self,
multiplier: u32,
timespan: polygon::Timespan,
from: &str,
to: &str,
params: Option<polygon::AggregateParams>,
) -> Result<polygon::AggregateResponse> {
polygon::stock_aggregates(&self.symbol, multiplier, timespan, from, to, params).await
}
pub async fn previous_close(
&self,
adjusted: Option<bool>,
) -> Result<polygon::AggregateResponse> {
polygon::stock_previous_close(&self.symbol, adjusted).await
}
pub async fn last_trade(&self) -> Result<polygon::LastTradeResponse> {
polygon::stock_last_trade(&self.symbol).await
}
pub async fn news(
&self,
limit: u32,
) -> Result<polygon::PaginatedResponse<polygon::NewsArticle>> {
let limit_str = limit.to_string();
polygon::stock_news(&[("ticker", &self.symbol), ("limit", &limit_str)]).await
}
pub async fn dividends(&self) -> Result<polygon::PaginatedResponse<polygon::Dividend>> {
polygon::stock_dividends(&[("ticker", &self.symbol)]).await
}
pub async fn splits(&self) -> Result<polygon::PaginatedResponse<polygon::Split>> {
polygon::stock_splits(&[("ticker", &self.symbol)]).await
}
pub async fn financials(
&self,
period: FinancialPeriod,
limit: Option<u32>,
) -> Result<polygon::PaginatedResponse<polygon::FinancialResult>> {
let mut params: Vec<(&str, &str)> = vec![("period_of_report_type", period.as_str())];
let limit_str;
if let Some(n) = limit {
limit_str = n.to_string();
params.push(("limit", &limit_str));
}
polygon::stock_financials(&self.symbol, ¶ms).await
}
pub async fn details(&self) -> Result<polygon::TickerDetailsResponse> {
polygon::ticker_details(&self.symbol).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn handle_holds_symbol() {
let h = PolygonHandle::new(Arc::from("AAPL"));
assert_eq!(h.symbol(), "AAPL");
}
#[test]
fn handle_clone_is_cheap_arc_clone() {
let h1 = PolygonHandle::new(Arc::from("AAPL"));
let h2 = h1.clone();
assert_eq!(h1.symbol(), h2.symbol());
}
#[allow(dead_code, clippy::manual_async_fn)]
async fn _polygon_method_signatures_compile(h: &super::PolygonHandle) {
use crate::adapters::polygon;
let _ = h.snapshot().await;
let _ = h
.aggregates(1, polygon::Timespan::Day, "2024-01-01", "2024-01-31", None)
.await;
let _ = h.previous_close(None).await;
let _ = h.last_trade().await;
let _ = h.news(10).await;
let _ = h.dividends().await;
let _ = h.splits().await;
let _ = h.financials(FinancialPeriod::Annual, None).await;
let _ = h.details().await;
}
}