Skip to main content

futu_rest/routes/qot/
qot_3401_plus.rs

1//! REST raw proto-json routes for public QOT 3401+ APIs.
2//!
3//! These endpoints intentionally expose generated public C2S JSON directly.
4//! The daemon Gateway handlers do the C++-aligned public→backend projection.
5
6use 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);