Skip to content

feat(compare): 2-4 标的基准化价格曲线纯函数(#334 基础切片) - #346

Merged
helsome merged 3 commits into
helsome:mainfrom
LVsarff:feat/compare-rebased-price-series
Oct 22, 2026
Merged

helsome merged 3 commits into
helsome:mainfrom
LVsarff:feat/compare-rebased-price-series

Conversation

@LVsarff

@LVsarff LVsarff commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

改了什么

为 #334 的第 1 步(基准化价格曲线)交付一个可独立审阅的基础切片:新增纯函数 buildRebasedPriceSeries 及其类型契约(packages/shared/src/compare/rebase.ts),并导出到 @finagent/shared/compare。不改动现有 buildComparison、UI 或数据网关——后续图表 UI 接线时可直接消费该契约。

核心规则(对应 issue 分步实现 1、2 的计算层部分):

  • 共同有效起始交易日 = 所有有效标的都有 bar 的最早日期;各自该日收盘价归一化为 100(baseTimestamp + baseCloses)。
  • 时间轴为基准日起 bar 时间戳并集;某标的缺 bar 的日期保留 undefined(gap),不补零、不前值填充——"gap 或有说明的前值展示"属于 UI 展示策略,计算层保留缺口供其选择。
  • 缺共同有效区间时明确不可比(comparable: false,reason: 'empty' | 'no-overlap'),不虚构每标的独立基线;部分标的缺数据时在 detail 中记录原因并在曲线中保持缺失,而不是伪造 0 或回填。
  • 输入 bars 内部去重(同 timestamp 保留最后一条,兼容数据源修正)、升序排序、过滤非有限值——乱序/脏数据不改变输出。
  • 拆股跳变在 raw 价格下如实保留(不虚构复权平滑);复权类型标注需数据源提供 adjustType 元信息,属后续工作。

为什么要改

Compare 目前只有逐指标的标量回报(1M/3M/1Y Return),无法直观对比 2–4 标的的走势相对强弱。基准化价格曲线(共同起点 = 100)是该增强的数据基础;先落地确定性纯函数契约 + fixture 回归测试,UI 接线与保存视图(schema version)在后续 PR 复用。

对应 Issue

#334(第 1 步基础切片)。已在 issue 下认领:#334 (comment)

验证(测试报告)

环境:Bun 1.4.0 / Windows 11(PowerShell 5)

bun test packages/shared/src/compare/rebase.test.ts
→ 10 passed / 0 failed(41 expect() calls)

bun test packages/shared
→ 827 passed / 47 failed(874 tests / 112 files)
→ 47 项失败经 stash 对照在 origin/main 同样复现(main: 817 pass / 47 fail),
  为本机 Windows 环境基线问题,与本次改动无关;本 PR 净增 10 pass / 0 fail

bun run --filter './packages/shared' typecheck
→ exit 0

fixture 覆盖(10 个用例):完全重叠日历归一化、不同上市日期取最晚共同起点、交易日历 gap 保留 undefined 不补零、raw 拆股跳变如实反映、乱序与重复 timestamp 输入、部分标的无数据、基准收盘价为 0 的除法保护、全空输入、日历完全不交集、空输入列表。

已知未完成项 / 后续工作

  • Compare UI 图表接线(消费 buildRebasedPriceSeries 输出渲染曲线);
  • 保存视图(instruments、时间窗、展示设置 + schema version);
  • 复权类型标注:待数据源(market.kline capability)透出 adjustType 元信息后,在契约中补可选透传字段;
  • FX 统一币种模式:需可追溯 FX 历史数据后另行设计。

无可见 UI 变化(纯逻辑层新增,未改任何现有组件)。

helsome#334 第 1 步的基础切片:新增 buildRebasedPriceSeries 纯函数,将已选标的的
日线收盘价归一化到共同有效起始交易日(基准 = 100),作为后续 Compare 图表
UI 接线可复用的确定性契约。

- 共同起始交易日 = 所有有效标的都有 bar 的最早日期,各自该日收盘价归一化为 100
- 时间轴为基准日起 bar 时间戳并集;缺 bar 的日期保留 undefined(gap),
  不补零、不前值填充——展示策略(gap vs 有说明前值)留给 UI 层
- 无有效数据、基准收盘价为 0 或日历完全不重叠时,明确返回不可比状态与原因,
  不虚构基线
- 输入 bars 内部去重(同 timestamp 保留最后一条)并升序排序,过滤非有限值
- 10 个 fixture 回归测试覆盖:完全重叠日历、不同上市日期、交易日历 gap、
  拆股跳变、乱序/重复输入、部分标的缺数据、零基准价、空输入与日历不交集

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

helsome commented Oct 18, 2026

Copy link
Copy Markdown
Owner

同步最新 main:#353 已合入(038f20cf2d87e3575ffbe5469967bdf6ef960dc8),现在已有免 API key 的 Yahoo Finance 备用数据源。请同步 main 后复用现有 provider router / market-data 接口,不再把支持范围内的行情验收统一卡在 Longbridge/Massive 凭证上。

支持范围是美股延迟报价、日/周 K 线和简要公司资料;不支持券商账户/持仓、财报、新闻、期权及分钟行情。保留实际 provider、时间与 delayed 标记,不能用缺失数据冒充 0 或“没有事件”。文档明确它是非官方、个人使用范围的接口,可能限流。

针对本 PR:请增加 Yahoo 日/周 K 线形状的兼容性用例,核对时间戳、共同有效起点与缺口保留。纯计算切片无需因此扩成取数/UI 全栈实现,仍不得把价格变化称为含分红总回报。

参考:接入说明 · 适配器。请区分 fixture 与真实联网结果;连接卡显示 connected 本身不证明实际取数成功。此评论同步新基线,不替代原有 review 或验收结论。

同步 main(helsome#353 Yahoo provider)后,按 review 要求针对 providers/yahoo/adapter.ts 的 mapKlines 输出形状补离线 fixture:
- 秒级开盘时刻时间戳透传(日/周线,无单位转换与偏移)
- null-OHLC 跳过产生的缺口保留为 undefined,不补零/前值填充
- 共同有效起点在秒级网格上取最晚共同 bar 日
- 混合时间戳单位(秒 vs 毫秒)明确 no-overlap,不静默归一化

rebase.ts 契约注释同步澄清时间戳单位透传约定。纯计算切片边界不变,未扩取数/UI 实现。

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
@LVsarff

LVsarff commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

同步最新 main:#353 已合入(038f20cf2d87e3575ffbe5469967bdf6ef960dc8),现在已有免 API key 的 Yahoo Finance 备用数据源。请同步 main 后复用现有 provider router / market-data 接口,不再把支持范围内的行情验收统一卡在 Longbridge/Massive 凭证上。

支持范围是美股延迟报价、日/周 K 线和简要公司资料;不支持券商账户/持仓、财报、新闻、期权及分钟行情。保留实际 provider、时间与 delayed 标记,不能用缺失数据冒充 0 或“没有事件”。文档明确它是非官方、个人使用范围的接口,可能限流。

针对本 PR:请增加 Yahoo 日/周 K 线形状的兼容性用例,核对时间戳、共同有效起点与缺口保留。纯计算切片无需因此扩成取数/UI 全栈实现,仍不得把价格变化称为含分红总回报。

参考:接入说明 ·适配器。请区分 fixture 与真实联网结果;连接卡显示 connected 本身不证明实际取数成功。此评论同步新基线,不替代原有 review 或验收结论。

已同步 main(038f20c)并按评论要求补充 Yahoo 日/周 K 线形状的离线 fixture 兼容用例(4 个,rebase.test.ts ):秒级开盘时刻时间戳透传、null-OHLC 跳过后的缺口保留undefined 、共同有效起点在秒级网格上取最晚共同 bar 日、混合时间戳单位明确报no-overlap 。rebase.ts 注释同步澄清了时间戳单位透传约定(原 "(ms epoch)" 表述与 Yahoo 秒级输出不符)。全部为 fixture 测试,未联网;纯计算切片边界未变。测试 14 pass / 0 fail,typecheck 通过。

@LVsarff

LVsarff commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

你好,跟进一下这个 PR 的最新进展。
我已经同步最新的 main 分支,并补充了 4 个离线 fixture 测试,覆盖 Yahoo 日线/周线数据兼容性,包括时间戳单位、共同有效起点和数据缺口保留等情况。目前 14 项测试全部通过,类型检查也已通过。
想确认一下,目前的修改是否符合验收要求?如果还有需要调整的地方,请告诉我,我会继续完善。感谢!

@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.

验收通过。

按 10/18 评论补的 Yahoo 日/周 K 线 fixture 与 buildRebasedPriceSeries 纯函数切片逻辑干净,可合入。感谢跟进。

@helsome
helsome merged commit fe1c913 into helsome:main Oct 22, 2026
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.

2 participants