webull_rs/endpoints/
market_data.rs1use crate::auth::AuthManager;
2use crate::endpoints::base::BaseEndpoint;
3use crate::error::WebullResult;
4use crate::models::market::{
5 Bar, BarQueryParams, CorpActionEventType, CorpActionParams, EodBarsParams, Instrument,
6 InstrumentParams, NewsArticle, NewsQueryParams, OptionChain, OptionChainQueryParams, Quote,
7 SnapshotParams, TimeFrame,
8};
9use reqwest::Client;
10use serde::Serialize;
11use std::sync::Arc;
12
13pub struct MarketDataEndpoints {
15 base: BaseEndpoint,
17}
18
19impl MarketDataEndpoints {
20 pub fn new(client: Client, base_url: String, auth_manager: Arc<AuthManager>) -> Self {
22 Self {
23 base: BaseEndpoint::new(client, base_url, auth_manager),
24 }
25 }
26
27 pub async fn get_quote(&self, symbol: &str) -> WebullResult<Quote> {
29 let path = format!("/api/quote/tickerRealTimes/{}", symbol);
30 self.base.get(&path).await
31 }
32
33 pub async fn get_quotes(&self, symbols: &[&str]) -> WebullResult<Vec<Quote>> {
35 #[derive(Serialize)]
36 struct SymbolsRequest<'a> {
37 symbols: Vec<&'a str>,
38 }
39
40 let request = SymbolsRequest {
41 symbols: symbols.to_vec(),
42 };
43
44 self.base.post("/api/quote/tickerRealTimes", &request).await
45 }
46
47 pub async fn get_snapshot(&self, params: &SnapshotParams) -> WebullResult<Vec<Quote>> {
49 self.base.post("/api/quote/snapshot", params).await
50 }
51
52 pub async fn get_stock_snapshot(&self, symbol: &str) -> WebullResult<Vec<Quote>> {
54 let params = SnapshotParams::new_stock(symbol);
55 self.get_snapshot(¶ms).await
56 }
57
58 pub async fn get_stock_snapshots(&self, symbols: &[&str]) -> WebullResult<Vec<Quote>> {
60 let params = SnapshotParams::new_stocks(symbols);
61 self.get_snapshot(¶ms).await
62 }
63
64 pub async fn get_history_bar(&self, params: &BarQueryParams) -> WebullResult<Vec<Bar>> {
66 self.base.post("/api/quote/history/bars", params).await
67 }
68
69 pub async fn get_option_chain(
71 &self,
72 params: &OptionChainQueryParams,
73 ) -> WebullResult<OptionChain> {
74 self.base.post("/api/options/list", params).await
75 }
76
77 pub async fn get_news(&self, params: &NewsQueryParams) -> WebullResult<Vec<NewsArticle>> {
79 self.base.post("/api/securities/news/list", params).await
80 }
81
82 pub async fn get_market_calendar(&self) -> WebullResult<Vec<String>> {
84 self.base.get("/api/securities/financial/calendar").await
85 }
86
87 pub async fn get_instrument(&self, params: &InstrumentParams) -> WebullResult<Vec<Instrument>> {
89 self.base.post("/api/quote/instruments", params).await
90 }
91
92 pub async fn get_stock_instrument(&self, symbol: &str) -> WebullResult<Vec<Instrument>> {
94 let params = InstrumentParams::new_stock(symbol);
95 self.get_instrument(¶ms).await
96 }
97
98 pub async fn get_stock_instruments(&self, symbols: &[&str]) -> WebullResult<Vec<Instrument>> {
100 let params = InstrumentParams::new_stocks(symbols);
101 self.get_instrument(¶ms).await
102 }
103
104 pub async fn get_eod_bar(&self, params: &EodBarsParams) -> WebullResult<Vec<Bar>> {
107 self.base.post("/api/quote/eod/bars", params).await
108 }
109
110 pub async fn get_instrument_eod_bars(
112 &self,
113 instrument_id: &str,
114 count: u32,
115 ) -> WebullResult<Vec<Bar>> {
116 let params = EodBarsParams::new(instrument_id, count);
117 self.get_eod_bar(¶ms).await
118 }
119
120 pub async fn get_instrument_eod_bars_with_date(
122 &self,
123 instrument_id: &str,
124 date: &str,
125 count: u32,
126 ) -> WebullResult<Vec<Bar>> {
127 let params = EodBarsParams::new(instrument_id, count).date(date);
128 self.get_eod_bar(¶ms).await
129 }
130
131 pub async fn get_corp_action(
134 &self,
135 params: &CorpActionParams,
136 ) -> WebullResult<Vec<Instrument>> {
137 self.base.post("/api/quote/corp/action", params).await
138 }
139
140 pub async fn get_stock_splits(&self, instrument_id: &str) -> WebullResult<Vec<Instrument>> {
142 let params = CorpActionParams::new(instrument_id, vec![CorpActionEventType::Split]);
143 self.get_corp_action(¶ms).await
144 }
145
146 pub async fn get_reverse_stock_splits(
148 &self,
149 instrument_id: &str,
150 ) -> WebullResult<Vec<Instrument>> {
151 let params = CorpActionParams::new(instrument_id, vec![CorpActionEventType::ReverseSplit]);
152 self.get_corp_action(¶ms).await
153 }
154
155 pub async fn get_all_corp_actions(&self, instrument_id: &str) -> WebullResult<Vec<Instrument>> {
157 let params = CorpActionParams::new(
158 instrument_id,
159 vec![
160 CorpActionEventType::Split,
161 CorpActionEventType::ReverseSplit,
162 ],
163 );
164 self.get_corp_action(¶ms).await
165 }
166
167 pub async fn get_daily_bars(&self, symbol: &str, count: Option<u32>) -> WebullResult<Vec<Bar>> {
169 let params = if let Some(count) = count {
170 BarQueryParams::new(symbol, "STK", TimeFrame::Day1, count)
171 } else {
172 BarQueryParams::new_stock(symbol, TimeFrame::Day1)
173 };
174
175 self.get_history_bar(¶ms).await
176 }
177
178 pub async fn get_intraday_bars(
180 &self,
181 symbol: &str,
182 time_frame: TimeFrame,
183 count: Option<u32>,
184 ) -> WebullResult<Vec<Bar>> {
185 let params = if let Some(count) = count {
186 BarQueryParams::new(symbol, "STK", time_frame, count)
187 } else {
188 BarQueryParams::new_stock(symbol, time_frame)
189 };
190
191 self.get_history_bar(¶ms).await
192 }
193}