{"record":{"id":"a9271758234ab323","repo":"ZhuLinsen/daily_stock_analysis","slug":"baostockfetcher-stock-code-aksharefetc","errorCode":null,"errorMessage":"BaostockFetcher 不支持美股 {stock_code}，请使用 AkshareFetcher 或 YfinanceFetcher","messagePattern":"BaostockFetcher 不支持美股 (.+?)，请使用 AkshareFetcher 或 YfinanceFetcher","errorType":"exception","errorClass":"DataFetchError","httpStatus":null,"severity":"warning","filePath":"data_provider/baostock_fetcher.py","lineNumber":205,"sourceCode":"        retry=retry_if_exception_type((ConnectionError, TimeoutError)),\n        before_sleep=before_sleep_log(logger, logging.WARNING),\n    )\n    def _fetch_raw_data(self, stock_code: str, start_date: str, end_date: str) -> pd.DataFrame:\n        \"\"\"\n        从 Baostock 获取原始数据\n        \n        使用 query_history_k_data_plus() 获取日线数据\n        \n        流程：\n        1. 检查是否为美股（不支持）\n        2. 使用上下文管理器管理连接\n        3. 转换股票代码格式\n        4. 调用 API 查询数据\n        5. 将结果转换为 DataFrame\n        \"\"\"\n        # 美股不支持，抛出异常让 DataFetcherManager 切换到其他数据源\n        if _is_us_code(stock_code):\n            raise DataFetchError(f\"BaostockFetcher 不支持美股 {stock_code}，请使用 AkshareFetcher 或 YfinanceFetcher\")\n\n        # 港股不支持，抛出异常让 DataFetcherManager 切换到其他数据源\n        if _is_hk_market(stock_code):\n            raise DataFetchError(f\"BaostockFetcher 不支持港股 {stock_code}，请使用 AkshareFetcher\")\n\n        # 北交所不支持，抛出异常让 DataFetcherManager 切换到其他数据源\n        if is_bse_code(stock_code):\n            raise DataFetchError(\n                f\"BaostockFetcher 不支持北交所 {stock_code}，将自动切换其他数据源\"\n            )\n        \n        # 转换代码格式\n        bs_code = self._convert_stock_code(stock_code)\n        \n        logger.debug(f\"调用 Baostock query_history_k_data_plus({bs_code}, {start_date}, {end_date})\")\n        \n        with self._baostock_session() as bs:\n            try:","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/baostock_fetcher.py#L187-L223","documentation":"A guard DataFetchError raised at the top of BaostockFetcher's fetch path when _is_us_code(stock_code) is True. Baostock covers only mainland A-shares; US tickers are rejected immediately (before code conversion or login) with a message naming the correct sources (Akshare or Yfinance). The intent is for DataFetcherManager to catch it and fall through to a US-capable fetcher.","triggerScenarios":"Passing US tickers ('AAPL', 'AMD', 'TSLA') to BaostockFetcher.fetch — typically because Baostock is early in the source priority list and the code format (bare uppercase letters) matches _is_us_code. No network call is made; the raise is deterministic.","commonSituations":"Single default fetcher used for a multi-market watchlist; US ticker with digits (e.g. some tickers) that the heuristic may or may not catch; testing with mixed symbols against one fetcher.","solutions":["Dispatch by market before calling: US symbols go to Akshare/Yfinance/AlphaVantage.","If Baostock must stay in a shared chain, keep it behind market-aware sources or accept the fallback cost.","Verify _is_us_code's heuristic covers your symbol format so US codes never reach the login/query stage."],"exampleFix":"# before\ndf = baostock_fetcher.fetch('AAPL', start, end)  # raises guard\n\n# after\nfrom data_provider.utils import is_us_stock_code\nif is_us_stock_code(code):\n    df = yfinance_fetcher.fetch(code, start, end)\nelse:\n    df = baostock_fetcher.fetch(code, start, end)","handlingStrategy":"validation","validationCode":"from data_provider.utils import is_us_stock_code\nif is_us_stock_code(code):\n    fetcher = yfinance_fetcher  # US goes here\nelse:\n    fetcher = baostock_fetcher","typeGuard":"from data_provider.utils import is_us_stock_code\n\ndef is_baostock_eligible(code: str) -> bool:\n    \"\"\"False for US codes Baostock rejects at its entry guard.\"\"\"\n    return not is_us_stock_code(code)","tryCatchPattern":"try:\n    df = baostock_fetcher.fetch(code, start, end)\nexcept DataFetchError as e:\n    if '不支持美股' in str(e):\n        df = yfinance_fetcher.fetch(code, start, end)\n    else:\n        raise","preventionTips":["Put market-aware dispatch (US → Yfinance/Akshare, A-share → Baostock) in front of the fetcher chain.","Keep US symbols in a separate config group from A-shares.","Log guard-type '不支持' errors at info level — they are routing noise, not faults."],"tags":["baostock","us-stocks","market-routing","guard"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}