Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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,有净值日反向校正作为兜底