ZhuLinsen/daily_stock_analysis · error · FutuPortfolioError
FUTU_ACC_ID 必须是正整数账户 ID
Error message
FUTU_ACC_ID 必须是正整数账户 ID
What it means
FutuPortfolioError raised in _configured_account_id (src/brokers/futu/portfolio.py:149) when FUTU_ACC_ID is set but int() cannot parse its value — e.g. 'abc', '12345 ', partial numbers, or account IDs containing separators. Unset/empty returns None (auto-discovery mode); only a set-but-non-numeric value raises.
Source
Thrown at src/brokers/futu/portfolio.py:149
address = None
if address is not None and address.version != 4:
raise FutuPortfolioError(
"futu-api==10.8.6808 的网络层仅支持 IPv4;"
f"FUTU_OPEND_HOST 当前为 {host!r},请改用 IPv4 地址或可解析到 IPv4 的主机名。"
)
return host, port
def _configured_account_id() -> Optional[int]:
"""Return the optional configured real account ID."""
value = (os.getenv("FUTU_ACC_ID") or "").strip()
if not value:
return None
try:
account_id = int(value)
except ValueError as exc:
raise FutuPortfolioError("FUTU_ACC_ID 必须是正整数账户 ID") from exc
if account_id <= 0:
raise FutuPortfolioError("FUTU_ACC_ID 必须是正整数账户 ID")
return account_id
def _configured_security_firm(api: _FutuApi) -> Any:
"""Resolve one firm, defaulting to the SDK's official auto-detection mode."""
name = (os.getenv("FUTU_SECURITY_FIRM") or "NONE").strip().upper()
firm = getattr(api.SecurityFirm, name, None)
if firm is None:
raise FutuPortfolioError(f"不支持的 FUTU_SECURITY_FIRM: {name}")
return firm
def _discover_real_accounts(api: _FutuApi, host: str, port: int) -> List[_FutuAccount]:
"""Discover explicitly ACTIVE NORMAL or MASTER REAL accounts."""
View on GitHub (pinned to 5159bd72e8)
Solutions
- Set FUTU_ACC_ID to the plain positive integer acc_id (no separators, labels, or quotes); get the exact value from OpenD's get_acc_list payload or leave it unset to auto-discover.
- Retype the .env line manually to remove invisible characters.
- If unsure of the ID, unset FUTU_ACC_ID first, let discovery list accounts, then pin the value.
Example fix
# before (.env) FUTU_ACC_ID=我的账户 / FUTU_ACC_ID=1,234,567 # after (.env) FUTU_ACC_ID=1234567
Defensive patterns
Strategy: validation
Validate before calling
def valid_acc_id_env(raw: str | None) -> bool:
if raw is None or not raw.strip():
return True # unset => auto-discovery
try:
return int(raw.strip()) > 0
except ValueError:
return False Prevention
- Use the numeric acc_id from get_acc_list, not the app display number.
- No separators, labels, or quotes in FUTU_ACC_ID.
- When unsure, unset the variable and let discovery print valid IDs.
When it happens
Trigger: Setting FUTU_ACC_ID to a broker login name, phone, or email instead of the numeric acc_id; values like '1,234,567' or 'ID-12345'; OCR/copy artifacts from the Futu app where the account number was copied with labels or spaces.
Common situations: Confusing the Futu trading account number shown in the app with the numeric acc_id returned by OpenD's get_acc_list; formatting the ID with thousands separators; leftover placeholder text from an .env template.
Related errors
- FUTU_OPEND_PORT 不是有效端口: {raw_port!r}
- Futu OpenD 地址无效: {host!r}:{port}
- 不支持的 FUTU_SECURITY_FIRM: {name}
- TUSHARE_HTTP_URL 必须以 http:// 或 https:// 开头,当前值为 {url!r}
- 加载 Futu OpenAPI SDK 失败: {exc}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/ac40353108fab77e.
Report an issue: GitHub.