{"record":{"id":"db94361ed739a979","repo":"ZhuLinsen/daily_stock_analysis","slug":"cannot-convert-stock-code-to-longbridge-symbol","errorCode":null,"errorMessage":"Cannot convert {stock_code} to Longbridge symbol","messagePattern":"Cannot convert (.+?) to Longbridge symbol","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"data_provider/longbridge_fetcher.py","lineNumber":877,"sourceCode":"            f\"[Longbridge] {symbol} 行情获取成功: \"\n            f\"价格={price}, 量比={volume_ratio}, 换手率={turnover_rate}\"\n        )\n        return quote\n\n    # ------------------------------------------------------------------\n    # BaseFetcher abstract methods (historical daily data)\n    # ------------------------------------------------------------------\n\n    def _fetch_raw_data(\n        self, stock_code: str, start_date: str, end_date: str\n    ) -> pd.DataFrame:\n        \"\"\"Fetch historical candlesticks from Longbridge.\"\"\"\n        if not self.is_available_for_request(\"daily_data\"):\n            raise RuntimeError(\"Longbridge temporarily unavailable for daily_data\")\n\n        symbol = _to_longbridge_symbol(stock_code)\n        if symbol is None:\n            raise ValueError(f\"Cannot convert {stock_code} to Longbridge symbol\")\n\n        ctx = self._get_ctx()\n        if ctx is None:\n            raise RuntimeError(\"Longbridge QuoteContext not available\")\n\n        from longbridge.openapi import Period, AdjustType\n\n        start_dt = datetime.strptime(start_date, \"%Y-%m-%d\").date()\n        end_dt = datetime.strptime(end_date, \"%Y-%m-%d\").date()\n\n        try:\n            candles = ctx.history_candlesticks_by_date(\n                symbol,\n                Period.Day,\n                AdjustType.ForwardAdjust,\n                start_dt,\n                end_dt,\n            )","sourceCodeStart":859,"sourceCodeEnd":895,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/longbridge_fetcher.py#L859-L895","documentation":"Raised by LongbridgeFetcher._fetch_raw_data when the helper _to_longbridge_symbol(stock_code) returns None, meaning the stock code cannot be mapped to a Longbridge-compatible symbol (e.g. US/HK/A-share formats outside its supported mapping). It is a ValueError raised before any network call, acting as a market-coverage guard so the DataFetcherManager can fail over to another provider.","triggerScenarios":"Calling fetch of historical daily data (BaseFetcher._fetch_raw_data) via LongbridgeFetcher with a stock code whose market/prefix is not covered by _to_longbridge_symbol, e.g. unsupported exchange suffixes, malformed codes, or markets Longbridge does not serve.","commonSituations":"Routing the whole stock universe (A股/港股/美股) through LongbridgeFetcher without market filtering; typos or non-normalized codes reaching the fetcher; adding a new market to the pipeline without extending _to_longbridge_symbol.","solutions":["Verify the stock code is a market Longbridge supports and normalize it before calling the fetcher.","Check/extend _to_longbridge_symbol in data_provider/longbridge_fetcher.py to cover the code format you pass in.","If the market is intentionally unsupported, exclude LongbridgeFetcher from that market's data source priority list so the manager picks Akshare/Yfinance instead."],"exampleFix":"// before\nfetcher = LongbridgeFetcher()\ndf = fetcher.get_stock_data(\"600519.XSHG\", \"2026-01-01\", \"2026-02-01\")  # ValueError\n\n// after\nfrom src.utils.stock_utils import normalize_stock_code\nsymbol_supported = _to_longbridge_symbol(normalize_stock_code(\"600519\")) is not None\nif symbol_supported:\n    df = fetcher.get_stock_data(normalize_stock_code(\"600519\"), \"2026-01-01\", \"2026-02-01\")\nelse:\n    df = manager.get_stock_data(...)  # route via DataFetcherManager fallback","handlingStrategy":"validation","validationCode":"from data_provider.longbridge_fetcher import _to_longbridge_symbol\nfrom src.utils.stock_utils import normalize_stock_code\n\ndef longbridge_supports(stock_code: str) -> bool:\n    return _to_longbridge_symbol(normalize_stock_code(stock_code)) is not None","typeGuard":"def is_longbridge_symbol(code: str) -> bool:\n    \"\"\"True when the code maps to a Longbridge symbol.\"\"\"\n    return _to_longbridge_symbol(normalize_stock_code(code)) is not None","tryCatchPattern":"try:\n    df = longbridge_fetcher.get_stock_data(code, start, end)\nexcept ValueError as e:\n    if \"Cannot convert\" in str(e):\n        df = manager.get_stock_data(code, start, end)  # next provider\n    else:\n        raise","preventionTips":["Normalize every stock code before passing it to any provider.","Keep per-market provider chains so unsupported markets never reach LongbridgeFetcher.","Add unit tests covering each market's symbol conversion for every provider you enable."],"tags":["longbridge","symbol-mapping","market-coverage","validation"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}