Skip to content

feat(engine): 多市場幣別傳導 + 匯率 gate — 台股美股混倉不再靜默算錯 (PR-2a of #129)#132

Merged
atomchung merged 2 commits into
mainfrom
feat/multi-market-currency
Jul 6, 2026
Merged

feat(engine): 多市場幣別傳導 + 匯率 gate — 台股美股混倉不再靜默算錯 (PR-2a of #129)#132
atomchung merged 2 commits into
mainfrom
feat/multi-market-currency

Conversation

@atomchung

Copy link
Copy Markdown
Owner

這是什麼

#129 Phase B 的 PR-2a:多市場/幣別資料傳導 + 匯率 gate + display currency 呈現規則(docs/prd-ledger.md §2.1–2.3、§2.5)。Closes #51(台股/多幣別從「靜默算錯」變真支援)、closes #31(帳本層 + 市值/幣別傳導到位;台股 format 由 Step 0 標準化 + Market/Currency 欄涵蓋)。

核心行為

  • 原幣記帳load() 收選填 Market/Currency 欄(缺 = US/USD,完全向後相容)。
  • 聚合層 USD 視圖:跨 ticker 聚合(sizing/分散權重、overview 金額、盈虧比拆帳、what-if、標的層排序)在混幣時走 usd_view(金額等比換算、ret 比率不變);per-ticker 呈現數字維持原幣。單一幣別組合(含純台股)走 identity 路徑——不抓匯率、行為零變化(13 個 mock persona sweep 驗證)。
  • 匯率 gatefetch_fx(yfinance {CUR}=X)離線安全——缺匯率降級為因子 1.0 + data_integrity.fx_gaps 明示警告,不猜不炸。
  • 契約新欄 currency_meta(TR_JSON + state,契約測試 key 集同步):aggregate_currency / fx / pnl_by_currency(原幣分桶)/ alpha_beta_note(混幣 α/β 未拆市場的誠實註記,指向 PR-2b)。
  • SKILL.md 💱 Display currency 段:語言→幣別(en→USD / zh-TW→TWD / zh-CN→CNY)、單一市場例外、合計換算+分項原幣、離線用上次 state 匯率快取並標「截至」、無匯率只出原幣。

Review(兩輪 finder + 修復)

  • 抓到並修ticker_diagnosis 的排序/佔比是跨 ticker 聚合,混幣時 TWD 名目數霸榜 → 改吃 USD 視圖(回歸測試鎖雙向排序);dim_size 跨幣別亂加的 dead-code 累計器刪除;README(雙語)+ AGENTS.md 的 CSV 欄位清單、card-spec.md 金額幣別規則同步。
  • 駁回:「單幣時 currency_meta 是 None」(main 恆構造完整 dict);「usd_view 會 reorder」(list comprehension 保序)。
  • pre-existing 的 requirements.md 簽名漂移記到 [process·P2] 跨檔同步靠人記:eval 三檔/README 雙語/demo 卡多處,缺機械 checker #113,非本輪引入。

測試

8 個新單元(混幣權重修正、ret 等比不變、缺匯率因子、分幣桶、衝突偵測、標的層排序)+ 契約 key 同步;2 發突變驗紅;六套全綠(離線確定性)。α/β per-market 拆分是 PR-2b(alpha_beta_note 已在卡上誠實標注過渡期)。

Closes #51, closes #31. Refs #129.

🤖 Generated with Claude Code

test and others added 2 commits July 6, 2026 22:39
…再靜默算錯 (refs #129, closes #51, closes #31)

PR-2a of #129 (prd-ledger.md §2). load() accepts optional Market/
Currency columns (default US/USD, fully backward compatible). New pure
functions: currency_map (per-ticker currency + conflict detection),
fetch_fx ({CUR}=X via yfinance, offline-safe, missing rates degrade to
factor 1.0 + data_integrity.fx_gaps warning), usd_view (pre-aggregation
USD view so dim_size/dim_diversify/overview_stats/payoff_attribution/
what_if aggregate on a common currency with zero signature changes),
pnl_by_currency (original-currency buckets for the presentation layer).

Single-currency portfolios (incl. pure-TWD) take the identity path — no
FX fetch, zero behavior change (13 mock personas sweep verified). Mixed
portfolios aggregate in USD; per-ticker numbers stay original currency.
TR_JSON + state gain top-level currency_meta (aggregate_currency, fx,
pnl_by_currency, alpha_beta_note pointing at PR-2b for per-market
alpha/beta); contract test key sets updated in lockstep. Plain card
prints an explicit currency note for mixed portfolios.

SKILL.md: new Display-currency section (language->currency mapping
en->USD/zh-TW->TWD/zh-CN->CNY, single-market exception, totals
converted + line items original, offline fx cache from last_state with
"rate as of" label, never guess a missing rate) + Step 1 consumption
list gains currency_meta.

Tests: 7 new unit cases (mixed-weight correction, ret invariance,
missing-fx factor, buckets, conflicts); 2 mutation probes verified red;
six suites green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mirror docs sync

Focused review on PR-2a (aggregation-semantics + mirror-drift finders):
- ticker_diagnosis ranking/weights are cross-ticker comparisons -> feed
  the USD view in mixed portfolios (TWD nominal amounts no longer
  dominate the top-N sort; ratio fields are scale-invariant). Regression
  test locks the ordering both ways.
- drop dim_size entry-size accumulator: never reached the output and
  summed across currencies (flagged dead by two review rounds)
- comment-guard pnl_by_currency call site (deliberately original-
  currency; converting it would defeat the buckets)
- mirror sync: README (EN+zh-TW) + AGENTS.md CSV column list gains
  optional Market/Currency; card-spec.md points amount-currency rules
  at currency_meta + SKILL Display-currency section
- pre-existing requirements.md signature drift logged on #113 (not
  introduced here)

Refuted from review: "currency_meta is None for single currency"
(main() always builds it); best_worst reorder claim (usd_view is
order-preserving by construction).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@atomchung atomchung merged commit b27fe61 into main Jul 6, 2026
3 checks passed
@atomchung atomchung deleted the feat/multi-market-currency branch July 6, 2026 14:59
atomchung added a commit that referenced this pull request Jul 12, 2026
…173) (#177)

engine 不長格式 parser(#89),認台股格式=Claude Step 0 職責——方案:Symbol 標完整 yfinance 代號(2330.TW/.TWO),#132 多市場基礎設施已足夠 engine 零改動;唯一真改=混幣錨點 fx latent gap。sample_tw_mixed persona + network smoke 驗 combined 口徑(台積電最大依賴/半導體橫跨台美/α-β 對 ^TWII)。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant