1use 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_corporate_short_brokers_tool_router, vis = "pub(crate)")]
12impl FutuServer {
13 #[tool(
14 description = "Daily short volume for HK/US securities. Futu API v10.6: OpenQuoteContext.get_daily_short_volume."
15 )]
16 async fn futu_get_daily_short_volume(
17 &self,
18 Parameters(req): Parameters<ShortInfoReq>,
19 req_ctx: RequestContext<RoleServer>,
20 ) -> std::result::Result<String, String> {
21 req.validate("futu_get_daily_short_volume")?;
22 tracing::info!(
23 tool = "futu_get_daily_short_volume",
24 symbol = %req.symbol,
25 next_key = ?req.next_key,
26 num = ?req.num
27 );
28 let client = self
29 .read_client_or_err("futu_get_daily_short_volume", &req_ctx, None, None)
30 .await?;
31 Self::wrap_result(
32 handlers::reference::get_daily_short_volume(
33 &client,
34 &req.symbol,
35 req.next_key.as_deref(),
36 req.num,
37 )
38 .await,
39 )
40 }
41
42 #[tool(
43 description = "Corporate action buyback records for HK/A-share securities. Futu API v10.6: OpenQuoteContext.get_corporate_actions_buybacks."
44 )]
45 async fn futu_get_corporate_actions_buybacks(
46 &self,
47 Parameters(req): Parameters<ShortInfoReq>,
48 req_ctx: RequestContext<RoleServer>,
49 ) -> std::result::Result<String, String> {
50 req.validate("futu_get_corporate_actions_buybacks")?;
51 tracing::info!(
52 tool = "futu_get_corporate_actions_buybacks",
53 symbol = %req.symbol,
54 next_key = ?req.next_key,
55 num = ?req.num
56 );
57 let client = self
58 .read_client_or_err("futu_get_corporate_actions_buybacks", &req_ctx, None, None)
59 .await?;
60 Self::wrap_result(
61 handlers::reference::get_corporate_actions_buybacks(
62 &client,
63 &req.symbol,
64 req.next_key.as_deref(),
65 req.num,
66 )
67 .await,
68 )
69 }
70
71 #[tool(
72 description = "Corporate action dividend records for securities. Futu API v10.6: OpenQuoteContext.get_corporate_actions_dividends."
73 )]
74 async fn futu_get_corporate_actions_dividends(
75 &self,
76 Parameters(req): Parameters<SymbolReq>,
77 req_ctx: RequestContext<RoleServer>,
78 ) -> std::result::Result<String, String> {
79 tracing::info!(
80 tool = "futu_get_corporate_actions_dividends",
81 symbol = %req.symbol
82 );
83 let client = self
84 .read_client_or_err("futu_get_corporate_actions_dividends", &req_ctx, None, None)
85 .await?;
86 Self::wrap_result(
87 handlers::reference::get_corporate_actions_dividends(&client, &req.symbol).await,
88 )
89 }
90
91 #[tool(
92 description = "Corporate action stock split records for HK/US securities. Futu API v10.6: OpenQuoteContext.get_corporate_actions_stock_splits."
93 )]
94 async fn futu_get_corporate_actions_stock_splits(
95 &self,
96 Parameters(req): Parameters<ShortInfoReq>,
97 req_ctx: RequestContext<RoleServer>,
98 ) -> std::result::Result<String, String> {
99 req.validate("futu_get_corporate_actions_stock_splits")?;
100 tracing::info!(
101 tool = "futu_get_corporate_actions_stock_splits",
102 symbol = %req.symbol,
103 next_key = ?req.next_key,
104 num = ?req.num
105 );
106 let client = self
107 .read_client_or_err(
108 "futu_get_corporate_actions_stock_splits",
109 &req_ctx,
110 None,
111 None,
112 )
113 .await?;
114 Self::wrap_result(
115 handlers::reference::get_corporate_actions_stock_splits(
116 &client,
117 &req.symbol,
118 req.next_key.as_deref(),
119 req.num,
120 )
121 .await,
122 )
123 }
124
125 #[tool(
126 description = "Short interest for HK/US securities. Futu API v10.6: OpenQuoteContext.get_short_interest."
127 )]
128 async fn futu_get_short_interest(
129 &self,
130 Parameters(req): Parameters<ShortInfoReq>,
131 req_ctx: RequestContext<RoleServer>,
132 ) -> std::result::Result<String, String> {
133 req.validate("futu_get_short_interest")?;
134 tracing::info!(
135 tool = "futu_get_short_interest",
136 symbol = %req.symbol,
137 next_key = ?req.next_key,
138 num = ?req.num
139 );
140 let client = self
141 .read_client_or_err("futu_get_short_interest", &req_ctx, None, None)
142 .await?;
143 Self::wrap_result(
144 handlers::reference::get_short_interest(
145 &client,
146 &req.symbol,
147 req.next_key.as_deref(),
148 req.num,
149 )
150 .await,
151 )
152 }
153
154 #[tool(
155 description = "Top ten net buy/sell brokers for HK securities. Futu API v10.6: OpenQuoteContext.get_top_ten_buy_sell_brokers."
156 )]
157 async fn futu_get_top_ten_buy_sell_brokers(
158 &self,
159 Parameters(req): Parameters<TopTenBuySellBrokersReq>,
160 req_ctx: RequestContext<RoleServer>,
161 ) -> std::result::Result<String, String> {
162 req.validate()?;
163 tracing::info!(
164 tool = "futu_get_top_ten_buy_sell_brokers",
165 symbol = %req.symbol,
166 days_before = ?req.days_before
167 );
168 let client = self
169 .read_client_or_err("futu_get_top_ten_buy_sell_brokers", &req_ctx, None, None)
170 .await?;
171 Self::wrap_result(
172 handlers::reference::get_top_ten_buy_sell_brokers(
173 &client,
174 &req.symbol,
175 req.days_before,
176 )
177 .await,
178 )
179 }
180}