1use axum::extract::{Json, State};
7use prost::Message;
8use serde::Serialize;
9use serde::de::DeserializeOwned;
10use serde_json::Value;
11
12use crate::adapter::{self, RestState};
13
14use super::RawApiResult;
15
16async fn raw_qot_request<Req, Rsp>(state: &RestState, proto_id: u32, body: Value) -> RawApiResult
17where
18 Req: Message + Default + DeserializeOwned,
19 Rsp: Message + Default + Serialize,
20{
21 adapter::proto_request_raw::<Req, Rsp>(state, proto_id, Some(body)).await
22}
23
24macro_rules! qot_raw_rest_endpoint {
25 ($fn_name:ident, $proto_const:ident, $module:ident) => {
26 pub async fn $fn_name(
27 State(state): State<RestState>,
28 Json(body): Json<Value>,
29 ) -> RawApiResult {
30 raw_qot_request::<futu_proto::$module::Request, futu_proto::$module::Response>(
31 &state,
32 futu_core::proto_id::$proto_const,
33 body,
34 )
35 .await
36 }
37 };
38}
39
40qot_raw_rest_endpoint!(
41 get_earnings_calendar,
42 QOT_GET_EARNINGS_CALENDAR,
43 qot_get_earnings_calendar
44);
45qot_raw_rest_endpoint!(
46 get_macro_indicator_list,
47 QOT_GET_MACRO_INDICATOR_LIST,
48 qot_get_macro_indicator_list
49);
50qot_raw_rest_endpoint!(
51 security_trading_sessions,
52 QOT_GET_SECURITY_TRADING_SESSIONS,
53 qot_get_security_trading_sessions
54);
55qot_raw_rest_endpoint!(
56 market_trading_sessions,
57 QOT_GET_MARKET_TRADING_SESSIONS,
58 qot_get_market_trading_sessions
59);
60qot_raw_rest_endpoint!(kline_pattern, QOT_GET_KLINE_PATTERN, qot_get_kline_pattern);
61qot_raw_rest_endpoint!(
62 kline_pattern_statistics,
63 QOT_GET_KLINE_PATTERN_STATISTICS,
64 qot_get_kline_pattern_statistics
65);
66qot_raw_rest_endpoint!(
67 kline_pattern_stocks,
68 QOT_GET_KLINE_PATTERN_STOCKS,
69 qot_get_kline_pattern_stocks
70);
71qot_raw_rest_endpoint!(
72 kline_pattern_performance,
73 QOT_GET_KLINE_PATTERN_PERFORMANCE,
74 qot_get_kline_pattern_performance
75);
76qot_raw_rest_endpoint!(
77 kline_pattern_catalog,
78 QOT_GET_KLINE_PATTERN_CATALOG,
79 qot_get_kline_pattern_catalog
80);
81qot_raw_rest_endpoint!(
82 stock_note_labels,
83 QOT_GET_STOCK_NOTE_LABELS,
84 qot_get_stock_note_labels
85);
86qot_raw_rest_endpoint!(stock_notes, QOT_GET_STOCK_NOTES, qot_get_stock_notes);
87qot_raw_rest_endpoint!(set_stock_note, QOT_SET_STOCK_NOTE, qot_set_stock_note);
88pub async fn hot_news(State(state): State<RestState>, Json(body): Json<Value>) -> RawApiResult {
89 raw_qot_request::<futu_proto::qot_get_hot_news::Request, futu_proto::qot_get_hot_news::Response>(
90 &state,
91 futu_core::proto_id::QOT_GET_HOT_NEWS,
92 body,
93 )
94 .await
95}
96
97pub async fn latest_news(State(state): State<RestState>, Json(body): Json<Value>) -> RawApiResult {
98 raw_qot_request::<
99 futu_proto::qot_get_latest_news::Request,
100 futu_proto::qot_get_latest_news::Response,
101 >(&state, futu_core::proto_id::QOT_GET_LATEST_NEWS, body)
102 .await
103}
104
105pub async fn watchlist_news(
106 State(state): State<RestState>,
107 Json(body): Json<Value>,
108) -> RawApiResult {
109 raw_qot_request::<
110 futu_proto::qot_get_watchlist_news::Request,
111 futu_proto::qot_get_watchlist_news::Response,
112 >(&state, futu_core::proto_id::QOT_GET_WATCHLIST_NEWS, body)
113 .await
114}
115
116pub async fn watchlist_announcement(
117 State(state): State<RestState>,
118 Json(body): Json<Value>,
119) -> RawApiResult {
120 raw_qot_request::<
121 futu_proto::qot_get_watchlist_announcement::Request,
122 futu_proto::qot_get_watchlist_announcement::Response,
123 >(
124 &state,
125 futu_core::proto_id::QOT_GET_WATCHLIST_ANNOUNCEMENT,
126 body,
127 )
128 .await
129}
130
131pub async fn watchlist_rating(
132 State(state): State<RestState>,
133 Json(body): Json<Value>,
134) -> RawApiResult {
135 raw_qot_request::<
136 futu_proto::qot_get_watchlist_rating::Request,
137 futu_proto::qot_get_watchlist_rating::Response,
138 >(&state, futu_core::proto_id::QOT_GET_WATCHLIST_RATING, body)
139 .await
140}
141
142pub async fn stock_news(State(state): State<RestState>, Json(body): Json<Value>) -> RawApiResult {
143 raw_qot_request::<
144 futu_proto::qot_get_stock_news::Request,
145 futu_proto::qot_get_stock_news::Response,
146 >(&state, futu_core::proto_id::QOT_GET_STOCK_NEWS, body)
147 .await
148}
149
150pub async fn etf_screen(State(state): State<RestState>, Json(body): Json<Value>) -> RawApiResult {
151 raw_qot_request::<
152 futu_proto::qot_get_etf_screen::Request,
153 futu_proto::qot_get_etf_screen::Response,
154 >(&state, futu_core::proto_id::QOT_ETF_SCREEN, body)
155 .await
156}
157
158pub async fn fund_screen(State(state): State<RestState>, Json(body): Json<Value>) -> RawApiResult {
159 raw_qot_request::<
160 futu_proto::qot_get_fund_screen::Request,
161 futu_proto::qot_get_fund_screen::Response,
162 >(&state, futu_core::proto_id::QOT_FUND_SCREEN, body)
163 .await
164}
165
166pub async fn future_screen(
167 State(state): State<RestState>,
168 Json(body): Json<Value>,
169) -> RawApiResult {
170 raw_qot_request::<
171 futu_proto::qot_get_future_screen::Request,
172 futu_proto::qot_get_future_screen::Response,
173 >(&state, futu_core::proto_id::QOT_FUTURE_SCREEN, body)
174 .await
175}
176
177pub async fn bond_screen(State(state): State<RestState>, Json(body): Json<Value>) -> RawApiResult {
178 raw_qot_request::<
179 futu_proto::qot_get_bond_screen::Request,
180 futu_proto::qot_get_bond_screen::Response,
181 >(&state, futu_core::proto_id::QOT_BOND_SCREEN, body)
182 .await
183}
184qot_raw_rest_endpoint!(
185 get_macro_indicator_history,
186 QOT_GET_MACRO_INDICATOR_HISTORY,
187 qot_get_macro_indicator_history
188);
189qot_raw_rest_endpoint!(
190 get_fed_watch_target_rate,
191 QOT_GET_FED_WATCH_TARGET_RATE,
192 qot_get_fed_watch_target_rate
193);
194qot_raw_rest_endpoint!(
195 get_fed_watch_dot_plot,
196 QOT_GET_FED_WATCH_DOT_PLOT,
197 qot_get_fed_watch_dot_plot
198);
199qot_raw_rest_endpoint!(
200 get_earnings_beat_rank,
201 QOT_GET_EARNINGS_BEAT_RANK,
202 qot_get_earnings_beat_rank
203);
204qot_raw_rest_endpoint!(
205 get_dividend_rank,
206 QOT_GET_DIVIDEND_RANK,
207 qot_get_dividend_rank
208);
209qot_raw_rest_endpoint!(
210 get_dividend_calendar,
211 QOT_GET_DIVIDEND_CALENDAR,
212 qot_get_dividend_calendar
213);
214qot_raw_rest_endpoint!(
215 get_economic_calendar,
216 QOT_GET_ECONOMIC_CALENDAR,
217 qot_get_economic_calendar
218);
219qot_raw_rest_endpoint!(
220 get_us_pre_market_rank,
221 QOT_GET_US_PRE_MARKET_RANK,
222 qot_get_us_pre_market_rank
223);
224qot_raw_rest_endpoint!(
225 get_us_after_hours_rank,
226 QOT_GET_US_AFTER_HOURS_RANK,
227 qot_get_us_after_hours_rank
228);
229qot_raw_rest_endpoint!(
230 get_us_overnight_rank,
231 QOT_GET_US_OVERNIGHT_RANK,
232 qot_get_us_overnight_rank
233);
234qot_raw_rest_endpoint!(
235 get_top_movers_rank,
236 QOT_GET_TOP_MOVERS_RANK,
237 qot_get_top_movers_rank
238);
239qot_raw_rest_endpoint!(get_hot_list, QOT_GET_HOT_LIST, qot_get_hot_list);
240qot_raw_rest_endpoint!(
241 get_short_selling_rank,
242 QOT_GET_SHORT_SELLING_RANK,
243 qot_get_short_selling_rank
244);
245qot_raw_rest_endpoint!(
246 get_period_change_rank,
247 QOT_GET_PERIOD_CHANGE_RANK,
248 qot_get_period_change_rank
249);
250qot_raw_rest_endpoint!(
251 get_high_dividend_soe_rank,
252 QOT_GET_HIGH_DIVIDEND_SOE_RANK,
253 qot_get_high_dividend_soe_rank
254);
255qot_raw_rest_endpoint!(
256 get_institution_list,
257 QOT_GET_INSTITUTION_LIST,
258 qot_get_institution_list
259);
260qot_raw_rest_endpoint!(
261 get_institution_profile,
262 QOT_GET_INSTITUTION_PROFILE,
263 qot_get_institution_profile
264);
265qot_raw_rest_endpoint!(
266 get_institution_distribution,
267 QOT_GET_INSTITUTION_DISTRIBUTION,
268 qot_get_institution_distribution
269);
270qot_raw_rest_endpoint!(
271 get_institution_holding_change,
272 QOT_GET_INSTITUTION_HOLDING_CHANGE,
273 qot_get_institution_holding_change
274);
275qot_raw_rest_endpoint!(
276 get_institution_holding_list,
277 QOT_GET_INSTITUTION_HOLDING_LIST,
278 qot_get_institution_holding_list
279);
280qot_raw_rest_endpoint!(
281 get_ark_fund_holding,
282 QOT_GET_ARK_FUND_HOLDING,
283 qot_get_ark_fund_holding
284);
285qot_raw_rest_endpoint!(
286 get_ark_stock_dynamic,
287 QOT_GET_ARK_STOCK_DYNAMIC,
288 qot_get_ark_stock_dynamic
289);
290qot_raw_rest_endpoint!(
291 get_ark_active_transaction,
292 QOT_GET_ARK_ACTIVE_TRANSACTION,
293 qot_get_ark_active_transaction
294);
295qot_raw_rest_endpoint!(
296 get_rating_change,
297 QOT_GET_RATING_CHANGE,
298 qot_get_rating_change
299);
300qot_raw_rest_endpoint!(
301 get_industrial_chain_list,
302 QOT_GET_INDUSTRIAL_CHAIN_LIST,
303 qot_get_industrial_chain_list
304);
305qot_raw_rest_endpoint!(
306 get_industrial_chain_detail,
307 QOT_GET_INDUSTRIAL_CHAIN_DETAIL,
308 qot_get_industrial_chain_detail
309);
310qot_raw_rest_endpoint!(
311 get_industrial_chain_by_plate,
312 QOT_GET_INDUSTRIAL_CHAIN_BY_PLATE,
313 qot_get_industrial_chain_by_plate
314);
315qot_raw_rest_endpoint!(
316 get_industrial_plate_info,
317 QOT_GET_INDUSTRIAL_PLATE_INFO,
318 qot_get_industrial_plate_info
319);
320qot_raw_rest_endpoint!(
321 get_industrial_plate_stock,
322 QOT_GET_INDUSTRIAL_PLATE_STOCK,
323 qot_get_industrial_plate_stock
324);
325qot_raw_rest_endpoint!(
326 get_heat_map_data,
327 QOT_GET_HEAT_MAP_DATA,
328 qot_get_heat_map_data
329);
330qot_raw_rest_endpoint!(
331 get_rise_fall_distribution,
332 QOT_GET_RISE_FALL_DISTRIBUTION,
333 qot_get_rise_fall_distribution
334);