brokerage_api/schwab/models/
streamer.rs

1// src/schwab/models/streamer.rs
2
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Debug, Clone)]
7pub enum StreamerMessage {
8    LevelOneEquity(LevelOneEquitiesResponse),
9    LevelOneOption(LevelOneOptionsResponse),
10    // We can add more variants here for other data types in the future
11}
12
13#[derive(Debug, Deserialize, Serialize, Clone)]
14#[serde(rename_all = "camelCase")]
15pub enum LevelOneOptionsField {
16    Symbol,
17    Description,
18    BidPrice,
19    AskPrice,
20    LastPrice,
21    HighPrice,
22    LowPrice,
23    ClosePrice,
24    TotalVolume,
25    OpenInterest,
26    Volatility,
27    MoneyIntrinsicValue,
28    ExpirationYear,
29    Multiplier,
30    Digits,
31    OpenPrice,
32    BidSize,
33    AskSize,
34    LastSize,
35    NetChange,
36    StrikePrice,
37    ContractType,
38    Underlying,
39    ExpirationMonth,
40    Deliverables,
41    TimeValue,
42    ExpirationDay,
43    DaysToExpiration,
44    Delta,
45    Gamma,
46    Theta,
47    Vega,
48    Rho,
49    SecurityStatus,
50    TheoreticalOptionValue,
51    UnderlyingPrice,
52    UvExpirationType,
53    MarkPrice,
54    QuoteTimeInLong,
55    TradeTimeInLong,
56    Exchange,
57    ExchangeName,
58    LastTradingDay,
59    SettlementType,
60    NetPercentChange,
61    MarkPriceNetChange,
62    MarkPricePercentChange,
63    ImpliedYield,
64    IsPennyPilot,
65    OptionRoot,
66    FiftyTwoWeekHigh,
67    FiftyTwoWeekLow,
68    IndicativeAskPrice,
69    IndicativeBidPrice,
70    IndicativeQuoteTime,
71    ExerciseType,
72}
73
74impl fmt::Display for LevelOneOptionsField {
75    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76        match self {
77            LevelOneOptionsField::Symbol => write!(f, "0"),
78            LevelOneOptionsField::Description => write!(f, "1"),
79            LevelOneOptionsField::BidPrice => write!(f, "2"),
80            LevelOneOptionsField::AskPrice => write!(f, "3"),
81            LevelOneOptionsField::LastPrice => write!(f, "4"),
82            LevelOneOptionsField::HighPrice => write!(f, "5"),
83            LevelOneOptionsField::LowPrice => write!(f, "6"),
84            LevelOneOptionsField::ClosePrice => write!(f, "7"),
85            LevelOneOptionsField::TotalVolume => write!(f, "8"),
86            LevelOneOptionsField::OpenInterest => write!(f, "9"),
87            LevelOneOptionsField::Volatility => write!(f, "10"),
88            LevelOneOptionsField::MoneyIntrinsicValue => write!(f, "11"),
89            LevelOneOptionsField::ExpirationYear => write!(f, "12"),
90            LevelOneOptionsField::Multiplier => write!(f, "13"),
91            LevelOneOptionsField::Digits => write!(f, "14"),
92            LevelOneOptionsField::OpenPrice => write!(f, "15"),
93            LevelOneOptionsField::BidSize => write!(f, "16"),
94            LevelOneOptionsField::AskSize => write!(f, "17"),
95            LevelOneOptionsField::LastSize => write!(f, "18"),
96            LevelOneOptionsField::NetChange => write!(f, "19"),
97            LevelOneOptionsField::StrikePrice => write!(f, "20"),
98            LevelOneOptionsField::ContractType => write!(f, "21"),
99            LevelOneOptionsField::Underlying => write!(f, "22"),
100            LevelOneOptionsField::ExpirationMonth => write!(f, "23"),
101            LevelOneOptionsField::Deliverables => write!(f, "24"),
102            LevelOneOptionsField::TimeValue => write!(f, "25"),
103            LevelOneOptionsField::ExpirationDay => write!(f, "26"),
104            LevelOneOptionsField::DaysToExpiration => write!(f, "27"),
105            LevelOneOptionsField::Delta => write!(f, "28"),
106            LevelOneOptionsField::Gamma => write!(f, "29"),
107            LevelOneOptionsField::Theta => write!(f, "30"),
108            LevelOneOptionsField::Vega => write!(f, "31"),
109            LevelOneOptionsField::Rho => write!(f, "32"),
110            LevelOneOptionsField::SecurityStatus => write!(f, "33"),
111            LevelOneOptionsField::TheoreticalOptionValue => write!(f, "34"),
112            LevelOneOptionsField::UnderlyingPrice => write!(f, "35"),
113            LevelOneOptionsField::UvExpirationType => write!(f, "36"),
114            LevelOneOptionsField::MarkPrice => write!(f, "37"),
115            LevelOneOptionsField::QuoteTimeInLong => write!(f, "38"),
116            LevelOneOptionsField::TradeTimeInLong => write!(f, "39"),
117            LevelOneOptionsField::Exchange => write!(f, "40"),
118            LevelOneOptionsField::ExchangeName => write!(f, "41"),
119            LevelOneOptionsField::LastTradingDay => write!(f, "42"),
120            LevelOneOptionsField::SettlementType => write!(f, "43"),
121            LevelOneOptionsField::NetPercentChange => write!(f, "44"),
122            LevelOneOptionsField::MarkPriceNetChange => write!(f, "45"),
123            LevelOneOptionsField::MarkPricePercentChange => write!(f, "46"),
124            LevelOneOptionsField::ImpliedYield => write!(f, "47"),
125            LevelOneOptionsField::IsPennyPilot => write!(f, "48"),
126            LevelOneOptionsField::OptionRoot => write!(f, "49"),
127            LevelOneOptionsField::FiftyTwoWeekHigh => write!(f, "50"),
128            LevelOneOptionsField::FiftyTwoWeekLow => write!(f, "51"),
129            LevelOneOptionsField::IndicativeAskPrice => write!(f, "52"),
130            LevelOneOptionsField::IndicativeBidPrice => write!(f, "53"),
131            LevelOneOptionsField::IndicativeQuoteTime => write!(f, "54"),
132            LevelOneOptionsField::ExerciseType => write!(f, "55"),
133        }
134    }
135}
136
137#[derive(Debug, Deserialize, Serialize, Clone)]
138#[serde(rename_all = "camelCase")]
139pub enum LevelOneEquitiesField {
140    Symbol,
141    BidPrice,
142    AskPrice,
143    LastPrice,
144    BidSize,
145    AskSize,
146    AskId,
147    BidId,
148    TotalVolume,
149    LastSize,
150    HighPrice,
151    LowPrice,
152    ClosePrice,
153    ExchangeId,
154    Marginable,
155    Description,
156    LastId,
157    OpenPrice,
158    NetChange,
159    FiftyTwoWeekHigh,
160    FiftyTwoWeekLow,
161    PeRatio,
162    AnnualDividendAmount,
163    DividendYield,
164    Nav,
165    ExchangeName,
166    DueDate,
167    RegularMarketQuote,
168    RegularMarketTrade,
169    RegularMarketLastPrice,
170    RegularMarketLastSize,
171    RegularMarketNetChange,
172    SecurityStatus,
173    MarkPrice,
174    QuoteTimeInLong,
175    TradeTimeInLong,
176    RegularMarketTradeTimeInLong,
177    BidTime,
178    AskTime,
179    AskMicId,
180    BidMicId,
181    LastMicId,
182    NetPercentChange,
183    RegularMarketPercentChange,
184    MarkPriceNetChange,
185    MarkPricePercentChange,
186    HardToBorrowQuantity,
187    HardToBorrowRate,
188    HardToBorrow,
189    Shortable,
190    PostMarketNetChange,
191    PostMarketPercentChange,
192}
193
194impl fmt::Display for LevelOneEquitiesField {
195    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
196        match self {
197            LevelOneEquitiesField::Symbol => write!(f, "0"),
198            LevelOneEquitiesField::BidPrice => write!(f, "1"),
199            LevelOneEquitiesField::AskPrice => write!(f, "2"),
200            LevelOneEquitiesField::LastPrice => write!(f, "3"),
201            LevelOneEquitiesField::BidSize => write!(f, "4"),
202            LevelOneEquitiesField::AskSize => write!(f, "5"),
203            LevelOneEquitiesField::AskId => write!(f, "6"),
204            LevelOneEquitiesField::BidId => write!(f, "7"),
205            LevelOneEquitiesField::TotalVolume => write!(f, "8"),
206            LevelOneEquitiesField::LastSize => write!(f, "9"),
207            LevelOneEquitiesField::HighPrice => write!(f, "10"),
208            LevelOneEquitiesField::LowPrice => write!(f, "11"),
209            LevelOneEquitiesField::ClosePrice => write!(f, "12"),
210            LevelOneEquitiesField::ExchangeId => write!(f, "13"),
211            LevelOneEquitiesField::Marginable => write!(f, "14"),
212            LevelOneEquitiesField::Description => write!(f, "15"),
213            LevelOneEquitiesField::LastId => write!(f, "16"),
214            LevelOneEquitiesField::OpenPrice => write!(f, "17"),
215            LevelOneEquitiesField::NetChange => write!(f, "18"),
216            LevelOneEquitiesField::FiftyTwoWeekHigh => write!(f, "19"),
217            LevelOneEquitiesField::FiftyTwoWeekLow => write!(f, "20"),
218            LevelOneEquitiesField::PeRatio => write!(f, "21"),
219            LevelOneEquitiesField::AnnualDividendAmount => write!(f, "22"),
220            LevelOneEquitiesField::DividendYield => write!(f, "23"),
221            LevelOneEquitiesField::Nav => write!(f, "24"),
222            LevelOneEquitiesField::ExchangeName => write!(f, "25"),
223            LevelOneEquitiesField::DueDate => write!(f, "26"),
224            LevelOneEquitiesField::RegularMarketQuote => write!(f, "27"),
225            LevelOneEquitiesField::RegularMarketTrade => write!(f, "28"),
226            LevelOneEquitiesField::RegularMarketLastPrice => write!(f, "29"),
227            LevelOneEquitiesField::RegularMarketLastSize => write!(f, "30"),
228            LevelOneEquitiesField::RegularMarketNetChange => write!(f, "31"),
229            LevelOneEquitiesField::SecurityStatus => write!(f, "32"),
230            LevelOneEquitiesField::MarkPrice => write!(f, "33"),
231            LevelOneEquitiesField::QuoteTimeInLong => write!(f, "34"),
232            LevelOneEquitiesField::TradeTimeInLong => write!(f, "35"),
233            LevelOneEquitiesField::RegularMarketTradeTimeInLong => write!(f, "36"),
234            LevelOneEquitiesField::BidTime => write!(f, "37"),
235            LevelOneEquitiesField::AskTime => write!(f, "38"),
236            LevelOneEquitiesField::AskMicId => write!(f, "39"),
237            LevelOneEquitiesField::BidMicId => write!(f, "40"),
238            LevelOneEquitiesField::LastMicId => write!(f, "41"),
239            LevelOneEquitiesField::NetPercentChange => write!(f, "42"),
240            LevelOneEquitiesField::RegularMarketPercentChange => write!(f, "43"),
241            LevelOneEquitiesField::MarkPriceNetChange => write!(f, "44"),
242            LevelOneEquitiesField::MarkPricePercentChange => write!(f, "45"),
243            LevelOneEquitiesField::HardToBorrowQuantity => write!(f, "46"),
244            LevelOneEquitiesField::HardToBorrowRate => write!(f, "47"),
245            LevelOneEquitiesField::HardToBorrow => write!(f, "48"),
246            LevelOneEquitiesField::Shortable => write!(f, "49"),
247            LevelOneEquitiesField::PostMarketNetChange => write!(f, "50"),
248            LevelOneEquitiesField::PostMarketPercentChange => write!(f, "51"),
249        }
250    }
251}
252
253// --- FIXED: Added #[serde(rename = ...)] attributes to all fields ---
254#[derive(Debug, Serialize, Deserialize, Clone)]
255pub struct LevelOneOptionsResponse {
256    #[serde(rename = "key")]
257    pub symbol: String,
258    #[serde(rename = "1")]
259    pub description: Option<String>,
260    #[serde(rename = "2")]
261    pub bid_price: Option<f64>,
262    #[serde(rename = "3")]
263    pub ask_price: Option<f64>,
264    #[serde(rename = "4")]
265    pub last_price: Option<f64>,
266    #[serde(rename = "5")]
267    pub high_price: Option<f64>,
268    #[serde(rename = "6")]
269    pub low_price: Option<f64>,
270    #[serde(rename = "7")]
271    pub close_price: Option<f64>,
272    #[serde(rename = "8")]
273    pub total_volume: Option<i64>,
274    #[serde(rename = "9")]
275    pub open_interest: Option<i64>,
276    #[serde(rename = "10")]
277    pub volatility: Option<f64>,
278    #[serde(rename = "11")]
279    pub money_intrinsic_value: Option<f64>,
280    #[serde(rename = "12")]
281    pub expiration_year: Option<i64>,
282    #[serde(rename = "13")]
283    pub multiplier: Option<f64>,
284    #[serde(rename = "14")]
285    pub digits: Option<i64>,
286    #[serde(rename = "15")]
287    pub open_price: Option<f64>,
288    #[serde(rename = "16")]
289    pub bid_size: Option<i64>,
290    #[serde(rename = "17")]
291    pub ask_size: Option<i64>,
292    #[serde(rename = "18")]
293    pub last_size: Option<i64>,
294    #[serde(rename = "19")]
295    pub net_change: Option<f64>,
296    #[serde(rename = "20")]
297    pub strike_price: Option<f64>,
298    #[serde(rename = "21")]
299    pub contract_type: Option<String>, // "CALL" or "PUT"
300    #[serde(rename = "22")]
301    pub underlying: Option<String>,
302    #[serde(rename = "23")]
303    pub expiration_month: Option<i64>,
304    #[serde(rename = "24")]
305    pub deliverables: Option<String>,
306    #[serde(rename = "25")]
307    pub time_value: Option<f64>,
308    #[serde(rename = "26")]
309    pub expiration_day: Option<i64>,
310    #[serde(rename = "27")]
311    pub days_to_expiration: Option<i64>,
312    #[serde(rename = "28")]
313    pub delta: Option<f64>,
314    #[serde(rename = "29")]
315    pub gamma: Option<f64>,
316    #[serde(rename = "30")]
317    pub theta: Option<f64>,
318    #[serde(rename = "31")]
319    pub vega: Option<f64>,
320    #[serde(rename = "32")]
321    pub rho: Option<f64>,
322    #[serde(rename = "33")]
323    pub security_status: Option<String>,
324    #[serde(rename = "34")]
325    pub theoretical_option_value: Option<f64>,
326    #[serde(rename = "35")]
327    pub underlying_price: Option<f64>,
328    #[serde(rename = "36")]
329    pub uv_expiration_type: Option<String>,
330    #[serde(rename = "37")]
331    pub mark_price: Option<f64>,
332    #[serde(rename = "38")]
333    pub quote_time_in_long: Option<i64>,
334    #[serde(rename = "39")]
335    pub trade_time_in_long: Option<i64>,
336    #[serde(rename = "40")]
337    pub exchange: Option<String>,
338    #[serde(rename = "41")]
339    pub exchange_name: Option<String>,
340    #[serde(rename = "42")]
341    pub last_trading_day: Option<i64>,
342    #[serde(rename = "43")]
343    pub settlement_type: Option<String>,
344    #[serde(rename = "44")]
345    pub net_percent_change: Option<f64>,
346    #[serde(rename = "45")]
347    pub mark_price_net_change: Option<f64>,
348    #[serde(rename = "46")]
349    pub mark_price_percent_change: Option<f64>,
350    #[serde(rename = "47")]
351    pub implied_yield: Option<f64>,
352    #[serde(rename = "48")]
353    pub is_penny_pilot: Option<bool>,
354    #[serde(rename = "49")]
355    pub option_root: Option<String>,
356    #[serde(rename = "50")]
357    pub fifty_two_week_high: Option<f64>,
358    #[serde(rename = "51")]
359    pub fifty_two_week_low: Option<f64>,
360    #[serde(rename = "52")]
361    pub indicative_ask_price: Option<f64>,
362    #[serde(rename = "53")]
363    pub indicative_bid_price: Option<f64>,
364    #[serde(rename = "54")]
365    pub indicative_quote_time: Option<i64>,
366    #[serde(rename = "55")]
367    pub exercise_type: Option<String>,
368}
369
370#[derive(Debug, Deserialize, Serialize, Clone)]
371pub struct LevelOneEquitiesResponse {
372    #[serde(rename = "key")]
373    pub symbol: String,
374    #[serde(rename = "1")]
375    pub bid_price: Option<f64>,
376    #[serde(rename = "2")]
377    pub ask_price: Option<f64>,
378    #[serde(rename = "3")]
379    pub last_price: Option<f64>,
380    #[serde(rename = "4")]
381    pub bid_size: Option<i64>,
382    #[serde(rename = "5")]
383    pub ask_size: Option<i64>,
384    #[serde(rename = "6")]
385    pub ask_id: Option<char>,
386    #[serde(rename = "7")]
387    pub bid_id: Option<char>,
388    #[serde(rename = "8")]
389    pub total_volume: Option<i64>,
390    #[serde(rename = "9")]
391    pub last_size: Option<i64>,
392    #[serde(rename = "10")]
393    pub high_price: Option<f64>,
394    #[serde(rename = "11")]
395    pub low_price: Option<f64>,
396    #[serde(rename = "12")]
397    pub close_price: Option<f64>,
398    #[serde(rename = "13")]
399    pub exchange_id: Option<String>,
400    #[serde(rename = "14")]
401    pub marginable: Option<bool>,
402    #[serde(rename = "15")]
403    pub description: Option<String>,
404    #[serde(rename = "16")]
405    pub last_id: Option<char>,
406    #[serde(rename = "17")]
407    pub open_price: Option<f64>,
408    #[serde(rename = "18")]
409    pub net_change: Option<f64>,
410    #[serde(rename = "19")]
411    pub fifty_two_week_high: Option<f64>,
412    #[serde(rename = "20")]
413    pub fifty_two_week_low: Option<f64>,
414    #[serde(rename = "21")]
415    pub pe_ratio: Option<f64>,
416    #[serde(rename = "22")]
417    pub annual_dividend_amount: Option<f64>,
418    #[serde(rename = "23")]
419    pub dividend_yield: Option<f64>,
420    #[serde(rename = "24")]
421    pub nav: Option<f64>,
422    #[serde(rename = "25")]
423    pub exchange_name: Option<String>,
424    #[serde(rename = "26")]
425    pub due_date: Option<String>,
426    #[serde(rename = "27")]
427    pub regular_market_quote: Option<bool>,
428    #[serde(rename = "28")]
429    pub regular_market_trade: Option<bool>,
430    #[serde(rename = "29")]
431    pub regular_market_last_price: Option<f64>,
432    #[serde(rename = "30")]
433    pub regular_market_last_size: Option<i64>,
434    #[serde(rename = "31")]
435    pub regular_market_net_change: Option<f64>,
436    #[serde(rename = "32")]
437    pub security_status: Option<String>,
438    #[serde(rename = "33")]
439    pub mark_price: Option<f64>,
440    #[serde(rename = "34")]
441    pub quote_time_in_long: Option<i64>,
442    #[serde(rename = "35")]
443    pub trade_time_in_long: Option<i64>,
444    #[serde(rename = "36")]
445    pub regular_market_trade_time_in_long: Option<i64>,
446    #[serde(rename = "37")]
447    pub bid_time: Option<i64>,
448    #[serde(rename = "38")]
449    pub ask_time: Option<i64>,
450    #[serde(rename = "39")]
451    pub ask_mic_id: Option<String>,
452    #[serde(rename = "40")]
453    pub bid_mic_id: Option<String>,
454    #[serde(rename = "41")]
455    pub last_mic_id: Option<String>,
456    #[serde(rename = "42")]
457    pub net_percent_change: Option<f64>,
458    #[serde(rename = "43")]
459    pub regular_market_percent_change: Option<f64>,
460    #[serde(rename = "44")]
461    pub mark_price_net_change: Option<f64>,
462    #[serde(rename = "45")]
463    pub mark_price_percent_change: Option<f64>,
464    #[serde(rename = "46")]
465    pub hard_to_borrow_quantity: Option<i64>,
466    #[serde(rename = "47")]
467    pub hard_to_borrow_rate: Option<f64>,
468    #[serde(rename = "48")]
469    pub hard_to_borrow: Option<i64>,
470    #[serde(rename = "49")]
471    pub shortable: Option<i64>,
472    #[serde(rename = "50")]
473    pub post_market_net_change: Option<f64>,
474    #[serde(rename = "51")]
475    pub post_market_percent_change: Option<f64>,
476    #[serde(rename = "assetMainType")]
477    pub asset_main_type: Option<String>,
478    #[serde(rename = "assetSubType")]
479    pub asset_sub_type: Option<String>,
480    pub cusip: Option<String>,
481    pub delayed: Option<bool>,
482}