futu_mcp/handlers/trade/
helpers.rs1use anyhow::{Result, bail};
5use futu_trd::types::{TrdEnv, TrdHeader, TrdMarket};
6
7pub fn parse_trd_market(s: &str) -> Result<TrdMarket> {
8 let trimmed = s.trim();
15 let upper = trimmed.to_ascii_uppercase();
16 let m = match upper.as_str() {
17 "HK" | "1" => TrdMarket::HK,
18 "US" | "2" => TrdMarket::US,
19 "CN" | "3" => TrdMarket::CN,
20 "HKCC" | "4" => TrdMarket::HKCC,
21 "FUTURES" | "5" => TrdMarket::Futures,
22 "SG" | "6" => TrdMarket::SG,
23 "AU" | "8" => TrdMarket::AU,
24 "JP" | "15" => TrdMarket::JP,
25 "MY" | "111" => TrdMarket::MY,
26 "CA" | "112" => TrdMarket::CA,
27 "HKFUND" | "HK_FUND" | "113" => TrdMarket::HKFund,
28 "USFUND" | "US_FUND" | "123" => TrdMarket::USFund,
29 other => bail!(
30 "unknown trd market {other:?} \
31 (HK|US|CN|HKCC|FUTURES|SG|AU|JP|MY|CA|HKFUND|USFUND \
32 or int 1/2/3/4/5/6/8/15/111/112/113/123 per Trd_Common.proto)"
33 ),
34 };
35 Ok(m)
36}
37
38pub fn parse_trd_env(s: &str) -> Result<TrdEnv> {
39 let e = match s.trim().to_ascii_lowercase().as_str() {
40 "simulate" | "sim" => TrdEnv::Simulate,
41 "real" => TrdEnv::Real,
42 other => bail!("unknown trd env {other:?} (real|simulate)"),
43 };
44 Ok(e)
45}
46
47pub fn parse_trd_env_int(s: &str) -> Result<i32> {
52 Ok(parse_trd_env(s)? as i32)
53}
54
55pub fn parse_trd_market_strict_no_fund(s: &str) -> Result<TrdMarket> {
60 let m = parse_trd_market(s)?;
61 match m {
62 TrdMarket::HKFund | TrdMarket::USFund => bail!(
63 "trd market HKFUND/USFUND (113/123) 仅 view-only read endpoints \
64 (positions/funds/cash-log/history-orders/history-fills) 真机 verified; \
65 active/calculation path (orders/deals/max_trd_qtys/margin_ratio/order_fee) \
66 用主市场. v1.4.102 codex 33 F5 / 34 F4 / 35 F4 fix."
67 ),
68 _ => Ok(m),
69 }
70}
71
72pub fn build_header_strict_no_fund(env: &str, acc_id: u64, market: &str) -> Result<TrdHeader> {
76 Ok(TrdHeader {
77 trd_env: parse_trd_env(env)?,
78 acc_id,
79 trd_market: parse_trd_market_strict_no_fund(market)?,
80 jp_acc_type: None,
81 })
82}
83
84pub fn build_header(env: &str, acc_id: u64, market: &str) -> Result<TrdHeader> {
85 Ok(TrdHeader {
86 trd_env: parse_trd_env(env)?,
87 acc_id,
88 trd_market: parse_trd_market(market)?,
89 jp_acc_type: None,
90 })
91}