1use std::future::Future;
4use std::sync::Arc;
5
6use futu_net::client::FutuClient;
7use rmcp::{
8 RoleServer, handler::server::wrapper::Parameters, service::RequestContext, tool, tool_router,
9};
10use serde::de::DeserializeOwned;
11
12use crate::handlers;
13use crate::tool_args::ProtoJsonReq;
14
15use super::FutuServer;
16
17async fn run_qot_proto_json<C2S, F, Fut>(
18 server: &FutuServer,
19 tool_name: &'static str,
20 label: &'static str,
21 req: ProtoJsonReq,
22 req_ctx: RequestContext<RoleServer>,
23 handler: F,
24) -> std::result::Result<String, String>
25where
26 C2S: DeserializeOwned,
27 F: FnOnce(Arc<FutuClient>, C2S) -> Fut,
28 Fut: Future<Output = anyhow::Result<String>>,
29{
30 let c2s = match handlers::proto_json::parse_c2s_json::<C2S>(label, &req.c2s_json) {
31 Ok(c2s) => c2s,
32 Err(err) => return FutuServer::tool_err(err),
33 };
34 let client = server
35 .read_client_or_err(tool_name, &req_ctx, req.api_key.as_deref(), None)
36 .await?;
37 FutuServer::wrap_result(handler(client, c2s).await)
38}
39
40#[tool_router(router = qot_3401_plus_tool_router, vis = "pub(crate)")]
41impl FutuServer {
42 #[tool(
43 description = "Get earnings calendar data. Public QOT 3401. `c2s_json` must be generated-proto JSON."
44 )]
45 async fn futu_get_earnings_calendar(
46 &self,
47 Parameters(req): Parameters<ProtoJsonReq>,
48 req_ctx: RequestContext<RoleServer>,
49 ) -> std::result::Result<String, String> {
50 run_qot_proto_json::<futu_proto::qot_get_earnings_calendar::C2s, _, _>(
51 self,
52 "futu_get_earnings_calendar",
53 "earnings-calendar",
54 req,
55 req_ctx,
56 |client, c2s| async move {
57 handlers::proto_json::earnings_calendar(&client, c2s).await
58 },
59 )
60 .await
61 }
62
63 #[tool(
64 description = "Get macro indicator list. Public QOT 3402. `c2s_json` must be generated-proto JSON."
65 )]
66 async fn futu_get_macro_indicator_list(
67 &self,
68 Parameters(req): Parameters<ProtoJsonReq>,
69 req_ctx: RequestContext<RoleServer>,
70 ) -> std::result::Result<String, String> {
71 run_qot_proto_json::<futu_proto::qot_get_macro_indicator_list::C2s, _, _>(
72 self,
73 "futu_get_macro_indicator_list",
74 "macro-indicator-list",
75 req,
76 req_ctx,
77 |client, c2s| async move {
78 handlers::proto_json::macro_indicator_list(&client, c2s).await
79 },
80 )
81 .await
82 }
83
84 #[tool(
85 description = "Get macro indicator history. Public QOT 3403. `c2s_json` must be generated-proto JSON."
86 )]
87 async fn futu_get_macro_indicator_history(
88 &self,
89 Parameters(req): Parameters<ProtoJsonReq>,
90 req_ctx: RequestContext<RoleServer>,
91 ) -> std::result::Result<String, String> {
92 run_qot_proto_json::<futu_proto::qot_get_macro_indicator_history::C2s, _, _>(
93 self,
94 "futu_get_macro_indicator_history",
95 "macro-indicator-history",
96 req,
97 req_ctx,
98 |client, c2s| async move {
99 handlers::proto_json::macro_indicator_history(&client, c2s).await
100 },
101 )
102 .await
103 }
104
105 #[tool(
106 description = "Get FedWatch target-rate data. Public QOT 3404. `c2s_json` must be generated-proto JSON."
107 )]
108 async fn futu_get_fed_watch_target_rate(
109 &self,
110 Parameters(req): Parameters<ProtoJsonReq>,
111 req_ctx: RequestContext<RoleServer>,
112 ) -> std::result::Result<String, String> {
113 run_qot_proto_json::<futu_proto::qot_get_fed_watch_target_rate::C2s, _, _>(
114 self,
115 "futu_get_fed_watch_target_rate",
116 "fed-watch-target-rate",
117 req,
118 req_ctx,
119 |client, c2s| async move {
120 handlers::proto_json::fed_watch_target_rate(&client, c2s).await
121 },
122 )
123 .await
124 }
125
126 #[tool(
127 description = "Get FedWatch dot-plot data. Public QOT 3405. `c2s_json` must be generated-proto JSON."
128 )]
129 async fn futu_get_fed_watch_dot_plot(
130 &self,
131 Parameters(req): Parameters<ProtoJsonReq>,
132 req_ctx: RequestContext<RoleServer>,
133 ) -> std::result::Result<String, String> {
134 run_qot_proto_json::<futu_proto::qot_get_fed_watch_dot_plot::C2s, _, _>(
135 self,
136 "futu_get_fed_watch_dot_plot",
137 "fed-watch-dot-plot",
138 req,
139 req_ctx,
140 |client, c2s| async move {
141 handlers::proto_json::fed_watch_dot_plot(&client, c2s).await
142 },
143 )
144 .await
145 }
146
147 #[tool(
148 description = "Get earnings beat ranking data. Public QOT 3406. `c2s_json` must be generated-proto JSON."
149 )]
150 async fn futu_get_earnings_beat_rank(
151 &self,
152 Parameters(req): Parameters<ProtoJsonReq>,
153 req_ctx: RequestContext<RoleServer>,
154 ) -> std::result::Result<String, String> {
155 run_qot_proto_json::<futu_proto::qot_get_earnings_beat_rank::C2s, _, _>(
156 self,
157 "futu_get_earnings_beat_rank",
158 "earnings-beat-rank",
159 req,
160 req_ctx,
161 |client, c2s| async move {
162 handlers::proto_json::earnings_beat_rank(&client, c2s).await
163 },
164 )
165 .await
166 }
167
168 #[tool(
169 description = "Get dividend ranking data. Public QOT 3407. `c2s_json` must be generated-proto JSON."
170 )]
171 async fn futu_get_dividend_rank(
172 &self,
173 Parameters(req): Parameters<ProtoJsonReq>,
174 req_ctx: RequestContext<RoleServer>,
175 ) -> std::result::Result<String, String> {
176 run_qot_proto_json::<futu_proto::qot_get_dividend_rank::C2s, _, _>(
177 self,
178 "futu_get_dividend_rank",
179 "dividend-rank",
180 req,
181 req_ctx,
182 |client, c2s| async move { handlers::proto_json::dividend_rank(&client, c2s).await },
183 )
184 .await
185 }
186
187 #[tool(
188 description = "Get dividend calendar data. Public QOT 3408. `c2s_json` must be generated-proto JSON."
189 )]
190 async fn futu_get_dividend_calendar(
191 &self,
192 Parameters(req): Parameters<ProtoJsonReq>,
193 req_ctx: RequestContext<RoleServer>,
194 ) -> std::result::Result<String, String> {
195 run_qot_proto_json::<futu_proto::qot_get_dividend_calendar::C2s, _, _>(
196 self,
197 "futu_get_dividend_calendar",
198 "dividend-calendar",
199 req,
200 req_ctx,
201 |client, c2s| async move {
202 handlers::proto_json::dividend_calendar(&client, c2s).await
203 },
204 )
205 .await
206 }
207
208 #[tool(
209 description = "Get economic calendar data. Public QOT 3409. `c2s_json` must be generated-proto JSON."
210 )]
211 async fn futu_get_economic_calendar(
212 &self,
213 Parameters(req): Parameters<ProtoJsonReq>,
214 req_ctx: RequestContext<RoleServer>,
215 ) -> std::result::Result<String, String> {
216 run_qot_proto_json::<futu_proto::qot_get_economic_calendar::C2s, _, _>(
217 self,
218 "futu_get_economic_calendar",
219 "economic-calendar",
220 req,
221 req_ctx,
222 |client, c2s| async move {
223 handlers::proto_json::economic_calendar(&client, c2s).await
224 },
225 )
226 .await
227 }
228
229 #[tool(
230 description = "Get US pre-market ranking data. Public QOT 3410. `c2s_json` must be generated-proto JSON."
231 )]
232 async fn futu_get_us_pre_market_rank(
233 &self,
234 Parameters(req): Parameters<ProtoJsonReq>,
235 req_ctx: RequestContext<RoleServer>,
236 ) -> std::result::Result<String, String> {
237 run_qot_proto_json::<futu_proto::qot_get_us_pre_market_rank::C2s, _, _>(
238 self,
239 "futu_get_us_pre_market_rank",
240 "us-pre-market-rank",
241 req,
242 req_ctx,
243 |client, c2s| async move {
244 handlers::proto_json::us_pre_market_rank(&client, c2s).await
245 },
246 )
247 .await
248 }
249
250 #[tool(
251 description = "Get US after-hours ranking data. Public QOT 3411. `c2s_json` must be generated-proto JSON."
252 )]
253 async fn futu_get_us_after_hours_rank(
254 &self,
255 Parameters(req): Parameters<ProtoJsonReq>,
256 req_ctx: RequestContext<RoleServer>,
257 ) -> std::result::Result<String, String> {
258 run_qot_proto_json::<futu_proto::qot_get_us_after_hours_rank::C2s, _, _>(
259 self,
260 "futu_get_us_after_hours_rank",
261 "us-after-hours-rank",
262 req,
263 req_ctx,
264 |client, c2s| async move {
265 handlers::proto_json::us_after_hours_rank(&client, c2s).await
266 },
267 )
268 .await
269 }
270
271 #[tool(
272 description = "Get US overnight ranking data. Public QOT 3412. `c2s_json` must be generated-proto JSON."
273 )]
274 async fn futu_get_us_overnight_rank(
275 &self,
276 Parameters(req): Parameters<ProtoJsonReq>,
277 req_ctx: RequestContext<RoleServer>,
278 ) -> std::result::Result<String, String> {
279 run_qot_proto_json::<futu_proto::qot_get_us_overnight_rank::C2s, _, _>(
280 self,
281 "futu_get_us_overnight_rank",
282 "us-overnight-rank",
283 req,
284 req_ctx,
285 |client, c2s| async move {
286 handlers::proto_json::us_overnight_rank(&client, c2s).await
287 },
288 )
289 .await
290 }
291
292 #[tool(
293 description = "Get top movers ranking data. Public QOT 3413. `c2s_json` must be generated-proto JSON."
294 )]
295 async fn futu_get_top_movers_rank(
296 &self,
297 Parameters(req): Parameters<ProtoJsonReq>,
298 req_ctx: RequestContext<RoleServer>,
299 ) -> std::result::Result<String, String> {
300 run_qot_proto_json::<futu_proto::qot_get_top_movers_rank::C2s, _, _>(
301 self,
302 "futu_get_top_movers_rank",
303 "top-movers-rank",
304 req,
305 req_ctx,
306 |client, c2s| async move { handlers::proto_json::top_movers_rank(&client, c2s).await },
307 )
308 .await
309 }
310
311 #[tool(
312 description = "Get hot-list data. Public QOT 3414. `c2s_json` must be generated-proto JSON."
313 )]
314 async fn futu_get_hot_list(
315 &self,
316 Parameters(req): Parameters<ProtoJsonReq>,
317 req_ctx: RequestContext<RoleServer>,
318 ) -> std::result::Result<String, String> {
319 run_qot_proto_json::<futu_proto::qot_get_hot_list::C2s, _, _>(
320 self,
321 "futu_get_hot_list",
322 "hot-list",
323 req,
324 req_ctx,
325 |client, c2s| async move { handlers::proto_json::hot_list(&client, c2s).await },
326 )
327 .await
328 }
329
330 #[tool(
331 description = "Get short-selling ranking data. Public QOT 3415. `c2s_json` must be generated-proto JSON."
332 )]
333 async fn futu_get_short_selling_rank(
334 &self,
335 Parameters(req): Parameters<ProtoJsonReq>,
336 req_ctx: RequestContext<RoleServer>,
337 ) -> std::result::Result<String, String> {
338 run_qot_proto_json::<futu_proto::qot_get_short_selling_rank::C2s, _, _>(
339 self,
340 "futu_get_short_selling_rank",
341 "short-selling-rank",
342 req,
343 req_ctx,
344 |client, c2s| async move {
345 handlers::proto_json::short_selling_rank(&client, c2s).await
346 },
347 )
348 .await
349 }
350
351 #[tool(
352 description = "Get period-change ranking data. Public QOT 3416. `c2s_json` must be generated-proto JSON."
353 )]
354 async fn futu_get_period_change_rank(
355 &self,
356 Parameters(req): Parameters<ProtoJsonReq>,
357 req_ctx: RequestContext<RoleServer>,
358 ) -> std::result::Result<String, String> {
359 run_qot_proto_json::<futu_proto::qot_get_period_change_rank::C2s, _, _>(
360 self,
361 "futu_get_period_change_rank",
362 "period-change-rank",
363 req,
364 req_ctx,
365 |client, c2s| async move {
366 handlers::proto_json::period_change_rank(&client, c2s).await
367 },
368 )
369 .await
370 }
371
372 #[tool(
373 description = "Get high-dividend SOE ranking data. Public QOT 3417. `c2s_json` must be generated-proto JSON."
374 )]
375 async fn futu_get_high_dividend_soe_rank(
376 &self,
377 Parameters(req): Parameters<ProtoJsonReq>,
378 req_ctx: RequestContext<RoleServer>,
379 ) -> std::result::Result<String, String> {
380 run_qot_proto_json::<futu_proto::qot_get_high_dividend_soe_rank::C2s, _, _>(
381 self,
382 "futu_get_high_dividend_soe_rank",
383 "high-dividend-soe-rank",
384 req,
385 req_ctx,
386 |client, c2s| async move {
387 handlers::proto_json::high_dividend_soe_rank(&client, c2s).await
388 },
389 )
390 .await
391 }
392
393 #[tool(
394 description = "Get institution list. Public QOT 3418. `c2s_json` must be generated-proto JSON."
395 )]
396 async fn futu_get_institution_list(
397 &self,
398 Parameters(req): Parameters<ProtoJsonReq>,
399 req_ctx: RequestContext<RoleServer>,
400 ) -> std::result::Result<String, String> {
401 run_qot_proto_json::<futu_proto::qot_get_institution_list::C2s, _, _>(
402 self,
403 "futu_get_institution_list",
404 "institution-list",
405 req,
406 req_ctx,
407 |client, c2s| async move { handlers::proto_json::institution_list(&client, c2s).await },
408 )
409 .await
410 }
411
412 #[tool(
413 description = "Get institution profile. Public QOT 3419. `c2s_json` must be generated-proto JSON."
414 )]
415 async fn futu_get_institution_profile(
416 &self,
417 Parameters(req): Parameters<ProtoJsonReq>,
418 req_ctx: RequestContext<RoleServer>,
419 ) -> std::result::Result<String, String> {
420 run_qot_proto_json::<futu_proto::qot_get_institution_profile::C2s, _, _>(
421 self,
422 "futu_get_institution_profile",
423 "institution-profile",
424 req,
425 req_ctx,
426 |client, c2s| async move {
427 handlers::proto_json::institution_profile(&client, c2s).await
428 },
429 )
430 .await
431 }
432
433 #[tool(
434 description = "Get institution holding distribution. Public QOT 3420. `c2s_json` must be generated-proto JSON."
435 )]
436 async fn futu_get_institution_distribution(
437 &self,
438 Parameters(req): Parameters<ProtoJsonReq>,
439 req_ctx: RequestContext<RoleServer>,
440 ) -> std::result::Result<String, String> {
441 run_qot_proto_json::<futu_proto::qot_get_institution_distribution::C2s, _, _>(
442 self,
443 "futu_get_institution_distribution",
444 "institution-distribution",
445 req,
446 req_ctx,
447 |client, c2s| async move {
448 handlers::proto_json::institution_distribution(&client, c2s).await
449 },
450 )
451 .await
452 }
453
454 #[tool(
455 description = "Get institution holding change list. Public QOT 3421. `c2s_json` must be generated-proto JSON."
456 )]
457 async fn futu_get_institution_holding_change(
458 &self,
459 Parameters(req): Parameters<ProtoJsonReq>,
460 req_ctx: RequestContext<RoleServer>,
461 ) -> std::result::Result<String, String> {
462 run_qot_proto_json::<futu_proto::qot_get_institution_holding_change::C2s, _, _>(
463 self,
464 "futu_get_institution_holding_change",
465 "institution-holding-change",
466 req,
467 req_ctx,
468 |client, c2s| async move {
469 handlers::proto_json::institution_holding_change(&client, c2s).await
470 },
471 )
472 .await
473 }
474
475 #[tool(
476 description = "Get institution holding list. Public QOT 3422. `c2s_json` must be generated-proto JSON."
477 )]
478 async fn futu_get_institution_holding_list(
479 &self,
480 Parameters(req): Parameters<ProtoJsonReq>,
481 req_ctx: RequestContext<RoleServer>,
482 ) -> std::result::Result<String, String> {
483 run_qot_proto_json::<futu_proto::qot_get_institution_holding_list::C2s, _, _>(
484 self,
485 "futu_get_institution_holding_list",
486 "institution-holding-list",
487 req,
488 req_ctx,
489 |client, c2s| async move {
490 handlers::proto_json::institution_holding_list(&client, c2s).await
491 },
492 )
493 .await
494 }
495
496 #[tool(
497 description = "Get ARK fund holding data. Public QOT 3423. `c2s_json` must be generated-proto JSON."
498 )]
499 async fn futu_get_ark_fund_holding(
500 &self,
501 Parameters(req): Parameters<ProtoJsonReq>,
502 req_ctx: RequestContext<RoleServer>,
503 ) -> std::result::Result<String, String> {
504 run_qot_proto_json::<futu_proto::qot_get_ark_fund_holding::C2s, _, _>(
505 self,
506 "futu_get_ark_fund_holding",
507 "ark-fund-holding",
508 req,
509 req_ctx,
510 |client, c2s| async move { handlers::proto_json::ark_fund_holding(&client, c2s).await },
511 )
512 .await
513 }
514
515 #[tool(
516 description = "Get ARK stock dynamic data. Public QOT 3424. `c2s_json` must be generated-proto JSON."
517 )]
518 async fn futu_get_ark_stock_dynamic(
519 &self,
520 Parameters(req): Parameters<ProtoJsonReq>,
521 req_ctx: RequestContext<RoleServer>,
522 ) -> std::result::Result<String, String> {
523 run_qot_proto_json::<futu_proto::qot_get_ark_stock_dynamic::C2s, _, _>(
524 self,
525 "futu_get_ark_stock_dynamic",
526 "ark-stock-dynamic",
527 req,
528 req_ctx,
529 |client, c2s| async move { handlers::proto_json::ark_stock_dynamic(&client, c2s).await },
530 )
531 .await
532 }
533
534 #[tool(
535 description = "Get ARK active transaction data. Public QOT 3425. `c2s_json` must be generated-proto JSON."
536 )]
537 async fn futu_get_ark_active_transaction(
538 &self,
539 Parameters(req): Parameters<ProtoJsonReq>,
540 req_ctx: RequestContext<RoleServer>,
541 ) -> std::result::Result<String, String> {
542 run_qot_proto_json::<futu_proto::qot_get_ark_active_transaction::C2s, _, _>(
543 self,
544 "futu_get_ark_active_transaction",
545 "ark-active-transaction",
546 req,
547 req_ctx,
548 |client, c2s| async move {
549 handlers::proto_json::ark_active_transaction(&client, c2s).await
550 },
551 )
552 .await
553 }
554
555 #[tool(
556 description = "Get analyst rating-change data. Public QOT 3426. `c2s_json` must be generated-proto JSON."
557 )]
558 async fn futu_get_rating_change(
559 &self,
560 Parameters(req): Parameters<ProtoJsonReq>,
561 req_ctx: RequestContext<RoleServer>,
562 ) -> std::result::Result<String, String> {
563 run_qot_proto_json::<futu_proto::qot_get_rating_change::C2s, _, _>(
564 self,
565 "futu_get_rating_change",
566 "rating-change",
567 req,
568 req_ctx,
569 |client, c2s| async move { handlers::proto_json::rating_change(&client, c2s).await },
570 )
571 .await
572 }
573
574 #[tool(
575 description = "Get industrial-chain list. Public QOT 3427. `c2s_json` must be generated-proto JSON."
576 )]
577 async fn futu_get_industrial_chain_list(
578 &self,
579 Parameters(req): Parameters<ProtoJsonReq>,
580 req_ctx: RequestContext<RoleServer>,
581 ) -> std::result::Result<String, String> {
582 run_qot_proto_json::<futu_proto::qot_get_industrial_chain_list::C2s, _, _>(
583 self,
584 "futu_get_industrial_chain_list",
585 "industrial-chain-list",
586 req,
587 req_ctx,
588 |client, c2s| async move {
589 handlers::proto_json::industrial_chain_list(&client, c2s).await
590 },
591 )
592 .await
593 }
594
595 #[tool(
596 description = "Get industrial-chain detail. Public QOT 3428. `c2s_json` must be generated-proto JSON."
597 )]
598 async fn futu_get_industrial_chain_detail(
599 &self,
600 Parameters(req): Parameters<ProtoJsonReq>,
601 req_ctx: RequestContext<RoleServer>,
602 ) -> std::result::Result<String, String> {
603 run_qot_proto_json::<futu_proto::qot_get_industrial_chain_detail::C2s, _, _>(
604 self,
605 "futu_get_industrial_chain_detail",
606 "industrial-chain-detail",
607 req,
608 req_ctx,
609 |client, c2s| async move {
610 handlers::proto_json::industrial_chain_detail(&client, c2s).await
611 },
612 )
613 .await
614 }
615
616 #[tool(
617 description = "Get industrial-chain by plate. Public QOT 3429. `c2s_json` must be generated-proto JSON."
618 )]
619 async fn futu_get_industrial_chain_by_plate(
620 &self,
621 Parameters(req): Parameters<ProtoJsonReq>,
622 req_ctx: RequestContext<RoleServer>,
623 ) -> std::result::Result<String, String> {
624 run_qot_proto_json::<futu_proto::qot_get_industrial_chain_by_plate::C2s, _, _>(
625 self,
626 "futu_get_industrial_chain_by_plate",
627 "industrial-chain-by-plate",
628 req,
629 req_ctx,
630 |client, c2s| async move {
631 handlers::proto_json::industrial_chain_by_plate(&client, c2s).await
632 },
633 )
634 .await
635 }
636
637 #[tool(
638 description = "Get industrial plate info. Public QOT 3430. `c2s_json` must be generated-proto JSON."
639 )]
640 async fn futu_get_industrial_plate_info(
641 &self,
642 Parameters(req): Parameters<ProtoJsonReq>,
643 req_ctx: RequestContext<RoleServer>,
644 ) -> std::result::Result<String, String> {
645 run_qot_proto_json::<futu_proto::qot_get_industrial_plate_info::C2s, _, _>(
646 self,
647 "futu_get_industrial_plate_info",
648 "industrial-plate-info",
649 req,
650 req_ctx,
651 |client, c2s| async move {
652 handlers::proto_json::industrial_plate_info(&client, c2s).await
653 },
654 )
655 .await
656 }
657
658 #[tool(
659 description = "Get industrial plate stocks. Public QOT 3431. `c2s_json` must be generated-proto JSON."
660 )]
661 async fn futu_get_industrial_plate_stock(
662 &self,
663 Parameters(req): Parameters<ProtoJsonReq>,
664 req_ctx: RequestContext<RoleServer>,
665 ) -> std::result::Result<String, String> {
666 run_qot_proto_json::<futu_proto::qot_get_industrial_plate_stock::C2s, _, _>(
667 self,
668 "futu_get_industrial_plate_stock",
669 "industrial-plate-stock",
670 req,
671 req_ctx,
672 |client, c2s| async move {
673 handlers::proto_json::industrial_plate_stock(&client, c2s).await
674 },
675 )
676 .await
677 }
678
679 #[tool(
680 description = "Get heat-map data. Public QOT 3432. `c2s_json` must be generated-proto JSON."
681 )]
682 async fn futu_get_heat_map_data(
683 &self,
684 Parameters(req): Parameters<ProtoJsonReq>,
685 req_ctx: RequestContext<RoleServer>,
686 ) -> std::result::Result<String, String> {
687 run_qot_proto_json::<futu_proto::qot_get_heat_map_data::C2s, _, _>(
688 self,
689 "futu_get_heat_map_data",
690 "heat-map-data",
691 req,
692 req_ctx,
693 |client, c2s| async move { handlers::proto_json::heat_map_data(&client, c2s).await },
694 )
695 .await
696 }
697
698 #[tool(
699 description = "Get rise/fall distribution. Public QOT 3433. `c2s_json` must be generated-proto JSON."
700 )]
701 async fn futu_get_rise_fall_distribution(
702 &self,
703 Parameters(req): Parameters<ProtoJsonReq>,
704 req_ctx: RequestContext<RoleServer>,
705 ) -> std::result::Result<String, String> {
706 run_qot_proto_json::<futu_proto::qot_get_rise_fall_distribution::C2s, _, _>(
707 self,
708 "futu_get_rise_fall_distribution",
709 "rise-fall-distribution",
710 req,
711 req_ctx,
712 |client, c2s| async move {
713 handlers::proto_json::rise_fall_distribution(&client, c2s).await
714 },
715 )
716 .await
717 }
718}