Skip to content

精确数字并不等于正确投资:单位、舍入与残差的数值核设计 ​

一个基金研究 Agent 算出 2.06 元,可能完全符合算术规则,却不适合当作投资建议:份额来自昨天,净值来自今天;不同币种被相加;费用已经体现在净值里,却又扣了一次。

因此,金融 Agent 不需要一位“万能数学裁判”,而需要严格区分两类责任:A33 Numeric 保证给定十进制数值、单位和舍入政策下的确定性结果;B03 等领域 Owner 选择公式、判断输入和分母是否适用,并决定业务结果的资格。本文围绕一条金额计算讲解 Numeric 的接口和实现边界。所有例子为合成输入;局部数值测试不代表金融研究质量已经获得认证。

一、输入必须保留计算以前的意义 ​

图 1:从原值到解释,数值核不应补造领域前提。

按起点分组阅读关系与条件;完整图保留在下方。

来源数据与原始精度
  • → 领域 Owner 选择对象/时点/方法
领域 Owner 选择对象/时点/方法
  • → 单位/尺度/运算绑定明确? (判断)
单位/尺度/运算绑定明确? (判断)
  • 否 → 局部拒绝并标明原因
  • 是 → A33 精确数值运算
A33 精确数值运算
  • → 返回 exact/rounded/residual
返回 exact/rounded/residual
  • → 领域 Owner 检查业务约束
领域 Owner 检查业务约束
  • → Result 保存身份和适用限制
Result 保存身份和适用限制
  • → 模型解释与原 Publication 交付
完整关系图 · 可放大查看细节
图 1:从原值到解释,数值核不应补造领域前提。
图 1:从原值到解释,数值核不应补造领域前提。 放大查看完整图 / Open full-size SVG

二进制浮点不能准确表达所有十进制小数,超过安全整数范围时甚至可能在解析阶段丢掉原始数字。把普通 number 最后格式化为两位小数,不能修复计算前已经发生的精度损失。

因此,输入采用十进制字符串,且把舍入政策显式传入:

json
{
  "quantity": { "value": "137", "unit": "CNY" },
  "factor": { "value": "0.015", "unit": "ratio" },
  "rounding": { "scale": 2, "mode": "half-toward-positive-infinity" }
}

这不是说 1.5% 是任何真实基金的合法费率;选择费率属于金融领域。

二、精度、单位、尺度与方法是四个问题 ​

维度示例最终责任
数值表示2.055、1e-400Numeric 保留十进制精度与比较结果
单位CNY、USD、shares:fund-A来源/领域声明;Numeric 拒绝不兼容运算
比例尺度0.25 ratio、25 percent领域按版本化合同显式换算,不按数值大小猜测
方法与分母收益率、费用、份额估值领域 Owner 选择,Numeric 不决策
结算/展示精度两位小数、货币量子领域指定政策,Numeric 执行

相同单位可以直接加减,CNY 与 USD 不应该被默认相加。份额乘同对象单位净值须由调用方声明维度:shares:fund-A × CNY/share:fund-A → CNY。Numeric 不推断基金对象,不查询实时汇率,也不保证来源数据新鲜。

百分点尤其容易出现尺度误判:0.02 decimal-difference 可按相应合同解释为 2 pp,但已经记录为 2 percentage-points 的源值不得再次乘 100。

三、舍入是一种规则,不是视觉格式化 ​

137 × 0.015 = 2.055 CNY。采用显式两位小数和已声明的 tie 政策:

json
{
  "exact": { "value": "2.055", "unit": "CNY" },
  "rounded": { "value": "2.06", "unit": "CNY" },
  "roundingResidual": { "value": "0.005", "unit": "CNY" }
}

此处残差定义为 rounded − exact,所以是正 0.005;它不是“计算错了”。负数更能检验政策:既有精确数值核采用 half-toward-positive-infinity,负向半分边界 −10.075 → −10.07,不是 −10.08。它符合明确的 tie 规则,但不是所有金融产品统一使用的舍入方法。

先计算、按领域政策结算、最后格式化,与“每一步先四舍五入再继续”通常不等价。

四、精确比较不能被展示层吞掉 ​

