{"record":{"id":"6732c4ed41485527","repo":"ZhuLinsen/daily_stock_analysis","slug":"tusharefetcher-stock-code-aksharefetch","errorCode":null,"errorMessage":"TushareFetcher 不支持美股 {stock_code}，请使用 AkshareFetcher 或 YfinanceFetcher","messagePattern":"TushareFetcher 不支持美股 (.+?)，请使用 AkshareFetcher 或 YfinanceFetcher","errorType":"exception","errorClass":"DataFetchError","httpStatus":null,"severity":"warning","filePath":"data_provider/tushare_fetcher.py","lineNumber":490,"sourceCode":"        从 Tushare 获取原始数据\n        \n        根据代码类型选择不同接口：\n        - 普通股票：daily()\n        - ETF 基金：fund_daily()\n        \n        流程：\n        1. 检查 API 是否可用\n        2. 检查是否为美股（不支持）\n        3. 执行速率限制检查\n        4. 转换股票代码格式\n        5. 根据代码类型选择接口并调用\n        \"\"\"\n        if self._api is None:\n            raise DataFetchError(\"Tushare API 未初始化，请检查 Token 配置\")\n        \n        # US stocks not supported\n        if _is_us_code(stock_code):\n            raise DataFetchError(f\"TushareFetcher 不支持美股 {stock_code}，请使用 AkshareFetcher 或 YfinanceFetcher\")\n        \n        # Rate-limit check\n        self._check_rate_limit()\n        \n        is_hk = _is_hk_market(stock_code)\n         # 判断是否为 ETF / 港股，以选择不同接口\n        is_etf = _is_etf_code(stock_code)\n        if is_hk:\n            ts_code = self._convert_hk_stock_code_for_tushare(stock_code)\n            api_name = \"hk_daily\"\n        else:\n            ts_code = self._convert_stock_code(stock_code)\n            api_name = \"fund_daily\" if is_etf else \"daily\"\n        \n        # Convert date format (Tushare requires YYYYMMDD)\n        ts_start = start_date.replace('-', '')\n        ts_end = end_date.replace('-', '')\n        ","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/tushare_fetcher.py#L472-L508","documentation":"TushareFetcher explicitly rejects US stock codes because Tushare pro has no US daily-quote interface in this integration. The guard runs after the API-init check and before rate limiting, so any US ticker reaching TushareFetcher fails immediately with DataFetchError. The message points at the two fetchers that do support US symbols (AkshareFetcher, YfinanceFetcher).","triggerScenarios":"Passing a US-style code (matched by _is_us_code, e.g. 'AAPL', 'MSFT.US') to TushareFetcher.fetch_stock_data. Happens when the multi-source fetch chain is ordered with Tushare first for a mixed watchlist (e.g. --stocks 600519,hk00700,AAPL) or when a US ETF is misclassified as A-share ETF.","commonSituations":"Mixed A/HK/US stock lists where the fallback chain tries every fetcher per symbol; user configures TUSHARE as preferred source globally; code normalization produces something _is_us_code matches (letters-only tickers).","solutions":["Ensure the data_provider fetcher chain includes AkshareFetcher or YfinanceFetcher so US symbols fall through to a supporting source (this error should trigger fallback, not abort).","If you call fetchers directly, route by market: use YfinanceFetcher/AkshareFetcher for US codes and TushareFetcher only for A-shares/HK/ETF.","Check the stock code format being passed — an A-share code that got mangled into a letter ticker can false-positive this guard.","If the whole run aborts on this error, inspect the fallback orchestrator: a single source rejecting a symbol must not be fatal (AGENTS.md data-source guardrail)."],"exampleFix":"# before\nfetcher = TushareFetcher()\ndf = fetcher.fetch_stock_data('AAPL')  # -> DataFetchError 不支持美股\n\n# after\nfrom data_provider.yfinance_fetcher import YfinanceFetcher\ndf = YfinanceFetcher().fetch_stock_data('AAPL') if _is_us_code('AAPL') else TushareFetcher().fetch_stock_data('AAPL')","handlingStrategy":"type-guard","validationCode":"from data_provider.tushare_fetcher import _is_us_code\n\nif _is_us_code(stock_code):\n    fetcher = yfinance_fetcher  # or akshare_fetcher\nelse:\n    fetcher = tushare_fetcher","typeGuard":"def is_tushare_supported(code: str) -> bool:\n    \"\"\"TushareFetcher covers A-shares/HK/ETF; US codes are rejected.\"\"\"\n    return not _is_us_code(code)","tryCatchPattern":"try:\n    df = tushare_fetcher.fetch_stock_data(code)\nexcept DataFetchError as e:\n    if \"不支持美股\" in str(e):\n        df = yfinance_fetcher.fetch_stock_data(code)\n    else:\n        raise","preventionTips":["Route symbols by market before choosing a fetcher; never send US tickers to TushareFetcher.","Keep Akshare/Yfinance in the chain so this rejection triggers fallback, not abort.","Test the fetch chain with a mixed A/HK/US list in CI."],"tags":["market-coverage","tushare","us-stocks","data-provider"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}