Conversation
`portfolioExposurePercent()` 在缺少 `marketValueBase` 时直接回退到 `marketValue`,而 `marketValue` 是按 `holding.currency`(持仓原币)计价的, 分母 `PortfolioSnapshot.totalAssets` 却是本币口径。二者币种不一致时,敞口 会被汇率倍数放大。 复现: - baseCurrency = 'USD',totalAssets = 100000 - 持仓 0700.HK,currency = 'HKD',marketValue = 780000,没有 marketValueBase 实际:返回 780(即 780% 敞口) 预期:敞口未知,返回 undefined 修复:新增 `baseCurrencyValue()` 辅助函数——优先使用已折算的 `marketValueBase`;仅在持仓币种与本币**已知且相同**时才用 `marketValue` 兜底。逻辑与 alerts 的 `evaluatePositionWeight()` 保持一致。 范围:仅 `portfolioExposurePercent()`,不动 `computePersonalImpact()` 及其余 pulse 逻辑。无可见 UI 变化(只是极端跨币种场景下不再给出错误数字)。 测试:`packages/shared/src/pulse/service.test.ts` 新增 2 个用例 (跨币种返回 undefined / 同币种返回 78)。旧代码下前者失败,新代码通过。
helsome
requested changes
Sep 22, 2026
helsome
left a comment
Owner
There was a problem hiding this comment.
有 1 个金融口径 blocker,需要 fail-closed 后再合:当前 baseCurrencyValue() 在 holding.currency 或 portfolio.baseCurrency 任一未知时仍返回原币 marketValue,这仍可能把未折算金额除以本币 totalAssets。这也没有真正对齐 Issue #158 所引用的 alerts.evaluatePositionWeight():后者只有在两边币种都已知且相同才允许 raw marketValue 兜底。请改为:无有限 marketValueBase 时,只有 holding/base currency 均存在且相等才返回 marketValue,否则 undefined;再补一个币种缺失的 focused 回归用例即可。现有 Bun/OS 报告及 head 的 Focused / Typecheck / Secret scan / advisory full suite 均已足够,其余无需扩大。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
portfolioExposurePercent()(packages/shared/src/pulse/service.ts)在缺少marketValueBase时直接回退到marketValue:marketValue按holding.currency(持仓原币)计价,而分母PortfolioSnapshot.totalAssets是本币口径。币种不一致时敞口被汇率倍数放大。复现
780(780% 敞口)undefined(敞口未知)根因
回退路径没有校验
holding.currency是否等于portfolio.baseCurrency。修复
新增
baseCurrencyValue()辅助函数:marketValueBase(永远安全);holding.currency与portfolio.baseCurrency已知且相同时才用marketValue兜底;undefined。该判定与 alerts 的
evaluatePositionWeight()(packages/shared/src/alerts/evaluators.ts)保持一致。
范围
仅
portfolioExposurePercent()。computePersonalImpact()及其余 pulse 逻辑未改动。无可见 UI 变化(只是极端跨币种场景下不再给出错误数字,改为"未知")。
测试
packages/shared/src/pulse/service.test.ts新增 2 个用例:undefined78回归证明:把修复回退成
holding.marketValueBase ?? holding.marketValue后,第一个用例 0 pass / 1 fail;修复后通过。
命令与结果:
基线说明:干净
origin/main(7c9b550)上bun run typecheck五个工作区全部exit 0,无基线故障;本 PR 未引入任何新的 advisory 失败。
环境
Closes #158