futu_cache/qot_market.rs
1//! v1.4.106 codex 1148 F2 (P2): 公共 `Qot_Common.QotMarket` → symbol suffix
2//! 转换。
3//!
4//! 此前 `crates/futu-gateway-qot/src/handlers/qot/option.rs::qot_market_to_symbol_suffix`
5//! 与 `crates/futu-gateway-core/src/bridge/mkt_id_refresh.rs` 各有一份 inline 表,
6//! 后者跑漂移 (`51 → HK_Future`、`62 → MY`、`72 → CA`、漏 `81 → FX`)。
7//! 现已继续下沉到 `futu-domain-static-data`;本模块保留兼容 wrapper,对齐
8//! proto 枚举:
9//!
10//! 来源: `proto/Qot_Common.proto:8-21`
11//! ```text
12//! QotMarket_Unknown = 0;
13//! QotMarket_HK_Security = 1; // 香港市场
14//! QotMarket_HK_Future = 2; // 港期货 (已废弃, 使用 HK_Security)
15//! QotMarket_US_Security = 11; // 美国市场
16//! QotMarket_CNSH_Security = 21; // 沪股市场
17//! QotMarket_CNSZ_Security = 22; // 深股市场
18//! QotMarket_SG_Security = 31; // 新加坡市场
19//! QotMarket_JP_Security = 41; // 日本市场
20//! QotMarket_AU_Security = 51; // 澳大利亚市场
21//! QotMarket_MY_Security = 61; // 马来西亚市场
22//! QotMarket_CA_Security = 71; // 加拿大市场
23//! QotMarket_FX_Security = 81; // 外汇市场
24//! QotMarket_CC_Security = 91; // 加密货币市场
25//! ```
26//!
27//! 后端 CMD 20106 `SecuritiesReq.symbols` 用 `"CODE.SUFFIX"` 格式 (e.g.
28//! `"AAPL.US"` / `"00700.HK"`)。本 helper 把 FTAPI QotMarket 值转为对应的
29//! 后端 symbol 后缀。
30//!
31//! 注意: 后端真正的"symbol_suffix"是从 `quote_config_svr.proto:82` 下发的
32//! 配置而不是硬编码 (C++ 不在源码内 hardcode 这个表)。daemon 直连 backend
33//! 时不查 quote_config,因此这里维护一份硬编码版作 cache-first 路由。下次
34//! backend 增加新市场时此处需同步更新。
35
36/// FTAPI `Qot_Common.QotMarket` (proto enum 值) → backend symbol suffix
37/// (`"CODE.{SUFFIX}"` 用于 CMD 20106 `SecuritiesReq.symbols`).
38///
39/// 返 `None` 表示 daemon 当前不支持的 market — caller 应**显式** skip /
40/// reject 而非 fallthrough。
41///
42/// **支持的市场**:
43/// - `1` (HK_Security) → `"HK"`
44/// - `2` (HK_Future, 已废弃) → `"HK"` (alias HK_Security, 与 option.rs
45/// 既有行为一致, 因为 backend 把 HK_Future symbol 当 HK 处理)
46/// - `11` (US_Security) → `"US"`
47/// - `21` (CNSH_Security) → `"SH"`
48/// - `22` (CNSZ_Security) → `"SZ"`
49/// - `31` (SG_Security) → `"SG"`
50/// - `41` (JP_Security) → `"JP"`
51/// - `51` (AU_Security) → `"AU"`
52/// - `61` (MY_Security) → `"MY"`
53/// - `71` (CA_Security) → `"CA"`
54/// - `81` (FX_Security) → `"FX"`
55/// - `91` (CC_Security) → `"CC"`
56///
57/// **不支持的市场返 None**: 0 (Unknown) / 任何其他值。
58#[must_use]
59pub fn qot_market_to_symbol_suffix(market: i32) -> Option<&'static str> {
60 futu_domain_static_data::qot_market_to_symbol_suffix(market)
61}
62
63/// Build backend CMD 20106 `SecuritiesReq.symbols` entry from FTAPI market+code.
64///
65/// Ref: moomoo
66/// `Src/FTQuant/Src/FTQuantServer/APIProto_StockInfoReq.cpp:487-550`
67/// `MakeReqSymbol`.
68///
69/// Most securities are `"CODE.SUFFIX"`, but plate/list codes are special:
70/// `LIST*` is converted to `BK*`, and existing `BK*` codes are sent without
71/// suffix. That mirrors C++ instead of treating every user code as a plain
72/// exchange symbol.
73#[must_use]
74pub fn make_cmd20106_symbol(market: i32, code: &str) -> Option<String> {
75 futu_domain_static_data::make_cmd20106_symbol(market, code)
76}
77
78/// Strip the synthetic suffix added by [`make_cmd20106_symbol`] when matching
79/// CMD 20106 response symbols back to cache keys.
80#[must_use]
81pub fn cmd20106_symbol_code(symbol: &str) -> &str {
82 futu_domain_static_data::cmd20106_symbol_code(symbol)
83}
84
85#[cfg(test)]
86mod tests;