HKUDS/Vibe-Trading · error · FutuConfigError

No Futu OpenD gateway is listening at {cfg.host}:{cfg.port}.

Error message

No Futu OpenD gateway is listening at {cfg.host}:{cfg.port}. Start OpenD, log in, and confirm the API port.

What it means

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.

Source

Thrown at agent/src/trading/connectors/futu/sdk.py:993

        import futu  # type: ignore
    except ModuleNotFoundError as exc:
        raise FutuDependencyError("futu-api is not installed; run `pip install futu-api`.") from exc
    return futu


def tcp_port_open(host: str, port: int, timeout: float = 0.5) -> bool:
    """Return whether a TCP socket accepts connections."""
    try:
        with socket.create_connection((host, int(port)), timeout=timeout):
            return True
    except OSError:
        return False


def _assert_gateway(cfg: FutuConfig) -> None:
    """Fail with a clean error when the local OpenD gateway is unreachable."""
    if not tcp_port_open(cfg.host, cfg.port):
        raise FutuConfigError(
            f"No Futu OpenD gateway is listening at {cfg.host}:{cfg.port}. "
            "Start OpenD, log in, and confirm the API port."
        )


def _trade_ctx(cfg: FutuConfig):
    """Open an ``OpenSecTradeContext`` against the local OpenD gateway."""
    _assert_gateway(cfg)
    futu = _require_futu()
    trd_market = getattr(futu.TrdMarket, cfg.filter_trdmarket, getattr(futu.TrdMarket, "HK"))
    security_firm = getattr(futu.SecurityFirm, cfg.security_firm, getattr(futu.SecurityFirm, "FUTUSECURITIES"))
    try:
        return futu.OpenSecTradeContext(
            filter_trdmarket=trd_market,
            host=cfg.host,
            port=cfg.port,
            security_firm=security_firm,
        )

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Start Futu OpenD and log in
  2. Verify the OpenD API port matches cfg.host/cfg.port (check OpenD settings)
  3. If OpenD is in Docker/remote, set host/port accordingly instead of localhost
  4. Wait for OpenD to fully initialize before first API call

Example fix

// before
{"host": "127.0.0.1", "port": 11111}
// after (OpenD on custom port 33333)
{"host": "127.0.0.1", "port": 33333}
Defensive patterns

Strategy: validation

Validate before calling

from src.trading.connectors.futu.sdk import tcp_port_open, load_config
cfg = load_config()
if not tcp_port_open(cfg.host, cfg.port, 1.0):
    raise RuntimeError('start Futu OpenD before trading')

Try / catch

try:
    positions = get_positions()
except FutuConfigError as exc:
    if 'OpenD gateway' in str(exc):
        notify_user('Please launch Futu OpenD and log in')
    raise

Prevention

When it happens

Trigger: OpenD desktop app not started, wrong host/port in FutuConfig (default port mismatch), OpenD listening on a different port, firewall blocking localhost port.

Common situations: 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.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/fd8fabda659cb120. Report an issue: GitHub.