ZhuLinsen/daily_stock_analysis · error · FutuPortfolioError
FUTU_ACC_ID 未匹配到可用的真实证券账户;请检查账户 ID、券商和 OpenD 登录状态。
Error message
FUTU_ACC_ID 未匹配到可用的真实证券账户;请检查账户 ID、券商和 OpenD 登录状态。
What it means
FutuPortfolioError raised in _discover_real_accounts (src/brokers/futu/portfolio.py:222) when FUTU_ACC_ID is configured but, after filtering discovered ACTIVE REAL accounts, none matches the configured ID. Discovery succeeded — the account list simply does not contain that ID (wrong ID, different broker firm, or the account is not in ACTIVE REAL state in OpenD).
Source
Thrown at src/brokers/futu/portfolio.py:222
returned_firm_name = _enum_text(row.get("security_firm"))
returned_firm = getattr(
api.SecurityFirm,
returned_firm_name,
security_firm,
)
seen_ids.add(acc_id)
accounts.append(_FutuAccount(acc_id=acc_id, security_firm=returned_firm))
except FutuPortfolioError:
raise
except Exception as exc: # noqa: BLE001 - translate SDK/network failures
raise FutuPortfolioError(f"查询 Futu 真实账户失败: {exc}") from exc
finally:
_safe_close(context)
if requested_acc_id is not None:
accounts = [account for account in accounts if account.acc_id == requested_acc_id]
if not accounts:
raise FutuPortfolioError(
"FUTU_ACC_ID 未匹配到可用的真实证券账户;请检查账户 ID、券商和 OpenD 登录状态。"
)
if not accounts:
raise FutuPortfolioError(
"未找到状态为 ACTIVE 的 Futu REAL 普通或 MASTER 证券账户"
)
return accounts
def _load_position_codes(
api: _FutuApi,
host: str,
port: int,
accounts: Iterable[_FutuAccount],
) -> List[str]:
"""Load deduplicated non-zero LONG position codes from selected accounts."""
View on GitHub (pinned to 5159bd72e8)
Solutions
- Unset FUTU_ACC_ID temporarily and let discovery log the available ACTIVE REAL accounts; copy the exact acc_id from that list.
- Confirm OpenD is logged into the broker that owns the account and the account status is ACTIVE in OpenD's UI.
- If you intended paper trading, note this source only supports REAL environments — SIMULATE accounts are filtered by design.
- Fix typos: the ID must be the plain positive integer acc_id.
Example fix
# before (.env) FUTU_ACC_ID=3865276 # app display number # after — discover first, then pin # 1) comment out FUTU_ACC_ID, run once, read logged acc_id values # 2) FUTU_ACC_ID=<exact acc_id from get_acc_list>
Defensive patterns
Strategy: validation
Validate before calling
def acc_id_exists(acc_id: int, discovered) -> bool:
return any(a.acc_id == acc_id for a in discovered) Try / catch
from src.brokers.futu.portfolio import FutuPortfolioError
try:
accounts = discover(api, host, port, requested_acc_id=acc_id)
except FutuPortfolioError as exc:
if '未匹配到可用的真实证券账户' in str(exc):
all_accounts = discover(api, host, port) # unset filter, inspect ids
log.error('configured %s; available: %s', acc_id, [a.acc_id for a in all_accounts])
raise Prevention
- Run discovery once without FUTU_ACC_ID to learn valid IDs, then pin.
- Use the OpenD acc_id, not the app's display account number.
- Remember this source filters to ACTIVE REAL NORMAL/MASTER accounts only.
When it happens
Trigger: FUTU_ACC_ID points to a SIMULATE account (filtered out because trd_env != REAL); the ID belongs to a different security firm than the one OpenD logged into; typo in the ID; the account exists but its acc_status is not ACTIVE; paper-trading IDs used against a real-account filter.
Common situations: Users copying the account number from Futu moomoo app (display number) instead of the OpenD acc_id; accounts under a second broker not logged into OpenD; account frozen/pending so status != ACTIVE.
Related errors
- FUTU_OPEND_PORT 不是有效端口: {raw_port!r}
- Futu OpenD 地址无效: {host!r}:{port}
- futu-api==10.8.6808 的网络层仅支持 IPv4;FUTU_OPEND_HOST 当前为 {host!r
- FUTU_ACC_ID 必须是正整数账户 ID
- 不支持的 FUTU_SECURITY_FIRM: {name}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/af32b7b619e382a6.
Report an issue: GitHub.