Skip to main content

futucli/cli/
commands.rs

1//! clap subcommand enum definitions.
2//!
3//! Kept separate from `cli.rs` so the root CLI module only owns global flags
4//! and re-exports the command type used by dispatch / REPL.
5
6use std::path::PathBuf;
7
8use clap::Subcommand;
9
10mod key;
11mod qot;
12mod tier_m;
13mod trade_read;
14mod trade_write;
15
16pub use key::GenKeyArgs;
17pub use qot::{
18    BrokerArgs, KlineArgs, OrderbookArgs, PlateListArgs, PlateStocksArgs, QuoteArgs, RtArgs,
19    SnapshotArgs, StaticArgs, SubArgs, TickerArgs,
20};
21pub use tier_m::{
22    AccountFlagArgs, BizGroupArgs, BondAnswerStateArgs, BondPositionListArgs, BondSingleAssetArgs,
23    BondTotalAssetArgs, BondTradeReminderArgs, CashDetailArgs, CashLogArgs, MarginInfoArgs,
24};
25pub use trade_read::{
26    AccCashFlowArgs, DealArgs, FundsArgs, HistoryDealsArgs, HistoryOrdersArgs, MarginRatioArgs,
27    MaxQtysArgs, OrderArgs, OrderFeeArgs, PositionArgs,
28};
29pub use trade_write::{CancelOrderArgs, ModifyOrderArgs, PlaceOrderArgs, ReconfirmOrderArgs};
30
31#[derive(Subcommand)]
32pub enum Command {
33    /// 探活:连接网关并测一次 RTT
34    Ping,
35
36    /// 获取基础实时报价(CLI 自动订阅 SubType::Basic)
37    Quote(QuoteArgs),
38
39    /// 获取股票快照(单次,无需订阅)
40    Snapshot(SnapshotArgs),
41
42    /// 订阅行情推送并持续打印(Ctrl-C 停止)
43    ///
44    /// v1.4.83 §10 新增 aliases: `subscribe` / `subscription`
45    #[command(visible_aliases = ["subscribe", "subscription"])]
46    Sub(SubArgs),
47
48    /// 获取历史 K 线
49    ///
50    /// v1.4.83 §10: `--symbol` / `--code` / `--stock` flag alias 替代 positional
51    Kline(KlineArgs),
52
53    /// 获取摆盘
54    ///
55    /// v1.4.83 §10: `--symbol` / `--code` / `--stock` flag alias 替代 positional
56    Orderbook(OrderbookArgs),
57
58    /// 获取逐笔成交
59    ///
60    /// v1.4.83 §10: `--symbol` / `--code` / `--stock` flag alias
61    Ticker(TickerArgs),
62
63    /// 获取分时数据
64    ///
65    /// v1.4.83 §10: `--symbol` / `--code` / `--stock` flag alias
66    Rt(RtArgs),
67
68    /// 获取静态信息(名称、每手数量、类型、上市时间等)
69    Static(StaticArgs),
70
71    /// 获取经纪队列
72    ///
73    /// v1.4.83 §10: `--symbol` / `--code` / `--stock` flag alias
74    Broker(BrokerArgs),
75
76    /// 列出板块集合
77    PlateList(PlateListArgs),
78
79    /// 列出板块内股票
80    PlateStocks(PlateStocksArgs),
81
82    /// 列出交易账户(默认显示 App 可见账户集合)
83    #[command(visible_alias = "accounts")]
84    Account {
85        /// 过滤交易市场:HK | US | CN | ... | all。不传时在 App 可见集合内不过滤。
86        #[arg(long)]
87        market: Option<String>,
88
89        /// 过滤券商:FutuHK | FutuInc/FutuUS | hk | us | 1..7 | all。不传时在 App 可见集合内不过滤。
90        #[arg(long, visible_alias = "firm")]
91        security_firm: Option<String>,
92
93        /// 排障模式:显示 daemon raw discovery 全集,包括 App 不单独展示的内部账户行。
94        #[arg(long)]
95        all: bool,
96    },
97
98    /// 查询账户资金
99    Funds(FundsArgs),
100
101    /// 查询持仓
102    Position(PositionArgs),
103
104    /// 查询当日订单
105    Order(OrderArgs),
106
107    /// 查询当日成交
108    Deal(DealArgs),
109
110    /// 解锁 / 锁定交易(gateway 进程级,重启失效)
111    ///
112    /// 密码来源优先级:--from-stdin > FUTU_TRADE_PWD 环境变量 > 交互式 prompt(无回显)。
113    /// 解锁成功后所有连同一网关的客户端(futucli / futu-mcp / Python)都可下单。
114    UnlockTrade {
115        /// 锁回交易(清除 gateway 侧 cipher 缓存)
116        #[arg(long)]
117        lock: bool,
118
119        /// 从 stdin 读一行作为密码(脚本管道友好,覆盖环境变量 / tty prompt)
120        #[arg(long)]
121        from_stdin: bool,
122
123        /// OTP / 令牌动态密码明文(v1.4.31+,2FA 用户必填)
124        ///
125        /// 若账号开启了"令牌动态密码"二次验证:首次 unlock 会收到 daemon 提示
126        /// `需要令牌动态密码`,再次调用带此参数即可。无 2FA 账号留空。
127        #[arg(long)]
128        otp: Option<String>,
129
130        /// 只解锁该券商下的账户。不传则解锁所有 broker(默认,向后兼容)。
131        /// 对齐 C++ OpenD 的 per-broker unlock 语义。
132        ///
133        /// 接受 3 种形式(v1.4.34 验证数字和别名确实能跑;clap 默认报错
134        /// 消息只列官方名,用 `--help` 看详细用法):官方名、1-7 数字、短别名。
135        #[arg(
136            long,
137            value_enum,
138            value_name = "FIRM",
139            long_help = "\
140只解锁该券商下的账户。不传则解锁所有 broker(默认,向后兼容)。
141
142接受 3 种形式(等价):
143  1. 官方名:FutuHK FutuUS FutuSG FutuAU FutuCA FutuMY FutuJP
144  2. 数字:   1       2      3      4      5      6      7
145            (HK)   (US)    (SG)   (AU)   (CA)   (MY)   (JP)
146  3. 短别名:hk / us / sg / au / ca / my / jp
147            (moomoo 账号 = us;其他别名 futu-hk / futu-us / mm 等)
148
149示例:
150  --security-firm 1
151  --security-firm hk
152  --security-firm FutuHK
153  --security-firm moomoo    # 等价 --security-firm us"
154        )]
155        security_firm: Option<crate::cmd::unlock::SecurityFirmArg>,
156
157        /// v1.4.34+ 只解锁指定 acc_id 列表(逗号分隔)。和 `--security-firm`
158        /// 同时传时取**交集**。解决同 broker 内影子账户拖垮主账户的场景——
159        /// 显式传主账户 acc_id,影子账户不进请求。
160        #[arg(long, value_delimiter = ',', value_name = "ACC_ID[,ACC_ID]...")]
161        acc_ids: Vec<u64>,
162    },
163
164    /// 把交易密码存到 OS keychain(v1.4+)
165    ///
166    /// 存完后 futu-mcp 的 `futu_unlock_trade` 工具可以在 LLM 需要下单时自动
167    /// 解锁,而不暴露明文密码给 LLM。默认以交互式 tty prompt 读入(无回显),
168    /// 自动化脚本可用 `--from-stdin` 从 stdin 读一行。
169    ///
170    /// 后端:macOS Keychain / Linux DBus Secret Service / Windows Credential Manager。
171    /// 每个登录账号一条独立条目(username = `trade-password.<account>`),
172    /// 避免多账号互相覆盖。
173    SetTradePwd {
174        /// 登录账号(牛牛号 / 手机号 / 邮箱)—— 和 futu-opend --login-account 完全一致
175        #[arg(long)]
176        account: String,
177
178        /// 从 stdin 读一行密码(脚本/CI 友好,不做二次确认)
179        #[arg(long)]
180        from_stdin: bool,
181    },
182
183    /// 清除 keychain 里某登录账号的交易密码
184    ClearTradePwd {
185        #[arg(long)]
186        account: String,
187    },
188
189    /// 把登录密码写入 OS keychain(v1.4.18+)
190    ///
191    /// 存完后 `futu-opend` 启动时如果没传 `--login-pwd` / `FUTU_PWD`,会自动
192    /// 从 keychain 读该账号的密码。每个账号一条独立条目(username =
193    /// `login-password.<account>`),避免多账号互相覆盖。
194    ///
195    /// 默认以交互式 tty prompt 读入(无回显,不进 shell history),自动化脚本
196    /// 可用 `--from-stdin` 从 stdin 读一行。
197    SetLoginPwd {
198        /// 账号(牛牛号 / 手机号 / 邮箱)—— 和 futu-opend --login-account 完全一致
199        #[arg(long)]
200        account: String,
201
202        /// 从 stdin 读一行密码(脚本/CI 友好,不做二次确认)
203        #[arg(long)]
204        from_stdin: bool,
205    },
206
207    /// 清除 keychain 里某账号的登录密码
208    ClearLoginPwd {
209        #[arg(long)]
210        account: String,
211    },
212
213    /// 进入交互式 REPL(共享一条长连接,历史记录,推送实时显示)
214    Repl,
215
216    /// 生成新的 futu-mcp API Key 并追加到 keys.json
217    ///
218    /// 明文 key 只会打印到 stdout 一次;文件中只存 SHA-256 hash。
219    /// 用法示例:
220    ///   futucli gen-key --id readonly --scopes qot:read,acc:read
221    ///   futucli gen-key --id sim-bot --scopes qot:read,trade:simulate --expires 30d
222    ///   futucli gen-key --id prod --scopes trade:real --allowed-markets HK \
223    ///       --allowed-symbols HK.00700,HK.09988 --max-order-value 50000 \
224    ///       --max-daily-value 200000 --hours-window 09:30-16:00 --expires 90d
225    GenKey(GenKeyArgs),
226
227    /// 就地编辑已有 key 的机器绑定(不重新生成明文)
228    ///
229    /// 用法示例:
230    ///   futucli bind-key --id sim-bot --this-machine           # 追加本机
231    ///   futucli bind-key --id sim-bot --machines aabb...,ccdd... # 追加指定指纹
232    ///   futucli bind-key --id sim-bot --replace --this-machine # 覆盖白名单
233    ///   futucli bind-key --id sim-bot --clear                  # 完全解绑
234    ///   futucli bind-key --id sim-bot --freeze                 # 临时冻结(allowed_machines = [])
235    /// 改完记得 SIGHUP 网关:kill -HUP $(pgrep futu-opend)
236    BindKey {
237        /// 要编辑的 key id
238        #[arg(long)]
239        id: String,
240
241        /// keys.json 路径。默认(按 OS):macOS ~/Library/Application Support/futu/keys.json / Linux ~/.config/futu/keys.json / Windows %APPDATA%/futu/keys.json
242        #[arg(long)]
243        keys_file: Option<PathBuf>,
244
245        /// 追加本机指纹
246        #[arg(long)]
247        this_machine: bool,
248
249        /// 追加指定指纹,逗号分隔的 64 位 hex
250        #[arg(long)]
251        machines: Option<String>,
252
253        /// 替换模式:用新指纹覆盖整个白名单(默认是追加)
254        #[arg(long, conflicts_with_all = &["clear", "freeze"])]
255        replace: bool,
256
257        /// 清除绑定:把 allowed_machines 置为 None(等同于未启用绑定)
258        #[arg(long, conflicts_with_all = &["freeze", "replace", "this_machine", "machines"])]
259        clear: bool,
260
261        /// 冻结:把 allowed_machines 置为 [](任何机器都不过)
262        #[arg(long, conflicts_with_all = &["clear", "replace", "this_machine", "machines"])]
263        freeze: bool,
264    },
265
266    /// 打印本机 machine-id 或指定 key_id 的绑定指纹
267    ///
268    /// 无 `--for-key` 时打印原始 machine-id(仅用于确认是不是同一台机器)。
269    /// 加 `--for-key <id>` 时打印指纹(可复制给签发者,写进该 key 的 allowed_machines)。
270    MachineId {
271        /// 要生成指纹的 key id(和签发方的 `gen-key --id` 保持一致)
272        #[arg(long)]
273        for_key: Option<String>,
274    },
275
276    /// 列出 keys.json 中所有 API Key(不含明文,明文只在 gen-key 时打印一次)
277    ///
278    /// 默认输出短表格 (含 ID/STATUS/SCOPES/MARKETS/SYMBOLS/ACCOUNTS/LIMITS/DAILY/WINDOW/BOUND/EXPIRES/NOTE).
279    /// 加 `--json` 输出机读 JSON (字段全, 含 hash / created_at / allowed_machines 等).
280    ListKeys {
281        /// keys.json 路径。默认(按 OS):macOS ~/Library/Application Support/futu/keys.json / Linux ~/.config/futu/keys.json / Windows %APPDATA%/futu/keys.json
282        #[arg(long)]
283        keys_file: Option<PathBuf>,
284
285        /// v1.4.106 codex 0608 F3 (P2): 输出 JSON 数组而不是短表格
286        ///
287        /// JSON 字段含完整 KeyRecord (hash / created_at / allowed_machines /
288        /// allowed_acc_ids / allowed_card_nums / allowed_symbols / hours_window
289        /// 等) 适合脚本 / agent 读取. 空 keys.json 输出 `[]`.
290        #[arg(long)]
291        json: bool,
292    },
293
294    /// 吊销一条 API Key(按 id 从 keys.json 删除;需要运行中的网关 SIGHUP 才生效)
295    RevokeKey {
296        /// 要吊销的 key id
297        #[arg(long)]
298        id: String,
299
300        /// keys.json 路径。默认(按 OS):macOS ~/Library/Application Support/futu/keys.json / Linux ~/.config/futu/keys.json / Windows %APPDATA%/futu/keys.json
301        #[arg(long)]
302        keys_file: Option<PathBuf>,
303
304        /// 确认吊销(未加 --yes 时仅 dry-run)
305        #[arg(long)]
306        yes: bool,
307    },
308
309    // ===== v1.4.25: 交易扩展命令 =====
310    /// 下单(Python SDK `OpenTradeContext.place_order`)
311    ///
312    /// **real env 必须带 `--confirm`**,防复制粘贴 / 回车误触。
313    /// 建议先在 simulate env 测通再走 real。
314    ///
315    /// **Market hours requirement**(v1.4.35 加):OpenD 协议层**不支持**非交易时段预提交订单。
316    /// 必须在活跃市场时段调用:
317    ///   - HK: 周一至五 09:30-16:00 HKT(开盘前 09:00-09:30 可用 `--order-type AUCTION`)
318    ///   - US: 周一至五 09:30-16:00 ET(HKT 冬令 22:30-05:00,夏令 21:30-04:00)
319    ///   - CN: 周一至五 09:30-11:30 + 13:00-15:00 CST
320    ///   - SG: 周一至五 09:00-17:00 SGT
321    ///   - JP: 周一至五 09:00-11:30 + 12:30-15:00 JST
322    ///   - AU: 周一至五 10:00-16:00 AEST/AEDT
323    ///   - CA: 周一至五 09:30-16:00 EST/EDT
324    ///
325    /// 非交易时段想使用服务端预提交队列挂单,请用**富途牛牛 / moomoo APP**;
326    /// 该队列不和 OpenD 共享。休市时调 `place-order` 会拿到服务端通用错 +
327    /// daemon 追加的 [hint] 说明,不要试图换 `--order-type` 绕过。
328    PlaceOrder(PlaceOrderArgs),
329
330    /// 改单 / 撤单 / 启停订单(Python SDK `OpenTradeContext.modify_order`)
331    ModifyOrder(ModifyOrderArgs),
332
333    /// 撤单(modify-order 的常用快捷方式,op=CANCEL)
334    CancelOrder(CancelOrderArgs),
335
336    /// 二次确认订单(Python SDK `OpenTradeContext.reconfirm_order`)
337    ReconfirmOrder(ReconfirmOrderArgs),
338
339    /// 查询历史订单(Python SDK `OpenTradeContext.history_order_list_query`)
340    HistoryOrders(HistoryOrdersArgs),
341
342    /// 查询历史成交(Python SDK `OpenTradeContext.history_deal_list_query`)
343    HistoryDeals(HistoryDealsArgs),
344
345    /// 查最大可买/可卖(Python SDK `OpenTradeContext.acctradinginfo_query`)
346    MaxQtys(MaxQtysArgs),
347
348    /// 查询融资融券比率(对齐 py-futu-api `get_margin_ratio`;v1.4.31)
349    MarginRatio(MarginRatioArgs),
350
351    /// 查询订单费用明细(对齐 py-futu-api `order_fee_query`;v1.4.31)
352    OrderFee(OrderFeeArgs),
353
354    // ===== v1.4.26 新增行情分析类 =====
355    /// 资金流向时间序列
356    CapitalFlow {
357        /// 证券 MARKET.CODE,如 HK.00700 / US.AAPL
358        symbol: String,
359        /// 周期类型:1=分时 2=1日 3=3日 4=5日 5=10日 6=20日 7=30日 8=60日 9=90日 10=180日 11=360日
360        #[arg(long, default_value_t = 1)]
361        period_type: i32,
362        /// 开始时间 YYYY-MM-DD HH:MM:SS(可选)
363        #[arg(long)]
364        begin: Option<String>,
365        /// 结束时间(可选)
366        #[arg(long)]
367        end: Option<String>,
368    },
369
370    /// 资金分布快照(超大/大/中/小单流入流出)
371    CapitalDistribution { symbol: String },
372
373    /// 市场状态查询(开盘/休市/午休)
374    MarketState {
375        /// 证券列表,逗号分隔,如 HK.00700,US.AAPL
376        symbols: String,
377    },
378
379    /// 股票所属板块
380    OwnerPlate {
381        /// 证券列表,逗号分隔
382        symbols: String,
383    },
384
385    /// 期权链(按到期日列出 call/put 合约)
386    OptionChain {
387        /// 正股 MARKET.CODE,如 HK.00700 / US.AAPL(位置参数或 --owner / --code 二选一)
388        #[arg(index = 1, value_name = "OWNER")]
389        owner: Option<String>,
390        /// v1.4.52 BUG-9: REST/MCP 风格命名参数 alias
391        #[arg(long = "owner", visible_alias = "code", conflicts_with = "owner")]
392        owner_arg: Option<String>,
393        /// 到期日范围开始 YYYY-MM-DD
394        #[arg(long)]
395        begin: String,
396        /// 到期日范围结束 YYYY-MM-DD
397        #[arg(long)]
398        end: String,
399        /// 期权类型:all|call|put(默认 all)
400        #[arg(long, default_value = "all")]
401        option_type: String,
402        /// Greek filter: delta 下限
403        #[arg(long)]
404        delta_min: Option<f64>,
405        /// Greek filter: delta 上限
406        #[arg(long)]
407        delta_max: Option<f64>,
408        /// Greek filter: implied volatility 下限(小数,如 0.3 = 30%)
409        #[arg(long)]
410        iv_min: Option<f64>,
411        /// Greek filter: implied volatility 上限(小数,如 0.3 = 30%)
412        #[arg(long)]
413        iv_max: Option<f64>,
414        /// Greek filter: open interest 下限
415        #[arg(long)]
416        oi_min: Option<f64>,
417        /// Greek filter: open interest 上限
418        #[arg(long)]
419        oi_max: Option<f64>,
420        /// Greek filter: gamma 下限
421        #[arg(long)]
422        gamma_min: Option<f64>,
423        /// Greek filter: gamma 上限
424        #[arg(long)]
425        gamma_max: Option<f64>,
426        /// Greek filter: vega 下限
427        #[arg(long)]
428        vega_min: Option<f64>,
429        /// Greek filter: vega 上限
430        #[arg(long)]
431        vega_max: Option<f64>,
432        /// Greek filter: theta 下限
433        #[arg(long)]
434        theta_min: Option<f64>,
435        /// Greek filter: theta 上限
436        #[arg(long)]
437        theta_max: Option<f64>,
438    },
439
440    // ===== v1.4.30 市场元数据 / 复权 / 自选 / 撤单 =====
441    /// 交易日列表(对齐 py-futu-api `request_trading_days`)
442    TradingDays {
443        /// 市场:HK / US / CN / NT / ST / JP / SG
444        #[arg(long)]
445        market: String,
446        /// 起始日期 YYYY-MM-DD
447        #[arg(long)]
448        begin: String,
449        /// 结束日期 YYYY-MM-DD
450        #[arg(long)]
451        end: String,
452    },
453
454    /// 复权因子(对齐 py-futu-api `get_rehab`;长期 K 线对齐 / 回测必用)
455    Rehab {
456        /// 证券 MARKET.CODE,如 HK.00700 / US.AAPL
457        symbol: String,
458    },
459
460    /// 停牌日查询(对齐 py-futu-api `get_suspend`)
461    Suspend {
462        /// 证券列表,逗号分隔(位置参数或 --code / --symbols 二选一)
463        #[arg(index = 1, value_name = "SYMBOLS")]
464        symbols: Option<String>,
465        /// v1.4.52 BUG-9: REST/MCP 风格命名参数 alias
466        #[arg(long = "code", visible_alias = "symbols", conflicts_with = "symbols")]
467        symbols_arg: Option<String>,
468        /// 起始日期 YYYY-MM-DD
469        #[arg(long)]
470        begin: String,
471        /// 结束日期 YYYY-MM-DD
472        #[arg(long)]
473        end: String,
474    },
475
476    /// 自选股分组下的股票(对齐 py-futu-api `get_user_security`)
477    UserSecurity {
478        /// 分组名(位置参数或 --group 二选一,用 `user-security-groups` 先看可用分组)
479        #[arg(index = 1, value_name = "GROUP")]
480        group: Option<String>,
481        /// v1.4.52 BUG-9: REST/MCP 风格命名参数 alias
482        #[arg(long = "group", conflicts_with = "group")]
483        group_arg: Option<String>,
484    },
485
486    /// 自选股分组列表(对齐 py-futu-api `get_user_security_group`)
487    UserSecurityGroups {
488        /// 分组类型:1=自定义 / 2=系统 / 3=全部(默认 3)
489        #[arg(long, default_value_t = 3)]
490        group_type: i32,
491    },
492
493    /// 涡轮列表(对齐 py-futu-api `get_warrant`;按成交量降序)
494    Warrant {
495        /// 可选正股 MARKET.CODE(不传则全市场)
496        #[arg(long)]
497        owner: Option<String>,
498        /// 分页起始 index (默认 0). v1.4.106 codex 0635 ζ36 F1: 暴露分页参数,
499        /// 拿下一页用 `--begin 20 --num 20` (响应含 last_page / all_count)
500        #[arg(long, default_value_t = 0)]
501        begin: i32,
502        /// 最大行数(1-200,默认 20)
503        #[arg(long, default_value_t = 20)]
504        num: i32,
505    },
506
507    /// 新股 IPO 列表(对齐 py-futu-api `get_ipo_list`)
508    IpoList {
509        /// 市场:HK / US / CN
510        #[arg(long)]
511        market: String,
512    },
513
514    /// 期货合约资料(对齐 py-futu-api `get_future_info`)
515    FutureInfo {
516        /// 期货代码列表,逗号分隔(如 HK.HSImain / US.MNQmain)
517        symbols: String,
518    },
519
520    /// 条件选股最小版(对齐 py-futu-api `get_stock_filter`;高级过滤走 REST)
521    StockFilter {
522        /// 市场:HK / US / CN
523        #[arg(long)]
524        market: String,
525        /// 分页起始(默认 0)
526        #[arg(long, default_value_t = 0)]
527        begin: i32,
528        /// 返回行数(1-200,默认 50)
529        #[arg(long, default_value_t = 50)]
530        num: i32,
531    },
532
533    /// 全部撤单(对齐 py-futu-api `cancel_all_order`)
534    ///
535    /// ⚠️ 风险:立即撤该账户**指定市场**(不传 --market 则全账户)所有
536    /// pending 订单,不可恢复。real env 必须 `--confirm`。
537    CancelAllOrder {
538        /// 账户 id;也可改用 --card-num 传 App 显示卡号
539        #[arg(index = 1, value_name = "ACC_ID")]
540        acc_id: Option<u64>,
541        /// App 显示卡号:4 位末尾或 16 位完整卡号
542        #[arg(long = "card-num")]
543        card_num: Option<String>,
544        /// 环境:simulate(默认)/ real
545        #[arg(long, default_value = "simulate")]
546        env: String,
547        /// 市场:HK / US / HKCC / CN(可选,不传则全账户)
548        #[arg(long)]
549        market: Option<String>,
550        /// real 环境必须带此 flag 确认(防误触)
551        #[arg(long)]
552        confirm: bool,
553    },
554
555    /// 网关全局状态(市场开闭 / 服务器版本 / 登录状态)
556    GlobalState,
557
558    /// 用户信息(昵称 / 各市场行情权限 / 订阅配额 / 历史 K 线配额)
559    UserInfo,
560
561    /// 行情权限概览(C++ OpenD GUI 风格分组;可选刷新最高行情权限)
562    QuoteRights {
563        /// 查询前先触发 request_highest_quote_right 刷新
564        #[arg(long)]
565        refresh: bool,
566    },
567
568    /// 延迟统计(行情推送 / 请求 / 下单三类延迟分布概要)
569    DelayStatistics,
570
571    /// v1.4.98 T2-8: NN+MM token 启用/绑定状态查询. unlock-trade -20011 时
572    /// 第一线诊断 (NN=Futu Token app, MM=moomoo Token app, 同协议异 app brand).
573    /// 输出 4 字段: nn/mm × enable/bind (1=已启用/绑定, 0=未启用/未绑定).
574    TokenState,
575
576    /// v1.4.98 T2-2: 无风险利率 (HK/US/JP, 期权定价基准). backend cmd 20231.
577    /// 输出 3 市场利率 (百分比 + raw uint64) + update_time.
578    RiskFreeRate,
579
580    /// v1.4.98 T2-1: 摆盘步长 (价位表) — backend cmd 6503.
581    /// PlaceOrder/ModifyOrder 校验价格合法性必备.
582    SpreadTable,
583
584    /// v1.4.98 T2-3: 逐笔统计 (avg_price / 主买/主卖/中性量等) — cmd 6365.
585    /// 前置: symbol 必须先 subscribe / get_static_info 触发 stock_id 缓存.
586    ///
587    /// v1.4.102 A3 alias: 加 positional `[SYMBOL]` 短写, 跟其他行情类
588    /// command (quote / snapshot / kline) 一致. `futucli ticker-statistic
589    /// HK.00700` 等同 `--symbol HK.00700`.
590    TickerStatistic {
591        /// 证券 symbol (e.g. HK.00700, US.AAPL) — 位置参数或 --symbol 二选一
592        #[arg(index = 1, value_name = "SYMBOL")]
593        symbol_pos: Option<String>,
594        /// 证券 symbol (named arg form, 兼容老用法)
595        #[arg(long = "symbol", conflicts_with = "symbol_pos")]
596        symbol: Option<String>,
597        /// 逐笔类型 0=ALL, 1=BUY, 2=SELL, 3=BUY_AND_SELL, 4=NEUTRAL
598        #[arg(long)]
599        ticker_type: Option<i32>,
600        /// 市场状态 0=ALL, 1=BEFORE, 2=TRADING, 3=AFTER
601        #[arg(long)]
602        stat_type: Option<u32>,
603    },
604
605    /// v1.4.106 codex 0500 ζ23-redo: 逐笔统计 Detail (价位级分布) — cmd 6366.
606    /// 配套 `ticker-statistic` (Info, cmd 6365): 先调 Info 拿 `ticker_time`,
607    /// 再调 Detail 同 `ticker_time` 拿这个时点的 DetailItem 列表 (price /
608    /// buy_volume / sell_volume / volume / ratio / neutral_volume).
609    /// 前置: symbol 必须先 subscribe / get_static_info 触发 stock_id 缓存.
610    TickerStatisticDetail {
611        /// 证券 symbol (e.g. HK.00700, US.AAPL) — 位置参数或 --symbol 二选一
612        #[arg(index = 1, value_name = "SYMBOL")]
613        symbol_pos: Option<String>,
614        /// 证券 symbol (named arg form, 兼容老用法)
615        #[arg(long = "symbol", conflicts_with = "symbol_pos")]
616        symbol: Option<String>,
617        /// 逐笔类型 0=ALL, 1=BUY, 2=SELL, 3=BUY_AND_SELL, 4=NEUTRAL
618        #[arg(long)]
619        ticker_type: Option<i32>,
620        /// 时间戳 (ms) — 通常从前一次 ticker-statistic call 拿到. 0/省略 = backend 默认
621        #[arg(long)]
622        ticker_time: Option<u64>,
623        /// 筛选 0=全部价位 / 1..N=top N 价位 (backend max ~100)
624        #[arg(long)]
625        select_num: Option<u32>,
626        /// 分页 起始项 (默认 0)
627        #[arg(long)]
628        data_from: Option<u32>,
629        /// 分页 size 单页最大 (默认 20)
630        #[arg(long)]
631        data_max_count: Option<u32>,
632        /// 市场状态 0=ALL, 1=BEFORE, 2=TRADING, 3=AFTER
633        #[arg(long)]
634        stat_type: Option<u32>,
635    },
636
637    // ===== v1.4.30 P2(100% 覆盖) =====
638    /// 查询当前订阅状态(已用 / 剩余额度 + 订阅清单)
639    QuerySubscription {
640        /// 是否查询所有连接(默认只查本连接)
641        #[arg(long)]
642        all_conn: bool,
643    },
644
645    /// 查询当前 daemon 已用订阅额度与历史 K 线额度
646    UsedQuota,
647
648    /// 反订阅行情数据(也可 --all 清空本连接所有订阅)
649    Unsubscribe {
650        /// 证券列表,逗号分隔(--all 时忽略)
651        #[arg(long, default_value = "")]
652        symbols: String,
653        /// 订阅类型 id 列表,逗号分隔(proto Qot_Common.SubType: 1=Basic 2=OrderBook
654        /// 4=Ticker 5=RT 6=KL_Day 7=KL_5Min 8=KL_15Min 9=KL_30Min 10=KL_60Min
655        /// 11=KL_1Min 12=KL_Week 13=KL_Month 14=Broker 15=KL_Quarter 16=KL_Year
656        /// 17=KL_3Min, 跳 3=None)
657        #[arg(long, default_value = "")]
658        sub_types: String,
659        /// 清空本连接所有订阅
660        #[arg(long)]
661        all: bool,
662    },
663
664    /// 历史 K 线下载配额
665    HistoryKlQuota {
666        /// 是否返回每只股票的下载详情(默认 false)
667        #[arg(long)]
668        detail: bool,
669    },
670
671    /// 持股变动(高管 / 机构 / 基金)
672    HoldingChange {
673        /// 证券 MARKET.CODE
674        symbol: String,
675        /// 持有者类别:1=机构 / 2=基金 / 3=高管
676        #[arg(long, default_value_t = 3)]
677        category: i32,
678        /// 开始时间 YYYY-MM-DD HH:MM:SS(可选)
679        #[arg(long)]
680        begin: Option<String>,
681        /// 结束时间(可选)
682        #[arg(long)]
683        end: Option<String>,
684    },
685
686    /// 修改自选股分组(add / del / move_out)
687    ModifyUserSecurity {
688        /// 分组名
689        group: String,
690        /// 操作:1=AddInto / 2=Delete / 3=MoveOut
691        #[arg(long)]
692        op: i32,
693        /// 证券列表,逗号分隔
694        symbols: String,
695    },
696
697    /// 股票代码变更 / 临时代码信息(目前仅港股)
698    CodeChange {
699        /// 证券列表,逗号分隔
700        symbols: String,
701    },
702
703    /// 设置到价提醒
704    SetPriceReminder {
705        /// 证券 MARKET.CODE
706        symbol: String,
707        /// 操作:1=Add / 2=Del / 3=Enable / 4=Disable / 5=Modify / 6=DelAll
708        #[arg(long)]
709        op: i32,
710        /// 提醒 key(modify/del/enable/disable 时必填)
711        #[arg(long)]
712        key: Option<i64>,
713        /// 提醒类型 (1=PriceUp 2=PriceDown 3=ChangeRateUp 4=ChangeRateDown
714        /// 5=5MinChangeRateUp 6=5MinChangeRateDown 7=VolumeUp 8=TurnoverUp
715        /// 9=TurnoverRateUp 10=BidPriceUp 11=AskPriceDown 12=BidVolUp 13=AskVolUp
716        /// 14=3MinChangeRateUp 15=3MinChangeRateDown — 见 Qot_Common.PriceReminderType)
717        #[arg(long)]
718        r#type: Option<i32>,
719        /// 频率(1=Always 2=OncePerDay 3=Once)
720        #[arg(long)]
721        freq: Option<i32>,
722        /// 阈值(add/modify 必填)
723        #[arg(long)]
724        value: Option<f64>,
725        /// 备注 (最多 40 半角字节 / 20 中文字符, 对齐 C++ NoteMaxLen)
726        #[arg(long)]
727        note: Option<String>,
728        /// v1.4.106 codex 1116 F4 [P2]: reminder session list, 逗号分隔.
729        /// (1=Open 2=USPre 3=USAfter 4=USOverNight)
730        /// 美股 + 留空 → daemon 默认补 [Open, USPre, USAfter] (对齐 C++).
731        #[arg(long, value_delimiter = ',')]
732        session: Vec<i32>,
733    },
734
735    /// 查询到价提醒(按 symbol 或 market)
736    PriceReminder {
737        /// 证券(和 --market 二选一)
738        #[arg(long)]
739        symbol: Option<String>,
740        /// 市场 code(Qot_Common::QotMarket,和 --symbol 二选一)
741        #[arg(long)]
742        market: Option<i32>,
743    },
744
745    /// 期权到期日列表
746    OptionExpirationDate {
747        /// 标的股 MARKET.CODE(位置参数或 --owner 二选一)
748        #[arg(index = 1, value_name = "OWNER")]
749        owner: Option<String>,
750        /// v1.4.52 BUG-9: REST/MCP 风格命名参数 alias
751        #[arg(long = "owner", conflicts_with = "owner")]
752        owner_arg: Option<String>,
753        /// 指数期权类型(仅恒指/国指)
754        #[arg(long)]
755        index_type: Option<i32>,
756    },
757
758    /// 订阅账户推送(订单 / 成交)
759    SubAccPush {
760        /// 账户 id 列表,逗号分隔
761        acc_ids: String,
762    },
763
764    /// 账户资金流水(对齐 `get_acc_cash_flow`)
765    AccCashFlow(AccCashFlowArgs),
766
767    /// v1.4.32+ daemon 健康状态快照(GET /api/admin/status)。
768    /// 同事提议的"快速看 daemon 在线不、broker 通不通、解锁没"工具。
769    /// scope 模式下 key 必须持 `admin` scope,否则被 bearer_auth 拒。
770    #[command(name = "daemon-status")]
771    DaemonStatus {
772        /// 目标 REST 端口 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
773        #[arg(long)]
774        rest_url: Option<String>,
775        /// v1.4.52 BUG-9: REST/MCP 风格用户习惯指定 port,自动转 http://127.0.0.1:<port>
776        #[arg(long, conflicts_with = "rest_url")]
777        rest_port: Option<u16>,
778        /// 带 Bearer Token(scope 模式下需要 admin scope 的 key)
779        #[arg(long)]
780        api_key: Option<String>,
781    },
782
783    /// v1.4.32+ 优雅退出 daemon(POST /api/admin/shutdown)。
784    /// daemon 响应 200 后 1 秒 `std::process::exit(0)`。是否重启由进程
785    /// supervisor(systemd / Docker)决定。
786    #[command(name = "daemon-shutdown")]
787    DaemonShutdown {
788        /// 目标 REST 端点 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
789        #[arg(long)]
790        rest_url: Option<String>,
791        /// v1.4.106 codex 0554 F5 [P3]: 风格一致性 — 与 daemon-status 对齐,
792        /// REST/MCP 风格用户习惯指定 port, 自动转 http://127.0.0.1:<port>.
793        #[arg(long, conflicts_with = "rest_url")]
794        rest_port: Option<u16>,
795        /// 带 Bearer Token(scope 模式下需要 admin scope 的 key)
796        #[arg(long)]
797        api_key: Option<String>,
798    },
799
800    /// v1.4.32+ 重置 trade cipher 缓存(POST /api/admin/reload)。
801    /// 用于"解锁状态错乱 / 换了交易密码"场景——清空 cipher 缓存后客户端
802    /// 必须重新 unlock-trade。不重启 daemon 进程,不影响 Platform / broker
803    /// TCP 连接。
804    #[command(name = "daemon-reload")]
805    DaemonReload {
806        /// 目标 REST 端点 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
807        #[arg(long)]
808        rest_url: Option<String>,
809        /// v1.4.106 codex 0554 F5 [P3]: 风格一致性 — 与 daemon-status 对齐,
810        /// REST/MCP 风格用户习惯指定 port, 自动转 http://127.0.0.1:<port>.
811        #[arg(long, conflicts_with = "rest_url")]
812        rest_port: Option<u16>,
813        /// 带 Bearer Token(scope 模式下需要 admin scope 的 key)
814        #[arg(long)]
815        api_key: Option<String>,
816    },
817
818    // ========================================================================
819    // v1.4.94 / v1.4.95 Tier M (mobile-driven extensions): 11 subcommand 镜像
820    // REST + MCP. 全 only-read (acc:read scope). 见 cmd/tier_m.rs.
821    // ========================================================================
822    /// 资金明细查询 (mobile-driven, 比 acc-cash-flow 字段更全) — v1.4.94 M1
823    ///
824    /// v1.4.102 A3 alias: positional `[ACC_ID]` 短写
825    /// (`futucli cash-log 12345 --begin-time ...` 等同 `--acc-id 12345`).
826    #[command(name = "cash-log")]
827    CashLog(CashLogArgs),
828
829    /// 单条资金流水详情 — v1.4.94 M1 + v1.4.102 A3 positional alias
830    #[command(name = "cash-detail")]
831    CashDetail(CashDetailArgs),
832
833    /// 业务分类元数据 — v1.4.94 M1 + v1.4.102 A3 positional alias
834    #[command(name = "biz-group")]
835    BizGroup(BizGroupArgs),
836
837    /// per-account margin info (HK / US / CN_AH) — v1.4.95 U2-D
838    ///
839    /// 与 `margin-ratio` (per-security ratio) 互补: 本命令给账户全景
840    /// (购买力 / 杠杆 / 风险等级 / 流动性 / HK-specific 港股保证金).
841    #[command(name = "margin-info")]
842    MarginInfo(MarginInfoArgs),
843
844    /// 账户合规标志查询 — v1.4.95 U2-A
845    ///
846    /// 高级交易准入 (期权 / 衍生品 / OTC / CFD 等) 强制要求.
847    /// 常用 flag_id: 5=US 期权确认, 22=衍生品风批 (合并新), 10=基金 KYC,
848    /// 16=PDT 风披, 23=美股 OTC. 详见 proto 头部完整 36+ 项列表.
849    #[command(name = "account-flag")]
850    AccountFlag(AccountFlagArgs),
851
852    /// 账户债券总持仓 (P&L 汇总) — v1.4.95 U2-B
853    #[command(name = "bond-total-asset")]
854    BondTotalAsset(BondTotalAssetArgs),
855
856    /// 单只债券持仓 (含派息/到期/通知) — v1.4.95 U2-B
857    #[command(name = "bond-single-asset")]
858    BondSingleAsset(BondSingleAssetArgs),
859
860    /// 账户债券持仓列表 — v1.4.95 U2-B
861    #[command(name = "bond-position-list")]
862    BondPositionList(BondPositionListArgs),
863
864    /// 是否需要答题 (suitability questionnaire) — v1.4.95 U2-B
865    #[command(name = "bond-answer-state")]
866    BondAnswerState(BondAnswerStateArgs),
867
868    /// 交易提醒 (是否可买/复杂/高风险/可卖/资格预审) — v1.4.95 U2-B
869    #[command(name = "bond-trade-reminder")]
870    BondTradeReminder(BondTradeReminderArgs),
871}