Skip to main content

alpaca_data/corporate_actions/
model.rs

1use std::collections::BTreeMap;
2
3use rust_decimal::Decimal;
4use serde::{Deserialize, Serialize};
5
6pub type UnknownCorporateAction = BTreeMap<String, serde_json::Value>;
7
8#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
9pub struct CorporateActions {
10    #[serde(default)]
11    pub forward_splits: Vec<ForwardSplit>,
12    #[serde(default)]
13    pub reverse_splits: Vec<ReverseSplit>,
14    #[serde(default)]
15    pub unit_splits: Vec<UnitSplit>,
16    #[serde(default)]
17    pub stock_dividends: Vec<StockDividend>,
18    #[serde(default)]
19    pub cash_dividends: Vec<CashDividend>,
20    #[serde(default)]
21    pub spin_offs: Vec<SpinOff>,
22    #[serde(default)]
23    pub cash_mergers: Vec<CashMerger>,
24    #[serde(default)]
25    pub stock_mergers: Vec<StockMerger>,
26    #[serde(default)]
27    pub stock_and_cash_mergers: Vec<StockAndCashMerger>,
28    #[serde(default)]
29    pub redemptions: Vec<Redemption>,
30    #[serde(default)]
31    pub name_changes: Vec<NameChange>,
32    #[serde(default)]
33    pub worthless_removals: Vec<WorthlessRemoval>,
34    #[serde(default)]
35    pub rights_distributions: Vec<RightsDistribution>,
36    #[serde(default)]
37    pub contract_adjustments: Vec<UnknownCorporateAction>,
38    #[serde(default)]
39    pub partial_calls: Vec<UnknownCorporateAction>,
40    #[serde(flatten)]
41    pub other: BTreeMap<String, Vec<UnknownCorporateAction>>,
42}
43
44impl CorporateActions {
45    pub(crate) fn merge(&mut self, mut next: Self) {
46        self.forward_splits.append(&mut next.forward_splits);
47        self.reverse_splits.append(&mut next.reverse_splits);
48        self.unit_splits.append(&mut next.unit_splits);
49        self.stock_dividends.append(&mut next.stock_dividends);
50        self.cash_dividends.append(&mut next.cash_dividends);
51        self.spin_offs.append(&mut next.spin_offs);
52        self.cash_mergers.append(&mut next.cash_mergers);
53        self.stock_mergers.append(&mut next.stock_mergers);
54        self.stock_and_cash_mergers
55            .append(&mut next.stock_and_cash_mergers);
56        self.redemptions.append(&mut next.redemptions);
57        self.name_changes.append(&mut next.name_changes);
58        self.worthless_removals.append(&mut next.worthless_removals);
59        self.rights_distributions
60            .append(&mut next.rights_distributions);
61        self.contract_adjustments
62            .append(&mut next.contract_adjustments);
63        self.partial_calls.append(&mut next.partial_calls);
64
65        for (key, mut values) in next.other {
66            self.other.entry(key).or_default().append(&mut values);
67        }
68    }
69}
70
71#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
72pub struct ForwardSplit {
73    pub id: String,
74    pub symbol: String,
75    pub cusip: String,
76    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
77    pub new_rate: Decimal,
78    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
79    pub old_rate: Decimal,
80    pub process_date: String,
81    pub ex_date: String,
82    pub record_date: Option<String>,
83    pub payable_date: Option<String>,
84    pub due_bill_redemption_date: Option<String>,
85}
86
87#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
88pub struct ReverseSplit {
89    pub id: String,
90    pub symbol: String,
91    pub old_cusip: String,
92    pub new_cusip: String,
93    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
94    pub new_rate: Decimal,
95    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
96    pub old_rate: Decimal,
97    pub process_date: String,
98    pub ex_date: String,
99    pub record_date: Option<String>,
100    pub payable_date: Option<String>,
101}
102
103#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
104pub struct UnitSplit {
105    pub id: String,
106    pub old_symbol: String,
107    pub old_cusip: String,
108    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
109    pub old_rate: Decimal,
110    pub new_symbol: String,
111    pub new_cusip: String,
112    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
113    pub new_rate: Decimal,
114    pub alternate_symbol: String,
115    pub alternate_cusip: String,
116    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
117    pub alternate_rate: Decimal,
118    pub process_date: String,
119    pub effective_date: String,
120    pub payable_date: Option<String>,
121}
122
123#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
124pub struct StockDividend {
125    pub id: String,
126    pub symbol: String,
127    pub cusip: String,
128    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
129    pub rate: Decimal,
130    pub process_date: String,
131    pub ex_date: String,
132    pub record_date: Option<String>,
133    pub payable_date: Option<String>,
134}
135
136#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
137pub struct CashDividend {
138    pub id: String,
139    pub symbol: String,
140    pub cusip: String,
141    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
142    pub rate: Decimal,
143    pub special: bool,
144    pub foreign: bool,
145    pub process_date: String,
146    pub ex_date: String,
147    pub record_date: Option<String>,
148    pub payable_date: Option<String>,
149    pub due_bill_on_date: Option<String>,
150    pub due_bill_off_date: Option<String>,
151}
152
153#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
154pub struct SpinOff {
155    pub id: String,
156    pub source_symbol: String,
157    pub source_cusip: String,
158    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
159    pub source_rate: Decimal,
160    pub new_symbol: String,
161    pub new_cusip: String,
162    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
163    pub new_rate: Decimal,
164    pub process_date: String,
165    pub ex_date: String,
166    pub record_date: Option<String>,
167    pub payable_date: Option<String>,
168    pub due_bill_redemption_date: Option<String>,
169}
170
171#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
172pub struct CashMerger {
173    pub id: String,
174    pub acquirer_symbol: Option<String>,
175    pub acquirer_cusip: Option<String>,
176    pub acquiree_symbol: String,
177    pub acquiree_cusip: String,
178    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
179    pub rate: Decimal,
180    pub process_date: String,
181    pub effective_date: String,
182    pub payable_date: Option<String>,
183}
184
185#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
186pub struct StockMerger {
187    pub id: String,
188    pub acquirer_symbol: String,
189    pub acquirer_cusip: String,
190    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
191    pub acquirer_rate: Decimal,
192    pub acquiree_symbol: String,
193    pub acquiree_cusip: String,
194    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
195    pub acquiree_rate: Decimal,
196    pub process_date: String,
197    pub effective_date: String,
198    pub payable_date: Option<String>,
199}
200
201#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
202pub struct StockAndCashMerger {
203    pub id: String,
204    pub acquirer_symbol: String,
205    pub acquirer_cusip: String,
206    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
207    pub acquirer_rate: Decimal,
208    pub acquiree_symbol: String,
209    pub acquiree_cusip: String,
210    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
211    pub acquiree_rate: Decimal,
212    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
213    pub cash_rate: Decimal,
214    pub process_date: String,
215    pub effective_date: String,
216    pub payable_date: Option<String>,
217}
218
219#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
220pub struct Redemption {
221    pub id: String,
222    pub symbol: String,
223    pub cusip: String,
224    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
225    pub rate: Decimal,
226    pub process_date: String,
227    pub payable_date: Option<String>,
228}
229
230#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
231pub struct NameChange {
232    pub id: String,
233    pub old_symbol: String,
234    pub old_cusip: String,
235    pub new_symbol: String,
236    pub new_cusip: String,
237    pub process_date: String,
238}
239
240#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
241pub struct WorthlessRemoval {
242    pub id: String,
243    pub symbol: String,
244    pub cusip: String,
245    pub process_date: String,
246}
247
248#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
249pub struct RightsDistribution {
250    pub id: String,
251    pub source_symbol: String,
252    pub source_cusip: String,
253    pub new_symbol: String,
254    pub new_cusip: String,
255    #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
256    pub rate: Decimal,
257    pub process_date: String,
258    pub ex_date: String,
259    pub record_date: Option<String>,
260    pub payable_date: String,
261    pub expiration_date: Option<String>,
262}