Skip to main content

Args

Struct Args 

Source
pub struct Args {
Show 29 fields pub cfg_file: Option<String>, pub config: Option<String>, pub ip: Option<String>, pub port: Option<u16>, pub login_account: Option<String>, pub login_pwd: Option<String>, pub login_pwd_md5: Option<String>, pub login_pwd_file: Option<String>, pub login_region: Option<LoginRegion>, pub platform: Option<Platform>, pub auth_server: Option<String>, pub device_id: Option<String>, pub reset_device: bool, pub setup_only: bool, pub verify_code: Option<String>, pub log_level: Option<LogLevel>, pub websocket_port: Option<u16>, pub telnet_port: Option<u16>, pub rest_port: Option<u16>, pub grpc_port: Option<u16>, pub rsa_private_key: Option<String>, pub json_log: bool, pub lang: Option<String>, pub rest_keys_file: Option<PathBuf>, pub grpc_keys_file: Option<PathBuf>, pub ws_keys_file: Option<PathBuf>, pub allow_tcp_unauthenticated: bool, pub audit_log: Option<PathBuf>, pub tz: Option<String>,
}
Expand description

FutuOpenD Rust Gateway — 完全替代 C++ OpenD

Fields§

§cfg_file: Option<String>

XML 配置文件路径 (兼容 C++ FutuOpenD.xml)

§config: Option<String>

TOML 配置文件路径 (v1.4.2+;字段与 CLI 参数对齐, CLI 参数覆盖).

codex 0547 F6 (P3): 字段白名单 (与 XmlConfig schema 一致):

  • 登录: login_account / login_pwd / login_pwd_md5 / login_pwd_file / login_region / platform
  • 监听: ip / port (alias api_port) / rest_port / grpc_port / websocket_port / telnet_port
  • 安全: rsa_private_key / rest_keys_file / grpc_keys_file / ws_keys_file / audit_log / allow_tcp_unauthenticated
  • 系统: lang / log_level / tz

不能写 TOML 的 CLI-only 字段 (运维 / 调试 / 一次性流程): device_id / reset_device / setup_only / verify_code / json_log / inject_auth_failure_every (dev-flags feature only)

任何 unknown field / typo 触发 fatal parse error (BUG-006 deny_unknown_fields), daemon abort. 不再 silent drop.

示例:

login_account = "123456"
ip = "0.0.0.0"
port = 11111
rest_port = 22222
grpc_port = 33333
rest_keys_file = "/etc/futu/keys.json"
audit_log = "/var/log/futu-audit.jsonl"
tz = "Asia/Hong_Kong"
§ip: Option<String>

API 服务监听地址

§port: Option<u16>

API 服务监听端口

§login_account: Option<String>

登录账号

§login_pwd: Option<String>

登录密码明文

§login_pwd_md5: Option<String>

登录密码 MD5 (32 位小写 hex)

§login_pwd_file: Option<String>

登录密码从文件读(v1.4.18+)——适用于 systemd LoadCredential= / Docker secrets 场景。argv 里只有文件路径,不会泄露明文。

文件内容:明文密码(末尾 \n 会被 trim 掉)。

§login_region: Option<LoginRegion>

后端连接区域 (gz / sh / hk) —— 仅对 --platform futunn 生效

这三个值是 futunn 平台的广州 / 上海 / 香港数据中心标识。

--platform moomoo 账户此 flag 会被忽略:daemon 内 commconfig 根据 user_attributionguaranteed_ip 列表覆盖。想切 moomoo 各区用 --platform moomoo + 账号本身决定归属。

v1.4.40 起 clap 封闭 enum 拒绝非法值(v1.4.39 及以前静默接受任意字符串)。

§platform: Option<Platform>

账号平台(v1.4.14+)—— futunn=牛牛/CN/HK,moomoo=US/SG/AU/JP/CA

