{"record":{"id":"4f3be17a8d1b80e1","repo":"ZhuLinsen/daily_stock_analysis","slug":"baostockfetcher-stock-code","errorCode":null,"errorMessage":"BaostockFetcher 不支持北交所 {stock_code}，将自动切换其他数据源","messagePattern":"BaostockFetcher 不支持北交所 (.+?)，将自动切换其他数据源","errorType":"exception","errorClass":"DataFetchError","httpStatus":null,"severity":"warning","filePath":"data_provider/baostock_fetcher.py","lineNumber":213,"sourceCode":"        \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:\n                # 查询日线数据\n                # adjustflag: 1-后复权，2-前复权，3-不复权\n                rs = bs.query_history_k_data_plus(\n                    code=bs_code,\n                    fields=\"date,open,high,low,close,volume,amount,pctChg\",\n                    start_date=start_date,\n                    end_date=end_date,\n                    frequency=\"d\",  # 日线","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/baostock_fetcher.py#L195-L231","documentation":"A guard DataFetchError raised in BaostockFetcher when is_bse_code(stock_code) is True — Beijing Stock Exchange codes (8xxxxx/4xxxxx style). Baostock does not cover BSE, so the fetcher raises with a message explicitly noting it will auto-switch sources ('将自动切换其他数据源'), matching the manager's fallback semantics.","triggerScenarios":"Fetching BSE tickers such as '832566' or '430047' through BaostockFetcher. Deterministic guard before any baostock login/query, so the cost is just one exception in the fallback loop.","commonSituations":"Watchlists including BSE/NEEQ names after 2021 BSE launch; 8-prefixed codes colliding with Shenzhen prefixes in naive routing logic; users surprised Baostock lacks BSE coverage.","solutions":["Route BSE codes to a BSE-capable source (e.g. Akshare's eastmoney interfaces).","In a manager loop, catch and continue on this message — it is a skip, not a failure.","Tag BSE codes in config so routing happens before the fetcher chain."],"exampleFix":"# before\ndf = baostock_fetcher.fetch('832566', start, end)  # raises\n\n# after\nfrom src.utils.stock_utils import is_bse_code\nif is_bse_code(code):\n    df = akshare_fetcher.fetch(code, start, end)  # BSE-capable\nelse:\n    df = baostock_fetcher.fetch(code, start, end)","handlingStrategy":"fallback","validationCode":"from src.utils.stock_utils import is_bse_code\nif is_bse_code(code):\n    fetcher = akshare_fetcher  # BSE-capable source","typeGuard":"from src.utils.stock_utils import is_bse_code\n\ndef is_baostock_eligible(code: str) -> bool:\n    \"\"\"Baostock covers A-shares only; BSE (8xx/4xx) must go elsewhere.\"\"\"\n    return not is_bse_code(code)","tryCatchPattern":"try:\n    df = baostock_fetcher.fetch(code, start, end)\nexcept DataFetchError as e:\n    if '北交所' in str(e):\n        df = akshare_fetcher.fetch(code, start, end)\n    else:\n        raise","preventionTips":["Tag BSE codes in config so routing happens before any fetch attempt.","Know Baostock's coverage (mainland A-shares only) when adding new markets to watchlists.","Treat the '将自动切换其他数据源' message as a designed skip, not an incident."],"tags":["baostock","bse","market-routing","guard"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}