Skip to main content

finance_query/adapters/polygon/stocks/
corporate_actions.rs

1//! Corporate action endpoints: dividends, splits, IPOs, ticker events.
2
3use serde::{Deserialize, Serialize};
4
5use crate::error::Result;
6
7use super::super::build_client;
8use super::super::models::PaginatedResponse;
9
10/// Dividend event.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12#[non_exhaustive]
13pub struct Dividend {
14    /// Ticker symbol.
15    pub ticker: Option<String>,
16    /// Cash amount per share.
17    pub cash_amount: Option<f64>,
18    /// Currency.
19    pub currency: Option<String>,
20    /// Declaration date.
21    pub declaration_date: Option<String>,
22    /// Dividend type (e.g., `"CD"` for cash).
23    pub dividend_type: Option<String>,
24    /// Ex-dividend date.
25    pub ex_dividend_date: Option<String>,
26    /// Frequency (e.g., `4` for quarterly).
27    pub frequency: Option<u32>,
28    /// Pay date.
29    pub pay_date: Option<String>,
30    /// Record date.
31    pub record_date: Option<String>,
32}
33
34/// Stock split event.
35#[derive(Debug, Clone, Serialize, Deserialize)]
36#[non_exhaustive]
37pub struct Split {
38    /// Ticker symbol.
39    pub ticker: Option<String>,
40    /// Execution date.
41    pub execution_date: Option<String>,
42    /// Split from factor.
43    pub split_from: Option<f64>,
44    /// Split to factor.
45    pub split_to: Option<f64>,
46}
47
48/// IPO event.
49#[derive(Debug, Clone, Serialize, Deserialize)]
50#[non_exhaustive]
51pub struct Ipo {
52    /// Ticker symbol.
53    pub ticker: Option<String>,
54    /// Company name.
55    pub name: Option<String>,
56    /// Listing date.
57    pub listing_date: Option<String>,
58    /// IPO price.
59    pub ipo_price: Option<f64>,
60    /// Currency.
61    pub currency: Option<String>,
62    /// Exchange.
63    pub primary_exchange: Option<String>,
64    /// Share price range low.
65    pub lot_size: Option<u64>,
66    /// IPO status.
67    pub ipo_status: Option<String>,
68}
69
70/// Ticker event.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72#[non_exhaustive]
73pub struct TickerEvent {
74    /// Event type.
75    #[serde(rename = "type")]
76    pub event_type: Option<String>,
77    /// Event date.
78    pub date: Option<String>,
79    /// Ticker change details.
80    pub ticker_change: Option<serde_json::Value>,
81}
82
83/// Ticker events response.
84#[derive(Debug, Clone, Serialize, Deserialize)]
85#[non_exhaustive]
86pub struct TickerEventsResponse {
87    /// Request ID.
88    pub request_id: Option<String>,
89    /// Response status.
90    pub status: Option<String>,
91    /// Ticker name.
92    pub name: Option<String>,
93    /// Events list.
94    pub events: Option<Vec<TickerEvent>>,
95}
96
97/// Fetch historical dividends.
98pub async fn stock_dividends(params: &[(&str, &str)]) -> Result<PaginatedResponse<Dividend>> {
99    let client = build_client()?;
100    client.get("/v3/reference/dividends", params).await
101}
102
103/// Fetch historical stock splits.
104pub async fn stock_splits(params: &[(&str, &str)]) -> Result<PaginatedResponse<Split>> {
105    let client = build_client()?;
106    client.get("/v3/reference/splits", params).await
107}
108
109/// Fetch IPO data.
110pub async fn stock_ipos(params: &[(&str, &str)]) -> Result<PaginatedResponse<Ipo>> {
111    let client = build_client()?;
112    client.get("/v1/reference/ipos", params).await
113}
114
115/// Fetch ticker events (name changes, mergers, etc.).
116pub async fn stock_ticker_events(ticker: &str) -> Result<TickerEventsResponse> {
117    let client = build_client()?;
118    let path = format!("/vX/reference/tickers/{}/events", ticker);
119    let json = client.get_raw(&path, &[]).await?;
120    serde_json::from_value(json).map_err(|e| crate::error::FinanceError::ResponseStructureError {
121        field: "ticker_events".to_string(),
122        context: format!("Failed to parse ticker events: {e}"),
123    })
124}