Skip to content

feat: add canonical instrument identity and symbol resolution - #59

Merged
helsome merged 3 commits into
helsome:mainfrom
weiliang-hub:codex/issue-23-instrument-resolver
Sep 11, 2026
Merged

feat: add canonical instrument identity and symbol resolution#59
helsome merged 3 commits into
helsome:mainfrom
weiliang-hub:codex/issue-23-instrument-resolver

Conversation

@weiliang-hub

@weiliang-hub weiliang-hub commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

改动说明

建立 Folio 自己的 canonical instrument identity / resolver,并接到 Longbridge 与 Massive 两个 provider adapter。用户输入 ticker / 公司名 / provider symbol 时先解析;唯一匹配才继续取数,歧义时返回候选而不是静默选错标的。行情、基本面、新闻以及 research evidence/report 通过 instrumentId 关联。

  • Folio 自有 instrumentId(上市维度 MIC:SYMBOL),不再用 ticker 当全局主键
  • resolver 覆盖 canonical id、symbol、公司名、provider alias;多候选返回 ambiguous
  • Longbridge / Massive 接收 canonical instrument,再转成各自 symbol(AAPL.US vs AAPL
  • quote / profile / news / financials 以及 ProviderProvenance、EvidenceRef、ResearchReport 打上 instrumentId
  • provider alias catalog 以 versioned snapshot 持久化(instruments.json),空仓时写入默认真实标的目录

关联 Issue

Closes #23

真实标的解析案例(验收要求 ≥5,含 1 个歧义 + 1 个跨 provider 不一致)

# 输入 结果 说明
1 AAPL.US XNAS:AAPL Longbridge alias
2 AAPL + provider massive XNAS:AAPL 跨 provider:Massive 用 AAPL,Longbridge 用 AAPL.US
3 0700.HK / Tencent XHKG:0700 港股
4 TSLA XNAS:TSLA 美股 canonical symbol
5 BABA.US XNYS:BABA 阿里美股上市
6 Alibaba ambiguous XNYS:BABA + XHKG:9988 歧义:美股 ADR vs 港股 9988,不会静默二选一

市场 hint:Alibaba + market=HKXHKG:9988

测试报告(正式审核前必填)

环境

  • Bun:1.4.2
  • OS:Windows 10/11 (PowerShell)
  • Node:v24.15.0

实际执行命令与结果

bun test --isolate packages/core/src/instrument.test.ts packages/shared/src/providers/instrument.test.ts packages/shared/src/providers/longbridge/longbridge.test.ts packages/shared/src/providers/massive/massive.test.ts packages/shared/src/providers/providers.test.ts
→ 95 pass / 0 fail

bun test --isolate packages/core packages/shared/src/research packages/shared/src/providers packages/shared/src/capabilities apps/electron/src/main/kernelHost.test.ts
→ 204 pass / 1 fail

packages/core tsc --noEmit
→ exit 0

packages/shared tsc --noEmit
→ exit 0

已知失败 / Baseline(如有)

UI 截图(涉及 UI 时必填)

  • 本 PR 不涉及 UI 变化

Scope / 后续

首版覆盖 US + HK 种子目录、两个 adapter、catalog 持久化与歧义上抛。完整证券主数据平台、运行时向 vendor 补全 ISIN 等不在范围内。

Copilot AI lite review requested due to automatic review settings September 11, 2026 08:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Four moderate issues remain involving alias ambiguity, immutable identity generation, snapshot timestamp validation, and asset-type validation.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a canonical instrument identity schema and deterministic resolver for US and HK instruments.

Changes:

  • Supports canonical IDs, symbols, names, provider aliases, and ambiguity results.
  • Adds versioned catalog snapshots and provider mappings.
  • Adds resolver and snapshot tests with public exports.
File summaries
File Description
packages/core/src/instrument.ts Canonical identity and resolution implementation
packages/core/src/instrument.test.ts Resolver and snapshot coverage
packages/core/src/index.ts Public export
Review details

Suppressed comments (2)

packages/core/src/instrument.ts:214

  • snapshot() rejects negative or non-finite updatedAt, but this deserialization path only checks schemaVersion. A persisted snapshot with an invalid timestamp is therefore accepted, bypassing the public snapshot contract; validate the timestamp here as well and cover malformed snapshots.
  static fromSnapshot(snapshot: InstrumentCatalogSnapshot): InstrumentResolver {
    if (snapshot.schemaVersion !== INSTRUMENT_CATALOG_SCHEMA_VERSION) {
      throw new Error(`Unsupported instrument catalog schema: ${snapshot.schemaVersion}`);
    }
    return new InstrumentResolver(snapshot.instruments);

packages/core/src/instrument.ts:121

  • assetType is required by CanonicalInstrument but is never checked by this runtime validator. Because fromSnapshot() feeds persisted data through it, a missing or invalid value can be accepted and returned as a canonical instrument, violating the declared asset-type contract; add an allowed-value check and a regression test before indexing.
    ['name', instrument.name],
    ['market', instrument.market],
    ['country', instrument.country],
    ['currency', instrument.currency],
  ];
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/core/src/instrument.ts Outdated
Comment on lines +157 to +161
/** Build a stable Folio id from an exchange MIC and its local symbol. */
export function createInstrumentId(exchangeMic: string, symbol: string): string {
const mic = normalizedCode(exchangeMic);
const localSymbol = normalizedCode(symbol);
if (!mic || !localSymbol) throw new Error('Exchange MIC and symbol are required.');
Comment thread packages/core/src/instrument.ts Outdated
Comment on lines +264 to +268
if (!providerId) {
const bySymbol = resolutionOf(
originalQuery,
'symbol',
candidates.filter((instrument) => normalizedCode(instrument.symbol) === code)
@weiliang-hub
weiliang-hub force-pushed the codex/issue-23-instrument-resolver branch from ae63baa to 52c8c11 Compare September 11, 2026 08:33
@weiliang-hub
weiliang-hub force-pushed the codex/issue-23-instrument-resolver branch from 52c8c11 to 471034c Compare September 11, 2026 09:27
@weiliang-hub weiliang-hub changed the title feat(core): add canonical instrument resolver foundation feat: add canonical instrument identity and symbol resolution Sep 11, 2026
AMBIGUOUS_INSTRUMENT 错误携带候选摘要,defineCapability 从 stamped data 写入 provenance.instrumentId。

@helsome helsome left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审通过。上一轮 Copilot 提到的 alias 冲突、snapshot updatedAtassetType 校验问题已经在后续提交中补上并有回归测试;测试报告也已补齐 Bun/OS、focused tests、baseline 说明。instrumentId 目前按 listing identity 使用,首版 catalog 的 MIC:SYMBOL 作为稳定目录键可以接受,后续证券主数据平台再演进不需要卡本 PR。无 UI 变化。

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Finance Data] Add canonical instrument identity and symbol resolution

3 participants