同手机号 / 邮箱可以在两边各注册独立账号(不同密码)。默认 futunn。 --auth-server 显式指定 URL 时覆盖 --platform

§auth_server: Option<String>

认证服务器 URL(覆盖 --platform 推导的默认值,主要给测试环境用)

§device_id: Option<String>

设备 ID(16 位 hex)—— 覆盖自动生成/持久化的值。

v1.4.17+ 默认从 ~/.futu-opend-rs/device-{hash}.dat 读(首次随机生成 并写入)。本参数用于显式指定,并更新持久化文件。

如果 device_id 被服务端锁定(error_code=15/21),可用 --reset-device 一键清空文件让下次启动随机生成新值。

§reset_device: bool

重置 device_id + credentials 文件后再启动(v1.4.17+)

当用户的 device_id 因空验证码 / 多次 SMS 输错被服务端锁定, 所有后续请求都返回 error_code=15 长时间没有登录 无法恢复。 本参数删除 ~/.futu-opend-rs/device-{hash}.datcredentials-{hash}.json,下次 login 重新生成随机 device_id 走 完整首登流程。

§setup_only: bool

只完成首次设备验证 + 凭据缓存后退出(v1.4.17+)

用于 systemd / Docker / cron 场景:先在前台终端手动跑一次 futu-opend --setup-only 完成 SMS 验证,写入 credentials 文件,然后 生产环境启动时直接走 remember-login 跳过 SMS。

§verify_code: Option<String>

v1.4.57 外部 UX-04(加拿大同事 SMS + Telegram 中继场景必需): 直接传入 SMS 验证码,跳过 stdin prompt。用于 agent / CI / 远程中继场景 (SMS 验证码通过 Telegram/IM 转发,60 秒失效,直接用 stdin 输入来不及)。

典型用法:

# 1. 先不带 --verify-code 启动触发 SMS(会 fail + 退出,但 SMS 已发)
futu-opend --setup-only --login-account X --login-pwd Y
# 2. 收到 SMS 后立即带验证码重新启动
futu-opend --setup-only --login-account X --login-pwd Y --verify-code 123456
§log_level: Option<LogLevel>

日志级别(v1.4.73 BUG-015: clap ValueEnum 约束有效值 trace/debug/info/warn/error/off, 非法值 parse 阶段拒绝 + 清晰错误,不再 silent 吞 log)

§websocket_port: Option<u16>

WebSocket 服务监听端口(可选,不指定则不启动 WebSocket)

§telnet_port: Option<u16>

Telnet 管理端口(可选,不指定则不启动 Telnet)

§rest_port: Option<u16>

REST API 监听端口(可选,不指定则不启动 REST API)

§grpc_port: Option<u16>

gRPC 服务监听端口(可选,不指定则不启动 gRPC)

§rsa_private_key: Option<String>

RSA 私钥文件路径(PEM 格式,启用后 InitConnect 使用 RSA 加解密)

§json_log: bool

JSON 格式日志

§lang: Option<String>

界面语言 (chs=简体中文, cht=繁体中文, en=英文)

§rest_keys_file: Option<PathBuf>

REST API Bearer Token 鉴权:加载 keys.json(futucli gen-key 生成)

不指定时 REST API 无鉴权(保持旧行为,启动 warn)。

§grpc_keys_file: Option<PathBuf>

gRPC Bearer Token 鉴权:加载 keys.json(futucli gen-key 生成)

不指定时 gRPC 无鉴权。通常与 –rest-keys-file 指向同一文件。

§ws_keys_file: Option<PathBuf>

核心 WebSocket Bearer Token 鉴权:加载 keys.json

v1.0 起核心 WS(--websocket-port,Futu SDK 使用的 binary WS)支持 握手 + per-message scope 鉴权。客户端用 ?token=<plaintext> query 或 Authorization: Bearer <plaintext> header 传 key。不指定这个 flag 时 WS 无鉴权(legacy 保持兼容,启动 warn)。通常与 --rest-keys-file 指向 同一文件。

