尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证vibe coding 出来的模拟基金交易系统:东方财富真实净值 + T+1 撮合规则、FIFO 份额批次阶梯赎回费、整数分账零浮点误差。React Router 8 / Cloudflare Workers / D1 / KV 免费全家桶,开发中
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
用真实基金数据玩模拟盘。真实 T+1 撮合、真实内扣申购费、真实 FIFO 阶梯赎回费, 每日签到领本金。部署在 Cloudflare 免费全家桶上,零成本运行。 市面上的模拟炒股大多用随机数或简化规则。这个项目较真的地方: • 真实数据:基金档案、费率、起购金额、历史净值全部来自东方财富公开接口 • 真实 T+1:交易日 15:00 前下单按当日净值成交,之后顺延至下一交易日; 每晚 20:30 由 Cron 拉取当日净值并撮合 • 真实内扣法申购费:净申购金额 = 申购金额 ÷ (1 + 费率), 而不是常见的错误实现 费用 = 金额 × 费率(外扣法会多收钱) • 真实 FIFO 阶梯赎回费:份额按批次先进先出消耗,每批按各自持有天数套费率档。 同一笔赎回可能同时按 1.5% 和 0.5% 两档计费——这就是为什么需要 share_lot 表, 只存持仓汇总是算不出正确赎回费的 • 整数存储:金额存「分」、份额/净值存 ×10000 整数,中间运算走 decimal.js。 绝不用浮点数算钱 申购 1000 元,费率 0.15%,确认日净值 1.3100: 赎回 300 份(持有 0 天,命中 <7天 档 1.5%): share_lot 与 holding 对账完全一致,一分不差。查看完整 README ↗
用真实基金数据玩模拟盘。真实 T+1 撮合、真实内扣申购费、真实 FIFO 阶梯赎回费, 每日签到领本金。部署在 Cloudflare 免费全家桶上,零成本运行。
模拟盘 · 数据来自公开接口 · 仅供学习,不构成投资建议
市面上的模拟炒股大多用随机数或简化规则。这个项目较真的地方:
净申购金额 = 申购金额 ÷ (1 + 费率),
而不是常见的错误实现 费用 = 金额 × 费率(外扣法会多收钱)share_lot 表,
只存持仓汇总是算不出正确赎回费的decimal.js。
绝不用浮点数算钱申购 1000 元,费率 0.15%,确认日净值 1.3100:
净申购 = 100000 ÷ 1.0015 = 99850 分 手续费 = 150 分(1.5 元)
份额 = 998.50 ÷ 1.31 = 762.2137 份
赎回 300 份(持有 0 天,命中 <7天 档 1.5%):
赎回总额 = 300 × 1.31 = 393.00 元
赎回费 = 39300 × 1.5% = 590 分(5.90 元)
到账 = 387.10 元
share_lot 与 holding 对账完全一致,一分不差。
| 身份 | 看主理人组合 | 看自己组合 | 下单 / 定投 / 签到 |
|---|---|---|---|
| 游客(未登录) | ✅ 只读(全部公开) | — | ❌ |
| 普通用户 | ✅ 只读 | ✅ 读写 | ✅(仅自己的) |
| 管理员(主理人) | ✅ 读写(即自己的盘) | 同上 | ✅ |
管理员由环境变量 ADMIN_USERNAME 指定,没有独立后台——
主理人的 /me 就是那个被公开的盘,/master 只是它的只读镜像。一份代码,两种身份。
| 层 | 选型 |
|---|---|
| 框架 | React Router v8(framework mode)+ Vite 8 |
| 运行时 | Cloudflare Workers |
| UI | Ant Design v6 + @ant-design/charts |
| 数据库 | Cloudflare D1(SQLite)+ Drizzle ORM |
| 缓存 | Cloudflare KV |
| 定时 | Cloudflare Cron Triggers |
| 密码 | PBKDF2(Web Crypto,Workers 跑不了 bcrypt) |
| 工具 | Zod + dayjs + decimal.js |
| 测试 | Vitest + @cloudflare/vitest-pool-workers(真实 workerd + 真实 D1) |
| 包管理 | pnpm |
pnpm install
pnpm db:migrate:local # 建本地 D1 表(首次必须)
pnpm dev
打开输出的 localhost 地址,注册一个账号即可开玩。
要成为「主理人」,用 wrangler.jsonc 里 ADMIN_USERNAME 指定的用户名注册。
D1 数据库与 KV 已在 Cloudflare 上创建好,wrangler.jsonc 里的 id 已填实:
| 资源 | 名称 / id |
|---|---|
| D1 | fund-plan-db(区域 WNAM) |
| KV | binding KV |
线上库已跑完迁移(12 张业务表)。合并到 main 后 GitHub Actions 自动执行
「测试 → 全绿 → 部署到 Cloudflare」流水线(含幂等 D1 迁移,
见 .github/workflows/deploy.yml);需要时也可本地手动 pnpm deploy。
本地开发用的是 miniflare 模拟的独立数据库(.wrangler/state/),与线上互不影响。
完整部署步骤见 docs/deployment.md。 开发约定与踩坑记录见 docs/development.md。
pnpm test # 领域层单测(纯函数,毫秒级)
pnpm test:workers # 应用层集成测试(真实 workerd + 真实 D1)
pnpm test:all # 全部
pnpm lint # 代码规范检查
pnpm verify # lint + typecheck + test,提交前全量校验
提交时 git 钩子会自动跑:pre-commit 对暂存文件跑 eslint --fix,
pre-push 跑 typecheck 与全部测试。
测试覆盖的关键场景:
share_lot 与 holding 对账一致性costBasisNavScaled,曾因缺 ×100 被低估百倍)app/
domain/ 纯函数领域层(撮合、赎回、定投、签到、估值、排行榜、资产时间线、交易日历)
services/ 应用层(数据接入、认证、下单、撮合、组合读取、排行榜聚合)
routes/ 页面与 loader/action
components/ 复用 UI(净值图、买入/赎回抽屉、组合视图、收益日历)
db/ Drizzle schema 与 client
workers/app.ts Worker 入口(fetch + scheduled)
drizzle/ 迁移 SQL
tests/ 单元测试与集成测试
docs/ 部署与开发指南(设计文档与实施计划为本地工作文档,不入库)
fundgz 接口从服务器直连被挡;T+1 撮合本身用收盘净值,不受影响app/domain/trading-calendar.ts,有净值日反向校正作为兜底