main
py 30 lines 1.15 KB
Raw
1 """Durable, provider-free canonical sector discovery."""
2 from __future__ import annotations
3
4 from collections import defaultdict
5 from collections.abc import Iterable
6
7 from app.sector_leaderboard import normalize_sector
8
9
10 def canonical_sector_counts(
11 instruments: Iterable[dict],
12 sector_by_instrument: dict[str, str | None],
13 ) -> list[dict[str, object]]:
14 """Count unique durable instruments by the backend's canonical sector label."""
15 identities_by_sector: dict[str, set[str]] = defaultdict(set)
16 labels: dict[str, str] = {}
17
18 for instrument in instruments:
19 identity = str(instrument.get("globalInstrumentId") or "").strip()
20 raw_sector = sector_by_instrument.get(identity)
21 if not identity or not raw_sector or not str(raw_sector).strip():
22 continue
23 normalized, label = normalize_sector(str(raw_sector))
24 identities_by_sector[normalized].add(identity)
25 labels.setdefault(normalized, label)
26
27 return [
28 {"name": labels[key], "instrumentCount": len(identities_by_sector[key])}
29 for key in sorted(identities_by_sector, key=lambda value: (labels[value].casefold(), labels[value]))
30 ]