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}