site logo

Marico's space

构建仓位平均计算器:数学计算正确性至关重要

Others 2026-09-04 17:34:17 7

最近帮朋友算股票均价,踩了几个坑,发现网上那些计算器要么要注册、要么一堆广告、要么干脆把手续费给漏了。自己写一个吧,顺便把整个过程记录下来,给有类似需求的朋友参考。

现有方案的坑

我搜了一圈在线计算器,说实话大部分都挺让人失望的。要么要求注册登录,要么藏在财经门户网站里广告比功能还多,还有些干脆把交易手续费给忽略了。

但真正的问题在哪?大多数计算器都搞错了一件事——你的保本价不等于均价。 你卖出的时候也是要交手续费的。所以如果均价是9.0051,你卖出价格定在9.0051实际上还是亏的,必须稍微高一点才能覆盖卖出的费用。

这就是我想填平的坑。

核心计算逻辑

计算本身是简单的加权平均,但手续费的处理才是关键。逻辑如下:

function compute(buys, currentRaw, commRate, stampRate, transferRate, minComm, sym) { let totalShares = 0, totalCost = 0; for (const { price, shares } of buys) { const amt = price * shares; const fee = amt * (commRate + transferRate) / 100; const actualFee = Math.max(fee, minComm); totalCost += amt + actualFee; totalShares += shares; } const avgCost = totalCost / totalShares; // 保本价需要包含卖出手续费 const sellFeePerShare = avgCost * (commRate + stampRate + transferRate) / 100; const breakEven = avgCost + sellFeePerShare; return { totalShares, totalCost, avgCost, breakEven };
}

这里的关键点在于保本价的计算。大多数工具只算到均价(avgCost)就停了,但这其实是误导性的。如果你在均价位置卖出,实际拿到手的钱会因为卖出手续费而变少。保本价需要略高一点——也就是卖出后扣除各项费用,恰好等于你买入时的总成本(含买入手续费)。

为什么选择纯前端方案

我当然可以用后端做,顺便加上用户账号、计算历史这些功能。但说实话,这种计算涉及个人仓位信息,你真的想让自己的持仓数据在某个服务器上飘着吗?

纯前端方案的好处:

  • 数据不离开浏览器
  • 没有服务器成本
  • 秒开秒用
  • 断网也能用

代价?没法持久化历史记录,也不能跨设备同步。但对这个使用场景来说,这个交换我完全可以接受。需要保存结果?截个图就行。

AI辅助开发的体验

这里就有意思了。这个工具我是用AI辅助开发的,过程相当有启发性。

AI做得好的部分

我用自然语言描述需求:"需要个计算器,输入多条买入记录(价格和股数),计算包含手续费的加权平均成本,并显示保本价。"AI给出了一个扎实的基础结构——HTML布局、动态添加行、基本样式。它甚至主动加了深色模式,都没问我要。

AI翻车的部分

第一版代码里有个细节bug。AI对每笔交易单独应用最低佣金,这个是对的,但在计算保本价时,卖出手续费的估算也套用了最低佣金——这就错了。最低佣金只在实际成交时才可能触发,不能按比例算进估算里。

对话过程大概是这样的:

我:保本价太高了。比如我买了100股、单价10块,最低佣金5元,那保本价不应该把最低佣金按比例算进去,因为卖出手续费是按比例计算的。 AI:你说得对。我来修复保本价计算,只用比例费率,不套最低佣金。

这是我在AI编程中观察到的典型模式——它很擅长搞定80%的通用场景,但边界情况和金融逻辑的准确性,还是得靠人。AI不知道"最低佣金不按比例适用"这个规则,它只是在匹配常见代码模式。

又一个AI漏掉的点:输入校验

AI最初假设所有输入都是合法数字。直到我指出可能有人会输入"abc"或者留空,它才加上校验。而且第一版校验过于激进,把一些合理的边界情况也给拦了——比如0股应该是报错,但报错信息写得让人摸不着头脑。

打磨过程

在AI生成初版之后,我又迭代了几个版本:

  1. 修正手续费计算 — 保本价那里的最低佣金逻辑需要调整
  2. 加入输入校验 — 带清晰的中文报错信息(毕竟目标用户是中文用户)
  3. 优化移动端体验 — 初版把所有输入挤在一行,手机上看着太挤了。改成网格布局,小屏自动堆叠
  4. 加上当前价格字段(可选) — 让用户可以直接看到浮动盈亏,不用另开计算器

浮动盈亏的计算也是我纠正AI的地方:

// AI第一版 — 错的
const floatPL = currentPrice * totalShares - totalCost; // 正确版本 — 包含卖出手续费
const sellFee = currentPrice * totalShares * (commRate + stampRate + transferRate) / 100;
const floatPL = currentPrice * totalShares - sellFee - totalCost;

这个差异很重要。如果你要展示某人的浮动盈亏,应该反映他现在卖出实际能拿到多少钱,而不是简单粗暴的现价减成本。

几点心得

1. 领域知识依然重要

AI能写代码,但它不会知道A股市场卖出时收印花税(0.05%),买入时不收;也不会知道有些券商最低佣金是5元。这些规则只有了解国内证券交易的人才清楚。

2. 用真实数据测试

AI生成的测试用例太理想化了。边界情况得我亲自测:

  • 价格输入0怎么办?
  • 股数输入负数呢?
  • 佣金费率是0但最低佣金是5元?
  • 超小额交易,最低佣金占主导时?

这些边界情况暴露了不测试就会上线的bug。

3. AI擅长UI,不擅长逻辑

这个项目里,AI生成的HTML和CSS基本可以直接用。JavaScript逻辑则需要多轮修正。我发现这个规律在多个项目里都适用——AI擅长结构和模板,业务逻辑需要人仔细把关。

最终成果

折腾了几个小时,得到了一个能正确处理各种边界情况的工具:

  • 支持多条买入记录,动态增删
  • 佣金、印花税、过户费都算进成本
  • 保本价包含卖出手续费
  • 可选输入当前价格,实时看浮动盈亏
  • 深色模式(程序员标配)
  • 纯前端,数据不离开浏览器

计算在毫秒级完成,界面响应流畅,整个项目就一个HTML文件。无需构建、无需依赖、没有服务器。

AI辅助开发的最终感想

这次经历再次印证了我的判断:AI编程工具确实好用,但它替代不了对问题领域的理解。AI大概帮我省了60%的时间,但剩下的40%需要我真正理解这个工具要干什么。

我的做法:

  1. 向AI清晰描述问题 — 越具体越好
  2. 仔细审查所有生成的逻辑 — 特别是涉及金额或计算的部分
  3. 自己创建边界测试用例 — AI不会帮你做这个
  4. 用精准的提示词迭代 — "修复手续费计算"比"哪里有问题"有效得多

如果你也在做类似的东西,不管是计算器还是其他应用,道理是一样的。AI能快速帮你到80%,最后那20%才是真正考验工程能力的地方。

对了,最近我顺便做了个浏览器端的小工具,让这个工作流更顺手一些。完全免费,正确处理所有手续费计算(希望如此),隐私优先因为所有计算都在本地跑。如果你感兴趣,可以去看看。

行了,我得去核对我的实际持仓均价和计算器结果是否一致了。预感会不太一样——因为我券商的手续费结构据说连他们客服自己都搞不清楚。