{"record":{"id":"fd8fabda659cb120","repo":"HKUDS/Vibe-Trading","slug":"no-futu-opend-gateway-is-listening-at-cfg-host","errorCode":null,"errorMessage":"No Futu OpenD gateway is listening at {cfg.host}:{cfg.port}. Start OpenD, log in, and confirm the API port.","messagePattern":"No Futu OpenD gateway is listening at (.+?):(.+?)\\. Start OpenD, log in, and confirm the API port\\.","errorType":"exception","errorClass":"FutuConfigError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/futu/sdk.py","lineNumber":993,"sourceCode":"        import futu  # type: ignore\n    except ModuleNotFoundError as exc:\n        raise FutuDependencyError(\"futu-api is not installed; run `pip install futu-api`.\") from exc\n    return futu\n\n\ndef tcp_port_open(host: str, port: int, timeout: float = 0.5) -> bool:\n    \"\"\"Return whether a TCP socket accepts connections.\"\"\"\n    try:\n        with socket.create_connection((host, int(port)), timeout=timeout):\n            return True\n    except OSError:\n        return False\n\n\ndef _assert_gateway(cfg: FutuConfig) -> None:\n    \"\"\"Fail with a clean error when the local OpenD gateway is unreachable.\"\"\"\n    if not tcp_port_open(cfg.host, cfg.port):\n        raise FutuConfigError(\n            f\"No Futu OpenD gateway is listening at {cfg.host}:{cfg.port}. \"\n            \"Start OpenD, log in, and confirm the API port.\"\n        )\n\n\ndef _trade_ctx(cfg: FutuConfig):\n    \"\"\"Open an ``OpenSecTradeContext`` against the local OpenD gateway.\"\"\"\n    _assert_gateway(cfg)\n    futu = _require_futu()\n    trd_market = getattr(futu.TrdMarket, cfg.filter_trdmarket, getattr(futu.TrdMarket, \"HK\"))\n    security_firm = getattr(futu.SecurityFirm, cfg.security_firm, getattr(futu.SecurityFirm, \"FUTUSECURITIES\"))\n    try:\n        return futu.OpenSecTradeContext(\n            filter_trdmarket=trd_market,\n            host=cfg.host,\n            port=cfg.port,\n            security_firm=security_firm,\n        )","sourceCodeStart":975,"sourceCodeEnd":1011,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/futu/sdk.py#L975-L1011","documentation":"Raised by _assert_gateway when the configured Futu OpenD gateway host:port does not accept TCP connections. All trading/quote context creation requires the local OpenD gateway to be running.","triggerScenarios":"OpenD desktop app not started, wrong host/port in FutuConfig (default port mismatch), OpenD listening on a different port, firewall blocking localhost port.","commonSituations":"Dev forgot to launch OpenD; OpenD configured with a custom API port not mirrored in the SDK config; OpenD still booting; Docker networking where localhost isn't the host.","solutions":["Start Futu OpenD and log in","Verify the OpenD API port matches cfg.host/cfg.port (check OpenD settings)","If OpenD is in Docker/remote, set host/port accordingly instead of localhost","Wait for OpenD to fully initialize before first API call"],"exampleFix":"// before\n{\"host\": \"127.0.0.1\", \"port\": 11111}\n// after (OpenD on custom port 33333)\n{\"host\": \"127.0.0.1\", \"port\": 33333}","handlingStrategy":"validation","validationCode":"from src.trading.connectors.futu.sdk import tcp_port_open, load_config\ncfg = load_config()\nif not tcp_port_open(cfg.host, cfg.port, 1.0):\n    raise RuntimeError('start Futu OpenD before trading')","typeGuard":null,"tryCatchPattern":"try:\n    positions = get_positions()\nexcept FutuConfigError as exc:\n    if 'OpenD gateway' in str(exc):\n        notify_user('Please launch Futu OpenD and log in')\n    raise","preventionTips":["Probe the OpenD port at startup with tcp_port_open before any API call","Keep the configured port in sync with OpenD's API port setting","In Docker, point host at the host gateway, not 127.0.0.1"],"tags":["futu","opend","gateway","connection-refused"],"backgroundTag":"gateway-connection-refused","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}