LabHub
学习 学习路径 课程

银行现场的语言

对账与差额清算,以及对账抓不住的东西

在 LabHub 中继续学习

目标

核对我方总账与对方机构的结算文件,将偏差缩小到逐笔交易;计算净额结算头寸;并找出原理上无法通过对账发现的重复转账。还要能将结果写成可发送到客户之外的形式。

为什么重要

对账是 FDE 在银行现场最常进行的工作,也是最常出错的工作。

第一个陷阱是对账对象。我方总账中混有仅授权但尚未完成清算的交易,这些交易不出现在对方结算文件中是正常的。如果不区分状态就进行对账,数十笔正常交易会被列为异常,真正的偏差反而被淹没其中。

第二个陷阱是如何解读偏差。必须分别查看笔数和金额。如果笔数相同而只有金额不同,说明双方对同一笔交易记录了不同金额;如果金额相同而只有笔数不同,说明一方合并或拆分了交易。原因不同,因此向客户提报的渠道也不同。

第三点最为重要。对账询问的是“两本账是否相同”,而不是“账本是否正确”。 如果超时后重发导致同一笔钱转出两次,我方总账和对方文件中都会同样留下两笔记录。总额对账会完美通过。唯一能够发现问题的位置是幂等键。

本次事件如下。收到 2026-08-25 的结算文件后,有人反馈总额不一致。共有三家机构,其中两家以不同方式出现偏差。

步骤

  1. 创建并运行 /root/bank/gen_settle.py,生成 /root/bank/settle.db/root/bank/partner_20260825.csv
  2. 将结算文件导入 settle.dbpartner 表,并在 /root/bank/recon_totals.csv 中输出按机构汇总的总计。表头为 counterparty,our_count,our_amount,partner_count,partner_amount,count_gap,amount_gap,我方只统计 stateSETTLED 的交易。
  3. 分别将 /root/bank/only_ours.csv/root/bank/only_partner.csvmsg_id,counterparty,amount 表头输出,并在 /root/bank/side_counts.txt 中写三行:only_ours=only_partner=naive_only_ours=。最后一个值表示不区分 state 进行对账时的数量。
  4. 将金额不同的交易输出到 /root/bank/amount_mismatch.csv,表头为 msg_id,our_amount,partner_amount,gap
  5. /root/bank/dup_msg.csv 中按 idem_key,msg_id,amount 表头保留与重复幂等键关联的所有报文,并在 /root/bank/dup.txt 中写三行:dup_keys=dup_msgs=extra_amount=
  6. /root/bank/net_position.csv 中按 counterparty,out_amount,in_amount,net 表头输出各机构的净额结算头寸。net 为收款减去付款。
  7. /root/bank/pending.txt 中写六行:auth_count=auth_amount=auth_out_amount=auth_in_amount=stale_auth=suspense_account=stale_authsent_at 早于 2026-08-22 的授权交易,suspense_account 是暂收款科目代码 2210
  8. /root/bank/recon_report.md 中按 ## 대사 결과 요약## 건수는 같은데 금액이 다른 건## 금액은 같은데 건수가 다른 건## 대사로는 잡히지 않는 것## 차액정산 포지션## 개인정보 취급 六个章节编写报告。账号只保留前 3 位和后 4 位,按 110-****-**1234 的形式脱敏;不得以任何形式写入居民登记号码和客户真实姓名。

参考

创建我方总账与对方结算文件

创建并运行 /root/bank/gen_settle.py,生成 /root/bank/settle.db/root/bank/partner_20260825.csv

使用 python3 创建 /root/bank/settle.db 和 /root/bank/partner_20260825.csv。259 笔报文中有 16 笔仅处于授权状态。

导入结算文件并核对各机构总计

将结算文件导入 settle.dbpartner 表,并在 /root/bank/recon_totals.csv 中输出按机构汇总的总计。表头为 counterparty,our_count,our_amount,partner_count,partner_amount,count_gap,amount_gap,我方只统计 stateSETTLED 的交易。

将对方文件导入 settle.db 的 partner 表后,可以用一条 SQL 完成对账。我方只统计 state 为 SETTLED 的交易,并分别查看笔数和金额。

筛出仅存在于一方的交易

分别将 /root/bank/only_ours.csv/root/bank/only_partner.csvmsg_id,counterparty,amount 表头输出,并在 /root/bank/side_counts.txt 中写三行:only_ours=only_partner=naive_only_ours=。最后一个值表示不区分 state 进行对账时的数量。

对账对象仅限已完成清算的交易。仅授权交易不出现在对方文件中是正常的;如果不按 state 缩小范围,16 笔正常交易都会被列为异常。

找出金额不同的交易

将金额不同的交易输出到 /root/bank/amount_mismatch.csv,表头为 msg_id,our_amount,partner_amount,gap

连接双方都存在的报文编号,只保留金额不同的记录。gap 为我方金额减去对方金额,其总和应与机构汇总中的金额差相同。

通过幂等键查找重复转账

/root/bank/dup_msg.csv 中按 idem_key,msg_id,amount 表头保留与重复幂等键关联的所有报文,并在 /root/bank/dup.txt 中写三行:dup_keys=dup_msgs=extra_amount=

按幂等键而不是报文编号分组。如果同一幂等键关联两条以上报文,说明重发被重复处理。超额部分是每个键保留一笔后剩余的交易。

计算净额结算头寸

/root/bank/net_position.csv 中按 counterparty,out_amount,in_amount,net 表头输出各机构的净额结算头寸。net 为收款减去付款。

按机构分别汇总付款(OUT)和收款(IN),net 为收款减去付款。对象是已完成结算的交易。

统计未结算项和暂收款余额

/root/bank/pending.txt 中写六行:auth_count=auth_amount=auth_out_amount=auth_in_amount=stale_auth=suspense_account=stale_authsent_at 早于 2026-08-22 的授权交易,suspense_account 是暂收款科目代码 2210

按方向分别统计仅授权的交易,并单独统计授权日期较早的交易。未结算项应按账龄管理,而不是只看笔数。

编写脱敏后的对账报告

/root/bank/recon_report.md 中按 ## 대사 결과 요약## 건수는 같은데 금액이 다른 건## 금액은 같은데 건수가 다른 건## 대사로는 잡히지 않는 것## 차액정산 포지션## 개인정보 취급 六个章节编写报告。账号只保留前 3 位和后 4 位,按 110-****-**1234 的形式脱敏;不得以任何形式写入居民登记号码和客户真实姓名。

需要六个章节。而且该文档会发送到客户之外——账号必须脱敏,居民登记号码和真实姓名则完全不要写入。