期货交易所强制减仓系统难点设计
2018-07-23上海期货交易所
上海期货交易所 孙 伟
0 引言
近年来,随着期货市场的发展,以及国内外错综复杂的宏观微观各种因素的影响,期货合约价格的波动幅度逐渐加大,市场各方所面临的风险概率也同步上升。为此,交易所非常有必要建设一个全方位的风险防范与化解工具。强制减仓系统是化解系统性市场风险的一个终极又有效的工具。
本文着重论述了准确的净持仓盈亏计算和合理的平仓数量分配方法,以及高效算法的实现。以此构建的强制减仓系统在2008年有色金属期货极端行情下得到应用,及时、合理、有效地化解了系统性风险,具有行业推广价值。
1 强制减仓系统概述
强制减仓是交易所风险控制措施中的一种,是指在极端行情发生时,交易所通过既定规则对深度亏损的客户仓位和盈利方客户的对手仓位进行平仓,从而及时止损,防范大规模违约事件发生,保护期货市场健康运行。
以上海期货交易所有色品种为例,强制减仓的执行方法是将D3交易日闭市时(强减合约D1,D2,D3连续三日发生同方向单边市)以停板价申报的未成交平仓报单,以D3交易日的停板价与该合约净持仓盈利客户按持仓比例自动撮合成交;同一客户持有双向持仓的,则其净持仓部分的平仓报单参与强制减仓计算,其余平仓报单与其对锁持仓自动对冲成交[1]。整个系统实现的难点是算法梳理和大数据量高效运算。
2 关键算法模块
强制减仓系统的关键算法内容有两个,一是准确计算客户净持仓盈亏,二是公平合理分配平仓数量。因此系统应具有两个关键模块:净持仓盈亏计算和平仓数量分配。
2.1 净持仓盈亏计算
盈亏计算模块用于计算每个会员客户每个合约当日的单位净持仓盈亏和盈亏率,以此作为对客户风险的评判依据。
客户单位净持仓盈亏计算流程如下[2]:
(1)根据平今数据调整客户当天开仓明细。
(2)根据平昨数据更新客户当前持仓明细。
(3)根据移仓流水更新客户当前持仓明细。
(4)计算客户单位净持仓盈亏及盈亏率。
为了提高计算客户净持仓盈亏的效率,可以保留客户当前持仓明细,下一交易日根据平今、平昨数据以及移仓流水调整客户当前持仓明细,避免每次重复从历史成交表获取开仓明细。
客户当前持仓明细分为总持仓明细、投机持仓明细及套保持仓明细,保留了从合约上市日到当天满足客户当前持仓量的多方和空方的历史开仓明细。
(1)净持仓盈亏的计算时间
每日净持仓盈亏的计算时间在交易确认完成后开始。
(2)根据平今数据更新客户当前持仓明细
(a)首先获取客户当天平今量,对客户当天的开仓记录进行平仓。
(b)平仓遵循先开先平原则。
(c)对客户当天开仓记录进行平仓操作,每平完一条当天开仓记录,从当天开仓明细中删除该条记录,平今量递减,当平今量小于某条记录的开仓量时,将该条记录的开仓量更新为开仓量-平今量。
(d)做完以上操作后的当天开仓明细即为平今操作后客户的当天新开仓的持仓明细,追加到相应的当前持仓明细。
(3)根据平昨数据更新客户当前持仓明细
(a)首先获取客户当天平昨量,对客户历史开仓明细记录进行平仓。
(b)平仓遵循先开先平原则。
(c)对客户历史开仓记录进行平仓操作,每平完一条历史开仓记录,从客户当前持仓明细中删除该条记录,平昨量递减,当平昨量小于历史某条记录的开仓量,将该条记录的开仓量更新为开仓量-平昨量。
(d)做完该操作后的客户当前持仓明细即为平昨操作后客户的当前持仓明细。
(4)根据移仓流水更新客户当前持仓明细
若客户当天有移仓数据,需对当前持仓明细进行更新操作。
(5)净持仓盈亏计算
客户单位净持仓盈亏分为三类:总净持仓盈亏、投机净持仓盈亏以及套保净持仓盈亏。计算公式如下:
(a)客户持仓均价=Σ(客户净持仓方向的开仓量*开仓价格)/客户净持仓量。
(b)客户单位净持仓盈亏=当前结算价-客户持仓均价。
(c)客户单位净持仓盈亏率=客户单位净持仓盈亏/当前结算价。
上述公式中持仓均价计算方法如下:
i.确定净持仓方向。获取客户净持仓量,即客户的多头持仓量减空头持仓量。若净持仓量值>0,则为多方;若净持仓量<0,则为空方;若净持仓量=0,则该客户盈亏和盈亏率都设置为0。
ii.根据客户净持仓方向从客户当前持仓明细中按交易日、成交编号降序,逐条获取开仓量和开仓价,净持仓量递减;若净持仓量小于与某条记录的开仓量时,则将最后获取的该条记录开仓量更新为剩余净持仓量,用于计算持仓总成本。经过以上操作,即获取到了满足该客户净持仓量的所有开仓数据。
iii.计算客户持仓均价,以及客户单位净持仓盈亏和盈亏率。
2.2 平仓数量分配
当市场出现连续单边市、风险不断累积形成系统性风险时,交易所可以依据交易规则对特定合约上的多空头寸进行非交易平仓,及时释放市场风险。
强制减仓的执行流程如下:
(1)判断是否满足强制减仓条件。
待减仓合约连续出现三个同方向单边市(D1,D2,D3)。
(2)确定平仓范围
亏损方:在D3交易日收市后,以涨跌停板价申报无法成交的,且客户该合约的单位净持仓亏损大于或等于D3交易日结算价6%的所有申报平仓单为待平仓有效报单[1]。
盈利方:凡是该合约客户单位净持仓盈利的投机持仓和客户单位净持仓盈利大于等于D3交易日结算价6%的保值持仓都属于待平仓的持仓范围[1]。
(3)内部对冲或者对锁
内部对冲分为以下二步:
(a)对持有双向持仓,有未成交停板价报单且亏损的客户:
i.根据未成交投机报单对冲相应的投机持仓,并生成平仓成交;
ii.根据未成交套保报单对冲相应的套保持仓,并生成平仓成交;
iii.如果还有未成交报单,并且还有双向持仓,则投机和套保相互对冲,并生成平仓成交,内部对冲结束;
iv.对于亏损大于等于6%的客户,最后剩余未成交报单参与强制减仓平仓分配;对于亏损小于6%的客户,最后剩余未成交报单不参与强制减仓平仓分配。
(b)对于持有双向头寸,不管有无停板价报单且有盈利的客户,内部对锁:
i.对锁投机持仓;
ii.对锁套保持仓;
iii.如果还有双向持仓,则投机和套保相互对锁;
iv未被锁仓的盈利方持仓将参与强制减仓平仓分配。
(4)分配平仓及生成平仓成交
在内部对冲或对锁后如果有效未成交报单量仍然大于零,则进行分配平仓操作。分配平仓量的原则如下:
在平仓范围内按盈利的大小和投机与保值的不同分成四级,逐级进行分配,具体分配量按剩余申报平仓数量与各级可平仓的盈利持仓量数量之比来计算。对于配对的结果,生成相应的平仓成交。
(5)平仓数量尾数的处理方法
首先对该级别每个客户按照小数部分由大到小的顺序进行排序,然后按照该排序的顺序进行分配,每个客户1手;对于小数部分相同的客户,如果分配数量不足,则按持仓时间的先后顺序进行分配。
3 高效运算能力设计
整个系统除了业务规则复杂,需要保证准确性外,另一重要特性是计算量大,且需要在尽可能短的时间内完成强制减仓处理,否则会影响正常结算。
系统中计算最耗时的模块是净持仓盈亏计算模块。交易所客户数量大,并仍在快速增长。交易的合约数量也在不断增加,成熟市场如CME交易合约达数千个,国内交易所将来也会达到这个数量级。客户单个合约的平均持仓时间约在3个月左右,而且几乎每个交易日都有交易。此模块要在如此海量数据的情况下准确计算总净持仓、投机净持仓及套保净持仓这三类盈亏。又考虑到目前交易所都有连续交易,为确保连续交易的正常进行,盘后风控处理的时间尽可能不超过30分钟。这意味着必须在30分钟内将各分类净持仓盈亏计算完毕,确定强制减仓分配额度,并完成分配。因此,计算效率非常重要,是系统设计的另一个关键点。
为了提高系统的计算速度,需要使用内存数据库技术,运算能力相比传统数据库可以提高两个数量级。同时采用分布式计算方式,并行分合约计算客户净持仓盈亏,分合约分配强制减仓额度。上海期货交易所研发的内存数据库(SMDB)实现了高效率大数据量的多频次存取及运算。SMDB采用C++ STL提高性能,采用高效的内存管理方式,应用多级索引结构,有效地降低了内存消耗和提升了访问效率,针对不同类型数据存取方式引入Hash、跳表和AVL树等多种形式的索引,支持原子性访问。服务器要求为CPU八核以上,处理器频率不低于3G,内存不少于256G,磁盘空间2T左右。以上配备和设计在上海期货交易所实测通过。
为此做了专门的数据存储访问效率实验,在同一机型配置的情况下,选择两款主流高性能数据库(通用型内存数据库TimesTen和Oracle cache)做对比测试,测试方法是从近一年交易所历史交易流水数据中进行查找、删除和插入操作,基于同样的字段构建索引,采用通用的SQL操作语句,表1所示是访问效率对比表[3]:
表1 访问效率对比表
4 总结
准确的净持仓盈亏计算是确定合理的参与强制减仓持仓范围的基础,高效的算法和系统处理能力是及时化解风险的保障。在极端行情发生时,系统性风险显现,依此设计的强制减仓系统无疑起到定海神针的作用。在2008年10月有色品种期货合约发生连续单边市时,强制减仓系统发挥了预期作用。减仓后,没有发生一起交收违约,也没有一个客户提出异议,有力地维护了期货市场的稳定,对于解决类似风险问题积累了宝贵的经验。强制减仓系统及其设计方法在行业极具推广价值。