1.00 CNY 与 0.999 CNY 在两位小数界面中可能都显示为 1.00,但前者仍严格大于后者,精确差额是 0.001。非常小的正十进制数(如 1e-400)也不能因为转换成普通 number 而被判等于零。

“现金不得为负”是领域规则;Numeric 只保证对选定同单位数值的比较。允许哪种容差、违反时应拒绝哪项交易假设,都由原业务 Owner 决定。

五、残差还可能揭示不可行约束 ​

图 2:不要用自然语言解释掩盖严格约束彼此冲突。

按起点分组阅读关系与条件;完整图保留在下方。

领域指定目标和约束
  • → A33 精确运算和比较
A33 精确运算和比较
  • → 守恒与约束都成立? (判断)
守恒与约束都成立? (判断)
  • 是 → 保留确定性结果
  • 否 → 返回差额和受影响字段
保留确定性结果
  • → 模型解释不替代领域批准
返回差额和受影响字段
  • → 领域有合法容差或调整政策? (判断)
领域有合法容差或调整政策? (判断)
  • 是 → 原领域局部调整后复算
  • 否 → 报告不可行或缺条件
原领域局部调整后复算
  • → 模型解释不替代领域批准
报告不可行或缺条件
  • → 模型解释不替代领域批准
完整关系图 · 可放大查看细节
图 2:不要用自然语言解释掩盖严格约束彼此冲突。
图 2:不要用自然语言解释掩盖严格约束彼此冲突。 放大查看完整图 / Open full-size SVG

假设某个合成配置要求三个权重严格等于 0.333,同时总和严格等于 1。精确相加为 0.999,差额 0.001。这不是浮点误差,也不是把三个权重展示成 33.3% 就能解决。

由哪个资产桶吸收差额、是否允许现金权重变化、容差多大,必须由投资领域决定。Numeric 只返回可复算的值;严格约束相互矛盾时,应保留局部不可行结论,而不是生成看似守恒的组合。

两个对照案例也说明了相同问题:已知价格但未知持仓日期,乘法精确仍不代表当前估值合格;假设费用可复算不等于实际扣款已经发生,净值已包含费用时不能再次默认扣减。

六、没有必要建立全局金融数学经理 ​

有些领域计算适合精确金额,有些统计计算(例如协方差估算)可以在声明样本和误差后使用浮点。将全部指标塞进 Numeric Manager,会迫使一个模块理解收益口径、产品条款、货币、来源身份和交易许可,接口复杂度反而变高。

Module应当拥有不应当拥有
A33 Numeric精确运算、单位匹配、舍入与残差投资公式选择与来源认证
A21 分析沙箱、输入绑定和真实脚本执行执行成功即金融正确
B03 投资计算金额、配置与领域约束全局 Run / Publication 否决
A16 Result结果身份、依赖和回读重新计算原业务结果
A23 Publication正文版本和交付统一金融语义裁判

一个够深的 Numeric Module 用小 Interface 把重复精度规则封在内部,给调用方 Leverage;领域规则留在各自 Module,得到 Locality。没必要再添加只负责转发方法的包装层。

七、怎样验证,而不夸大结论 ​

最小回归集应该包括:137 × 0.015 的 exact/rounded/residual、负数 tie、CNY/USD 加法拒绝、同基金份额×净值的显式绑定、错基金绑定拒绝、1.00 与 0.999 的精确比较、极小非零值,以及目标权重不可行案例。

固定字符串和期望输出可以证明这些局部机制,但不能据此宣称真实基金收益口径、投资建议、交易或所有历史数字都已经正确。

结语 ​

Numeric 的强保证不是“所有 Agent 数字都正确”,而是:给定合法十进制输入、单位绑定和舍入政策,运算可复算,残差可解释,非法操作被局部拒绝。 金融领域继续负责方法、依据、适用性与授权,精确数学才不会越权成为投资真值。

延伸阅读:金融数字的时点、口径与复算 · Python 算过了,投研报告为什么还会错 · 模型会理解,代码才授权。

与个人博客并行:这里按问题连续阅读,博客保留时间线。 · 联系邮箱:hpoenixf@foxmail.com · 微信:hpoenixf0510