ZhuLinsen/daily_stock_analysis · error · DataFetchError

Pytdx 无法连接任何服务器

Error message

Pytdx 无法连接任何服务器

What it means

DataFetchError raised after _pytdx_session() iterates every configured TDX host and none of api.connect(host, port, time_out=5) succeeds. The fetcher then marks a connection cooldown (see error 162) and re-raises, so subsequent calls fail fast for a while.

Source

Thrown at data_provider/pytdx_fetcher.py:228

        try:
            # 尝试连接服务器(自动选择最优)
            for i in range(len(self._hosts)):
                host_idx = (self._current_host_idx + i) % len(self._hosts)
                host, port = self._hosts[host_idx]
                
                try:
                    if api.connect(host, port, time_out=5):
                        connected = True
                        self._current_host_idx = host_idx
                        logger.debug(f"Pytdx 连接成功: {host}:{port}")
                        break
                except Exception as e:
                    logger.debug(f"Pytdx 连接 {host}:{port} 失败: {e}")
                    continue
            
            if not connected:
                self._mark_connection_cooldown("Pytdx 无法连接任何服务器")
                raise DataFetchError("Pytdx 无法连接任何服务器")
            
            yield api
            
        finally:
            # 确保断开连接
            try:
                api.disconnect()
                logger.debug("Pytdx 连接已断开")
            except Exception as e:
                logger.warning(f"Pytdx 断开连接时出错: {e}")
    
    def _get_market_code(self, stock_code: str) -> Tuple[int, str]:
        """
        根据股票代码判断市场
        
        Pytdx 市场代码:
        - 0: 深圳
        - 1: 上海

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Verify outbound connectivity to a known TDX host (e.g. nc <host> 7709) from the runtime host.
  2. Catch DataFetchError at the manager level and fall back to Akshare/Tushare for A-share daily data; the cooldown means retries against pytdx will not help immediately.
  3. Refresh the host list in PytdxFetcher configuration if the public TDX servers have changed.

Example fix

# before
try:
    df = pytdx_fetcher.get_stock_data("600519", start, end)
except DataFetchError as e:
    raise  # every request fails for the cooldown window

# after
try:
    df = pytdx_fetcher.get_stock_data("600519", start, end)
except DataFetchError as e:
    logger.warning(f"pytdx failed, falling back: {e}")
    df = akshare_fetcher.get_stock_data("600519", start, end)
Defensive patterns

Strategy: fallback

Validate before calling

import socket

def tdx_host_reachable(host: str, port: int = 7709, timeout: float = 3.0) -> bool:
    try:
        with socket.create_connection((host, port), timeout=timeout):
            return True
    except OSError:
        return False

Try / catch

try:
    df = pytdx_fetcher.get_stock_data(code, start, end)
except DataFetchError as e:
    if "无法连接任何服务器" in str(e):
        df = akshare_fetcher.get_stock_data(code, start, end)  # cooldown already started; go elsewhere
    else:
        raise

Prevention

When it happens

Trigger: get_security_bars / realtime quote flows when all hosts in self._hosts are unreachable or refuse connections within the 5s timeout: server outage, blocked egress, wrong host list, or DNS resolution issues.

Common situations: Corporate firewall blocking the TDX TCP ports; the hardcoded/public TDX server IP list gone stale; transient ISP-level outage in mainland-China network paths; container with no outbound internet.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/1c35e9b73b869b8c. Report an issue: GitHub.