csv-parser: keep LLM-mapped tickers; don't pass them through T212 mapping
The route's resolve-slice loop is T212-specific — it looks tickers up against the InstrumentMap, which only has T212's universe. For the LLM path the ticker is already Yahoo-ready (e.g. VOD.L, ASML.AS), so sending it through resolve_slice produced spurious "could not be resolved" warnings and dropped the positions. Fix: ParsedPie gains a ``tickers_resolved`` flag (default False for T212 backward-compat); _apply_mapping in the LLM path sets it True and also extracts currency from the LLM-mapped currency_col into a new ``ParsedPosition.currency`` field. The route branches on the flag: LLM-path positions are kept verbatim with a best-effort InstrumentMap lookup for nicer name/currency overrides, never dropped. Integration test tightened to assert all 5 IBKR fixture positions round-trip with the right currencies (USD / GBP / EUR). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
b8ebba9503
commit
bc55ab7d26
4 changed files with 74 additions and 13 deletions
|
|
@ -37,7 +37,10 @@ _REQUIRED_FIELDS = ("slice", "quantity")
|
|||
|
||||
@dataclass(frozen=True)
|
||||
class ParsedPosition:
|
||||
slice: str # T212 shortcode, e.g. "SGLN"
|
||||
slice: str # T212 shortcode (e.g. "SGLN") or a
|
||||
# Yahoo-ready ticker (e.g. "VOD.L")
|
||||
# when produced by the LLM path —
|
||||
# see ParsedPie.tickers_resolved.
|
||||
name: str
|
||||
invested_value: float | None
|
||||
current_value: float | None
|
||||
|
|
@ -46,6 +49,10 @@ class ParsedPosition:
|
|||
dividends_gained: float | None = None
|
||||
dividends_cash: float | None = None
|
||||
dividends_reinvested: float | None = None
|
||||
currency: str | None = None # Populated by the LLM path from the
|
||||
# mapped currency_col; the T212 path
|
||||
# leaves it None and gets currency
|
||||
# from the InstrumentMap row.
|
||||
|
||||
@property
|
||||
def average_price(self) -> float | None:
|
||||
|
|
@ -67,6 +74,11 @@ class ParsedPie:
|
|||
invested: float | None # totals from the Total row
|
||||
value: float | None
|
||||
result: float | None
|
||||
tickers_resolved: bool = False # True when ``slice`` on each position
|
||||
# is already a Yahoo-ready ticker
|
||||
# (LLM path). False (default) means
|
||||
# tickers must still be resolved via
|
||||
# the T212 InstrumentMap.
|
||||
|
||||
|
||||
def _normalise_header(h: str) -> str:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue