Yuanhao Feng

返回

Cambio

把零散换汇记录变成真实持仓成本,检验择时有没有用。

为什么做#

留学几年陆续换了不少外币,每次汇率都不一样。时间久了,“手上这些外币平均花了多少钱”这个问题,银行流水和汇率软件都答不了。Cambio 从零散的成交记录算出真实持仓成本,再拿来跟市场汇率比。

只处理本位币和外币之间的兑换,不做任意币种交叉。每笔交易保存当时的本位币设置,事后改配置不会篡改历史。

持仓与成本#

交易按时间顺序重放,用移动加权平均法计算成本。买入时新成本按金额权重并入成本池,卖出按现有均价结算,差额计入已实现损益,不改写剩余持仓的成本。手续费折入有效汇率,不单独列支。持仓清零时成本池重置。

账本页上方有一张决策卡,拿最新市场价和个人均价做对比,显示浮盈浮亏和偏离幅度。

账单页中的持仓、个人均价、市场现价和今日决策卡。

账本页:交易记录汇总为当前持仓,决策卡对比个人均价与市场现价。

择时分析#

统计页把市场日线、持仓量和个人成本画在同一条时间轴上。市场价每天变动,成本线只在成交日移动,每笔交易对均价的影响可以直接看到。下单前可以用 What-if 模拟,输入一笔假设交易,实时预览对持仓和均价的变化,确认后再入账。模拟和正式入账跑的是同一套计算。

统计页中的成交点、个人成本曲线与同期市场汇率。

统计页:成交点、个人成本与市场汇率在同一时间轴上。

择时复盘提供两个量化基准:TWAP 是同期市场的时间加权均价,衡量是否优于随机时点;DCA 是每天等额买入的加权调和均价,衡量是否跑赢了一个不需要判断的机械策略。

深色模式下的择时复盘页,比较个人均价、同期市场均价与定投基准。

择时复盘:个人均价与 TWAP、DCA 对照,标注最优和最差成交。

技术细节#

Monorepo 分四个包。packages/core 是纯函数的领域引擎,只依赖 decimal.js,所有持仓计算、模拟和择时分析都在这里完成。packages/shared 用 Zod 定义全部请求和响应的 schema,前后端共享类型,同时驱动校验和 OpenAPI 文档生成。API 层是 Fastify 5 + Drizzle + PostgreSQL,前端是 React 19 + Vite + TanStack Router。

金额全链路十进制运算:数据库用 numeric 存储,API 传输字符串,领域层用 decimal.js,不经过浮点数。整条持仓历史沿时间轴单趟 O(n) 计算。

认证基于服务端 Session,密码用 Argon2id 哈希,token 用 SHA-256 存储,支持改密码后一次吊销所有会话。分享功能通过可撤销、可过期的只读链接实现,只展示持仓汇总,不暴露单笔交易和备注。