Feature request: UK market support
The loader layer and MCP get_market_data support US, HK, India, Korea, Canada, Vietnam, and crypto — but not UK equities. LSE (.L) symbols currently resolve to _unresolved.
Current failure (the motivation)
Root cause: _SOURCE_PATTERNS has no .L rule, so UK symbols fall through to the tushare default. _detect_market also defaults them to a_share. The symbol is then routed down the China fallback chain (tencent → mootdx → eastmoney → baostock → akshare → tushare → local), which cannot serve LSE — several seconds of network attempts later it surfaces _unresolved, indistinguishable from a genuinely dead ticker.
Forcing source=yahoo works today:
VOD.L → OK 15 bars (close 116.60, 2026-08-04)
SHEL.L → OK 15 bars
HSBA.L → OK 15 bars
Proposal (working fix, locally verified)
Treat UK as a first-class market with the same parity as Canada/US:
-
src/market_data.py — _SOURCE_PATTERNS: add ^[A-Z0-9&.\-]+\.L$ → yahoo (mirrors Canada .TO/.V); yahoo_loader _is_supported gate: add .L/.IL
-
backtest/engines/_market_hooks.py — _MARKET_PATTERNS: add .L → uk_equity; _MARKET_CURRENCY: uk_equity: GBP (currently returns UNKNOWN:uk_equity)
-
backtest/loaders/registry.py — FALLBACK_CHAINS: add "uk_equity": ["yahoo", "yfinance", "local"] (mirrors ca_equity)
-
backtest/runner.py — _MARKET_TO_SOURCE: add uk_equity: yahoo (currently backtests silently fall to the tushare engine); composite dispatch → GlobalEquityEngine(market="uk")
-
Price units — Yahoo serves LSE names in pence (GBp): VOD.L close is ~117p, HSBA.L ~1500p; without normalization the engine prices a £1.17 share at £117 (100× notional error on positions, and on SDRT). Normalize OHLC ÷100 at the loader boundary (Yahoo chart-meta currency == "GBp"; yfinance fallback suffix rule), declare currency_conversion in provenance, bump loader cache version so pre-normalization parquet is never served
-
SDRT cost model — 0.5% Stamp Duty Reserve Tax on purchases, penny rounding with exact-½p rounds-up (HMRC FA86/S99(13), STSM014030)
Exemptions scope (deliberate): we model the statutory Main Market rate only. AIM shares, UCITS ETFs, gilts and new issues are not auto-detected — the engine has no symbol-aware asset-class classification (per-symbol tax databases drift; a wrong exemption is worse than the flat rate). Caller's control surface: uk_stamp_tax: 0.0 exempts a whole run (exempt-only baskets). The known boundary: a mixed Main-Market + exempt basket in one run pays statutory on everything. Possible follow-up (not built): per-symbol exempt config (uk_stamp_tax_exempt: [...]), which requires widening calc_commission to carry the symbol; AIM auto-detection via Yahoo exchange metadata is feasible, UCITS/new-issue auto-detection is not recommended.
-
Journal/shadow consumers — _infer_market_from_symbol: .L → "uk" (journal trades currently land in "other" and shadow analysis silently degrades to NaN price features); shadow _MARKET_KEY_MAP/labels: uk → uk_equity, "UK equity"
-
Financial statements — `get_financial_statements`: `.L` → Yahoo quoteSummary (income/balance/cashflow annual histories + indicators); `get_fundamentals` stays US-only by contract (SEC XBRL PIT panels — no honest UK source for filed-date PIT), fails loud for UK
-
Tests: source/market/submarket/currency; yahoo + yfinance GBp scaling; market-data provenance; engine economics incl. HMRC rounding cases; journal inference; registry chain contract
Question to maintainers
Is UK support in scope for the project? Happy to adjust scope per your call. Remaining candidates for follow-ups: London market-open spec in MARKET_SPECS (missing market fails loud today, never silent) and symbol-search UK suffix hints.
Feature request: UK market support
The loader layer and MCP
get_market_datasupport US, HK, India, Korea, Canada, Vietnam, and crypto — but not UK equities. LSE (.L) symbols currently resolve to_unresolved.Current failure (the motivation)
Root cause:
_SOURCE_PATTERNShas no.Lrule, so UK symbols fall through to thetusharedefault._detect_marketalso defaults them toa_share. The symbol is then routed down the China fallback chain (tencent → mootdx → eastmoney → baostock → akshare → tushare → local), which cannot serve LSE — several seconds of network attempts later it surfaces_unresolved, indistinguishable from a genuinely dead ticker.Forcing
source=yahooworks today:Proposal (working fix, locally verified)
Treat UK as a first-class market with the same parity as Canada/US:
src/market_data.py—_SOURCE_PATTERNS: add^[A-Z0-9&.\-]+\.L$→yahoo(mirrors Canada.TO/.V); yahoo_loader_is_supportedgate: add.L/.ILbacktest/engines/_market_hooks.py—_MARKET_PATTERNS: add.L→uk_equity;_MARKET_CURRENCY:uk_equity: GBP(currently returnsUNKNOWN:uk_equity)backtest/loaders/registry.py—FALLBACK_CHAINS: add"uk_equity": ["yahoo", "yfinance", "local"](mirrorsca_equity)backtest/runner.py—_MARKET_TO_SOURCE: adduk_equity: yahoo(currently backtests silently fall to thetushareengine); composite dispatch →GlobalEquityEngine(market="uk")Price units — Yahoo serves LSE names in pence (GBp): VOD.L close is ~117p, HSBA.L ~1500p; without normalization the engine prices a £1.17 share at £117 (100× notional error on positions, and on SDRT). Normalize OHLC ÷100 at the loader boundary (Yahoo chart-meta
currency == "GBp"; yfinance fallback suffix rule), declarecurrency_conversionin provenance, bump loader cache version so pre-normalization parquet is never servedSDRT cost model — 0.5% Stamp Duty Reserve Tax on purchases, penny rounding with exact-½p rounds-up (HMRC FA86/S99(13), STSM014030)
Exemptions scope (deliberate): we model the statutory Main Market rate only. AIM shares, UCITS ETFs, gilts and new issues are not auto-detected — the engine has no symbol-aware asset-class classification (per-symbol tax databases drift; a wrong exemption is worse than the flat rate). Caller's control surface:
uk_stamp_tax: 0.0exempts a whole run (exempt-only baskets). The known boundary: a mixed Main-Market + exempt basket in one run pays statutory on everything. Possible follow-up (not built): per-symbol exempt config (uk_stamp_tax_exempt: [...]), which requires wideningcalc_commissionto carry the symbol; AIM auto-detection via Yahoo exchange metadata is feasible, UCITS/new-issue auto-detection is not recommended.Journal/shadow consumers —
_infer_market_from_symbol:.L→"uk"(journal trades currently land in"other"and shadow analysis silently degrades to NaN price features); shadow_MARKET_KEY_MAP/labels:uk→uk_equity,"UK equity"Financial statements — `get_financial_statements`: `.L` → Yahoo quoteSummary (income/balance/cashflow annual histories + indicators); `get_fundamentals` stays US-only by contract (SEC XBRL PIT panels — no honest UK source for filed-date PIT), fails loud for UK
Tests: source/market/submarket/currency; yahoo + yfinance GBp scaling; market-data provenance; engine economics incl. HMRC rounding cases; journal inference; registry chain contract
Question to maintainers
Is UK support in scope for the project? Happy to adjust scope per your call. Remaining candidates for follow-ups: London market-open spec in
MARKET_SPECS(missing market fails loud today, never silent) and symbol-search UK suffix hints.