Skip to content

Leveraged Forex account discovery and reads

These reads require acc:read, with no additional qot:read requirement. A nonempty API-key market allowlist must contain FX. They are disabled by default and use the existing experimental-read switch. Live backend behavior is unverified.

REST MCP / CLI
POST /api/get-forex-accounts futu_get_forex_accounts / get-forex-accounts
POST /api/get-forex-risk-control futu_get_forex_risk_control / get-forex-risk-control
POST /api/get-forex-symbol-configs futu_get_forex_symbol_configs / get-forex-symbol-configs
POST /api/get-forex-account-quote-context futu_get_forex_account_quote_context / get-forex-account-quote-context
POST /api/get-forex-assets futu_get_forex_assets / get-forex-assets
POST /api/preview-forex-margin futu_preview_forex_margin / preview-forex-margin

Every request requires broker_id and extension_version: 1. The source currently covers HK (1001) and SG (1008). Selection must resolve to a currently authenticated broker and never grants account access. MCP forwards the current caller through the configured OpenD REST URL. CLI uses --rest-url, --api-key, and --c2s-json.

Discover accounts first and use the returned long account_id. Inventory reports common_state, granted_state, known_empty, and batch revision. Stale rows retained during an incomplete refresh are display-only and cannot authorize the next read. Explicit refresh is finite, with no polling. Each caller's final result uses that caller's current account permissions. An empty account allowlist retains the existing ordinary-read unrestricted meaning.

Risk control additionally requires account_id. Margin preview requires account_id, stock_id, volume_scaled, and at least one nonempty price_buy or price_sell. Volume is an exact unsigned integer: 100000000 represents one lot; zero is valid and differs from omission. Price strings are not converted to floating point. Empty sides are omitted. The trading symbol comes from one current authoritative static record, never a caller override.

Responses retain raw status, amount strings, both preview sides, four-language labels, and optional-field presence. Business errors retain the complete public response without internal diagnostic text. Missing amounts are not replaced with zero, and currencies are not inferred. The backend Forex market identifier is not public TrdMarket=9.

These endpoints do not place orders, change TP/SL, close positions, or transfer funds. They do not claim that the full Forex trading workflow is available. Account metadata supports selection without exposing KYC details or sibling accounts.

Asset reads also require account_id, currency, exclude_zero_positions, use_option_combo, exclude_delisted, and quote_options. Currency must be USD, HKD, CNH, SGD, JPY, or KRW. Quote options contain before, after, and overnight. All six booleans must be explicit; false is valid. The current authenticated state supplies quote permissions, overnight capability and any available unlock cipher; callers cannot override them. A requested overnight option is omitted when the broker is known not to support it; unknown capability rejects the read.

Asset output preserves aggregate and market funds, cash combinations, position groups, position limits and underlying margins, including raw string precision and field absence. Internal diagnostics and compatibility responses are excluded. Foreign account references or changes to qualification, caller permissions or connection ownership fail the request. Missing aggregate funds cannot produce empty success. This read does not update ordinary trading account funds or positions caches.

get-forex-account-quote-context requires broker_id, the current Forex account_id, and extension_version: 1. It returns raw retcode, group_name, and system_mode, preserving absent fields, empty group names and unknown mode values. A successfully received empty message can return all three fields absent: this means no context was returned. It does not grant quote or trading authority. The read does not set a global group, subscribe, poll or refresh a cache. Transport and decode failures remain errors; business errors retain safe response data.

get-forex-symbol-configs requires only broker_id and extension_version: 1. It reads raw settings for the authenticated broker without account discovery; account-limited keys with acc:read and the required FX market access may use it. Output preserves all eight symbol fields, absence, empty strings, raw numbers, list order and duplicates. Empty success means no configuration was returned. The list is not trading authority, and digits is not the stock price-accuracy field. No cache, subscription or configuration is changed.

Forex trade unlock describes explicit credential management.

Shared display quotes

The regular Qot_Sub, Qot_GetBasicQot, Qot_GetRT, Qot_GetKL and Qot_RequestHistoryKL interfaces accept securities with market: 81 for shared Forex quotes. Enable desktop_phase2_reads and grant qot:read; a nonempty market allowlist must include FX. These use the regular quote request shapes, without the account extensions' broker_id, account_id or extension_version fields.

Basic, RT and the existing fifteen KLine periods are supported. Basic, RT and current KLine reads retain their subscription requirements. Historical KLine reads retain quota rules and do not populate the live KLine cache. Forward and backward adjustment follow the current dividend policy; ETH/ALL normalize to RTH in this shared Forex display mode. The current login session determines the shared display context; these quotes do not establish account-group trading prices.

Reads, cache updates, first pushes and continuous pushes check the current source. Subscription-based reads and native first pushes also recheck their original subscription, preventing queued work from becoming valid again after unsubscription and re-registration. Native clients retain push-registration requirements; REST WebSocket and gRPC retain their existing scope and market filters. The feature is disabled by default. Live backend behavior is unverified.