1use rust_decimal::Decimal;
2use serde::{Deserialize, Serialize};
3
4use crate::stocks::Currency;
5
6use super::{CashDividendSubType, PartialCallLotteryType};
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 partial_calls: Vec<PartialCall>,
38 #[serde(default)]
39 pub reorganizations: Vec<Reorganization>,
40}
41
42impl CorporateActions {
43 pub(crate) fn merge(&mut self, mut next: Self) {
44 self.forward_splits.append(&mut next.forward_splits);
45 self.reverse_splits.append(&mut next.reverse_splits);
46 self.unit_splits.append(&mut next.unit_splits);
47 self.stock_dividends.append(&mut next.stock_dividends);
48 self.cash_dividends.append(&mut next.cash_dividends);
49 self.spin_offs.append(&mut next.spin_offs);
50 self.cash_mergers.append(&mut next.cash_mergers);
51 self.stock_mergers.append(&mut next.stock_mergers);
52 self.stock_and_cash_mergers
53 .append(&mut next.stock_and_cash_mergers);
54 self.redemptions.append(&mut next.redemptions);
55 self.name_changes.append(&mut next.name_changes);
56 self.worthless_removals.append(&mut next.worthless_removals);
57 self.rights_distributions
58 .append(&mut next.rights_distributions);
59 self.partial_calls.append(&mut next.partial_calls);
60 self.reorganizations.append(&mut next.reorganizations);
61 }
62}
63
64#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
65pub struct ForwardSplit {
66 pub id: String,
67 pub symbol: String,
68 pub cusip: String,
69 pub isin: Option<String>,
70 pub currency: Option<Currency>,
71 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
72 pub new_rate: Decimal,
73 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
74 pub old_rate: Decimal,
75 pub process_date: String,
76 pub ex_date: String,
77 pub record_date: Option<String>,
78 pub payable_date: Option<String>,
79 pub due_bill_redemption_date: Option<String>,
80}
81
82#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
83pub struct ReverseSplit {
84 pub id: String,
85 pub symbol: String,
86 pub old_cusip: String,
87 pub old_isin: Option<String>,
88 pub new_cusip: String,
89 pub new_isin: Option<String>,
90 pub new_symbol: Option<String>,
91 pub currency: Option<Currency>,
92 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
93 pub new_rate: Decimal,
94 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
95 pub old_rate: Decimal,
96 pub process_date: String,
97 pub ex_date: String,
98 pub record_date: Option<String>,
99 pub payable_date: Option<String>,
100}
101
102#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
103pub struct UnitSplit {
104 pub id: String,
105 pub old_symbol: String,
106 pub old_cusip: String,
107 pub old_isin: Option<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 pub new_isin: Option<String>,
113 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
114 pub new_rate: Decimal,
115 pub alternate_symbol: String,
116 pub alternate_cusip: String,
117 pub alternate_isin: Option<String>,
118 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
119 pub alternate_rate: Decimal,
120 pub currency: Option<Currency>,
121 pub process_date: String,
122 pub effective_date: String,
123 pub payable_date: Option<String>,
124}
125
126#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
127pub struct StockDividend {
128 pub id: String,
129 pub symbol: String,
130 pub cusip: String,
131 pub isin: Option<String>,
132 pub currency: Option<Currency>,
133 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
134 pub rate: Decimal,
135 pub process_date: String,
136 pub ex_date: String,
137 pub record_date: Option<String>,
138 pub payable_date: Option<String>,
139}
140
141#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
142pub struct CashDividend {
143 pub id: String,
144 pub symbol: String,
145 pub cusip: String,
146 pub isin: Option<String>,
147 pub currency: Option<Currency>,
148 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
149 pub rate: Decimal,
150 pub special: bool,
151 pub foreign: bool,
152 pub sub_type: Option<CashDividendSubType>,
153 pub process_date: String,
154 pub ex_date: String,
155 pub record_date: Option<String>,
156 pub payable_date: Option<String>,
157 pub due_bill_on_date: Option<String>,
158 pub due_bill_off_date: Option<String>,
159}
160
161#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
162pub struct SpinOff {
163 pub id: String,
164 pub source_symbol: String,
165 pub source_cusip: String,
166 pub source_isin: Option<String>,
167 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
168 pub source_rate: Decimal,
169 pub new_symbol: String,
170 pub new_cusip: String,
171 pub new_isin: Option<String>,
172 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
173 pub new_rate: Decimal,
174 pub currency: Option<Currency>,
175 pub process_date: String,
176 pub ex_date: String,
177 pub record_date: Option<String>,
178 pub payable_date: Option<String>,
179 pub due_bill_redemption_date: Option<String>,
180}
181
182#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
183pub struct CashMerger {
184 pub id: String,
185 pub acquirer_symbol: Option<String>,
186 pub acquirer_cusip: Option<String>,
187 pub acquirer_isin: Option<String>,
188 pub acquiree_symbol: String,
189 pub acquiree_cusip: String,
190 pub acquiree_isin: Option<String>,
191 pub currency: Option<Currency>,
192 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
193 pub rate: Decimal,
194 pub process_date: String,
195 pub effective_date: String,
196 pub payable_date: Option<String>,
197}
198
199#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
200pub struct StockMerger {
201 pub id: String,
202 pub acquirer_symbol: String,
203 pub acquirer_cusip: String,
204 pub acquirer_isin: Option<String>,
205 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
206 pub acquirer_rate: Decimal,
207 pub acquiree_symbol: String,
208 pub acquiree_cusip: String,
209 pub acquiree_isin: Option<String>,
210 pub currency: Option<Currency>,
211 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
212 pub acquiree_rate: Decimal,
213 pub process_date: String,
214 pub effective_date: String,
215 pub payable_date: Option<String>,
216}
217
218#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
219pub struct StockAndCashMerger {
220 pub id: String,
221 pub acquirer_symbol: String,
222 pub acquirer_cusip: String,
223 pub acquirer_isin: Option<String>,
224 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
225 pub acquirer_rate: Decimal,
226 pub acquiree_symbol: String,
227 pub acquiree_cusip: String,
228 pub acquiree_isin: Option<String>,
229 pub currency: Option<Currency>,
230 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
231 pub acquiree_rate: Decimal,
232 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
233 pub cash_rate: Decimal,
234 pub process_date: String,
235 pub effective_date: String,
236 pub payable_date: Option<String>,
237}
238
239#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
240pub struct Redemption {
241 pub id: String,
242 pub symbol: String,
243 pub cusip: String,
244 pub isin: Option<String>,
245 pub currency: Option<Currency>,
246 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
247 pub rate: Decimal,
248 pub process_date: String,
249 pub payable_date: Option<String>,
250}
251
252#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
253pub struct NameChange {
254 pub id: String,
255 pub old_symbol: String,
256 pub old_cusip: String,
257 pub old_isin: Option<String>,
258 pub new_symbol: String,
259 pub new_cusip: String,
260 pub new_isin: Option<String>,
261 pub currency: Option<Currency>,
262 pub process_date: String,
263}
264
265#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
266pub struct WorthlessRemoval {
267 pub id: String,
268 pub symbol: String,
269 pub cusip: String,
270 pub isin: Option<String>,
271 pub currency: Option<Currency>,
272 pub process_date: String,
273}
274
275#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
276pub struct RightsDistribution {
277 pub id: String,
278 pub source_symbol: String,
279 pub source_cusip: String,
280 pub source_isin: Option<String>,
281 pub new_symbol: String,
282 pub new_cusip: String,
283 pub new_isin: Option<String>,
284 pub currency: Option<Currency>,
285 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
286 pub rate: Decimal,
287 pub process_date: String,
288 pub ex_date: String,
289 pub record_date: Option<String>,
290 pub payable_date: String,
291 pub expiration_date: Option<String>,
292}
293
294#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
295pub struct PartialCall {
296 pub id: String,
297 pub symbol: String,
298 pub process_date: String,
299 pub currency: Option<Currency>,
300 pub cusip: Option<String>,
301 pub isin: Option<String>,
302 #[serde(
303 default,
304 deserialize_with = "alpaca_core::decimal::deserialize_option_decimal_from_string_or_number"
305 )]
306 pub dividend_rate: Option<Decimal>,
307 pub lottery_date: Option<String>,
308 pub lottery_type: Option<PartialCallLotteryType>,
309 pub payable_date: Option<String>,
310 #[serde(
311 default,
312 deserialize_with = "alpaca_core::decimal::deserialize_option_decimal_from_string_or_number"
313 )]
314 pub price: Option<Decimal>,
315 pub record_date: Option<String>,
316 pub results_publication_date: Option<String>,
317}
318
319#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
320pub struct Reorganization {
321 pub id: String,
322 pub symbol: String,
323 pub cusip: String,
324 pub process_date: String,
325 pub effective_date: String,
326 pub isin: Option<String>,
327 pub currency: Option<Currency>,
328 #[serde(
329 default,
330 deserialize_with = "alpaca_core::decimal::deserialize_option_decimal_from_string_or_number"
331 )]
332 pub cash_rate: Option<Decimal>,
333 pub payable_date: Option<String>,
334 #[serde(default)]
335 pub stock_movements: Vec<ReorganizationStockMovement>,
336}
337
338#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
339pub struct ReorganizationStockMovement {
340 pub symbol: String,
341 pub cusip: String,
342 pub isin: Option<String>,
343 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
344 pub new_rate: Decimal,
345 #[serde(deserialize_with = "alpaca_core::decimal::deserialize_decimal_from_string_or_number")]
346 pub source_rate: Decimal,
347}