{"record":{"id":"76194b5d7fc11335","repo":"ZhuLinsen/daily_stock_analysis","slug":"active-futu-real-master","errorCode":null,"errorMessage":"未找到状态为 ACTIVE 的 Futu REAL 普通或 MASTER 证券账户","messagePattern":"未找到状态为 ACTIVE 的 Futu REAL 普通或 MASTER 证券账户","errorType":"exception","errorClass":"FutuPortfolioError","httpStatus":null,"severity":"error","filePath":"src/brokers/futu/portfolio.py","lineNumber":227,"sourceCode":"            )\n            seen_ids.add(acc_id)\n            accounts.append(_FutuAccount(acc_id=acc_id, security_firm=returned_firm))\n    except FutuPortfolioError:\n        raise\n    except Exception as exc:  # noqa: BLE001 - translate SDK/network failures\n        raise FutuPortfolioError(f\"查询 Futu 真实账户失败: {exc}\") from exc\n    finally:\n        _safe_close(context)\n\n    if requested_acc_id is not None:\n        accounts = [account for account in accounts if account.acc_id == requested_acc_id]\n        if not accounts:\n            raise FutuPortfolioError(\n                \"FUTU_ACC_ID 未匹配到可用的真实证券账户；请检查账户 ID、券商和 OpenD 登录状态。\"\n            )\n\n    if not accounts:\n        raise FutuPortfolioError(\n            \"未找到状态为 ACTIVE 的 Futu REAL 普通或 MASTER 证券账户\"\n        )\n    return accounts\n\n\ndef _load_position_codes(\n    api: _FutuApi,\n    host: str,\n    port: int,\n    accounts: Iterable[_FutuAccount],\n) -> List[str]:\n    \"\"\"Load deduplicated non-zero LONG position codes from selected accounts.\"\"\"\n\n    codes: List[str] = []\n    seen_codes = set()\n    skipped_short_count = 0\n    skipped_unknown_side_count = 0\n","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/brokers/futu/portfolio.py#L209-L245","documentation":"FutuPortfolioError raised in _discover_real_accounts (src/brokers/futu/portfolio.py:227) when no FUTU_ACC_ID is configured and the discovered account list (filtered to trd_env=REAL, acc_status=ACTIVE, acc_role in supported roles) is empty. OpenD answered the query but reports zero usable real trading accounts.","triggerScenarios":"OpenD logged in with trading disabled or no securities account; only a SIMULATE account present; accounts exist but acc_status is not ACTIVE (frozen, pending activation); account role not NORMAL/MASTER; OpenD connected to a market without trading permission.","commonSituations":"Fresh OpenD setup where the Futu account has no opened securities account; accounts frozen by the broker; OpenD logged into a paper-trading profile; missing market/trade permissions on the account.","solutions":["Open the OpenD console and verify a REAL securities account exists with ACTIVE status and trading enabled for the target market.","If only a simulate account exists, switch OpenD login to the real account (this source intentionally excludes SIMULATE).","Re-login OpenD and re-run; status can lag after activation until OpenD refreshes.","If the account role is unusual, check _SUPPORTED_ACCOUNT_ROLES in the module and whether your role (e.g. joint/custody) is supported."],"exampleFix":"# standalone diagnosis — see what OpenD actually reports\nfrom futu import OpenSecTradeContext, TrdMarket, SecurityFirm\nctx = OpenSecTradeContext(host='127.0.0.1', port=11111,\n                          filter_trdmarket=TrdMarket.NONE,\n                          security_firm=SecurityFirm.NONE)\nret, data = ctx.get_acc_list()\nprint(data[['acc_id', 'trd_env', 'acc_status', 'acc_role']])\nctx.close()","handlingStrategy":"validation","validationCode":"def has_active_real_account(rows) -> bool:\n    for row in rows:\n        if str(getattr(row.get('trd_env'), 'name', row.get('trd_env'))).upper() == 'REAL' \\\n           and str(getattr(row.get('acc_status'), 'name', row.get('acc_status'))).upper() == 'ACTIVE':\n            return True\n    return False","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify in the OpenD console that a REAL securities account exists and is ACTIVE before enabling the Futu source.","Remember SIMULATE accounts and non-NORMAL/MASTER roles are excluded by design.","Re-login OpenD after account activation so status refreshes."],"tags":["futu","opend","account","setup"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}