Skip to main content

futu_mcp/tools/
option_analytics.rs

1use std::future::Future;
2use std::sync::Arc;
3
4use futu_net::client::FutuClient;
5use rmcp::{RoleServer, handler::server::wrapper::Parameters, service::RequestContext};
6use serde::de::DeserializeOwned;
7
8use crate::handlers;
9use crate::tool_args::ProtoJsonReq;
10
11use super::FutuServer;
12
13async fn run<C2s, F, Fut>(
14    server: &FutuServer,
15    tool_name: &'static str,
16    label: &'static str,
17    req: ProtoJsonReq,
18    req_ctx: RequestContext<RoleServer>,
19    handler: F,
20) -> std::result::Result<String, String>
21where
22    C2s: DeserializeOwned,
23    F: FnOnce(Arc<FutuClient>, C2s) -> Fut,
24    Fut: Future<Output = anyhow::Result<String>>,
25{
26    let c2s = match handlers::proto_json::parse_c2s_json::<C2s>(label, &req.c2s_json) {
27        Ok(c2s) => c2s,
28        Err(error) => return FutuServer::tool_err(error),
29    };
30    let client = server
31        .read_client_or_err(tool_name, &req_ctx, req.api_key.as_deref(), None)
32        .await?;
33    FutuServer::wrap_result(handler(client, c2s).await)
34}
35
36impl FutuServer {
37    async fn futu_get_option_market_statistic_impl(
38        &self,
39        Parameters(req): Parameters<ProtoJsonReq>,
40        req_ctx: RequestContext<RoleServer>,
41    ) -> std::result::Result<String, String> {
42        run::<futu_proto::qot_get_option_market_statistic::C2s, _, _>(
43            self,
44            "futu_get_option_market_statistic",
45            "option-market-statistic",
46            req,
47            req_ctx,
48            |client, c2s| async move {
49                handlers::proto_json::option_market_statistic(&client, c2s).await
50            },
51        )
52        .await
53    }
54
55    async fn futu_get_option_underlying_his_statistic_impl(
56        &self,
57        Parameters(req): Parameters<ProtoJsonReq>,
58        req_ctx: RequestContext<RoleServer>,
59    ) -> std::result::Result<String, String> {
60        run::<futu_proto::qot_get_option_underlying_his_statistic::C2s, _, _>(
61            self,
62            "futu_get_option_underlying_his_statistic",
63            "option-underlying-his-statistic",
64            req,
65            req_ctx,
66            |client, c2s| async move {
67                handlers::proto_json::option_underlying_his_statistic(&client, c2s).await
68            },
69        )
70        .await
71    }
72
73    async fn futu_get_option_underlying_overview_impl(
74        &self,
75        Parameters(req): Parameters<ProtoJsonReq>,
76        req_ctx: RequestContext<RoleServer>,
77    ) -> std::result::Result<String, String> {
78        run::<futu_proto::qot_get_option_underlying_overview::C2s, _, _>(
79            self,
80            "futu_get_option_underlying_overview",
81            "option-underlying-overview",
82            req,
83            req_ctx,
84            |client, c2s| async move {
85                handlers::proto_json::option_underlying_overview(&client, c2s).await
86            },
87        )
88        .await
89    }
90
91    async fn futu_get_option_underlying_his_volatility_impl(
92        &self,
93        Parameters(req): Parameters<ProtoJsonReq>,
94        req_ctx: RequestContext<RoleServer>,
95    ) -> std::result::Result<String, String> {
96        run::<futu_proto::qot_get_option_underlying_his_volatility::C2s, _, _>(
97            self,
98            "futu_get_option_underlying_his_volatility",
99            "option-underlying-his-volatility",
100            req,
101            req_ctx,
102            |client, c2s| async move {
103                handlers::proto_json::option_underlying_his_volatility(&client, c2s).await
104            },
105        )
106        .await
107    }
108
109    async fn futu_get_option_underlying_rank_impl(
110        &self,
111        Parameters(req): Parameters<ProtoJsonReq>,
112        req_ctx: RequestContext<RoleServer>,
113    ) -> std::result::Result<String, String> {
114        run::<futu_proto::qot_get_option_underlying_rank::C2s, _, _>(
115            self,
116            "futu_get_option_underlying_rank",
117            "option-underlying-rank",
118            req,
119            req_ctx,
120            |client, c2s| async move {
121                handlers::proto_json::option_underlying_rank(&client, c2s).await
122            },
123        )
124        .await
125    }
126
127    async fn futu_get_option_rank_impl(
128        &self,
129        Parameters(req): Parameters<ProtoJsonReq>,
130        req_ctx: RequestContext<RoleServer>,
131    ) -> std::result::Result<String, String> {
132        run::<futu_proto::qot_get_option_rank::C2s, _, _>(
133            self,
134            "futu_get_option_rank",
135            "option-rank",
136            req,
137            req_ctx,
138            |client, c2s| async move { handlers::proto_json::option_rank(&client, c2s).await },
139        )
140        .await
141    }
142
143    async fn futu_get_option_event_impl(
144        &self,
145        Parameters(req): Parameters<ProtoJsonReq>,
146        req_ctx: RequestContext<RoleServer>,
147    ) -> std::result::Result<String, String> {
148        run::<futu_proto::qot_get_option_event::C2s, _, _>(
149            self,
150            "futu_get_option_event",
151            "option-event",
152            req,
153            req_ctx,
154            |client, c2s| async move { handlers::proto_json::option_event(&client, c2s).await },
155        )
156        .await
157    }
158
159    async fn futu_get_option_event_alert_impl(
160        &self,
161        Parameters(req): Parameters<ProtoJsonReq>,
162        req_ctx: RequestContext<RoleServer>,
163    ) -> std::result::Result<String, String> {
164        run::<futu_proto::qot_get_option_event_alert::C2s, _, _>(self, "futu_get_option_event_alert", "option-event-alert", req, req_ctx, |client, c2s| async move { handlers::proto_json::option_event_alert(&client, c2s).await }).await
165    }
166
167    async fn futu_set_option_event_alert_impl(
168        &self,
169        Parameters(req): Parameters<ProtoJsonReq>,
170        req_ctx: RequestContext<RoleServer>,
171    ) -> std::result::Result<String, String> {
172        run::<futu_proto::qot_set_option_event_alert::C2s, _, _>(
173            self,
174            "futu_set_option_event_alert",
175            "set-option-event-alert",
176            req,
177            req_ctx,
178            |client, c2s| async move {
179                handlers::proto_json::set_option_event_alert(&client, c2s).await
180            },
181        )
182        .await
183    }
184
185    async fn futu_get_option_zero_dte_screener_impl(
186        &self,
187        Parameters(req): Parameters<ProtoJsonReq>,
188        req_ctx: RequestContext<RoleServer>,
189    ) -> std::result::Result<String, String> {
190        run::<futu_proto::qot_get_option_zero_dte_screener::C2s, _, _>(
191            self,
192            "futu_get_option_zero_dte_screener",
193            "option-zero-dte-screener",
194            req,
195            req_ctx,
196            |client, c2s| async move {
197                handlers::proto_json::option_zero_dte_screener(&client, c2s).await
198            },
199        )
200        .await
201    }
202
203    async fn futu_get_option_zero_dte_contract_impl(
204        &self,
205        Parameters(req): Parameters<ProtoJsonReq>,
206        req_ctx: RequestContext<RoleServer>,
207    ) -> std::result::Result<String, String> {
208        run::<futu_proto::qot_get_option_zero_dte_contract::C2s, _, _>(
209            self,
210            "futu_get_option_zero_dte_contract",
211            "option-zero-dte-contract",
212            req,
213            req_ctx,
214            |client, c2s| async move {
215                handlers::proto_json::option_zero_dte_contract(&client, c2s).await
216            },
217        )
218        .await
219    }
220
221    async fn futu_get_option_earnings_screener_impl(
222        &self,
223        Parameters(req): Parameters<ProtoJsonReq>,
224        req_ctx: RequestContext<RoleServer>,
225    ) -> std::result::Result<String, String> {
226        run::<futu_proto::qot_get_option_earnings_screener::C2s, _, _>(
227            self,
228            "futu_get_option_earnings_screener",
229            "option-earnings-screener",
230            req,
231            req_ctx,
232            |client, c2s| async move {
233                handlers::proto_json::option_earnings_screener(&client, c2s).await
234            },
235        )
236        .await
237    }
238
239    async fn futu_get_option_seller_screener_impl(
240        &self,
241        Parameters(req): Parameters<ProtoJsonReq>,
242        req_ctx: RequestContext<RoleServer>,
243    ) -> std::result::Result<String, String> {
244        run::<futu_proto::qot_get_option_seller_screener::C2s, _, _>(
245            self,
246            "futu_get_option_seller_screener",
247            "option-seller-screener",
248            req,
249            req_ctx,
250            |client, c2s| async move {
251                handlers::proto_json::option_seller_screener(&client, c2s).await
252            },
253        )
254        .await
255    }
256}
257
258include!(concat!(
259    env!("OUT_DIR"),
260    "/generated_mcp_routes_option_analytics.rs"
261));