负油价甩锅程序员?

   日期:2020-04-30     浏览:98    评论:0    
核心提示:作者 | 马超责编 | 伍杏玲出品 |程序人生(ID:coder_life)4月21日凌晨,WTI 数据库

作者 | 马超

责编 | 伍杏玲

出品 | 程序人生(ID:coder_life) 

4月21日凌晨,WTI 5月原油期货结算价跌至负数的-37.63美元/桶,令人意外的是,这只“黑天鹅,竟波及众多来自国内的中行原油宝产品客户,不但造成原油宝投资者血本无归,还倒欠银行资金的境地。从目前中行的回应来看,要求原油宝客户补回缺口资金,下面笔者就来带大家从IT的角度来解读一下此事件。

无杠杆的原油宝,怎么会倒贴钱?

从原油宝的说明上来看,该产品属于无杠杆产品,那么用户的钱是怎么亏的呢?

原油宝的穿透损失出现得很神奇,我们看到WTI的最小价格变动为1美分,也就是当价格为1美分时,假如客户认为今后价格将反弹,他就可以用100美元本金,买入1万手的多单,多单的含义是客户以现价买入原油,然后以交割价格卖出。假如油价从1美分反弹到1美元,交割价格就是1美元,那么就会直接给客户带来1万美元的收益;而假如油价跌到0,也就是将100美元的本金赔进去,这看起来还真是挺完美的。

但是万万没想到的是油价不仅没有反弹,还跌成了负值,这时客户按照交割价-37.63美元卖出1万桶原油,就需要倒贴买家37.63万美元才行,造成原油宝这种无杠杆产品,产生超出本金损失的罪魁祸首,是函数输入范围超出预期

千年虫、负油价祸出同门?

提起“千年虫”问题可能很多90后的程序员没什么印象,不过对于笔者来说,记忆犹新。

千年虫问题起源于60年代,由于当时计算机存储器的成本很高,计算字长也不够,如果用四位数字表示年份,就要多占用内存空间,因此当时最流行的企业级开发语言COBOL以及现在很多数据库的原型SABRE,都为节省存储空间,默认使用两位数字表示年份。虽然后来计算机字长变长,内存价格降低,但在使用两位数字来表示年份的做法,却由于惯性力量而被沿袭下来,直到21世纪即将来临的1997年,业界才开始拉起了“千年虫”警钟,并很快引起了全球关注。

千年虫的影响堪称是世纪Bug的级别,人们一度怀疑千年虫是否会导致核武的误发射问题。冈比亚成为全球受千年虫影响最为严重的国家,除不少地方电力供应中断外,其海空交通、金融和政府服务也经常中断。对于我国来说,著名的7-11便利连锁店计算机系统把2001年当成1901年,许多使用信用卡用户无法正常刷卡。

本质上讲千年虫与负油价都是输入参数越界的问题,“千年虫”使用两位空间计数的话,99加1就变成0了,而“负油价”则意味着卖东西需要倒贴钱,针对这种负油价的情况,交易软件的行为的确无法预测,所以这一切基本可以回归到一个IT的基本问题,当一个8位的整型到了其上限127的情况下再加1,输出到底应该是什么?

平衡-系统设计的艺术

如果奇点的情况不可预知,那么系统就只能在几种目标下寻求平衡了,这样的平衡术成为了系统的制约条件,比如分布式系统的CAP原则,货币系统受到蒙代尔三角的制约。

在本文“千年虫”、“负油价”的讨论范围内,这种平衡术就要求系统设计者在健壮性、容错性与连续性之间做出平衡。如果一味强调健壮性,那么一旦系统发生错误,就很可能让错误扩大,酿成更大危机;如果单纯追求容错性,那么经常带病上岗的系统,健壮性又不会太强。

比如对于负油价的例子,我们看到绝大多数与WTI连接的系统,在合法性检查时,都会拒绝发送价格为负值的请求,正是这个原因造成原油宝无法正常平仓,不过这个锅不能完全由程序员来背,因为不能确定发送负油价请求到交易所,会产生何种后果。因此这时到底选择容错性还是健壮性其实也未为可知。

再举一个电竞的例子,在王者荣耀的比赛中到底是选择以孙膑为核心的容错体系,还是选择以后羿为核心的硬刚体系,就是在做这样的平衡。以健壮性为第一目标的体系,特别容易因为C位的倒地而猝死;容错性为核心的体系则容易被对手在前期就积累优势,从而不断被滚雪球,最终慢性死亡。所谓一代版本一代强,最终的版本之子,往往游戏的设计者都不能预测,所以也可以看到现在基本主流的即时战略和MOBA类游戏厂商都会有体验服,以提前获取游戏平衡性调整的资料,仅靠纸上谈兵几乎无法预测实际情况。

所以复杂系统只能做平衡,十全十美的策略并不存在。

取舍-系统的应对之道

虽然从某种程度上讲千年虫与负油价都是边界的问题,但是千年虫对于其跨越1999年的行为是可以提前预期的,而负油价却不行。一个属于已知行为的异常,一个属于不可预期的异常,因此要应对危机,首先要了解异常与错误的类型。

已知异常:最具代表的例子就是千年虫了,一般是由于系统设计时忽略的问题或者其它已知问题引起的,也被称作检查性异常。比如我们现在乘坐飞机火车都需要查验身份证件,对付这类异常都需要有对应的预案或者处理流程。对于系统整体来讲,服务不应该因此类异常中断。

未知错误:这种情况一般是由系统设计时无法预期的边界而产生的,系统设计人员无法将系统运行时所遇情况考虑完整,未知错误出现后到底是让程序继续运行,还是崩溃蓝屏退出,其实是健壮性与容错性之间的抉择。

重要错误:如堆栈溢出,磁盘IO错误等等,遇到此类错误到底是立即蓝屏或者崩溃以防事态扩大。但是未知错误与重要错误往往边界不清,处理逻辑也很麻烦。

复杂系统的异常处理原则就是做好检查性异常的处理流程,不过这其中的处理方案其实非常难以取舍。只能提示尽量使用Java中Finally的机制,以便保存好错误现场情况后续复盘,出现不可预期的问题时尽快提示人工介入兜底。

更多精彩推荐

入职不到一年被提名晋升 ,历经双十一大考,10 年阿里老兵成长之路

从开发者到讲师的心路历程与必知必会 | 原力计划

17 年微软老兵,非典型跨领域 AI 科研之路

如何通过深度学习,完成计算机视觉中的所有工作?

国家发改委正式将「区块链」纳入新基建

关于 Docker ,你必须了解的核心都在这里了!

你点的每个“在看”,我都认真当成了喜欢

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服