反洗钱系统在券商内部的观感很矛盾:业务一线觉得它只会添堵——好好的客户被限制出金,反复要求补充职业信息;合规部门又觉得它永远是漏勺——真出了问题,第一个被问责的是监测为什么没报。这两个观感都成立,因为这套系统的目标本来就不是"方便"也不是"抓全",而是在可解释的口径下做到可证明的尽职。这篇讲大额与可疑两条报送线的系统实现,重点在监测口径和补正闭环。
两类报告:一条按金额,一条按怀疑
法规依据主要是人民银行令〔2016〕第 3 号《金融机构大额交易和可疑交易报告管理办法》。两条线标准完全不同:
大额交易报告是纯阈值触发。常见口径:单笔或当日累计现金交易人民币 5 万元(含)以上、外币等值 1 万美元(含)以上;非自然人账户与其他账户之间当日单笔或累计 200 万元以上的款项划转;自然人账户 50 万元以上。这类不需要任何主观判断,系统按日扫流水,命中生成报告,T 日内(大额交易为发生之日起 5 个工作日内)批量报送。工程上它是典型的批处理问题:单日全公司流水过千万条,聚合加阈值过滤,跑完也就几分钟。
可疑交易报告(STR)没有金额门槛,触发条件是"有合理理由怀疑交易涉嫌洗钱"——这句话落到系统里就是一套监测模型加人工甄别。3 号令同时要求金融机构以"风险为本"制定自定义监测标准,不能只靠人民银行的参考指标。所以每家的可疑规则库都是私有资产:地下钱庄对手方的资金快进快出、休眠户突然激活且高频划转、开户后立即修改联系方式并大额交易、与恐怖组织名单国家有资金往来……规则命中率低是常态,万分之几的命中率里再靠人工筛掉九成误报,剩下的才形成报告。
"以客户为单位":最被低估的口径陷阱
大额标准里到处是"当日累计"和"以客户为单位"。这两个词合起来意味着:聚合维度不是账户,而是客户号(OneID),时间粒度是自然日,范围是该客户名下所有账户的全部资金划转。
实践中这里出过太多错。客户在 A 营业部转 30 万、B 营业部转 30 万,按账户看两笔都不达标,按客户看当日累计 60 万必须报——系统如果按账户粒度扫,就是系统性漏报。反过来,客户做了银证转账又转回,同一笔资金在银行和券商流水里各出现一次,聚合时去重规则没定清楚又会重复报。我们当时的口径文档里专门有一节"同一资金流的认定",定义以资金账号加交易对手账号加金额配对去重,这个口径后来在现场检查时被调取了实现文档,属于"可证明尽职"的关键证据。
跨账户聚合还牵出一个架构问题:客户号与资金账号是 1:N(《账户表设计》讲过的三层模型),而交易流水的分布式存储往往按资金账号分片。按客户聚合等于一次跨分片的 shuffle,日终批量没问题,想做实时监测就得提前把流水按客户号路由一遍。实时 STR 监测的成本大头在这,不在规则引擎。
监测引擎与报送链路
可疑监测引擎本身是套规则管道:流水事件进来,先过名单过滤(恐怖组织、制裁名单,命中直接报送且冻结),再过行为规则打分,超过阈值的生成预警案例(case),归并到同一客户后进入人工甄别队列。甄别结论有三类:排除(误报,要填理由,理由会反哺规则调优)、继续观察(挂起)、确认可疑(生成 STR 报送)。
送出去的报告不是终点。监测分析中心的接收端会做格式校验和要素校验,要素不齐会打回补正,补正同样有deadline。链路里必须维护报送状态机:
$$ \text{待报送} \to \text{已报送} \to \begin{cases} \text{接收成功} \\ \text{补正中} \to \text{重新报送} \end{cases} $$
补正最常见的坑是客户九要素不全(职业、联系方式、证件有效期过期未更新)。这就要求报送系统反向驱动客户信息治理——报告质量差的根源往往在开户环节的信息采集质量,这又回到《适当性管理》那篇会讲的客户信息完整性。
漏报的代价
处罚逻辑值得每个开发者理解。监管检查反洗钱,看的不是你抓到了多少,而是监测标准是否健全、运行是否有效、漏报是否有系统性原因。某期行业处罚通报里,一家公司被罚的核心事实是其监测规则三年未更新,期间业务形态已经大变(第三方存管、跨行划转占比翻倍),规则库还停留在旧口径——这被认定为"未有效履行反洗钱义务",罚的是怠于维护,不是漏掉的那几笔。
对系统的直接推论:规则库和口径是生产资产,需要版本管理、定期评审、变更留痕,和在《审计日志》里讲的留痕要求一样,每次规则调整都要能回答"谁、什么时候、为什么改了阈值"。这套东西平时是纯成本,出事那天是唯一值钱的东西。