futu_mcp/tools/
reference_screen_unusual.rs1use crate::handlers;
4use crate::tool_args::*;
5use rmcp::{
6 RoleServer, handler::server::wrapper::Parameters, service::RequestContext, tool, tool_router,
7};
8
9use super::FutuServer;
10
11#[tool_router(router = reference_screen_unusual_tool_router, vis = "pub(crate)")]
12impl FutuServer {
13 #[tool(
14 description = "Stock screener. Futu API v10.6: OpenQuoteContext.stock_screen. The c2s argument is the full Qot_StockScreen C2S JSON object."
15 )]
16 async fn futu_stock_screen(
17 &self,
18 Parameters(req): Parameters<StockScreenReq>,
19 req_ctx: RequestContext<RoleServer>,
20 ) -> std::result::Result<String, String> {
21 tracing::info!(tool = "futu_stock_screen");
22 let client = self
23 .read_client_or_err("futu_stock_screen", &req_ctx, None, None)
24 .await?;
25 Self::wrap_result(handlers::reference::stock_screen(&client, req.c2s).await)
26 }
27
28 #[tool(
29 description = "Option screener. Futu API v10.6: OpenQuoteContext.option_screen. The c2s argument is the full Qot_OptionScreen C2S JSON object."
30 )]
31 async fn futu_option_screen(
32 &self,
33 Parameters(req): Parameters<OptionScreenReq>,
34 req_ctx: RequestContext<RoleServer>,
35 ) -> std::result::Result<String, String> {
36 tracing::info!(tool = "futu_option_screen");
37 let client = self
38 .read_client_or_err("futu_option_screen", &req_ctx, None, None)
39 .await?;
40 Self::wrap_result(handlers::reference::option_screen(&client, req.c2s).await)
41 }
42
43 #[tool(
44 description = "Warrant screener. Futu API v10.6: OpenQuoteContext.warrant_screen. The c2s argument is the full Qot_WarrantScreen C2S JSON object."
45 )]
46 async fn futu_warrant_screen(
47 &self,
48 Parameters(req): Parameters<WarrantScreenReq>,
49 req_ctx: RequestContext<RoleServer>,
50 ) -> std::result::Result<String, String> {
51 tracing::info!(tool = "futu_warrant_screen");
52 let client = self
53 .read_client_or_err("futu_warrant_screen", &req_ctx, None, None)
54 .await?;
55 Self::wrap_result(handlers::reference::warrant_screen(&client, req.c2s).await)
56 }
57
58 #[tool(
59 description = "Technical indicator unusual-move summary. Futu API v10.6: OpenQuoteContext.get_technical_unusual."
60 )]
61 async fn futu_get_technical_unusual(
62 &self,
63 Parameters(req): Parameters<TechnicalUnusualReq>,
64 req_ctx: RequestContext<RoleServer>,
65 ) -> std::result::Result<String, String> {
66 tracing::info!(
67 tool = "futu_get_technical_unusual",
68 stock_symbol = %req.stock_symbol,
69 time_range = ?req.time_range,
70 indicator_filter_count = req.indicator_filters.len(),
71 language_id = ?req.language_id
72 );
73 let client = self
74 .read_client_or_err("futu_get_technical_unusual", &req_ctx, None, None)
75 .await?;
76 Self::wrap_result(
77 handlers::reference::get_technical_unusual(
78 &client,
79 &req.stock_symbol,
80 req.time_range,
81 req.indicator_filters,
82 req.language_id,
83 )
84 .await,
85 )
86 }
87
88 #[tool(
89 description = "Financial unusual-change summary. Futu API v10.6: OpenQuoteContext.get_financial_unusual."
90 )]
91 async fn futu_get_financial_unusual(
92 &self,
93 Parameters(req): Parameters<FinancialUnusualReq>,
94 req_ctx: RequestContext<RoleServer>,
95 ) -> std::result::Result<String, String> {
96 tracing::info!(
97 tool = "futu_get_financial_unusual",
98 stock_symbol = %req.stock_symbol,
99 time_range = ?req.time_range,
100 analysis_dimension_count = req.analysis_dimensions.len(),
101 language_id = ?req.language_id
102 );
103 let client = self
104 .read_client_or_err("futu_get_financial_unusual", &req_ctx, None, None)
105 .await?;
106 Self::wrap_result(
107 handlers::reference::get_financial_unusual(
108 &client,
109 &req.stock_symbol,
110 req.time_range,
111 req.analysis_dimensions,
112 req.language_id,
113 )
114 .await,
115 )
116 }
117
118 #[tool(
119 description = "Derivative unusual-change summary. Futu API v10.6: OpenQuoteContext.get_derivative_unusual."
120 )]
121 async fn futu_get_derivative_unusual(
122 &self,
123 Parameters(req): Parameters<DerivativeUnusualReq>,
124 req_ctx: RequestContext<RoleServer>,
125 ) -> std::result::Result<String, String> {
126 tracing::info!(
127 tool = "futu_get_derivative_unusual",
128 stock_symbol = %req.stock_symbol,
129 time_range = ?req.time_range,
130 analysis_dimension_count = req.analysis_dimensions.len(),
131 language_id = ?req.language_id
132 );
133 let client = self
134 .read_client_or_err("futu_get_derivative_unusual", &req_ctx, None, None)
135 .await?;
136 Self::wrap_result(
137 handlers::reference::get_derivative_unusual(
138 &client,
139 &req.stock_symbol,
140 req.time_range,
141 req.analysis_dimensions,
142 req.language_id,
143 )
144 .await,
145 )
146 }
147}