八月,杭州进入最热的时候。
白天出门,空气像被煮过。柏油路面发软,脚踩上去有一点黏。楼下便利店的冷柜玻璃上凝着水珠,手指划过去,会留下一道透明的痕。午后雷阵雨来得很急,云压下来,风先到,窗户哗哗响,几分钟后雨砸在地上,白花花一片。雨下半小时就停,太阳重新出来,水汽从地面往上蒸,整座城市像一个没有泄压口的锅炉。
市场也像锅炉。
七月那场爆仓以后,指数并没有真正稳住。今天反弹,明天再跌。救市资金进场,暂停IPO,大股东不能减持,券商喊话,媒体发社论。各种阀门被临时拧上去,各种堵漏材料被拍在裂缝上。管子还在漏,只是喷得没有七月八日那天那么高。
Aurora停了。
这是它上线以来第一次连续停机超过三天。
我没有让程序自动交易。账户里剩下十二万多,后来几次反弹和清仓,扣掉损失和手续费,还剩十二万一千。这个数字放在那里,像事故现场抢出来的一截管子。烧黑了,变形了,但没完全断。
我把代码打印出来。
不是全部,三千多行太厚。我只打印交易模块、风控模块、委托模块和日志模块。A4纸一共一百二十七页,放在桌上有两厘米厚。打印店老板把纸递给我时说:"论文?"
"差不多。"
论文是给别人看的。这个是给事故看的。
我用蓝色钢笔一行一行划。不是改代码,是先看。看每个函数的输入,看每个返回值,看每个假设。过去写程序时,我喜欢在屏幕上改,改完运行,错了再改。现在不行。事故之后不能急着动扳手。要先看现场。水从哪里喷出来,阀门在哪个位置失效,压力表有没有读数,管壁为什么薄。
第一处问题:止损逻辑依赖成交。
触发止损后,程序发出卖单,然后等待成交。若未成交,只做重试。重试次数无上限,但重试的委托价格仍然是跌停价或接近跌停价。正常市场里,这没有问题;极端市场里,价格不是问题,买盘才是问题。
我在旁边写:
"止损不是发单。止损是离场。发单不等于离场。"
第二处问题:流动性检测太弱。
原来的流动性指标只看过去五日平均成交额和当前盘口买卖量。它没有识别连续跌停,也没有识别全市场同时失去流动性的情况。像只看一根支管的流量,却不看主干管是否已经堵死。
我写:
"个股流动性之外,必须有市场流动性。主干管堵,支管数据无效。"
第三处问题:最大回撤控制没有强制停机。
账户从高点回撤超过百分之二十时,程序只降低仓位;超过百分之三十时,再降低;没有一个硬停止。它像一个人被打到流血,却只是走慢一点,没有离开拳台。
我写:
"回撤不是参数,是事故等级。达到事故等级,停机。"
连续十天,我没有看论坛。
也没有给K发消息。他的头像灰着,帖子停在七月底。赵启明打过两次电话,一次说公司在内部追责,一次说他可能要被降职。两次他都没有多说。电话里他的声音像被砂纸磨过,粗糙,干,短。
我每天做三件事:看代码,改代码,回测。
早上七点起。煮面,放一个鸡蛋。八点开电脑。先把前一天写的改动重新读一遍。九点半市场开盘,但我不交易,只看。看盘口,看跌停家数,看成交额,看救市资金拉权重时指数和个股的分裂。下午三点收盘,导出数据。晚上写代码。
代码一层一层加。
第一层,极端行情保护。
条件包括:全市场跌停数量超过阈值;主要指数单日跌幅超过阈值;连续两个交易日成交额异常放大且上涨家数低于一成;持仓个股买一量低于卖一量的十分之一。满足任意两项,系统进入Extreme状态。Extreme状态下,不再开新仓,不再加仓,已有持仓按可成交优先原则分批撤离。
不是按价格最优撤离,是按能出去撤离。
第二层,流动性黑名单。
连续两日跌停且成交额急剧萎缩的股票,进入黑名单。黑名单标的即使出现技术反弹,也不参与。因为反弹可能只是水锤。管道被堵住后,压力波反向传回来,会让压力表短暂跳动,但那不是正常水流。
第三层,最大回撤停机。
账户从历史高点回撤超过百分之十五,仓位上限降到三分之一;超过百分之二十五,停止交易五个交易日;超过百分之三十五,人工复核,不允许自动恢复。程序需要我手动输入确认码,才能重新启动。
确认码我写成了一句很长的话:
"I understand liquidity can disappear."
我理解流动性会消失。
每次要重新启动,都必须打完这句话。不是为了英文,是为了让手指记住。手指比脑子诚实。脑子会忘,手指打过的东西会留下肌肉记忆。
八月中旬,Aurora v2的雏形出来。
我没有立刻上线。先用2015年6月到7月的数据回测。
第一遍,仍然亏。亏幅小了,但还是大。因为极端状态触发太晚。
第二遍,我把全市场跌停数量阈值调低。结果过于敏感,五月的正常调整也触发了停机。
第三遍,增加成交额结构判断。跌停数量上升同时,跌停股成交额低于前五日均值的三成,才认定为流动性枯竭。这样可以区分正常下跌和卖不出去的下跌。
第四遍,加入指数分层。权重被拉红但中小盘继续跌停时,不解除风险状态。因为救指数不等于救账户。赵启明那句话,我写进了注释:
# index rescue is not portfolio rescue
第五遍,回测结果出来。
若使用v2,七月八日账户高点回撤约百分之二十八,不是百分之八十五。仍然难看,但活着。十二万不会变成十二万,而是大约五十多万。损失仍然大,却不会直接失去继续交易的资格。
我看着回测曲线。它没有原来那条漂亮。五月六月,v2少赚很多。因为它在风险升高时提前降仓,错过了一部分上涨。曲线斜率低,显得笨重,不够锋利。
但它没有断。
没有断,比好看重要。
八月二十六日,晚上。
杭州下了一场暴雨。雨从傍晚六点开始,持续到十点。楼下积水漫过路牙,电动车从水里骑过去,车轮带起两道白浪。雨水顺着窗玻璃往下流,流成一条一条透明的线。远处有雷声,闷在云后面,像很大的铁皮被人推了一下。
我坐在桌前,把最后一段代码提交到本地仓库。
提交信息:
"Aurora v2: extreme risk protection."
然后翻开笔记本。
蓝色钢笔。新的一页。
我写:
"2015年8月。重建。"
下面列了三条:
"一,极端行情保护:识别市场级流动性枯竭。"
"二,流动性检测:卖得出去比卖什么价更重要。"
"三,最大回撤控制:达到事故等级,停机。"
再下面:
"管子不是因为水流而存在。管子存在,是为了在水压异常时不爆。"
写到这里,我停了一下。雨声很大,像无数细小的委托同时砸向地面。窗台上有水渗进来,积成一小滩。我拿毛巾擦掉。擦完以后,玻璃边缘还湿着。
事故之后,所有接口都要重新看一遍。哪怕是窗户。
九月前一天,我给赵启明打电话。
"我准备重新上线。"
"多少仓位?"
"三分之一。"
"这么低?"
"先活着。"
他在电话那头笑了一下。声音很哑,但确实是笑。
"你现在比我像基金经理。"
"我只剩十二万。"
"十二万也是钱。"
"嗯。"
他说:"我被降了。"
我没有立刻接话。
"从区域经理降到研究员。工资砍了一半多。客户那边还在闹。公司说市场风险,不全是我的责任,但总要有人背一点。"
"你还好吗?"
"活着。"
活着。
这两个字从他嘴里出来,比任何安慰都有重量。
挂电话后,我把Aurora v2的开关停在"ready"状态。没有立刻启动。像修好一段管道以后,先不急着开闸。要等胶干,等焊缝冷却,等压力表归零。
夜里十一点,我关灯前看了一眼屏幕。
账户余额:121,084。
Aurora v2:Ready。
窗外雨停了。路面还有水,路灯照上去,反出一片橙色。水没有消失,只是换了地方。它从天上落到地上,从地上流进下水道,再从管道流到河里。
水会继续流。
九月,重新开闸。