You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[design·P2] A weekly review given part of the book withdraws its current-view figures — computing them over the canonical book is the other half of #630 #634
Design. Follow-up to #630, which stopped the wrong number but did not deliver the right one. Needs owner scoping before implementation — the cheap versions are all wrong in a way that is hard to see.
#630's acceptance had two halves. The landed fix delivers one:
A weekly file covering part of the book no longer publishes a whole-book claim measured over it. The current-view surfaces are withdrawn and the gap is disclosed (accounting_reconciliation), the durable metrics stay None instead of 1.0, engine_state.holdings becomes the canonical ledger book, and no oversize/concentration breach is recorded from the partial view.
It does not compute concentration over the canonical book. A user who hands in only this period's trades now gets no sizing, diversification, ETF-structure, unrealized-P&L, what-if or per-ticker reading that week, where a user who re-supplies the whole history gets all of them.
Withdrawing is the fail-closed answer and it is a strict improvement on a fabricated 100%. It is not the answer the product wants: handing over the new trades is ordinary use, nothing in flows/weekly-review.md asks for a cumulative file, and the ingest path is built to append incrementals.
Why this is not a small change
The engine's whole current-book view is derived from the supplied rows, in trade_recap.main:
held = fifo_held(open_lots) # from the CSV's own trades
tickers = {r["ticker"] for r in rts} | set(held.keys())
px, yf_err = fetch_prices(tickers | bench, ...) # the price universe
cur_map / currencies # the currency map, from rows
Everything downstream reads held/held_u/held_dx: dim_size, dim_diversify, instrument_policy.portfolio_analysis, dim_avgdown, overview_stats, what_if, ticker_diagnosis, the mkt_weights that pick the alpha/beta scope, data_integrity.unclassified_drivers, cash_position's held_mv, account_perf, and build_state's holdings/n_held/metrics/problem_events.
So measuring the wider book is not a matter of swapping a denominator:
The price universe is built from the CSV's tickers. Valuing the recorded book from a one-ticker week would put that ticker on market value and every other position on cost basis — a systematically mixed basis, not a data-availability accident.
B. Feed the engine the full history. Reconstruct prior trades from the ledger and hand them to the engine alongside the new file, so the weekly path becomes the cumulative path. Correct by construction for every consumer above, and it is what a cumulative-file user already gets — but it changes what a weekly review measures: round_trips, dim_exit, dim_hold, realized P&L, payoff attribution and alpha/beta would span the whole history rather than the period. That may well be right (two round trips is not an exit-discipline diagnosis, and insufficient_data fires on almost every incremental week today), but it is a product decision, not a refactor. review._rows_from_ledger is explicitly documented as unsuitable for prepare.
C. Read the canonical partition the review already computes._virtual_review_basis builds a portfolio_basis.query_current_book over the post-import virtual ledger on every CSV prepare — currency-correct, split-aware, with its own coverage.scope — and then keeps it only as a change-detection receipt. Having the current-view dimensions read that instead of trade_recap.current_book_projection is the "collapse to one reader" move, and it settles [design·P2] A considered trade is measured on a different basis than the card, and the record itself can lag the real book #456's "two bases" question for the card. It also means deciding how dim_diversify's sector/AI classification maps onto the canonical book and what happens under bounded_valued_subset.
What the owner needs to settle
Should a weekly review's behavioral diagnosis (exits, holding time, payoff, alpha) stay scoped to the period, or span the recorded history like the current-view half? Option B only works if the answer is "span it".
Status
Design. Follow-up to #630, which stopped the wrong number but did not deliver the right one. Needs owner scoping before implementation — the cheap versions are all wrong in a way that is hard to see.
What #630 left
#630's acceptance had two halves. The landed fix delivers one:
accounting_reconciliation), the durable metrics stayNoneinstead of1.0,engine_state.holdingsbecomes the canonical ledger book, and nooversize/concentrationbreach is recorded from the partial view.Withdrawing is the fail-closed answer and it is a strict improvement on a fabricated 100%. It is not the answer the product wants: handing over the new trades is ordinary use, nothing in
flows/weekly-review.mdasks for a cumulative file, and the ingest path is built to append incrementals.Why this is not a small change
The engine's whole current-book view is derived from the supplied rows, in
trade_recap.main:Everything downstream reads
held/held_u/held_dx:dim_size,dim_diversify,instrument_policy.portfolio_analysis,dim_avgdown,overview_stats,what_if,ticker_diagnosis, themkt_weightsthat pick the alpha/beta scope,data_integrity.unclassified_drivers,cash_position'sheld_mv,account_perf, andbuild_state'sholdings/n_held/metrics/problem_events.So measuring the wider book is not a matter of swapping a denominator:
prepareaggregating a missing FX rate as 1.0. Weighting a mixed-currency book through that is the inverted-largest-holding failure [bug·data·M1-blocker] Split-adjusted shares can be valued against prices on a different split basis #583 exists to prevent.Options, none free
trade_recapreadsTR_LEDGERalready. The book would have to be derived before the price request, which reordersmain()against [architecture·implementation] One market-data resolver — minimum Yahoo calls, one fact bundle for prepare and consider #605's ordering constraint, and it needs a split map before the review has resolved one.round_trips,dim_exit,dim_hold, realized P&L, payoff attribution and alpha/beta would span the whole history rather than the period. That may well be right (two round trips is not an exit-discipline diagnosis, andinsufficient_datafires on almost every incremental week today), but it is a product decision, not a refactor.review._rows_from_ledgeris explicitly documented as unsuitable forprepare._virtual_review_basisbuilds aportfolio_basis.query_current_bookover the post-import virtual ledger on every CSV prepare — currency-correct, split-aware, with its owncoverage.scope— and then keeps it only as a change-detection receipt. Having the current-view dimensions read that instead oftrade_recap.current_book_projectionis the "collapse to one reader" move, and it settles [design·P2] A considered trade is measured on a different basis than the card, and the record itself can lag the real book #456's "two bases" question for the card. It also means deciding howdim_diversify's sector/AI classification maps onto the canonical book and what happens underbounded_valued_subset.What the owner needs to settle
portfolio_basis's (option C, closing [design·P2] A considered trade is measured on a different basis than the card, and the record itself can lag the real book #456 for this surface), or staytrade_recap's with a wider input (option A)?Related