§allow_tcp_unauthenticated: bool

v1.4.104 eli S-001 (P0) fix: native TCP (FTAPI port --port) 显式 允许无 auth 接受连接.

背景: native TCP FTAPI 协议 (Python SDK / C++ OpenD 用) 没有 Authorization header 概念, InitConnect proto 无 Bearer 字段. 加 keystore 后无法做 caller-specific scope 检查.

默认行为 (v1.4.104+): 配置任一 keys file (--rest-keys-file / --grpc-keys-file / --ws-keys-file) → daemon 关闭 TCP 端口 (fail-closed, 防 v1.4.103 eli S-001 跨 surface bypass).

显式 opt-in 此 flag → 保留 TCP 端口, daemon 启动 loud warn 用户该 端口完全无 auth.

§audit_log: Option<PathBuf>

审计日志输出:JSONL 文件路径或目录

  • 带扩展名的路径(如 /var/log/futu-audit.jsonl)→ 单文件 append
  • 不带扩展名 / 以 / 结尾(如 /var/log/futu-audit/)→ 每日滚动, 文件名 futu-audit.log + 日期后缀

只记录 auth / 交易 事件(target = “futu_audit”),常规日志不受影响。

§tz: Option<String>

v1.4.87 #3 G1: 时区覆盖 (IANA name, 如 “Asia/Hong_Kong” / “America/New_York”)

用于 hours_window 限额检查等 “local time” 语义. 不指定时用系统 TZ 环境变量, 仍未设则用 UTC. 典型场景:

  • Daemon 跑在 UTC server 但想 HK 交易时段限额 → --tz Asia/Hong_Kong
  • Daemon 跑在 local workstation 且 TZ 已正确 → 不用 --tz

优先级: --tz flag > TZ env var > UTC.

Trait Implementations§

Source§

impl Args for Args

Source§

fn group_id() -> Option<Id>

Report the [ArgGroup::id][crate::ArgGroup::id] for this set of arguments
Source§

fn augment_args<'b>(__clap_app: Command) -> Command

Append to [Command] so it can instantiate Self via [FromArgMatches::from_arg_matches_mut] Read more
Source§

fn augment_args_for_update<'b>(__clap_app: Command) -> Command

Append to [Command] so it can instantiate self via [FromArgMatches::update_from_arg_matches_mut] Read more
Source§

impl CommandFactory for Args

Source§

fn command<'b>() -> Command

Build a [Command] that can instantiate Self. Read more
Source§

fn command_for_update<'b>() -> Command

Build a [Command] that can update self. Read more
Source§

impl Debug for Args

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl FromArgMatches for Args

Source§

fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>

Instantiate Self from [ArgMatches], parsing the arguments as needed. Read more
Source§

fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>

Instantiate Self from [ArgMatches], parsing the arguments as needed. Read more
Source§

fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>

Assign values from ArgMatches to self.
Source§

fn update_from_arg_matches_mut( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>

Assign values from ArgMatches to self.
Source§

impl Parser for Args

§

fn parse() -> Self

Parse from std::env::args_os(), [exit][Error::exit] on error.
§

fn try_parse() -> Result<Self, Error>

Parse from std::env::args_os(), return Err on error.
§

fn parse_from<I, T>(itr: I) -> Self
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Parse from iterator, [exit][Error::exit] on error.
§

fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Parse from iterator, return Err on error.
§

fn update_from<I, T>(&mut self, itr: I)
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Update from iterator, [exit][Error::exit] on error. Read more
§

fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,

Update from iterator, return Err on error.

Auto Trait Implementations§

§

impl Freeze for Args

§

impl RefUnwindSafe for Args

§

impl Send for Args

§

impl Sync for Args

§

impl Unpin for Args

§

impl UnsafeUnpin for Args

§

impl UnwindSafe for Args

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more