Skip to content

pulse: 组合敞口百分比把未折算的 marketValue 直接除以本币 totalAssets #158

Description

@wxrbyte

问题

portfolioExposurePercent()packages/shared/src/pulse/service.ts)在计算持仓敞口占比时:

const weight = holding.marketValueBase ?? holding.marketValue
...
return round2((weight / total) * 100)

marketValue 是按 holding.currency(持仓原币)计价的,而分母 PortfolioSnapshot.totalAssets
是本币口径。当数据提供方只给出 marketValue、没有 marketValueBase(或该字段缺失)时,
函数会用一个外币金额去除以本币总额,敞口被汇率倍数放大。

复现

const portfolio: PortfolioSnapshot = {
  baseCurrency: 'USD',
  totalAssets: 100_000,
  accounts: [],
  holdings: [
    { symbol: '0700.HK', name: 'Tencent', currency: 'HKD', marketValue: 780_000 },
  ],
  fetchedAt: Date.now(),
}
portfolioExposurePercent('0700.HK', portfolio)
  • 实际:780(780% 敞口 —— 把 780,000 HKD 当成 780,000 USD 去除以 100,000 USD 的总资产)
  • 预期:undefined(敞口未知)

根因

缺少 marketValueBase 时直接回退到 marketValue,未校验币种是否与 portfolio.baseCurrency
一致。

对比参照

同一个仓库里 alerts 的 evaluatePositionWeight()packages/shared/src/alerts/evaluators.ts
已经正确处理了这一点:只有在持仓币种与本币已知且相同时才用未折算金额兜底,否则视为未知。
pulse 这里应当与之一致。

影响

Pulse / 个人化影响面板在跨币种持仓下会给出明显错误的敞口百分比(可能 > 100%),
进而污染"个人影响"排序与展示。

环境

  • Bun 1.3.4 / Windows

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

claimedClaimed by a contributor and currently in progress

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions