1#![allow(unused_imports)]
4
5use rmcp::schemars;
6use serde::{Deserialize, Serialize};
7
8use crate::tool_enums;
9use crate::tool_enums::ToolEnum;
10
11use super::*;
12
13#[derive(Debug, Deserialize, schemars::JsonSchema)]
14#[serde(deny_unknown_fields)]
15pub struct SymbolReq {
16 #[schemars(
17 description = "Security symbol in MARKET.CODE format, e.g. HK.00700, US.AAPL \
18 (alias: code / stock / security for SDK compat)"
19 )]
20 #[serde(alias = "code", alias = "stock", alias = "security")]
24 pub symbol: String,
25}
26
27#[derive(Debug, Deserialize, schemars::JsonSchema)]
28#[serde(deny_unknown_fields)]
29pub struct SymbolListReq {
30 #[schemars(description = "Array of security symbols in MARKET.CODE format \
31 (e.g. [\"HK.00700\", \"US.AAPL\"]). Field name is \
32 `symbols` (Rust native snake_case); aliases: `stocks` \
33 / `code_list` / `symbol_list` / `security_list` \
34 for SDK compat.")]
35 #[serde(
38 alias = "stocks",
39 alias = "code_list",
40 alias = "symbol_list",
41 alias = "security_list"
42 )]
43 pub symbols: Vec<String>,
44}
45
46#[derive(Debug, Deserialize, schemars::JsonSchema)]
47#[serde(deny_unknown_fields)]
48pub struct KLineReq {
49 #[schemars(description = "Security symbol (MARKET.CODE); alias: code / stock")]
50 #[serde(alias = "code", alias = "stock")]
52 pub symbol: String,
53 #[schemars(
54 description = "K-line type: day|week|month|quarter|year|1min|3min|5min|15min|30min|60min \
55 (alias: ktype / k_type / kl_type for SDK compat)"
56 )]
57 #[serde(default = "default_kl_type", alias = "ktype", alias = "k_type")]
58 pub kl_type: String,
59 #[schemars(
60 description = "Number of candles to return (default 100); alias: num / max_count / req_count"
61 )]
62 #[serde(alias = "num", alias = "max_count", alias = "req_count")]
63 pub count: Option<i32>,
64 #[schemars(
65 description = "Start date yyyy-MM-dd (optional; default computed from count); alias: begin_time / from"
66 )]
67 #[serde(alias = "begin_time", alias = "from")]
68 pub begin: Option<String>,
69 #[schemars(
70 description = "End date yyyy-MM-dd (optional; default today); alias: end_time / to"
71 )]
72 #[serde(alias = "end_time", alias = "to")]
73 pub end: Option<String>,
74}
75
76#[derive(Debug, Deserialize, schemars::JsonSchema)]
77#[serde(deny_unknown_fields)]
78pub struct OrderBookReq {
79 #[schemars(description = "Security symbol (MARKET.CODE); alias: code / stock / security")]
80 #[serde(alias = "code", alias = "stock", alias = "security")]
82 pub symbol: String,
83 #[schemars(description = "Order book depth, 1-10 (default 10); alias: num")]
84 #[serde(default = "default_depth", alias = "num")]
85 pub depth: i32,
86}
87
88#[derive(Debug, Deserialize, schemars::JsonSchema)]
89#[serde(deny_unknown_fields)]
90pub struct TickerReq {
91 #[schemars(description = "Security symbol (MARKET.CODE); alias: code / stock / security")]
92 #[serde(alias = "code", alias = "stock", alias = "security")]
94 pub symbol: String,
95 #[schemars(
96 description = "Number of ticks to fetch (default 100, max 1000); alias: num / max_count / req_count"
97 )]
98 #[serde(
99 default = "default_ticker_count",
100 alias = "num",
101 alias = "max_count",
102 alias = "req_count"
103 )]
104 pub count: i32,
105}
106
107#[derive(Debug, Deserialize, schemars::JsonSchema)]
108#[serde(deny_unknown_fields)]
109pub struct PlateListReq {
110 #[schemars(description = "Market: HK|HK_FUTURE|US|SH|SZ")]
111 pub market: String,
112 #[schemars(
113 description = "Plate set: all|industry|region|concept (default all); alias: plate_set_type"
114 )]
115 #[serde(default = "default_plate_set", alias = "plate_set_type")]
117 pub plate_set: String,
118}
119
120#[derive(Debug, Deserialize, schemars::JsonSchema)]
121#[serde(deny_unknown_fields)]
122pub struct PlateStocksReq {
123 #[schemars(
124 description = "Plate symbol, MARKET.CODE format (e.g. HK.LIST1001); alias: symbol / code / plate_code"
125 )]
126 #[serde(alias = "symbol", alias = "code", alias = "plate_code")]
128 pub plate: String,
129}
130
131#[derive(Debug, Deserialize, schemars::JsonSchema)]
132#[serde(deny_unknown_fields)]
133pub struct MarketStateReq {
134 #[schemars(
135 description = "Symbols list in MARKET.CODE format; alias: stocks / code_list / symbol_list / security_list"
136 )]
137 #[serde(
139 alias = "stocks",
140 alias = "code_list",
141 alias = "symbol_list",
142 alias = "security_list"
143 )]
144 pub symbols: Vec<String>,
145}
146
147#[derive(Debug, Deserialize, schemars::JsonSchema)]
148#[serde(deny_unknown_fields)]
149pub struct HistoryKLineReq {
150 #[schemars(description = "Security symbol (MARKET.CODE); alias: code / stock")]
151 #[serde(alias = "code", alias = "stock")]
153 pub symbol: String,
154 #[schemars(
155 description = "K-line type: day|week|month|quarter|year|1min|3min|5min|15min|30min|60min \
156 (default day); alias: ktype / k_type"
157 )]
158 #[serde(default = "default_kl_type", alias = "ktype", alias = "k_type")]
159 pub kl_type: String,
160 #[schemars(description = "Rehab type: none|forward|backward (default none)")]
161 #[serde(default = "default_rehab_none")]
162 pub rehab_type: String,
163 #[schemars(description = "Start date yyyy-MM-dd; alias: begin_time / start_time / from")]
164 #[serde(alias = "begin_time", alias = "start_time", alias = "from")]
165 pub begin: String,
166 #[schemars(description = "End date yyyy-MM-dd; alias: end_time / to")]
167 #[serde(alias = "end_time", alias = "to")]
168 pub end: String,
169 #[schemars(
170 description = "Max number of candles to return (default 1000, range 1-1000). \
171 If omitted, the gateway uses 1000; pass explicit 0 to request no limit \
172 only when you can handle a large response. alias: num / count / req_count"
173 )]
174 #[serde(
178 default = "default_history_kline_max_count",
179 alias = "num",
180 alias = "count",
181 alias = "req_count"
182 )]
183 pub max_count: Option<i32>,
184}
185
186#[derive(Debug, Deserialize, schemars::JsonSchema)]
187#[serde(deny_unknown_fields)]
188pub struct ReferenceReq {
189 #[schemars(description = "Underlying symbol (e.g. HK.00700, US.AAPL); alias: code / stock")]
190 #[serde(alias = "code", alias = "stock")]
192 pub symbol: String,
193 #[schemars(
198 description = "Reference type: warrant|future (default warrant). Note: option is NOT supported — use futu_get_option_chain instead."
199 )]
200 #[serde(default = "default_reference_type")]
201 pub reference_type: String,
202}
203
204#[derive(Debug, Deserialize, schemars::JsonSchema)]
205#[serde(deny_unknown_fields)]
206pub struct OptionChainReq {
207 #[schemars(
208 description = "Underlying stock symbol (e.g. HK.00700, US.AAPL); alias: symbol / owner / code / stock"
209 )]
210 #[serde(alias = "symbol", alias = "owner", alias = "code", alias = "stock")]
212 pub owner_symbol: String,
213 #[schemars(
214 description = "Expiry range begin date yyyy-MM-dd; alias: begin / start_time / from"
215 )]
216 #[serde(alias = "begin", alias = "start_time", alias = "from")]
217 pub begin_time: String,
218 #[schemars(description = "Expiry range end date yyyy-MM-dd; alias: end / to")]
219 #[serde(alias = "end", alias = "to")]
220 pub end_time: String,
221 #[schemars(description = "Option type: all|call|put (default all)")]
222 pub option_type: Option<String>,
223
224 #[schemars(
227 description = "Optional Greek filter: only return options with delta in [min, max]. Typical ATM range: 0.3 to 0.7 for calls, -0.7 to -0.3 for puts."
228 )]
229 pub delta_min: Option<f64>,
230 #[schemars(description = "See delta_min.")]
231 pub delta_max: Option<f64>,
232 #[schemars(description = "Implied volatility filter min (decimal, e.g. 0.3 = 30%).")]
233 pub iv_min: Option<f64>,
234 #[schemars(description = "See iv_min.")]
235 pub iv_max: Option<f64>,
236 #[schemars(description = "Open interest (contracts) filter min, integer.")]
237 pub oi_min: Option<f64>,
238 #[schemars(description = "See oi_min.")]
239 pub oi_max: Option<f64>,
240 #[schemars(description = "Gamma filter min (decimal).")]
241 pub gamma_min: Option<f64>,
242 #[schemars(description = "See gamma_min.")]
243 pub gamma_max: Option<f64>,
244 #[schemars(description = "Vega filter min (decimal).")]
245 pub vega_min: Option<f64>,
246 #[schemars(description = "See vega_min.")]
247 pub vega_max: Option<f64>,
248 #[schemars(description = "Theta filter min (decimal).")]
249 pub theta_min: Option<f64>,
250 #[schemars(description = "See theta_min.")]
251 pub theta_max: Option<f64>,
252}
253
254#[derive(Debug, Deserialize, schemars::JsonSchema)]
255#[serde(deny_unknown_fields)]
256pub struct WarrantReq {
257 #[schemars(
258 description = "Underlying stock symbol (e.g. HK.00700); None = whole-market warrants. Alias: symbol / owner / code"
259 )]
260 #[serde(default, alias = "symbol", alias = "owner", alias = "code")]
262 pub owner_symbol: Option<String>,
263 #[schemars(description = "Pagination begin index (default 0); alias: offset / skip")]
267 #[serde(default, alias = "offset", alias = "skip")]
268 pub begin: i32,
269 #[schemars(description = "Max rows (1-200, default 20); alias: count / max_count / req_count")]
270 #[serde(
271 default = "default_warrant_num",
272 alias = "count",
273 alias = "max_count",
274 alias = "req_count"
275 )]
276 pub num: i32,
277}
278
279#[derive(Debug, Deserialize, schemars::JsonSchema)]
280#[serde(deny_unknown_fields)]
281pub struct IpoListReq {
282 #[schemars(
283 description = "Market code — **Qot_Common.QotMarket enum**. Accept int (1=HK, 11=US, 21=SH, 22=SZ) \
284 OR string (\"HK\" / \"US\" / \"SH\" / \"SZ\" / ...). v1.4.84 §5 B2 双接."
285 )]
286 #[serde(deserialize_with = "tool_enums::deser_market_as_i32")]
288 pub market: i32,
289}
290
291#[derive(Debug, Deserialize, schemars::JsonSchema)]
292#[serde(deny_unknown_fields)]
293pub struct FutureInfoReq {
294 #[schemars(
295 description = "Array of future contract symbols in MARKET.CODE format \
296 (e.g. [\"HK.HSImain\", \"US.MNQmain\"]). Alias: stocks / \
297 code_list / symbol_list / security_list"
298 )]
299 #[serde(
301 alias = "stocks",
302 alias = "code_list",
303 alias = "symbol_list",
304 alias = "security_list"
305 )]
306 pub symbols: Vec<String>,
307}
308
309#[derive(Debug, Deserialize, schemars::JsonSchema)]
310#[serde(deny_unknown_fields)]
311pub struct UserSecurityGroupReq {
312 #[schemars(description = "Group type: 1=all, 2=custom, 3=system (default 1)")]
313 #[serde(default = "default_user_security_group_type")]
314 pub group_type: i32,
315}
316
317#[derive(Debug, Deserialize, schemars::JsonSchema)]
318#[serde(deny_unknown_fields)]
319pub struct StockFilterReq {
320 #[schemars(
321 description = "Market code — **Qot_Common.QotMarket enum**. Accept int (1=HK, 11=US, 21=SH, 22=SZ) \
322 OR string (\"HK\" / \"US\" / ...). v1.4.84 §5 B2 双接."
323 )]
324 #[serde(deserialize_with = "tool_enums::deser_market_as_i32")]
326 pub market: i32,
327 #[schemars(description = "Pagination begin index (default 0); alias: offset / skip")]
328 #[serde(default, alias = "offset", alias = "skip")]
330 pub begin: i32,
331 #[schemars(description = "Max rows (1-200, default 50); alias: count / max_count / req_count")]
332 #[serde(
333 default = "default_stock_filter_num",
334 alias = "count",
335 alias = "max_count",
336 alias = "req_count"
337 )]
338 pub num: i32,
339}
340
341#[derive(Debug, Deserialize, schemars::JsonSchema)]
342#[serde(deny_unknown_fields)]
343pub struct TradingDaysReq {
344 #[schemars(
345 description = "Market code — **Qot_Common.TradeDateMarket enum** (i32, NOT QotMarket!): \
346 1=HK, 2=US, 3=CN, 4=NorthboundSZ/SH, 5=SouthboundHK, 6=JP_Future, 7=SG_Future. \
347 Different from QotMarket (ipo_list/stock_filter use 1=HK 11=US 21=SH 22=SZ). \
348 v1.4.30 P3 documented inconsistency."
349 )]
350 pub market: i32,
351 #[schemars(description = "Begin date (yyyy-MM-dd); alias: begin / start_time / from")]
352 #[serde(alias = "begin", alias = "start_time", alias = "from")]
354 pub begin_time: String,
355 #[schemars(description = "End date (yyyy-MM-dd); alias: end / to")]
356 #[serde(alias = "end", alias = "to")]
357 pub end_time: String,
358}
359
360#[derive(Debug, Deserialize, schemars::JsonSchema)]
361#[serde(deny_unknown_fields)]
362pub struct SuspendReq {
363 #[schemars(description = "Array of security symbols in MARKET.CODE format \
364 (e.g. [\"HK.00700\", \"HK.09988\"]). Alias: stocks / code_list / symbol_list / security_list")]
365 #[serde(
367 alias = "stocks",
368 alias = "code_list",
369 alias = "symbol_list",
370 alias = "security_list"
371 )]
372 pub symbols: Vec<String>,
373 #[schemars(description = "Begin date (yyyy-MM-dd); alias: begin / start_time / from")]
374 #[serde(alias = "begin", alias = "start_time", alias = "from")]
375 pub begin_time: String,
376 #[schemars(description = "End date (yyyy-MM-dd); alias: end / to")]
377 #[serde(alias = "end", alias = "to")]
378 pub end_time: String,
379}
380
381#[derive(Debug, Deserialize, schemars::JsonSchema)]
382#[serde(deny_unknown_fields)]
383pub struct UserSecurityReq {
384 #[schemars(
385 description = "Watchlist group name (use futu_get_user_security_group to list groups); alias: group / name"
386 )]
387 #[serde(alias = "group", alias = "name")]
389 pub group_name: String,
390}
391
392#[derive(Debug, Deserialize, schemars::JsonSchema)]
393#[serde(deny_unknown_fields)]
394pub struct HistoryKlQuotaReq {
395 #[schemars(
396 description = "Whether to fetch detailed per-symbol download history (default false)"
397 )]
398 #[serde(default)]
399 pub get_detail: bool,
400}
401
402#[derive(Debug, Deserialize, schemars::JsonSchema)]
403#[serde(deny_unknown_fields)]
404pub struct HoldingChangeReq {
405 #[schemars(
406 description = "Underlying stock symbol (e.g. HK.00700, US.AAPL); alias: code / stock"
407 )]
408 #[serde(alias = "code", alias = "stock")]
410 pub symbol: String,
411 #[schemars(
412 description = "Holder category: 1=Institution, 2=Fund, 3=Executive; alias: category"
413 )]
414 #[serde(alias = "category")]
415 pub holder_category: i32,
416 #[schemars(
417 description = "Begin time YYYY-MM-DD HH:MM:SS (optional); alias: begin / start_time / from"
418 )]
419 #[serde(default, alias = "begin", alias = "start_time", alias = "from")]
420 pub begin_time: Option<String>,
421 #[schemars(description = "End time YYYY-MM-DD HH:MM:SS (optional); alias: end / to")]
422 #[serde(default, alias = "end", alias = "to")]
423 pub end_time: Option<String>,
424}
425
426#[derive(Debug, Deserialize, schemars::JsonSchema)]
427#[serde(deny_unknown_fields)]
428pub struct ModifyUserSecurityReq {
429 #[schemars(description = "Watchlist group name; alias: group / name")]
430 #[serde(alias = "group", alias = "name")]
432 pub group_name: String,
433 #[schemars(
434 description = "Op: 1=AddInto, 2=Delete (from this group), 3=MoveOut; alias: op_type / operation"
435 )]
436 #[serde(alias = "op_type", alias = "operation")]
437 pub op: i32,
438 #[schemars(
439 description = "Security symbols to add/delete/move; alias: stocks / code_list / symbol_list / security_list"
440 )]
441 #[serde(
442 alias = "stocks",
443 alias = "code_list",
444 alias = "symbol_list",
445 alias = "security_list"
446 )]
447 pub symbols: Vec<String>,
448}
449
450#[derive(Debug, Deserialize, schemars::JsonSchema)]
451#[serde(deny_unknown_fields)]
452pub struct CodeChangeReq {
453 #[schemars(
454 description = "Security symbols to query (currently HK only); alias: stocks / code_list / symbol_list / security_list"
455 )]
456 #[serde(
458 alias = "stocks",
459 alias = "code_list",
460 alias = "symbol_list",
461 alias = "security_list"
462 )]
463 pub symbols: Vec<String>,
464}
465
466#[derive(Debug, Deserialize, schemars::JsonSchema)]
467#[serde(deny_unknown_fields)]
468pub struct SetPriceReminderReq {
469 #[schemars(description = "Security symbol (e.g. \"HK.00700\"). Field aliases: \
470 `code` / `stock` (deprecated — prefer canonical `symbol`).")]
471 #[serde(alias = "code", alias = "stock")]
472 pub symbol: String,
473 #[schemars(
474 description = "Op: 1=Add / SetAdd, 2=Del / SetDel, 3=Enable / SetEnable, \
475 4=Disable / SetDisable, 5=Modify, 6=DeleteAll / DelAll. \
476 Accepts integer code OR string form (e.g. 1 or \"Add\"). \
477 Aliases for the field name: `op_type` / `operation` \
478 (deprecated — prefer canonical `op`)."
479 )]
480 #[serde(
481 alias = "op_type",
482 alias = "operation",
483 deserialize_with = "tool_enums::deser_price_reminder_op_as_i32"
484 )]
485 pub op: i32,
486 #[schemars(
487 description = "Reminder key (from get_price_reminder; required for modify/del/enable/disable)"
488 )]
489 #[serde(default)]
490 pub key: Option<i64>,
491 #[schemars(description = "Qot_Common::PriceReminderType: \
492 1=PriceUp, 2=PriceDown, 3=ChangeRateUp, 4=ChangeRateDown, \
493 5=5MinChangeRateUp, 6=5MinChangeRateDown, 7=VolumeUp, 8=TurnoverUp, \
494 9=TurnoverRateUp, 10=BidPriceUp, 11=AskPriceDown, 12=BidVolUp, \
495 13=AskVolUp, 14=3MinChangeRateUp, 15=3MinChangeRateDown.")]
496 #[serde(default)]
497 pub reminder_type: Option<i32>,
498 #[schemars(
499 description = "Qot_Common::PriceReminderFreq: 1=Always, 2=OncePerDay, 3=Once. \
500 Required for op=1 (Add) — the gateway rejects Add without freq. \
501 Optional for op=5 (Modify) / 2/3/4 (Del/Enable/Disable) where the \
502 backend preserves the existing value when omitted."
503 )]
504 #[serde(default)]
505 pub freq: Option<i32>,
506 #[schemars(description = "Threshold value (required for Add/Modify)")]
507 #[serde(default)]
508 pub value: Option<f64>,
509 #[schemars(
510 description = "User note (optional). Maximum length: 40 half-width bytes \
511 (~20 CN characters or 40 ASCII characters) using UTF-16 \
512 half-/full-width counting (each ASCII code unit = 1 byte, \
513 each non-ASCII code unit = 2 bytes)."
514 )]
515 #[serde(default)]
516 pub note: Option<String>,
517 #[schemars(
523 description = "Reminder session list (PriceReminderMarketStatus: 1=Open, 2=USPre, \
524 3=USAfter, 4=USOverNight). For US stocks, an empty list defaults to \
525 [Open, USPre, USAfter]; for non-US securities the list is cleared."
526 )]
527 #[serde(default)]
528 pub reminder_session_list: Vec<i32>,
529}
530
531impl SetPriceReminderReq {
532 pub fn validate(&self) -> Result<(), String> {
544 match self.op {
545 1 => {
546 if self.reminder_type.is_none() {
547 return Err(
548 "SetPriceReminderReq op=1 (Add): `reminder_type` is required \
549 (PriceReminderType enum 1-15)"
550 .to_string(),
551 );
552 }
553 if self.freq.is_none() {
559 return Err("SetPriceReminderReq op=1 (Add): `freq` is required \
560 (PriceReminderFreq enum 1=Always / 2=OncePerDay / 3=Once)"
561 .to_string());
562 }
563 if self.value.is_none() {
564 return Err(
565 "SetPriceReminderReq op=1 (Add): `value` is required (threshold \
566 value for reminder_type)"
567 .to_string(),
568 );
569 }
570 }
571 2..=4 => {
572 if self.key.is_none() {
573 return Err(format!(
574 "SetPriceReminderReq op={} ({}): `key` is required (from \
575 get_price_reminder response)",
576 self.op,
577 match self.op {
578 2 => "Del",
579 3 => "Enable",
580 _ => "Disable",
581 }
582 ));
583 }
584 }
585 5 => {
586 if self.key.is_none() {
587 return Err(
588 "SetPriceReminderReq op=5 (Modify): `key` is required (from \
589 get_price_reminder response)"
590 .to_string(),
591 );
592 }
593 }
594 6 => {} _ => {
596 return Err(format!(
597 "SetPriceReminderReq: unknown op={}, expected 1=Add|2=Del|3=Enable|\
598 4=Disable|5=Modify|6=DeleteAll",
599 self.op
600 ));
601 }
602 }
603 for &session in &self.reminder_session_list {
608 if !matches!(session, 1..=4) {
609 return Err(format!(
610 "SetPriceReminderReq: invalid reminder_session_list entry \
611 {session} (PriceReminderMarketStatus 1=Open / 2=USPre / \
612 3=USAfter / 4=USOverNight)"
613 ));
614 }
615 }
616 Ok(())
617 }
618}
619
620#[derive(Debug, Deserialize, schemars::JsonSchema)]
621#[serde(deny_unknown_fields)]
622pub struct GetPriceReminderReq {
623 #[schemars(description = "Security symbol (MARKET.CODE, e.g. HK.00700). \
624 **Exactly one of `symbol` or `market` must be set.** \
625 Passing both: symbol wins. Passing neither returns an error. \
626 v1.4.30 P3: schema-level oneOf not enforceable via serde; runtime check in handler. \
627 Alias: code / stock")]
628 #[serde(default, alias = "code", alias = "stock")]
630 pub symbol: Option<String>,
631 #[schemars(
632 description = "Market code — **Qot_Common.QotMarket enum**. Accept int (1=HK, 11=US, 21=CN) \
633 OR string (\"HK\" / \"US\" / \"CN\"). \
634 **Exactly one of `symbol` or `market` required** (see symbol field doc). \
635 v1.4.84 §5 B2 双接."
636 )]
637 #[serde(default, deserialize_with = "tool_enums::deser_market_as_option_i32")]
639 pub market: Option<i32>,
640}
641
642impl GetPriceReminderReq {
643 pub fn validate(&self) -> Result<(), String> {
648 if self.symbol.is_none() && self.market.is_none() {
649 return Err(
650 "GetPriceReminderReq: exactly one of `symbol` or `market` is required \
651 (neither provided)"
652 .to_string(),
653 );
654 }
655 Ok(())
657 }
658}
659
660#[derive(Debug, Deserialize, schemars::JsonSchema)]
661#[serde(deny_unknown_fields)]
662pub struct OptionExpirationDateReq {
663 #[schemars(
664 description = "Underlying stock symbol (HK/US equities + HSI/HSCEI only); alias: symbol / owner / code / stock"
665 )]
666 #[serde(alias = "symbol", alias = "owner", alias = "code", alias = "stock")]
668 pub owner_symbol: String,
669 #[schemars(description = "For index options only: Qot_Common::IndexOptionType (optional)")]
670 #[serde(default)]
671 pub index_option_type: Option<i32>,
672}
673
674#[derive(Debug, Deserialize, schemars::JsonSchema)]
675#[serde(deny_unknown_fields)]
676pub struct BizGroupReq {
677 #[schemars(description = "Trade env: real / simulate (default real)")]
678 #[serde(default = "default_env", alias = "trd_env")]
679 pub env: String,
680 #[schemars(description = "Trading account ID (u64)")]
681 pub acc_id: u64,
682 #[schemars(
683 description = "Optional legacy market hint; accepted for backward compatibility but ignored. Daemon derives backend market from acc_id/account cache."
684 )]
685 #[serde(
686 default,
687 deserialize_with = "tool_enums::deser_trd_market_as_option_string"
688 )]
689 pub market: Option<String>,
690}
691
692#[derive(Debug, Deserialize, schemars::JsonSchema)]
693#[serde(deny_unknown_fields)]
694pub struct BondSymbolReq {
695 #[schemars(description = "Trade env: real / simulate (default real)")]
696 #[serde(default = "default_env", alias = "trd_env")]
697 pub env: String,
698 #[schemars(description = "Trading account ID (u64) for per-broker routing")]
699 pub acc_id: u64,
700 #[schemars(description = "Market: HK / US / SG (仅 3 市场有债券业务)")]
701 pub market: String,
702 #[schemars(description = "Bond symbol (债券代码, 如 HK1234 或 11000018)")]
703 pub symbol: String,
704}
705
706#[derive(Debug, Deserialize, schemars::JsonSchema)]
708#[serde(deny_unknown_fields)]
709pub struct TickerStatisticReq {
710 #[schemars(description = "Security symbol in MARKET.CODE format, e.g. HK.00700, US.AAPL")]
711 #[serde(alias = "code", alias = "stock", alias = "security")]
712 pub symbol: String,
713 #[schemars(
714 description = "Ticker type filter: 0=ALL, 1=BUY, 2=SELL, 3=BUY_AND_SELL, 4=NEUTRAL (default ALL)"
715 )]
716 #[serde(default)]
717 pub ticker_type: Option<i32>,
718 #[schemars(description = "Market session: 0=ALL, 1=BEFORE, 2=TRADING, 3=AFTER (default ALL)")]
719 #[serde(default)]
720 pub stat_type: Option<u32>,
721}
722
723#[derive(Debug, Deserialize, schemars::JsonSchema)]
728#[serde(deny_unknown_fields)]
729pub struct TickerStatisticDetailReq {
730 #[schemars(description = "Security symbol in MARKET.CODE format, e.g. HK.00700, US.AAPL")]
731 #[serde(alias = "code", alias = "stock", alias = "security")]
732 pub symbol: String,
733 #[schemars(
734 description = "Ticker type filter: 0=ALL, 1=BUY, 2=SELL, 3=BUY_AND_SELL, 4=NEUTRAL (default ALL)"
735 )]
736 #[serde(default)]
737 pub ticker_type: Option<i32>,
738 #[schemars(
739 description = "Ticker timestamp (ms) — usually from prior futu_get_ticker_statistic call. \
740 0 / omit = use backend latest available."
741 )]
742 #[serde(default)]
743 pub ticker_time: Option<u64>,
744 #[schemars(
745 description = "Filter type: 0=all price levels, 1..N=top N levels (backend max ~100)"
746 )]
747 #[serde(default)]
748 pub select_num: Option<u32>,
749 #[schemars(description = "Pagination start offset (default 0)")]
750 #[serde(default)]
751 pub data_from: Option<u32>,
752 #[schemars(description = "Pagination size, max items returned (default 20)")]
753 #[serde(default)]
754 pub data_max_count: Option<u32>,
755 #[schemars(description = "Market session: 0=ALL, 1=BEFORE, 2=TRADING, 3=AFTER (default ALL)")]
756 #[serde(default)]
757 pub stat_type: Option<u32>,
758}
759
760#[derive(Debug, Deserialize, schemars::JsonSchema)]
761#[serde(deny_unknown_fields)]
762pub struct QuoteRightsReq {
763 #[schemars(description = "If true, trigger request_highest_quote_right before querying")]
764 #[serde(default)]
765 pub refresh: Option<bool>,
766}