2020年3月,全球金融市场正在经历自2008年以来最剧烈的波动。美股在十天之内熔断了四次,A股虽然跌幅相对较小,但日内波动率也飙到了平时三倍以上。我认识的一个在拼多多做搜索算法的工程师,在那个月的最后一个周末——也就是他预设的季度再平衡日——做了一件让我至今提起来都心生敬意的事。
那天早上他打开账户,看到他权益仓位的实际占比因为过去一个季度债券微涨、股票暴跌,已经从目标比例的百分之六十跌到了百分之五十出头。按照他的再平衡规则,他应该卖出一部分债券,买入一部分股票,把权益仓位拉回百分之六十。当时全世界都在恐慌性抛售一切和股票沾边的东西,美股期货天天熔断,朋友圈里到处是“现金为王”的刷屏。他坐在书桌前盯着屏幕上的数字沉默了一会儿,然后按他的原计划执行了再平衡操作——卖出了大约百分之十的债券仓位,用那笔钱买入了沪深300ETF。
当天晚上他给我发了一条消息,只有一行字:“我今天的操作,在朋友圈里应该被归为‘疯了’那一类。但我只是跑了一行我三个月前写好的CI脚本。”

CI脚本的定时触发:时间到了就执行,不管今天是什么天气
持续集成最核心的设计理念不是自动化本身——自动化只是手段。持续集成最核心的理念是:代码变更必须按照预设的频率、以预定义的流程、在不受人为情绪干扰的条件下,集成到主分支并触发完整的构建和测试流水线。你不能因为今天心情不好就跳过CI,不能因为这次提交的改动特别大就手动绕过静态检查,不能因为“这次集成大概率会失败”就推迟到明天。到了触发时间,流水线就启动。构建失败就修,构建成功就部署。和你今天早餐吃了什么、昨天大盘跌了多少、明天有没有重磅宏观数据发布,没有任何关系。
你的资产再平衡就是一条CI流水线。它的触发条件不是“当我觉得市场已经足够恐慌”或者“当估值已经回到合理区间”。你不是市场的估值裁判,你是你自己系统的运维工程师。运维工程师不负责判断市场情绪,只负责按时执行预定义的运维脚本。
在你的日历上圈定一个雷打不动的日期。建议选每个季度最后一个月的最后一个周末——3月、6月、9月、12月。这四个时间点均匀分布在全年,每个季度之间的间隔足够长,让你的资产比例有足够的时间发生有意义的漂移,同时也不至于长到你的配置已经严重偏离目标而你浑然不觉。如果你觉得一个季度太频繁,每半年一次也可以,但不要低于每年一次。年度再平衡的问题是窗口间隔太长,期间你的权益仓位可能已经从百分之六十漂到百分之七十,你需要卖出的高权重资产体量会积累到让你在执行时产生巨大的心理阻力。季度频率把每次再平衡的操作量摊薄到更容易执行的程度,就像你把一个大的代码提交拆成几次小的提交,每一次的风险和冲突解决成本都更低。
触发日期到了的那天早上,你打开电脑,登录你的证券账户和基金账户,开始执行一条你过去三个月从未干预过的预定脚本。不管这三个月里市场发生了什么——暴涨也好,暴跌也好,震荡也好——脚本照常执行。你是这个系统的运维工程师,不是这条流水线的需求方。需求是三个月前你在上一季架构评审会上已经定好的,你现在只是在做部署。
构建步骤:四步走完一条完整的再平衡流水线
你的CI脚本有四步,每一步都对应你在Jenkins或GitLab CI里写过无数次的构建阶段。
第一步,Checkout——拉取当前持仓快照。打开你的投资日志或者你用的记账工具,把你所有账户里每一类资产的当前市值拉出来。不需要精确到分,精确到千位就够。股票类——包括指数基金、行业ETF、主动型基金、个股——全部加总。固收类——国债、大额存单、债券基金、货币基金——全部加总。黄金、QDII、Crypto、以及其他另类资产,各自单独列一行。算出每一类资产占你总资产的实际比例,写在一列里。旁边再写一列你的目标配置比例——那个你在上一次季度架构评审会上确定的、写在你投资日志里的目标权重。
第二步,Static Analysis——计算偏离度。用实际比例减去目标比例,得到每一项资产的偏离值。如果权益类目标比例是百分之六十,实际已经涨到了百分之六十五,偏离值就是正的百分之五。如果固收类目标比例是百分之三十,实际跌到了百分之二十七,偏离值就是负的百分之三。你不需要对每一个微小的偏离都做调整——给自己设一个偏离容忍度,比如偏离超过百分之五才触发操作,少于百分之五就继续持有不动。容忍度的存在是为了减少不必要的交易频率和摩擦成本,不是给你留一个“再看看”的心理后门。
第三步,Build——生成操作清单。把那些正向偏离超过容忍度的资产标成红色——这些是你需要卖出的部分。把那些负向偏离超过容忍度的资产标成绿色——这些是你需要买入的部分。每一笔操作只写三行:从哪个资产、卖出多少金额、用这笔钱买入哪个目标资产。这张清单应该简短到你不需要花超过十分钟来执行。如果清单上出现了超过五笔操作,你上一次架构评审时定的目标比例可能过于碎片化了,下一次评审时考虑合并一些重叠的资产类别。
第四步,Deploy——执行。打开你的交易软件,按清单逐笔执行,不挑时间,不挑价位。不要等到下午两点半觉得“今天尾盘可能要跳水”所以拖到收盘前再卖,也不要因为“今天涨得挺好的要不明年再平衡的时候再卖”而推迟。你这条流水线没有“等待最优执行时点”这个步骤。你在第三章第四节学过,你的系统里没有实时竞价的负载均衡器,只有一个按固定频率调度的反向代理。反向代理不会问后端服务器“你觉得现在是处理这个请求的最佳时机吗”,它直接转发。
构建失败的处理:如果你发现自己不敢执行,停下来,排查根因
CI流水线最常见的失败模式不是代码有Bug——代码有Bug很容易定位。最常见的失败模式是构建脚本本身就跑不过去:环境变量没配好,依赖库版本冲突,某个测试用例在本地能过但在CI容器里就是超时。这个时候,成熟的工程师不会在流水线配置里加一行“跳过此步骤”来强行让构建变绿。成熟的工程师会停下来,看日志,定位是环境的问题、配置的问题、还是测试用例本身设计的问题,然后修复它。
你的再平衡流水线也可能在某些极端时刻跑不过去。不是技术上的跑不过去——你的券商App不会阻止你下单。是你心理上的构建失败:你盯着那张操作清单,手指悬在卖出按钮上,脑子里有一个声音在不断放大——“现在卖债券买股票?所有人都在跑,你要逆着人群往里冲?你确定吗?”
如果你发现自己在这个时刻无法执行你自己预先写好的再平衡脚本,不要强行执行,也不要偷偷跳过。停下来,回到你的投资日志里,写一行记录:“某年某月某日,季度再平衡触发。操作清单已生成,但未能执行。原因是——”然后诚实地写下你不敢执行的那个原因。是市场波动率超出了你的心理承受阈值?那么你的权益类目标比例可能设得太高了,你需要在下一次架构评审时把它调下来,而不只是在再平衡日逼自己去执行一个你已经实质上无法承受的比例。是你对某一类资产的基本面产生了根本性的怀疑,不再相信它值得被配置?那是一个合理的问题,但这个问题应该在架构评审会上讨论和决策,不应该在你应该执行运维操作的再平衡日突然冒出来主导你的判断。先按原计划执行再平衡,然后把这个问题记入下一次架构评审的议题清单,在会上决定是否修改目标配置。在此之前,现有配置就是生产环境,你无权在部署窗口里临时修改生产环境参数。
每一次不敢执行,都是一次你对自己系统了解不足的暴露。暴露不是坏事,不记录、不修复才是。就像CI构建失败本身不是事故,构建失败之后没人看日志、没人修、流水线就那样一直红着,才是事故。你的再平衡流水线偶尔红一次没关系,你只要每次都看日志、每次都修,它最终会稳定到一个你能在绝大多数市场环境下都面不改色执行完毕的状态。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/oscar999/article/details/163543940




