ZhuLinsen/daily_stock_analysis · warning · DataSourceUnavailableError

Pytdx temporarily unavailable: {self._last_unavailable_reaso

Error message

Pytdx temporarily unavailable: {self._last_unavailable_reason or 'connection cooldown'}

What it means

DataSourceUnavailableError raised at the top of PytdxFetcher._pytdx_session() when the fetcher is in a connection cooldown (set by _mark_connection_cooldown after repeated TDX server connection failures). It signals 'back off, this provider is temporarily down' rather than a permanent failure, and includes the last recorded unavailability reason.

Source

Thrown at data_provider/pytdx_fetcher.py:199

            logger.warning("pytdx 未安装,请运行: pip install pytdx")
            return None
    
    @contextmanager
    def _pytdx_session(self) -> Generator:
        """
        Pytdx 连接上下文管理器
        
        确保:
        1. 进入上下文时自动连接
        2. 退出上下文时自动断开
        3. 异常时也能正确断开
        
        使用示例:
            with self._pytdx_session() as api:
                # 在这里执行数据查询
        """
        if self._is_in_connection_cooldown():
            raise DataSourceUnavailableError(
                f"Pytdx temporarily unavailable: {self._last_unavailable_reason or 'connection cooldown'}"
            )

        TdxHq_API = self._get_pytdx()
        if TdxHq_API is None:
            raise DataFetchError("pytdx 库未安装")
        
        api = TdxHq_API()
        connected = False
        
        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):

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Treat this as transient: catch DataSourceUnavailableError in the DataFetcherManager chain and fall back to another A-share provider (Akshare/Tushare) for the cooldown window.
  2. Fix the root cause of the cooldown: verify outbound TCP connectivity to the TDX hosts (default port 7709) and check _last_unavailable_reason in logs.
  3. If cooldowns are too aggressive/long for your workload, tune the cooldown duration used by _mark_connection_cooldown.

Example fix

# before
with fetcher._pytdx_session() as api:  # DataSourceUnavailableError during cooldown
    data = api.get_security_bars(...)

# after
try:
    with fetcher._pytdx_session() as api:
        data = api.get_security_bars(...)
except DataSourceUnavailableError:
    data = akshare_fetcher.get_stock_data(code, start, end)  # fallback provider
Defensive patterns

Strategy: fallback

Validate before calling

if fetcher._is_in_connection_cooldown():
    reason = fetcher._last_unavailable_reason or "cooldown"
    logger.info(f"pytdx in cooldown ({reason}); using fallback")
    df = akshare_fetcher.get_stock_data(code, start, end)

Try / catch

try:
    with fetcher._pytdx_session() as api:
        data = api.get_security_bars(category=9, market=m, code=c, start=0, count=n)
except DataSourceUnavailableError:
    data = None  # manager moves to the next A-share provider; do not retry pytdx now

Prevention

When it happens

Trigger: Entering the _pytdx_session() context manager after a prior session failed to connect to any TDX host and marked cooldown; the cooldown timer has not yet expired, so every market-data call (get_security_bars, get_security_quotes, ...) raises immediately.

Common situations: TDX quote servers unreachable from the host (firewall, GFW-adjacent network, datacenter blocking port 7709); burst of requests after a network blip triggering cooldown; running scheduled analysis while the network is down.

Related errors


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