Skip to main content

futucli/cli/commands/
sys.rs

1//! System/status clap argument structs split from commands.rs.
2
3use std::path::PathBuf;
4
5use clap::{Args, Subcommand};
6
7#[derive(Args)]
8pub struct VerificationArgs {
9    /// VerificationType: 1=Picture, 2=Phone.
10    #[arg(long = "type")]
11    pub(crate) verification_type: i32,
12    /// VerificationOp: 1=Request, 2=InputAndLogin.
13    #[arg(long)]
14    pub(crate) op: i32,
15    /// Required for op=2; ignored for op=1.
16    #[arg(long)]
17    pub(crate) code: Option<String>,
18}
19
20#[derive(Args)]
21pub struct QuoteRightsArgs {
22    /// 查询前先触发 request_highest_quote_right 刷新
23    #[arg(long)]
24    pub(crate) refresh: bool,
25}
26
27#[derive(Args)]
28pub struct QuoteCapabilityArgs {
29    /// 股票代码,MARKET.CODE 格式(位置参数)或 `--symbol`/`--code` 指定
30    #[arg(index = 1, value_name = "SYMBOL")]
31    pub(crate) symbol_positional: Option<String>,
32
33    /// 股票代码,MARKET.CODE 格式
34    #[arg(
35        long = "symbol",
36        visible_aliases = ["code", "stock"],
37        conflicts_with = "symbol_positional",
38        value_name = "SYMBOL"
39    )]
40    pub(crate) symbol_arg: Option<String>,
41}
42
43#[derive(Args)]
44pub struct TickerStatisticArgs {
45    /// 证券 symbol (e.g. HK.00700, US.AAPL) — 位置参数或 --symbol 二选一
46    #[arg(index = 1, value_name = "SYMBOL")]
47    pub(crate) symbol_pos: Option<String>,
48
49    /// 证券 symbol (named arg form, 兼容老用法)
50    #[arg(long = "symbol", conflicts_with = "symbol_pos")]
51    pub(crate) symbol: Option<String>,
52
53    /// 逐笔类型 0=ALL, 1=BUY, 2=SELL, 3=BUY_AND_SELL, 4=NEUTRAL
54    #[arg(long)]
55    pub(crate) ticker_type: Option<i32>,
56
57    /// 市场状态 0=ALL, 1=BEFORE, 2=TRADING, 3=AFTER
58    #[arg(long)]
59    pub(crate) stat_type: Option<u32>,
60}
61
62#[derive(Args)]
63pub struct TickerStatisticDetailArgs {
64    /// 证券 symbol (e.g. HK.00700, US.AAPL) — 位置参数或 --symbol 二选一
65    #[arg(index = 1, value_name = "SYMBOL")]
66    pub(crate) symbol_pos: Option<String>,
67
68    /// 证券 symbol (named arg form, 兼容老用法)
69    #[arg(long = "symbol", conflicts_with = "symbol_pos")]
70    pub(crate) symbol: Option<String>,
71
72    /// 逐笔类型 0=ALL, 1=BUY, 2=SELL, 3=BUY_AND_SELL, 4=NEUTRAL
73    #[arg(long)]
74    pub(crate) ticker_type: Option<i32>,
75
76    /// 时间戳 (ms) — 通常从前一次 ticker-statistic call 拿到. 0/省略 = backend 默认
77    #[arg(long)]
78    pub(crate) ticker_time: Option<u64>,
79
80    /// 筛选 0=全部价位 / 1..N=top N 价位 (backend max ~100)
81    #[arg(long)]
82    pub(crate) select_num: Option<u32>,
83
84    /// 分页 起始项 (默认 0)
85    #[arg(long)]
86    pub(crate) data_from: Option<u32>,
87
88    /// 分页 size 单页最大 (默认 20)
89    #[arg(long)]
90    pub(crate) data_max_count: Option<u32>,
91
92    /// 市场状态 0=ALL, 1=BEFORE, 2=TRADING, 3=AFTER
93    #[arg(long)]
94    pub(crate) stat_type: Option<u32>,
95}
96
97#[derive(Args)]
98pub struct QuerySubscriptionArgs {
99    /// 是否查询所有连接(默认只查本连接)
100    #[arg(long)]
101    pub(crate) all_conn: bool,
102}
103
104#[derive(Args)]
105pub struct UnsubscribeArgs {
106    /// 证券列表,逗号分隔(--all 时忽略)
107    #[arg(long, default_value = "")]
108    pub(crate) symbols: String,
109
110    /// 订阅类型 id 列表,逗号分隔(proto Qot_Common.SubType: 1=Basic 2=OrderBook
111    /// 4=Ticker 5=RT 6=KL_Day 7=KL_5Min 8=KL_15Min 9=KL_30Min 10=KL_60Min
112    /// 11=KL_1Min 12=KL_Week 13=KL_Month 14=Broker 15=KL_Quarter 16=KL_Year
113    /// 17=KL_3Min 18=KL_10Min 19=KL_120Min 20=KL_180Min 21=KL_240Min,
114    /// 22=OrderBook_Odd, 跳 3=None)
115    #[arg(long, default_value = "")]
116    pub(crate) sub_types: String,
117
118    /// 清空本连接所有订阅
119    #[arg(long)]
120    pub(crate) all: bool,
121}
122
123#[derive(Args)]
124pub struct HistoryKlQuotaArgs {
125    /// 是否返回每只股票的下载详情(默认 false);总额度跟随账号动态 API quota
126    #[arg(long)]
127    pub(crate) detail: bool,
128}
129
130#[derive(Args)]
131pub struct DaemonStatusArgs {
132    /// 目标 REST 端口 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
133    #[arg(long)]
134    pub(crate) rest_url: Option<String>,
135
136    /// REST/MCP 风格端口短写,自动转为 http://127.0.0.1:<port>
137    #[arg(long, conflicts_with = "rest_url")]
138    pub(crate) rest_port: Option<u16>,
139
140    /// 带 Bearer Token(scope 模式下需要 admin scope 的 key)
141    #[arg(long)]
142    pub(crate) api_key: Option<String>,
143}
144
145#[derive(Args)]
146pub struct PushSubscriberInfoArgs {
147    /// 目标 REST 端点 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
148    #[arg(long)]
149    pub(crate) rest_url: Option<String>,
150
151    /// REST/MCP 风格用户习惯指定 port,自动转 http://127.0.0.1:<port>
152    #[arg(long, conflicts_with = "rest_url")]
153    pub(crate) rest_port: Option<u16>,
154
155    /// 带 Bearer Token(scope 模式下需要 acc:read scope)
156    #[arg(long)]
157    pub(crate) api_key: Option<String>,
158}
159
160#[derive(Args)]
161pub struct DoctorArgs {
162    /// 目标 REST 端点 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
163    #[arg(long)]
164    pub(crate) rest_url: Option<String>,
165
166    /// REST/MCP 风格用户习惯指定 port,自动转 http://127.0.0.1:<port>
167    #[arg(long, conflicts_with = "rest_url")]
168    pub(crate) rest_port: Option<u16>,
169
170    /// 带 Bearer Token(scope 模式下建议使用 admin + qot:read + metrics:read scope)
171    #[arg(long)]
172    pub(crate) api_key: Option<String>,
173
174    /// 可选 MARKET.CODE;提供后 doctor 会额外查询 market-state 和 quote-capability
175    /// 辅助判断闭市、开市断流、行情权限或静态缓存问题
176    #[arg(long)]
177    pub(crate) symbol: Option<String>,
178
179    /// 写出脱敏诊断包到指定目录(不存在则创建)
180    #[arg(long, value_name = "DIR")]
181    pub(crate) bundle: Option<PathBuf>,
182
183    /// 不检查公开 version.json;适合离线或严格内网环境
184    #[arg(long)]
185    pub(crate) no_update_check: bool,
186
187    /// version.json URL;默认读 FUTU_UPDATE_CHECK_URL,未设置则用 https://futuapi.com/version.json
188    #[arg(long)]
189    pub(crate) update_url: Option<String>,
190
191    /// 更新检查 HTTP 超时,单位毫秒
192    #[arg(long, default_value_t = 800)]
193    pub(crate) update_timeout_ms: u64,
194}
195
196#[derive(Args)]
197pub struct VersionArgs {
198    /// 请求公开 version.json 检查是否有新版本;默认只显示本地版本,不联网
199    #[arg(long)]
200    pub(crate) check: bool,
201
202    /// version.json URL;默认读 FUTU_UPDATE_CHECK_URL,未设置则用 https://futuapi.com/version.json
203    #[arg(long)]
204    pub(crate) url: Option<String>,
205
206    /// 更新检查 HTTP 超时,单位毫秒
207    #[arg(long, default_value_t = 800)]
208    pub(crate) timeout_ms: u64,
209}
210
211#[derive(Args)]
212pub struct LanguagePackArgs {
213    #[command(subcommand)]
214    pub(crate) command: LanguagePackCommand,
215}
216
217#[derive(Subcommand)]
218pub enum LanguagePackCommand {
219    /// 查看本地语言包 cache / fallback 状态
220    Status {
221        /// 语言包 cache 根目录;默认按 OS cache dir 或 FUTU_LANGUAGE_PACK_CACHE_DIR
222        #[arg(long, value_name = "DIR")]
223        cache_dir: Option<PathBuf>,
224    },
225    /// 从本地 Languages 目录导入 api_lang.ini / static_lang.ini
226    Import {
227        /// 包含 en/zh_cn 子目录的 Languages 根目录
228        #[arg(long, value_name = "DIR")]
229        dir: PathBuf,
230
231        /// 语言包 cache 根目录;默认按 OS cache dir 或 FUTU_LANGUAGE_PACK_CACHE_DIR
232        #[arg(long, value_name = "DIR")]
233        cache_dir: Option<PathBuf>,
234
235        /// 写入 manifest 的语言包版本
236        #[arg(long, default_value = "manual-import")]
237        pack_version: String,
238
239        /// 写入 manifest 的来源说明
240        #[arg(long, default_value = "manual-import")]
241        source: String,
242
243        /// 可选 profile/client_type 说明;仅用于复盘,不参与协议
244        #[arg(long)]
245        profile: Option<String>,
246    },
247    /// 从显式配置的 HTTPS endpoint 拉取语言包 manifest 并更新 last-good
248    Update {
249        /// 完整 manifest URL,或必须以 `/` 结尾的目录 URL(自动追加 manifest.json)。默认不配置、不联网
250        #[arg(long, value_name = "URL")]
251        endpoint: String,
252
253        /// 语言包 cache 根目录;默认按 OS cache dir 或 FUTU_LANGUAGE_PACK_CACHE_DIR
254        #[arg(long, value_name = "DIR")]
255        cache_dir: Option<PathBuf>,
256
257        /// HTTP 超时,单位毫秒
258        #[arg(long, default_value_t = 3000)]
259        timeout_ms: u64,
260
261        /// 可选语言过滤,逗号分隔:en,zh_cn
262        #[arg(long)]
263        lang: Option<String>,
264    },
265}
266
267#[derive(Args)]
268pub struct StaticStatusArgs {
269    /// 目标 REST 端点 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
270    #[arg(long)]
271    pub(crate) rest_url: Option<String>,
272
273    /// REST/MCP 风格用户习惯指定 port,自动转 http://127.0.0.1:<port>
274    #[arg(long, conflicts_with = "rest_url")]
275    pub(crate) rest_port: Option<u16>,
276
277    /// 带 Bearer Token(scope 模式下需要 admin scope 的 key)
278    #[arg(long)]
279    pub(crate) api_key: Option<String>,
280}
281
282#[derive(Args)]
283pub struct StaticWarmupArgs {
284    /// 需要显式 warmup 的股票代码,MARKET.CODE 格式,可多个
285    #[arg(required = true)]
286    pub(crate) symbols: Vec<String>,
287}
288
289#[derive(Args)]
290pub struct SurfaceArgs {
291    /// 只显示存在 NotExposed surface 的 endpoint
292    #[arg(long)]
293    pub(crate) gaps: bool,
294
295    /// 输出指定 endpoint 的新增/变更防漏 checklist;可传 canonical、REST path、MCP tool 或 CLI subcommand
296    #[arg(long, value_name = "ENDPOINT")]
297    pub(crate) checklist: Option<String>,
298}
299
300#[derive(Args)]
301pub struct DaemonShutdownArgs {
302    /// 目标 REST 端点 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
303    #[arg(long)]
304    pub(crate) rest_url: Option<String>,
305
306    /// REST/MCP 风格端口短写,自动转为 http://127.0.0.1:<port>。
307    #[arg(long, conflicts_with = "rest_url")]
308    pub(crate) rest_port: Option<u16>,
309
310    /// 带 Bearer Token(scope 模式下需要 admin scope 的 key)
311    #[arg(long)]
312    pub(crate) api_key: Option<String>,
313}
314
315#[derive(Args)]
316pub struct DaemonReloadArgs {
317    /// 目标 REST 端点 URL(默认从 FUTU_REST_URL 环境变量读,或 http://127.0.0.1:22222)
318    #[arg(long)]
319    pub(crate) rest_url: Option<String>,
320
321    /// REST/MCP 风格端口短写,自动转为 http://127.0.0.1:<port>。
322    #[arg(long, conflicts_with = "rest_url")]
323    pub(crate) rest_port: Option<u16>,
324
325    /// 带 Bearer Token(scope 模式下需要 admin scope 的 key)
326    #[arg(long)]
327    pub(crate) api_key: Option<String>,
328}