ZhuLinsen/daily_stock_analysis · error · DataFetchError
Tushare 获取数据失败: {e}
Error message
Tushare 获取数据失败: {e} What it means
The catch-all DataFetchError for TushareFetcher: any exception from the pro API call that does NOT match the quota keywords ('quota'/'配额'/'limit'/'权限') is wrapped here. Typical roots are network failures to api.tushare.pro, invalid/expired token rejected at call time, unsupported ts_code after conversion, or interface-argument errors (bad start/end date).
Source
Thrown at data_provider/tushare_fetcher.py:546
else:
# Regular A-share stocks use daily interface
df = self._api.daily(
ts_code=ts_code,
start_date=ts_start,
end_date=ts_end,
)
return df
except Exception as e:
error_msg = str(e).lower()
# 检测配额超限
if any(keyword in error_msg for keyword in ['quota', '配额', 'limit', '权限']):
logger.warning(f"Tushare 配额可能超限: {e}")
raise RateLimitError(f"Tushare 配额超限: {e}") from e
raise DataFetchError(f"Tushare 获取数据失败: {e}") from e
def _normalize_data(self, df: pd.DataFrame, stock_code: str) -> pd.DataFrame:
"""
标准化 Tushare 数据
Tushare daily / fund_daily 返回的列名:
ts_code, trade_date, open, high, low, close, pre_close, change, pct_chg, vol, amount
需要映射到标准列名:
date, open, high, low, close, volume, amount, pct_chg
单位缩放仅适用于 A 股(及 ETF 等使用同一套单位的接口):
- vol 按「手」计,乘以 100 转为「股」
- amount 按「千元」计,乘以 1000 转为「元」
港股 hk_daily 返回的 vol / amount 已是可直接使用的量级,不做上述缩放。
"""
df = df.copy()View on GitHub (pinned to 5159bd72e8)
Solutions
- Read the chained cause (raise ... from e) — the original exception text in {e} identifies network vs auth vs argument errors.
- Verify the converted ts_code: python -c on _convert_stock_code for the failing symbol and test it on tushare.pro's online console.
- Check connectivity/egress to api.tushare.pro and retry transient network failures.
- If persistent, let the fallback chain serve the symbol from Akshare/Yfinance and file the ts_code issue with the converter.
Defensive patterns
Strategy: fallback
Validate before calling
import socket
# cheap reachability check before a batch run
try:
socket.create_connection(("api.tushare.pro", 443), timeout=5).close()
reachable = True
except OSError:
reachable = False Try / catch
try:
df = tushare_fetcher.fetch_stock_data(code)
except DataFetchError as e:
logger.warning("Tushare failed for %s: %s; falling back", code, e)
df = akshare_fetcher.fetch_stock_data(code) # or yfinance, per market Prevention
- Always chain data sources; a single-source failure must not abort the analysis run (repo guardrail).
- Log the wrapped cause chain (e.__cause__) — the real reason is in the original exception.
- Smoke-test ts_code conversion for new symbol formats before batch runs.
When it happens
Trigger: POST to api.tushare.pro timing out or DNS-failing; token invalidated after construction; _convert_stock_code producing a ts_code Tushare rejects; passing dates where ts_start > ts_end or in wrong format; HK code routed to hk_daily without permission (message lacking quota keywords).
Common situations: Running in CI/scheduled Actions with restricted egress; token rotated but process holds old config; watchlist containing codes (e.g. odd ETF prefixes) the converter mishandles; weekends/holidays yielding empty ranges that some interfaces reject.
Related errors
- {call_name} 调用超过 {wait_seconds:g}s,已放弃等待
- Akshare 所有渠道获取失败: {last_error}
- Akshare 获取 ETF 数据失败: {e}
- [AlphaVantage] HTTP request failed for {symbol}: {e}
- {market_label} {stock_code} 获取失败: {errors joined by newline}
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/a3da4780d1761b65.
Report an issue: GitHub.