← Financial Cloud Cloud Cloud Club · 构建文章

极点宏观|Financial Cloud Cloud · 构建文章

与 Kiro 一起开发:重建损益排行榜背后的量化分析引擎

系列: Kiro 工作坊

文章: 34

文章
Kiro 工作坊
01 使用 Kiro 构建:他加禄语学习 App 的提示优先产品设计工作坊
Kiro 工作坊
02 使用 Kiro 构建:他加禄语 学习 App 的教育优先开发技巧工作坊
Kiro 工作坊
03 使用 Kiro 构建:他加禄语 学习 App 的深入开发流程工作坊
Kiro 工作坊
04 使用 Kiro 构建:将 他加禄语 学习 App 本地化为中文变体工作坊
Kiro 工作坊
05 使用 Kiro 构建:他加禄语 卡片的语法与发音补强流水线工作坊
Kiro 工作坊
06 使用 Kiro 构建:他加禄语 学习 App 中可审查的独特额外例句工作坊
Kiro 工作坊
07 与 Kiro 同行:晶圆厂工程健康度 Hook 工作坊
Kiro 工作坊
08 与 Kiro 同行:蚀刻工艺窗口风险测试自动化工作坊
Kiro 工作坊
09 与 Kiro 同行:黄光微影漂移风险开发工作坊
Kiro 工作坊
10 工程团队入门 — 日常工厂值班使用 fab spc drift sync portal
Kiro 工作坊
11 工程团队附录 — fab spc drift sync portal 的日常工厂值班使用
Kiro 工作坊
12 Kiro:规格驱动工厂软件的现场工程工作坊
Kiro 工作坊
13 Kiro:实施 Lab — 从零构建具类型的 Factory Risk Portal
Kiro 工作坊
14 Kiro:工程开发人员的提示、代码和类型标准手册
Kiro 工作坊
15 Kiro:为什么强 React 提示可以防止类型宣告错误启动
Kiro 工作坊
17 与 Kiro 一起构建:建立工厂自动化门户 React UI
Kiro 工作坊
18 与 Kiro 一同构建:打造工厂自动化门户背后的自动化分析引擎
Kiro 工作坊
19 与 Kiro 一起实施:将 AI 工厂自动化辅助程序新增至工厂自动化门户
Kiro 工作坊
21 Kiro:2 小时专业开发人员工作坊指南
Kiro 工作坊
22 Kiro:从零建置 Fab SPC Drift Synchronization Portal
Kiro 工作坊
23 Kiro:提示词库与深度代码说明附录
Kiro 工作坊
30 与 Kiro 一起构建:建立工厂自动化门户 UI
Kiro 工作坊
31 与 Kiro 一起构建:打造工厂自动化门户背后的自动化分析引擎
Kiro 工作坊
32 与 Kiro 一起实施:为工厂自动化门户添加 AI 工厂自动化辅助程序
Kiro 工作坊
33 与 Kiro 一起开发:重建 CME Direct 风格的量化损益排行榜 UI
Kiro 工作坊
34 与 Kiro 一起开发:重建损益排行榜背后的量化分析引擎
Kiro 工作坊
35 与 Kiro 一起构建:适用于量化排行榜的 AWS AI 驱动交易台助理
Kiro 工作坊
36 单页交易平台 SOP
Kiro 工作坊
AgentCore
A1 使用 AgentCore 与 Strands 构建:Gateway MCP 工具织网开发者工作坊
AgentCore
A2 使用 AgentCore 与 Strands 构建:受治理的多 Agent 风险系统开发者工作坊
AgentCore
A3 使用 AgentCore 与 Strands 构建:运行时主权风险代理人开发者工作坊
AgentCore
模拟考场
E1 用 Vibe Coding 打造多语言 AWS 认证模拟题上线系统
模拟考场
E2 利用 Vibe Coding 开发技巧打造 AWS 认证模拟练习室
模拟考场
E3 打造静态 AWS 模拟考场背后的练习引擎
模拟考场
Amazon Q
Q1 Amazon Q:面向 ACM 证书自动续订的 CloudShell 优先开发人员工作坊
Amazon Q
Tagalog 练习室
T1 用提示词优先的产品设计,为 AWS Manila Community Day 构建 Tagalog 学习应用
Tagalog 练习室
T2 用教育优先的开发提示,为 AWS Manila Community Day 构建 Tagalog 学习应用
Tagalog 练习室
T3 面向 AWS Manila Community Day 的 Tagalog 学习应用深度开发流程
Tagalog 练习室
T4 为 AWS Manila Community Day 将 Tagalog 学习应用本地化为中文变体
Tagalog 练习室
T5 为 AWS Manila Community Day 的 Tagalog 卡片构建语法与发音增强流水线
Tagalog 练习室
T6 在 AWS Manila Community Day 的 Tagalog 学习应用中,让额外示例唯一且可审查
Tagalog 练习室
路线图
R1 企业级 Data Analytics Roadmap 一百个深度情境题
路线图
R2 前端开发路线图:真实企业场景
路线图
香港 Community Day
C1 与 AWS Community Day 共度香港周末:从云端议程到维港灯火
香港 Community Day
C2 演讲者的奢华周末:讲述你的 AWS 故事,再让香港登场
香港 Community Day
C3 在香港的七十二小时:AWS Community Day 演讲者的深度行程
香港 Community Day
马尼拉 Community Day
C4 AWS Community Day Manila:一场连接云技术、城市文化与真挚友谊的快乐周末
马尼拉 Community Day
C5 AWS Community Day Manila:云端建设者在菲律宾感受最幸福的精神
马尼拉 Community Day
C6 AWS Community Day Manila:在快乐之城构建、打破、重来,并找到归属
马尼拉 Community Day
C7 菲律宾马尼拉初次到访建议
马尼拉 Community Day
菲律宾 × 香港
C8 菲律宾香港资本市场升级
菲律宾 × 香港
回测
B1 使用 Bedrock AgentCore 和 Strands Agents 构建机构级 Amazon 只做多回测代理
只做多 AMZN 代理:AgentCore、Strands 与可审计的 Backtrader 台账。
B2 使用 Backtrader、AgentCore 和 Strands Agents 构建具备市场状态感知能力的 Amazon 头寸管理
把市场状态当成头寸控制,而不是图表注释。
B3 使用 Nasdaq、S&P 500、Dow、AgentCore 与 Strands 构建相对基准的 Amazon 择时系统
相对 Nasdaq、S&P 500 与道琼斯判断 AMZN 时机。
B4 使用 Bedrock AgentCore、Strands Agents 与 Backtrader 构建受治理的 Amazon 交易历史工厂
把回测做成可审计的交易历史工厂。
B5 使用 Bedrock AgentCore 与 Strands Agents 构建代理式 Amazon 回测运营模型 [Part 1]
先建立运营模型,再争论结果。
B6 为 Amazon 择时与头寸管理构建自定义 Cerebro 代码解读 [第 2 部分]
先讲 Cerebro 引擎,再讲图表。
B7 为 Amazon 策略结果与经验教训构建交易员复盘记录 [Part 3]
把策略排名写成交易员复盘记录。
B8 使用 AgentCore 和 Strands 构建受治理的 FSI Amazon 头寸管理手册 [第 4 部分]
受治理的 FSI Amazon 头寸管理手册。
B9 使用 Amazon Bedrock AgentCore 构建主权风险交易代理,分析收益率差、FX 对冲与债务重新定价
主权风险代理:收益率差、外汇对冲与债务重定价。
B11 构建现代波动率交易与合法泰国恢复规划智能体:内存驱动的 Strands 多智能体风险保护系统
记忆驱动的 Strands 智能体:波动率与泰国恢复规划。
B12 使用 Amazon Bedrock AgentCore Memory 构建做空跨式交易风险治理
做空跨式的交易风险治理。
B13 在 Amazon EKS 上构建生产环境就绪的信用与收益质押 AI 智能体
在 EKS 上跑生产级信用与收益质押智能体。
挑战
01 周末生产力挑战:Fab SPC 漂移同步门户
Fab SPC 漂移审查与建议门户。
02 周末生产力挑战:Quant P&L Commander — AWS 上由 AI 驱动的交易生产力门户
AWS 上由 AI 驱动的交易生产力门户。
03 周末烦人任务挑战:交易台在云端、链上、空中执行摘要
DeskPulse 日常交易执行摘要。
04 周末 Agent 挑战:早上 6 点交易风险审查
无人值守、以证据为基础的早间交易风险简报。
05 周末创意挑战:领导力卡牌游戏
浏览器版创意引导卡牌。
06 全栈挑战:社区日留言板应用程序
浏览器版活动通信空间。
领导力卡牌
01 Leadership Card Game: 云没有自动化的最后一项技能:像领导者一样说话
写给 构建者的一篇现场随笔:语言、勇气,以及 Leadership Card Game
02 领导力回合解剖:Leadership Card Game 究竟如何玩
写给 构建者的引导员实地指南:如何把演练嵌进真实会议
03 Leadership Card Game: 当机会不再属于组织者
写给 构建者的田野随笔:权力转移、多语言领导力练习夜,以及走完入口、资源与叙事的职业弧线
04 周末创意挑战:Leadership Card Game
一篇构建者手记:愿景、架构,以及周末创意挑战教会我的事
05 从周末挑战项目到 $1,386 众筹:改变你在职场现身方式的领导力练习
一个周末做出的作品,变成 600 张卡的在线领导力练习室,并筹到 $1,386。
06 从周末挑战项目到 $1,386 众筹:进入科技产业的第一天路径
一个周末挑战如何变成具备 600 张卡、由 AWS 驱动的多语产品,并筹到 $1,386?
07 从周末挑战项目到 $1,386 众筹:用转移机会建立专业品牌
一个周末挑战把领导想法做成能跑的多语产品,并筹到 $1,386。
08 Leadership Card Game — 众筹活动
筹款目标: HKD 5,000 已筹金额: HKD 1,386 距目标还差: HKD 3,614 进度: 28% 创作者: D.C. Dan · L.L. Diana · L.K. Lva 所在地: 日本、香港、新加坡 投资人权益: 即期价值、私密会员卡牌编辑器云(Private Membership Card…
09 PR/FAQ 01 — Leadership Card Game 面向社区构建者正式推出
「逆向工作法」文档 · 对外新闻稿 + FAQ 产品: Leadership Card Game 受众: 社区经理、志愿组织者、早期职业构建者
10 PR/FAQ 02 — 企业引导员采用 Leadership Card Game 开展现场领导力演练
「逆向工作法」文档 · 对外新闻稿 + FAQ 产品: Leadership Card Game 受众: 学习与发展负责人、人员管理者、敏捷教练、企业引导员
10 PR/FAQ 03 — 多语言 Leadership Card Game 为构建者归属开放全球练习室
「逆向工作法」文档 · 对外新闻稿 + FAQ 产品: Leadership Card Game 受众: 全球 构建者、双语社区、跨境产品团队、开源导师
AWS Builder Center
01 AWS Builder Center、社区精神与 AWS Builder Jacket
霓虹信号、共享创意,以及为构建者打造的外套。
02 走进 AWS Builder Center:一座能学习、贡献,也让人有归属感的全球技术平台
一段精彩旅程,不一定从机场开始。
03 AWS Community Builder 的巨大成功
当构建者公开分享,整个社区就会一起前进。
04 AWS Builder Center 的巨大成功
一座为好奇心打造、充满活力的全球街区。
05 周末走进 AWS Builder Center:从社区灵感到令人难忘的 AWS Builder Jacket
星期五晚上,开始于构建者熟悉的感觉:有一个点子,正卡在问题与可能性之间。

摘要: 本独立工作坊将教导开发者使用 Kiro、TypeScript、纯财务函数、SVG 图表生成器、测试以及受控的实时模拟,重新构建上传的排行榜中的量化 JavaScript 逻辑。开发者将实现收益率、回撤、波动率、Calmar 比率、VaR、最佳单日、最差单日、胜率、排序、搜索过滤、走势图路径、权益曲线、直方图,以及具备完整原型覆盖率与审查任务的更新循环安全性。

工作坊目的

这个为期 2 小时的工作坊专注于 Demo 背后的分析与交互引擎。本工作坊不侧重于 UI 样式,而是将原始的 JavaScript 行为提取到可测试的 TypeScript 模块中。开发者将学习如何使用 Kiro 来设计财务函数、测试边缘案例、解释指标含义,并在不引入可靠性存疑的计算情况下保留实时更新行为。

Demo 功能覆盖地图

本工作坊涵盖以下 Demo 实现细节:

  • 包含 8 位交易员的参与者数组 P:策略、净值(NAV)%、每日 %、夏普比率、盈利因子、胜率、偏度、最大回撤(Max DD)以及净值序列。
  • 市场数组 M:包含 ES、CL、GC、BTC、状态标签、变动值与迷你序列。
  • 格式化辅助函数:带正负号的百分比显示与正/负类别(class)选择。
  • ret(series):每日收益率序列。
  • dd(series):回撤序列。
  • avg, sd, perc:平均值、标准差、百分位数。
  • path:SVG 折线路径生成。
  • spark, eqChart, ddChart, hist:迷你图与完整图表生成概念。
  • panel:衍生高级指标,包含区间收益率、已实现波动率、Calmar 比率、VaR 95、最佳单日、最差单日、胜率、最大回撤。
  • data:搜索与排序行为。
  • render:数据行构建与展开面板状态保留。
  • stat:参与者人数、最佳夏普比率、平均胜率、最佳净值。
  • 5 秒模拟净值与每日收益率更新循环。

目标开发者

  • 将仪表板数学公式转换为经过测试模块的量化开发者。
  • 正在学习财务指标实现的 TypeScript 开发者。
  • 需要确定性图表路径生成的前端工程师。
  • 正在学习如何使用 Kiro 审查数学与边缘案例的工程师。

两小时议程

时间 模块 开发者产出
0:00-0:10 提取需求 来自 HTML Demo 的分析资产清单
0:10-0:25 Kiro 指引设置 指标正负号、单位、测试与模拟规则
0:25-0:45 指标引擎 收益率、回撤、波动率、百分位数、Calmar 比率
0:45-1:05 聚合引擎 排行榜统计数据与排序/过滤逻辑
1:05-1:25 SVG 图表引擎 走势图、权益曲线、回撤、直方图路径
1:25-1:45 实时模拟 受控更新循环与状态安全性
1:45-1:55 测试 单元测试与基于属性的测试
1:55-2:00 Kiro 审查 边缘案例与生产环境强化待办清单

架构

src/domain/
├─ types.ts              # Trader, Market, RiskMetrics, SortKey
├─ formatting.ts         # 带正负号的百分比与类别
├─ calculations.ts       # 收益率、回撤、波动率、百分位数
├─ leaderboard.ts        # 搜索、排序、统计数据、数据行模型
├─ charts.ts             # SVG 路径与图表模型函数
├─ simulator.ts          # 确定性更新循环辅助函数
└─ __tests__/
   ├─ calculations.test.ts
   ├─ leaderboard.test.ts
   ├─ charts.test.ts
   └─ simulator.test.ts

财务指标定义与交易决策用途

指标 Demo 公式或解读 交易决策用途
区间收益率 (Window Return) (最后一个 NAV / 第一个 NAV - 1) * 100。 衡量显示窗口内的累计绩效。
每日收益率 (Daily Return) (今日 NAV / 前日 NAV - 1) * 100。 显示短期贡献并驱动直方图条形。
已实现波动率 (Realized Volatility) 每日收益率的标准差乘以 sqrt(252)。 用于比较不同策略之间的风险强度。
回撤 (Drawdown) (当前 NAV / 历史高点 - 1) * 100。 检测策略从其峰值下跌了多少。
最大回撤 (Max Drawdown) 序列中的最小回撤值。 用于风险限制和止损审查阈值。
Calmar 比率 (Calmar Ratio) 区间收益率除以最大回撤的绝对值。 比较收益效率与资金痛苦程度。
VaR 95 简化 Demo 中每日收益率的第五百分位数。 根据历史收益率近似估算下行风险阈值。
最佳单日 (Best Day) 最大每日收益率。 识别潜在的向上跳空潜力。
最差单日 (Worst Day) 最小每日收益率。 识别单一期间的下行冲击。
胜率 (Win Rate) 正每日收益率天数除以总天数。 衡量一致性,但不衡量交易规模。
盈利因子 (Profit Factor) 来自参与者数据的数据行质量指标。 比较总收益与总损失,作为策略质量指标。
偏度 (Skew) Demo 数据行的不对称性指标。 负偏度警告可能存在下行尾部行为。

步骤 1 — 为财务计算添加 Kiro 指引设置

创建 .kiro/steering/quant-math.md:

# 量化数学指引设置

- 将所有显示的收益率视为百分点,而非小数。
- 回撤必须为零或负数。
- 在此 Demo 中,VaR 95 为每日收益率的第五百分位数。
- 已实现波动率使用 sqrt(252) 进行年化。
- 保持所有财务函数为纯函数(pure functions)且无副作用。
- 请勿虚构实时或真实的市场数据。

创建 .kiro/steering/testing.md:

# 测试指引

每个财务公式都需要确定性的单元测试。
使用属性风格的测试(property-style tests)来验证不变量,例如回撤 <= 0。
测试空数组、单点数组、平坦净值、全胜净值、全败净值、无效净值以及极端回撤。

Kiro 提示词示例

创建一个规格说明,将上传的排行榜 JavaScript 提取至 TypeScript 分析模块中。包含财务公式定义、排序与搜索行为、SVG 路径生成、实时模拟行为、测试与边缘案例。

商业逻辑: 指引设置在生成代码之前先定义财务含义。开发者需要一致的单位与正负号惯例,以避免产生误导性的排名。

代码逻辑: Kiro 使用指引设置规则来生成纯函数与测试,而不是将计算嵌入 UI 渲染中。

预期结果: Kiro 为分析引擎生成需求/设计/任务流程。

系统设计原理解析:

  1. 量化数学指引设置是强制性的,因为原始原型包含诸如 ret、dd 和 perc 等简短的辅助函数名称;生产环境开发者需要明确的定义。
  2. 测试指引设置与数学指引设置分开,因为测试覆盖率是一项工程政策,而非财务公式。
  3. “不虚构实时数据”的规则保持了工作坊的真实性。模拟数据只有在明确标记为 Demo 行为时才能使用。

步骤 2 — 定义类型

创建 src/domain/types.ts:

export type SortKey = 'navPct' | 'dailyPct' | 'sharpe' | 'profitFactor' | 'winRatePct' | 'maxDrawdownPct';

export type Trader = {
    name: string;
    strategy: string;
    navPct: number;
    dailyPct: number;
    sharpe: number;
    profitFactor: number;
    winRatePct: number;
    skew: number;
    maxDrawdownPct: number;
    series: number[];
};

export type AdvancedMetrics = {
    windowReturnPct: number;
    realizedVolPct: number;
    calmarRatio: number;
    valueAtRisk95Pct: number;
    bestDayPct: number;
    worstDayPct: number;
    winRatePct: number;
    maxDrawdownPct: number;
};

商业逻辑: 类型记录了哪些值是原始输入,哪些是衍生分析指标。

代码逻辑: SortKey 模拟了 Demo 的排序按钮。Trader 对应参与者对象,而 AdvancedMetrics 对应详细信息面板的区块。

预期结果: TypeScript 在开发过程中能捕捉到无效的排序键或缺失的指标字段。

系统设计原理解析:

  1. 明确的类型取代了隐式的 JavaScript 对象形状。这至关重要,因为交易仪表板经常需要通过新增字段来演进。
  2. 排序键使用领域名称(domain names),而非 UI 标签(如 SR 或 PF),这使代码更容易理解,同时在呈现层保留标签。
  3. 高级指标与交易员输入分离,因为 Calmar 和 VaR 等数值是从 series 计算而来,而非手动维护。

步骤 3 — 实现计算

创建 src/domain/calculations.ts:

import type { AdvancedMetrics } from './types';

export function returnsPct(series: number[]): number[] {
    if (series.length < 2) return [];
    return series.slice(1).map((value, index) => ((value / series[index]) - 1) * 100);
}

export function drawdownPct(series: number[]): number[] {
    if (!series.length) return [];
    let peak = series[0];
    return series.map(value => {
        peak = Math.max(peak, value);
        return peak === 0 ? 0 : ((value / peak) - 1) * 100;
    });
}

export function average(values: number[]): number {
    return values.length ? values.reduce((a, b) => a + b, 0) / values.length : 0;
}

export function standardDeviation(values: number[]): number {
    const m = average(values);
    return values.length ? Math.sqrt(average(values.map(v => (v - m) ** 2))) : 0;
}

export function percentile(values: number[], p: number): number {
    if (!values.length) return 0;
    const sorted = [...values].sort((a, b) => a - b);
    const index = Math.min(sorted.length - 1, Math.max(0, Math.floor((p / 100) * sorted.length)));
    return sorted[index];
}

export function advancedMetrics(series: number[]): AdvancedMetrics {
    const r = returnsPct(series);
    const d = drawdownPct(series);
    const windowReturnPct = series.length >= 2 ? ((series.at(-1)! / series[0]) - 1) * 100 : 0;
    const maxDrawdownPct = d.length ? Math.min(...d) : 0;
    return {
        windowReturnPct,
        realizedVolPct: standardDeviation(r) * Math.sqrt(252),
        calmarRatio: maxDrawdownPct === 0 ? 0 : windowReturnPct / Math.abs(maxDrawdownPct),
        valueAtRisk95Pct: percentile(r, 5),
        bestDayPct: r.length ? Math.max(...r) : 0,
        worstDayPct: r.length ? Math.min(...r) : 0,
        winRatePct: r.length ? r.filter(x => x > 0).length / r.length * 100 : 0,
        maxDrawdownPct,
    };
}

商业逻辑: 这些函数使用专业名称与安全的空数组处理行为,重现了分析面板的逻辑。

代码逻辑: 代码将原型辅助函数转换为可组合的函数。advancedMetrics 聚合了详细信息面板中显示的特定区块数值。

预期结果: 传入 Sofia 的净资产价值(NAV)序列会返回大约 18.4% 的区间收益率、负的最大回撤,以及面板所需的高级分析数值。

系统设计原理解析:

  1. 纯函数使分析引擎可用于 UI、API、测试或批处理作业。这保护了业务逻辑免受 UI 重构的影响。
  2. advancedMetrics 集中了面板计算,因此 React 详细信息面板不需要重复公式。
  3. 百分位数方法刻意镜像了原始的简化 Demo。工作坊应解释生产环境的 VaR 需要更强大的方法论与数据治理。

步骤 4 — 实现排序、过滤与摘要统计

创建 src/domain/leaderboard.ts:

import type { SortKey, Trader } from './types';

export function signed(value: number, digits = 1, suffix = ''): string {
    return `${value >= 0 ? '+' : ''}${value.toFixed(digits)}${suffix}`;
}

export function searchAndSort(traders: Trader[], query: string, sortKey: SortKey): Trader[] {
    const q = query.trim().toLowerCase();
    return traders
        .filter(t => !q || t.name.toLowerCase().includes(q) || t.strategy.toLowerCase().includes(q))
        .sort((a, b) => sortKey === 'maxDrawdownPct' ? a.maxDrawdownPct - b.maxDrawdownPct : b[sortKey] - a[sortKey]);
}

export function boardStats(traders: Trader[]) {
    return {
        participants: traders.length,
        bestSharpe: Math.max(...traders.map(t => t.sharpe)),
        avgWinRatePct: traders.reduce((s, t) => s + t.winRatePct, 0) / traders.length,
        bestNavPct: Math.max(...traders.map(t => t.navPct)),
    };
}

商业逻辑: 用户可以按绩效或质量进行排名,并按人员或策略进行搜索。摘要统计数据支持快速的交易台级别读取。

代码逻辑: 该函数重现了 Demo 的 data() 和 stat() 行为。最大回撤采用升序排序,因为在原始逻辑中,较低的回撤代表较好的风险控制。

预期结果: 按净资产价值(NAV)排序会将 Sofia 排在第一位。搜索 crypto 会返回 Lucia Fernandez 和 Carmen Lopez。

系统设计原理解析:

  1. 排序从渲染中分离出来,因此测试可以独立于 UI 证明排名行为。
  2. 搜索同时使用姓名与策略,因为原始 Demo 允许用户通过策略风格来发现交易员,而不仅仅是看名字。
  3. 最大回撤排序经过特殊处理,因为风险指标通常与收益指标的方向相反。

步骤 5 — 实现 SVG 路径辅助函数

创建 src/domain/charts.ts:

export function svgPath(values: number[], width: number, height: number, padding = 18): string {
    if (!values.length) return '';
    const min = Math.min(...values);
    const max = Math.max(...values);
    const range = max - min || 1;
    const innerWidth = width - padding * 2;
    const innerHeight = height - padding * 2;
    return values.map((value, index) => {
        const x = padding + index * innerWidth / Math.max(1, values.length - 1);
        const y = padding + innerHeight - ((value - min) / range) * innerHeight;
        return `${index ? 'L' : 'M'}${x.toFixed(1)} ${y.toFixed(1)}`;
    }).join(' ');
}

export function histogramBars(returns: number[], width: number, height: number, padding = 18) {
    const maxAbs = Math.max(...returns.map(Math.abs), 1);
    const barWidth = (width - padding * 2) / Math.max(1, returns.length);
    const mid = height / 2;
    return returns.map((value, index) => {
        const barHeight = Math.abs(value) / maxAbs * (height / 2 - padding);
        return {
            x: padding + index * barWidth + 1,
            y: value >= 0 ? mid - barHeight : mid,
            width: Math.max(2, barWidth - 2),
            height: barHeight,
            positive: value >= 0,
        };
    });
}

商业逻辑: 图表帮助交易员比仅看数字更快理解趋势、回撤压力与每日收益率分布。

代码逻辑: svgPath 镜像了原型的路径生成器。histogramBars 将收益率转换为正/负条形的矩形几何形状。

预期结果: 相同的净资产价值(NAV)序列可以生成走势图、权益曲线、回撤线与收益率直方图。

系统设计原理解析:

  1. 图表几何形状在纯函数中计算,因此无需浏览器渲染即可进行测试。
  2. 路径函数将数值归一化到视窗(view box)。这使得同一个辅助函数可以同时支持小型走势图与大型图表。
  3. 直方图条形带有 positive 标记,因此 UI 可以直接应用绿色或红色样式,而无需重新计算正负号逻辑。

步骤 6 — 实现受控的实时模拟

创建 src/domain/simulator.ts:

import type { Trader } from './types';

export function nextDemoTick(traders: Trader[], random = Math.random): Trader[] {
    return traders.map(trader => {
        const bump = (random() - 0.48) * 0.18;
        const nextDailyPct = Number((trader.dailyPct + bump).toFixed(2));
        const nextNavPct = Number((trader.navPct + bump * 0.25).toFixed(2));
        return {
            ...trader,
            dailyPct: nextDailyPct,
            navPct: nextNavPct,
            series: [...trader.series.slice(1), 100 + nextNavPct],
        };
    });
}

商业逻辑: Demo 每 5 秒更新一次以模拟实时看板。开发者必须明确将其标记为模拟数据,而非真实市场数据。

代码逻辑: 该函数镜像了原始的更新循环,但使随机性可注入(injectable)以进行确定性测试。

预期结果: 每个 Tick 都会微调每日收益率、微调净资产价值(NAV)、移动序列窗口,并附加一个新的合成净值点。

系统设计原理解析:

  1. 随机性是注入的,因为测试需要确定性的行为。这保留了实时 Demo 的感觉,又不会使测试变得不稳定(flaky)。
  2. 序列通过丢弃最旧的点来使用滚动窗口(rolling window)。这保留了图表长度并避免了内存无限制增长。
  3. 该函数返回新对象,而不是修改(mutating)原始数组,符合 React 状态管理预期。

步骤 7 — 添加测试

创建 src/domain/__tests__/calculations.test.ts:

import { describe, expect, it } from 'vitest';
import { advancedMetrics, drawdownPct, returnsPct } from '../calculations';

describe('量化计算', () => {
    it('从 NAV 计算收益率', () => {
        expect(returnsPct([100, 110, 99]).map(x => Number(x.toFixed(2)))).toEqual([10, -10]);
    });

    it('回撤绝不为正数', () => {
        expect(drawdownPct([100, 120, 90, 130]).every(x => x <= 0)).toBe(true);
    });

    it('创建高级面板指标', () => {
        const metrics = advancedMetrics([100, 105, 99.75]);
        expect(Number(metrics.windowReturnPct.toFixed(2))).toBe(-0.25);
        expect(Number(metrics.maxDrawdownPct.toFixed(2))).toBe(-5.00);
    });
});

Kiro 提示词示例

审查分析模块与测试。为每个 Demo 参与者序列、净值(NAV)与最大回撤(Max DD)的排序行为、按策略关键字搜索、SVG 路径边界、直方图正负条形,以及注入随机值的确定性模拟新增测试案例。

商业逻辑: 测试保护了驱动交易解读的计算公式。

代码逻辑: 单元测试验证了已知的数值示例,并可扩展以覆盖所有参与者。

预期结果: npx vitest run 通过且 Kiro 提出了额外的覆盖建议。

系统设计原理解析:

  1. 已知值测试可快速捕捉公式退化(regressions)。财务审查人员很容易理解这些测试。
  2. 要求 Kiro 新增特定参与者的回归测试,使数据或公式的变更不会意外更改显示的分析结果。
  3. 图表测试专注于几何边界,因为 SVG 视觉测试成本高昂且对本工作坊而言并非必要。

最终实验室挑战

询问 Kiro:

生成一份完整的分析差异报告,对比 TypeScript 模块与原始 Demo 的 JavaScript 函数:sg、cl、id、ret、dd、avg、sd、perc、path、spark、eqChart、ddChart、hist、panel、data、render、tog、stat、markets、clock 以及 5 秒更新循环。识别哪些已实现、哪些刻意移至 React,以及哪些仍需要测试。

完成检查清单

  • [ ] 所有参与者与市场数据皆已定义类型。
  • [ ] 收益率、回撤、波动率、百分位数、Calmar 比率、VaR、最佳/最差单日以及胜率皆已实现。
  • [ ] 搜索与排序重现了 Demo 的行为。
  • [ ] SVG 路径与直方图几何形状为纯函数。
  • [ ] 实时模拟已明确标记并在测试中具备确定性。
  • [ ] Kiro 已审查数学边缘案例。
  • [ ] 测试涵盖了计算、排序、图表与模拟。

附录 — 用于分析测试的完整参与者与市场覆盖范围

使用此检查清单以确保分析引擎覆盖完整的 HTML Demo,而不仅仅是示例数据行:

  • Sofia Garcia — 跨资产凸性宏观阿尔法 (Cross-Asset Convex Macro Alpha):NAV +18.4%, 每日 +0.42%, 夏普比率 0.73, 盈利因子 1.8, 胜率 58%, 偏度 +0.44, 最大回撤 18。
  • Lucia Fernandez — 加密货币动能轮动 (Crypto Momentum Rotation):NAV +16.9%, 每日 +0.88%, 夏普比率 0.91, 盈利因子 1.7, 胜率 61%, 偏度 +0.31, 最大回撤 22。
  • Carmen Lopez — 加密货币套利与波动率 (Crypto Carry & Volatility):NAV +14.2%, 每日 -0.31%, 夏普比率 0.68, 盈利因子 1.6, 胜率 56%, 偏度 +0.22, 最大回撤 25。
  • Elena Martin — 全球宏观趋势跟随 (Global Macro Trend Rider):NAV +11.8%, 每日 +0.17%, 夏普比率 0.62, 盈利因子 1.5, 胜率 54%, 偏度 +0.18, 最大回撤 17。
  • Marta Sanchez — 利率与外汇相对价值 (Rates & FX Relative Value):NAV +9.6%, 每日 +0.09%, 夏普比率 0.57, 盈利因子 1.4, 胜率 53%, 偏度 +0.09, 最大回撤 15。
  • Paula Romero — 权益因子集合 (Equity Factor Ensemble):NAV +7.1%, 每日 -0.12%, 夏普比率 0.49, 盈利因子 1.3, 胜率 52%, 偏度 -0.04, 最大回撤 14。
  • Ana Torres — 大宗商品突破系统 (Commodity Breakout System):NAV +5.4%, 每日 +0.28%, 夏普比率 0.42, 盈利因子 1.2, 胜率 51%, 偏度 +0.12, 最大回撤 19。
  • Laura Navarro — 多资产均值回归 (Multi-Asset Mean Reversion):NAV +3.8%, 每日 -0.06%, 夏普比率 0.35, 盈利因子 1.1, 胜率 49%, 偏度 -0.11, 最大回撤 16。

市场卡片回归案例:

  • ES: +0.38%, 买方堆叠 (BID STACK), 序列 [20,21,20,22,23,23,24,25,24,26]。
  • CL: -0.22%, 卖方成交 (OFFER HIT), 序列 [30,29,31,28,27,26,25,24,23,22]。
  • GC: +0.62%, 买方堆叠 (BID STACK), 序列 [18,18.5,19,18.7,20,21,20.5,22,23,23.5]。
  • BTC: +2.18%, 买方堆叠 (BID STACK), 序列 [20,22,21,24,26,25,29,28,32,34]。

Kiro 完整覆盖提示词:

生成一个回归测试套件,加载所有 8 个参与者数据行与所有 4 个市场卡片。验证摘要统计数据、每个排序键的排序顺序、按每个策略关键字搜索、每个序列的 SVG 路径,以及每个参与者的高级面板指标。

原始 Demo 参考

本工作坊基于上传的 aws_quant_pnl_leaderboard_v3.html Demo。该 Demo 包含一个 CME Direct 风格的深色工作空间、参与者排行榜、市场卡片、可排序/可搜索的损益板、高级分析面板、图表函数、响应式 CSS、实时 HKT 时钟以及模拟的周期性资产净值更新。所有数据均视为 Demo 占位符数据,不构成投资建议。


进阶开发者附加动手实践实验室 — HTML 图形分析

这些实验室通过分析上传的 HTML 文件的 SVG 图表图形来扩展量化分析工作坊。它们专注于原型如何将资产净值(NAV)序列、回撤数组与每日收益率转化为视觉标记。它们不会重复基础财务公式或 UI 组件迁移。

进阶图形分析目标

到本节结束时,进阶开发者将能够:

  • 解释 HTML 如何将数值序列转换为 SVG 路径、区域、线条与条形。
  • 通过确定性测试验证图表几何形状。
  • 将视觉编码逻辑与财务计算分离。
  • 构建协助审查人员理解图形含义的图表审查元数据(chart-audit metadata)。
  • 检测由尺度、填充(padding)或边缘案例数据引起的误导性图表输出。

来自 HTML 文件的图表图形清单

上传的 HTML 使用了几个 JavaScript 函数来生成 SVG 图形:

  • path(a,w,h,p) 将序列归一化为 SVG M 与 L 指令。
  • spark(a) 渲染紧凑的数据行与市场卡片走势图。
  • grid(w,h,p) 建立水平网格线与底部轴线。
  • eqChart(a) 渲染带有填充区域与 NAV 起始/结束标签的权益曲线。
  • ddChart(a) 将回撤渲染为零轴下方的红色水位线形状。
  • hist(a) 围绕中线渲染每日收益率条形,使用独立的正、负类别(classes)。

进阶实验室 1 — 图表几何契约测试

目标: 建立测试以证明 SVG 几何形状保持在图表边界内,并安全地处理平坦、过短以及剧烈波动的序列。

创建 src/domain/__tests__/chartGeometry.test.ts:

import { describe, expect, it } from 'vitest';
import { svgPath, histogramBars } from '../charts';

function extractNumbers(path: string): number[] {
  return path.match(/-?\d+(\.\d+)?/g)?.map(Number) ?? [];
}

describe('SVG 图表几何契约', () => {
  it('将路径坐标保持在视窗填充边界之内', () => {
    const d = svgPath([100, 102, 101, 104], 120, 32, 2);
    const numbers = extractNumbers(d);
    const xs = numbers.filter((_, index) => index % 2 === 0);
    const ys = numbers.filter((_, index) => index % 2 === 1);

    expect(Math.min(...xs)).toBeGreaterThanOrEqual(2);
    expect(Math.max(...xs)).toBeLessThanOrEqual(118);
    expect(Math.min(...ys)).toBeGreaterThanOrEqual(2);
    expect(Math.max(...ys)).toBeLessThanOrEqual(30);
  });

  it('渲染平坦序列时不会发生除以零的几何错误', () => {
    const d = svgPath([100, 100, 100], 120, 32, 2);
    expect(d).toContain('M');
    expect(d).toContain('L');
    expect(d).not.toContain('NaN');
    expect(d).not.toContain('Infinity');
  });

  it('围绕中线建立正向和负向的直方图条形', () => {
    const bars = histogramBars([1, -2, 0.5], 680, 120, 18);
    expect(bars.some((bar) => bar.positive)).toBe(true);
    expect(bars.some((bar) => !bar.positive)).toBe(true);
  });
});

Kiro 提示词:

为上传的 HTML 的路径、走势图、权益曲线、回撤与直方图行为生成图表几何测试。验证坐标边界、无 NaN 或 Infinity、平坦序列行为、短序列行为、正/负直方图标记,以及各个 Demo 参与者序列的绘图一致性。

预期结果: 开发者可以重构图表代码,而不会意外产生损坏的 SVG。

进阶实验室 2 — SVG 视觉编码文档

目标: 记录财务概念与图形标记之间的关系,使图表行为可供审查。

创建 docs/svg-visual-encoding.md:

# SVG 视觉编码笔记

## 走势图 (Sparkline)

- 数据输入:NAV 序列或市场迷你序列。
- 标记类型:单一绿线。
- 用途:紧凑的趋势预览。
- 风险:未显示 Y 轴尺度,因此不应视为精确测量。

## 权益曲线 (Equity curve)

- 数据输入:指数化(indexed)的 NAV 序列。
- 标记类型:绿线加上半透明填充区域。
- 用途:可视化的累计绩效路径。
- 标签:第一个 NAV 值与最后一个 NAV 值。

## 回撤水位线 (Drawdown waterline)

- 数据输入:从 NAV 派生出的回撤百分比序列。
- 标记类型:红线以及零轴下方的红色填充区域。
- 用途:显示从峰值到谷值的痛苦与恢复压力。

## 每日损益直方图 (Daily P&L histogram)

- 数据输入:每日收益率序列。
- 标记类型:围绕水平中线的垂直条形。
- 正向编码:中线之上的绿色条形。
- 负向编码:中线之下的红色条形。

Kiro 提示词:

为 HTML 图表创建视觉编码文档。使用数据输入、SVG 标记类型、颜色编码、尺度限制与审查注意事项来解释走势图、权益曲线、回撤水位线与每日损益直方图。

预期结果: 图表图形对开发者、设计师与风险审查人员变得易于解释。

进阶实验室 3 — 图表审查元数据生成器

目标: 为每张图表生成元数据,以便审查人员检查尺度、极值、范围、正负条形计数与标签文字。

创建 src/domain/chartAudit.ts:

import { drawdownPct, returnsPct } from './calculations';

export type SeriesAudit = {
  pointCount: number;
  min: number;
  max: number;
  range: number;
  first: number;
  last: number;
};

export type ChartAudit = {
  nav: SeriesAudit;
  drawdown: SeriesAudit;
  returns: SeriesAudit & {
    positiveCount: number;
    negativeCount: number;
    zeroCount: number;
  };
};

function auditSeries(values: number[]): SeriesAudit {
  if (!values.length) {
    return { pointCount: 0, min: 0, max: 0, range: 0, first: 0, last: 0 };
  }

  const min = Math.min(...values);
  const max = Math.max(...values);

  return {
    pointCount: values.length,
    min,
    max,
    range: max - min,
    first: values[0],
    last: values.at(-1)!,
  };
}

export function auditChartSeries(navSeries: number[]): ChartAudit {
  const drawdown = drawdownPct(navSeries);
  const returns = returnsPct(navSeries);
  const returnsAudit = auditSeries(returns);

  return {
    nav: auditSeries(navSeries),
    drawdown: auditSeries(drawdown),
    returns: {
      ...returnsAudit,
      positiveCount: returns.filter((value) => value > 0).length,
      negativeCount: returns.filter((value) => value < 0).length,
      zeroCount: returns.filter((value) => value === 0).length,
    },
  };
}

Kiro 提示词:

为每个净值(NAV)序列新增图表审查元数据。包含点数、最小值、最大值、范围、首/尾值、回撤范围、收益率范围,以及正/负/零收益率计数。为所有 8 个参与者序列新增测试。

预期结果: 分析审查人员无需打开浏览器即可检查图表输入与尺度风险。

进阶实验室 4 — 误导性图形边缘案例实验室

目标: 教导开发者识别图形在技术上正确但视觉上具有误导性的边缘案例。

创建 docs/misleading-chart-edge-cases.md:

# 误导性图表边缘案例

## 平坦序列 (Flat series)

平坦的 NAV 序列会产生一条直线,但如果忽略了标签,视觉范围的退化可能会使极微小的变动看起来比实际更大。

## 单点序列 (Single-point series)

单个点无法代表趋势。图表应渲染安全的占位符或显示数据不足的消息。

## 极端离群值 (Extreme outlier)

一个巨大的跳空可能会压缩所有其他变动,使正常的波动看起来像消失了一样。

## 短收益率窗口 (Short return window)

包含 14 个收益率的直方图具有教育意义,但不足以得出稳健的分布结论。

## 缺少尺度标签 (Missing scale labels)

走势图对于快速形状识别很有用,但不应被视为精确的风险证据。

Kiro 提示词:

为 HTML 图表函数创建误导性图表边缘案例指南。涵盖平坦序列、单点序列、极端离群值、短收益率窗口、缺少 Y 轴尺度以及直方图解读限制。

进阶实验室 5 — 图表渲染验收标准

目标: 在生产环境重构验收之前,定义图表图形的验收标准。

创建 docs/chart-rendering-acceptance-criteria.md:

# 图表渲染验收标准

## 权益曲线 (Equity curve)

- 使用与 HTML 原型相同的归一化坐标逻辑。
- 包含可见的线条与填充区域。
- 标注第一个和最后一个 NAV 值。
- 不渲染 NaN 或 Infinity。

## 回撤水位线 (Drawdown waterline)

- 渲染前回撤值必须为零或负数。
- 零轴清晰可见。
- 红色区域随回撤加深而向下增长。
- 最大回撤标签与计算出的最小回撤相符。

## 每日收益率直方图 (Daily return histogram)

- 正向条形显示在中线之上。
- 负向条形显示在中线之下。
- 数值为零的条形不会引发视觉错误。
- 在所有支持的图表尺寸下,条形宽度保持清晰可见。

## 走势图 (Sparkline)

- 紧凑的图表不包含未支持的尺度声明。
- 保留所有参与者与市场迷你序列的趋势形状。

Kiro 提示词:

为 React/SVG 重构生成图表渲染验收标准。包含权益曲线、回撤水位线、每日收益率直方图与走势图检查。尽可能将每个视觉断言与确定性测试相连接。

进阶最终挑战 — SVG 图表保真度审查

询问 Kiro:

对上传的 HTML 文件进行 SVG 图表保真度审查。对比路径归一化、填充(padding)、权益区域闭合、网格线、回撤零轴、直方图中线、正负条形放置、标签以及边缘案例行为。产出优先顺序修复待办清单。

进阶图形分析完成检查清单

  • [ ] 图表几何测试验证了边界与无效数字保护。
  • [ ] 视觉编码文档解释了每种 SVG 图表类型。
  • [ ] 图表审查元数据总结了 NAV、回撤与收益率序列。
  • [ ] 误导性图表的边缘案例已记录成册。
  • [ ] 渲染验收标准保护了图表重构。