GitHub 简介写「quantifies your margin of safety」。代码里没有内在价值、没有安全边际、没有估值字段。现在是净值 + XIRR + 退休投影。
三层分工
Harvest
把公开市场与另类数据采进 Mongo / ClickHouse。运维用,不是投资产品。
OHLC
选股、回测、信号、A 股纸面账户。行情来自网关 + 只读 Harvest。
x-margin
记你的真钱。离线、手工价、本地 SQLite。不读湖。
Mongo SoT + CH 时序] H -->|只读契约| O[OHLC
PG SoT + CH 副本] O -->|纸面买卖 T+1| P[Paper Account
不是真钱] U[券商流水 / 手工价] -->|手录| X[x-margin SQLite] X --> N[净值 · XIRR · 退休] X -.->|不要接| H O -.->|不要混域| X
读懂 x-margin
个人真实资金净值账本。单页 dashboard,无路由。模态录入 → createServerFn → better-sqlite3 → hook 全量重算。
| 层 | 文件 | 职责 |
|---|---|---|
| 实体 | src/lib/db-schemas.ts | 现金账户、存取转、持仓、买卖/分红/拆股/费用、价格快照、退休设置 |
| 账本 | position-state / portfolio / xirr / retirement | 持仓状态、现金、XIRR、退休投影 |
| 写入 | src/server/* | 几乎无业务校验的 CRUD;删账户 CASCADE 买卖流水 |
| 展示 | src/routes/index.tsx | 账户 / 流水 / 组合 / 持仓 / 退休 |
阅读顺序:db-schemas.ts → db.ts → position-state.ts → portfolio.ts → use-portfolio-history.ts → index.tsx。
对照表
| 维度 | x-margin | Harvest | OHLC |
|---|---|---|---|
| 一句话 | 记我的真钱 | 把公开数据采进湖 | 用湖做研究 / 模拟 |
| 用户 | 投资者 | 运维 | 研究员 |
| 钱是真的吗 | 是。现金 + 持仓由流水推导 | 否。公募披露持仓、价快照 | 否。Paper Account,T+1 |
| 价格从哪来 | 手工 price_snapshots | Yahoo / 通达信 / 巨潮 / 东财… | PG 日线 + 网关;港美日线主源是 Harvest CH |
| 持久化 | 单机 SQLite | Mongo SoT + CH + Redis | PG SoT + CH 副本;跨库只读 Harvest |
| 在线 | 刻意离线 | 生产常驻计算/存储分离 | 同拓扑;CLI / Web / GraphQL / bots |
| 备份 | 无 | 每日 mongodump 滚动保留 | PG dump;CH 可重建 |
| 领域模型 | 无 CONTEXT.md | 源 / 类别 / 跨仓契约 | 10 个 bounded context + ADR |
| 成熟度 | 0.0.1,无 CI | 生产在跑,有 CI | 0.75.1,NO GREEN NO MERGE |
| 依赖另外两个 | 无 | 被 OHLC 只读 | 硬依赖 Harvest(ADR-0037 / 0044) |
OHLC 的 ohlc portfolio / avgCost 是模拟盘或市场筹码分布,不是税基。Harvest 的 fund_holdings 是基金公司持仓披露。
成熟度雷达
主观评分,只用来对照工程纪律,不是产品分。x-margin 的 UI 分高,账本与运维分低。
x-margin:已核实的账本问题
审计对象 XFreeCoder/x-margin,HEAD 2b6d827。未跑测试(仓库无安装)。未启动桌面壳。
| # | 问题 | 影响 | 工作量 |
|---|---|---|---|
| 1 | 历史曲线漏掉分红和费用 | use-portfolio-history 把分红/费用写死成 0。Analytics 累计收益画错。 |
S |
| 2 | 卖超仓只 clamp | 持仓变 0,卖出金额全进卖出所得,投入成本不动。卖出表单不看持仓。 | S |
| 3 | 删现金账户 CASCADE 买卖流水 | 对话框只报 cash record 数。算了 txCount 没用。持仓成本 silently 变。 |
S |
| 4 | XIRR 失败显示 +0.00% | 牛顿法不收敛或现金流同号时,主面板年化收益看起来是零。 | S |
| 5 | positive() 拒绝 0 |
免佣、0% 通胀、0 储蓄存不进去。设置文案还说开支按通胀增长,实现是 Fisher 折现。 | S |
| 6 | 生产 mapRow 不跑 Zod |
只在 DEV safeParse,然后 as T。坏行进 Decimal / UI。 |
S |
| 7 | 没有 schema migration | 只有 CREATE IF NOT EXISTS。现有用户库加列是空操作。 |
M |
| 8 | 写路径零测试 | 四个 lib 单测。XIRR / 退休大量 not.toBeNull()。上面 1–4 都漏了。 |
M |
| 9 | 无 CI;TanStack 钉 latest |
脚本在,没人跑。八个 @tanstack/* 是浮动版本。 |
S |
| 10 | 文档与代码相反 | README 写 localStorage;AGENTS 写 server functions unused;mock-data 指向已删脚本。 |
S |
看过、否掉
getDb并发竞态 — 同步函数,JS 单线程。- 未鉴权 server fn = 漏洞 — 本地单用户,没有证据绑了非 loopback。
- 全表
SELECT */ 历史 O(dates×positions) — 个人账本量级,现在优化是投机。 - 把 14 个 create/update 收成 factory — 刚按类型拆开。
tsconfig.exclude: ["server"]跳过src/server— 排除的是仓库根server/。
不该做的事
- 不要把真钱账本塞进 OHLC。 会和 Paper Account 混域,且 OHLC 是在线多服务,违背离线前提。
- 不要让 Harvest 存个人持仓。 它是湖,不是 PMS。
- 现在不要给 x-margin 接行情。 产品写明手工价。真要接,只读 OHLC / Harvest,当填价助手,别当账本源。
唯一真重叠:两边都有「账户 + 流水推持仓 + 均价」。差在 OHLC 是 A 股 T+1、印花税、收盘价结算;x-margin 是多品种、手工价、XIRR、退休。
下一步
对照另外两个,x-margin 缺的是账本正确性和备份,不是再做一个迷你 OHLC。
- 先写钱路径的表征测试(含历史分红、超卖、级联删除)。
- 修 #1–#4:历史收益、超卖拒绝、删账户、XIRR 空值。
- 加 schema version,再谈任何表结构变更。
- 导出 / 导入 / 显示数据库路径。Harvest 有滚动备份,x-margin 重装即清盘。
- Deno Desktop ×
better-sqlite3先实证再谈发布。
方法与限度
- 对象:x-margin(克隆审读)+ Harvest + OHLC 本地仓库。
- 方法:README / CONTEXT / AGENTS / ADR + 源码交叉检索。无 Understand-Anything 图谱。
- 未做:三仓都没在本轮启动;x-margin 未跑 typecheck / test(无
node_modules)。 - 脱敏:本页不含内网地址、凭据、SSH、数据库连接串。