技术博客

投顾组合调仓与跟投:信号到订单的批量复制

第 113 / 141 篇 · 2026-04-29 · secfin · 基金投顾调仓批量执行

投顾组合管理人决定调仓——把组合里 A 基金的权重从 20% 降到 0%,把 B 基金从 0% 提到 20%——这只是一个信号。真正的系统工作是把这条信号在当天晚上复制成几十万条客户级申购赎回申请,保证每个客户的持仓比例尽量贴近目标组合。这一篇讲这条复制链路的工程实现。

从目标权重到客户指令

假设组合管理人给出目标权重向量 $\mathbf{w}^{new}$,客户 $i$ 当前授权资产市值为 $A_i$(上一日净值口径),则该客户的目标卖出金额为:

$$ s_i = A_i \times (w^{old}_{A} - w^{new}_{A}) $$

卖出的所得(扣除赎回费后)再按新权重分配到买入指令。这个公式有个微妙的循环依赖:$A_i$ 本身包含 A 基金当前的市值,而卖出 A 影响市值。工程上的标准解法是固定基准:以调仓前一日的客户持仓市值为基准算所有金额,卖出的回收金额与目标买入金额之间的差额沉淀为现金偏离,下一轮调仓再吸收。

凑整与最小单位

公式算出来的金额是连续的,基金份额不是。公募基金申购最低 1 元(或 1 份),份额保留两位小数,按比例缩放后必须凑整。凑整策略直接影响跟投精度:

  • 逐笔舍入:每条指令四舍五入到分。客户本金小(几百块)时,1 分钱占的比例不小,长期累积出明显偏离;
  • 最大份额法:对买入指令,把客户的可用金额除以申请日未知净值算出的份额预估再舍入——但净值未知(未知价原则,见《基金申购赎回的确认流程》篇),T 日申请按 T 日净值成交,系统发起指令时并不知道能成交多少份额,只能按预估控制金额;
  • 现金回填:买入金额若超过卖出回收加预留现金,直接从客户绑定的银行卡代扣(如果协议授权了),否则生成指令失败,进人工处理队列。

本金小的客户跟投精度天然差,这是业务属性不是系统缺陷,但系统要在组合层面量化暴露:每天算每个客户的跟踪偏离度(实际权重 − 目标权重,按市值),偏离超过阈值(比如 ±5%)的客户进再平衡清单——调仓信号之外,偏离度本身就是日常再平衡触发器。

未知价带来的偏差

调仓信号写明的权重是按发出时刻的净值估的,实际执行时:

  • 赎回按 T 日净值成交,款项 T+1 或更晚到账,买入指令要等钱到账才能发——所以一次调仓实际是"T 日卖、T+1 或 T+2 买"的序列,中间隔了市场波动;
  • 两只基金一卖一买,各自的净值走势让成交比例偏离信号比例,剧烈行情下调仓完成度可能差好几个百分点。

处理方式是把"一次调仓"建模成一个批次的多笔指令:卖单先全部发出,买单等资金到账流水触发后发出,批次状态机(已发起 → 待资金 → 执行中 → 完成/部分完成)在投顾系统里要可查可干预。部分完成的批次(比如买入时某只基金大额限购)留下残差现金,进下一批次的偏离度计算。

批量性能与派发

一次调仓几十万客户,指令生成是批处理,但发出要按销售机构分桶:客户的基金账户分散在银行、券商、基金公司直销多个渠道,每个渠道一份指令文件(或 API 批量接口),各自校验、各自报 TA。分桶有两个约束:

一是渠道时序:直销渠道当天可发,部分代销机构要求指令文件在日切前送达,错过就顺延,顺延期间市场波动由投顾机构承担跟投偏差的责任。二是幂等:指令文件重发(渠道没回执)不能让 TA 确认两遍——申请流水号由投顾机构统一生成,全局唯一,TA 侧按流水号去重(《成交回报与确认》篇的幂等设计在申购场景的对应)。

调仓信号到客户订单的复制链路 调仓信号 目标权重向量 按比例缩放 s = A × 权重差 凑整与边界 最小单位/金额上限 按渠道分桶 生成指令文件 T 日卖单 赎回按 T 日净值 资金到账 流水触发买单 T+1/T+2 买单 部分完成留残差 批次状态机:已发起 → 待资金 → 执行中 → 完成/部分完成; 每日计算跟踪偏离度,超阈值客户进再平衡清单,流水号全局唯一保幂等

跟投链路的关键认知:信号是组合管理人的,执行是概率性的。未知价、资金在途、凑整残差,让每一次调仓的结果都带着噪声。系统能做的是把噪声量化(偏离度)、把过程可追(批次状态机)、把重发安全(幂等),而不是假装复制是精确的。