Crypto量化高频体验总结
人工智能与量化交易算法知识库 2024-04-21 21:02 美国
以下文章来源于Quant搬砖工 ,作者quant搬砖队工头
Quant搬砖工.
稳健的收益要一点一点赚,量化的板砖要一块一块搬!
前言
前两天在翻历史文章的时候,看到我自己21年1月的时候写了个什么币圈量化入门的文章,翻进去第一反应是,这写的都是啥啊,难怪没人看。所以,就更新下近两年来币圈量化的体验,也算做个记录。
事先声明:以下内容都是基于OKX的实践,没有任何利益相关,主要API开发文档比较详细,所以就稍微在这个基础上踩坑一下。
先说结论:爱过!但是高频真的坑很多!
下面来详细说说所经历的过程和趟过的坑。
taker策略
做高频策略首先想到的肯定是做taker策略,毕竟感觉上风险相对可控,有机会就出手,没机会就蛰伏,怎么算就稳赚不赔。
策略构建流程还是和传统品种一样:数据>因子>做组合>设阈值做交易
在此,感谢身边各位做高频大佬的鼎力相助,学习到了很多。
一、数据
数据层面,数字货币和国内传统品种就存在着一些区别。
首先,订单簿和逐笔成交数据等需要分别订阅不同的频道并分别处理,这样首先遇到的问题就是,在回测时的数据对齐问题。
虽然每条数据都会有附带的交易所时间戳,但是因为是互联网行情,可能不同的频道或者甚至同一个频道的不同条数据其实是从不同的物理服务器发出的,因而交易所时间戳存在不准确的概率,从实践中也发现确实如此。所以,保存历史数据时一定要保存接收到本条数据时的本地服务器时间戳,后续拼接数据按照本地服务器时间戳拼接数据,否则会出现各种奇奇怪怪的问题。
此外,交易所提供的深度行情数据种类很多要按需选择,同时也要注意各种数据之间的区别。
其中books和books5推送频率为100ms,bbo-tbt、books-l2-tbt和books50-l2-tbt推送频率是10ms,本着有快就用快的数据的原则,主要使用的是bbo-tbt和books50-l2-tbt两种。但是需要注意,bbo-tbt仅推送1档数据,即:买一、卖一的量和价;books50-l2-tbt推送上下50档的数据,即:买1至买50、卖1至卖50。
而且,虽然他们推送的频率都是10ms,但是这个10ms的频率是有变化则推送,没有变化则不推送,所以应该说最快的推送频率是10ms;因为档位数量原因,在同样时间内,books50-l2-tbt推送的数据条数大概率比bbo-tbt多,是最接近10ms数据频率的数据,可以利用这个特性将用数据条数作用来做时间计数。当然,books-l2-tbt推送200档频率应该更高,但是太占用计算资源,大量数据也用不到,不考虑。
此外,books50-l2-tbt的推送规则为:首次订阅推送全量档位的数据,后续推送变化的档位数据,所以如果需要知道每个时间节点的全量档位数据,需要自己在本地拼接。本地拼接完,要和交易所提供的验证码进行验证,对上了就是拼接正确,如果对不上,只能及时止损,重新订阅获取一次全量行情。对于拼接的处理速度,python略显吃力,建议上c++。具体的操作还是去看交易所的文档,这里就不做赘述,github上也多搜搜。
二、因子
因子和传统策略类似,主要是:订单簿、订单流、跨交易所价差等几类。
但是实际测试和实践中,发现以下几个问题:
1、从因子值与未来收益的角度,订单簿类因子IC整体较高,且IC值稳定。订单流和跨交易所价差等因子,稳定性较差,不同行情阶段可能出现较长时间的IC值反向迹象。但是订单簿类因子效果时效性较短衰减速度快,即使做一段时间累加等操作后,也只能降低预测能力,不能增加有效时间。
2、仅从因子值和未来收益相关性高低的角度评价时间序列因子并不准确。观察到当行情比较平淡的时间段,因子的IC会更高。究其原因,平淡的行情改变了因子和未来收益的分布,降低了极端值的比例,从而增加IC,而这些对于我们后续通过预测获取收益毫无作用。(后续在这个思路下,增加了极端值IC的衡量,发现订单流类型的因子虽然整体IC弱鸡,但是极端值IC表现优异,加入模型可以发生意想不到的优化)因子选择还是以实际表现为准,不能只看纸面统计量表现。
3、订单簿因子变化特别快。这可能也是造成问题1的原因。因为没有对报撤单的约束,所以大家都疯狂在盘口报撤单。可以明显感受到,盘口挂单量的变化比成交或者价格变快不止一个数量级。大币种常年1档上有显著的流动性,且保持买卖价差保持最小变动价位。但是这些挂单流动性其实都是滑头,订单流一来就跑,说到底都是相互卷的做市策略。以这种盘口来做预测的有效性需要大打折扣,而这所有的市场微观结构和交易所的制度也有着分不开的关系,本质就是一代版本一代神,这个后面再细说。
三、交易
1、手续费
到交易层面,高频首先需要关注的就是手续费。交易所一般采用分级手续费,级别越高手续费越低。以okx的usdt永续合约为例:
最高等级的账户,被动成交是负手续费,即:成交即赚钱,剩下的就是考虑怎么把手里的或出掉;不同等级的账户,手续费差异巨大。但是可以发现,即使是最高等级的账户,主动成交手续费,和传统期货对比而言也是偏高的。所以,还是交易所吸血旱涝保收啊。
做高频,如果不先搞一个高等级账户,起跑线都和别人不一样,那基本就不用做了。
2、延时
在数字货币交易所做交易,大部分人应该都没有colocation服务器,是自己租一个云服务器,wesocket接入互联网行情。不知道是不是交易所抠门,不愿意加服务器配置,比较常见的现象是:成交清淡的时候行情延时完美,成交量一大就开始延时急剧增加。而成交量大的时候往往是行情波动比较剧烈的时候,这个时候叠加大延时不就是坑爹么?但是换个思路想一下,这个时候大家都卡,那就看命呗,突然有种当年用宿舍校园网组团打副本的感觉。不过这样也不容易赢家通吃,多少漏点肉出来
。
四、taker小结
数字货币中,仅有几个大币种流动性比较好,但是波动性个人感觉和股指期货类似;小币种虽然波动也大,但是流动性确实比较辣鸡。这种被动成交负手续费、主动成交高手续费的机制也造成了大币种上各种maker策略盛行。taker策略经过好一阵子的折腾,也是无法稳定跑赢taker手续费,何况延时啥的也不占优势。
想着maker应该对延时要求低一些,本着打不过就加入的精神,于是开始了maker策略的踩坑之旅。
maker策略
maker策略即做市商策略,想着看到这里的读者应该都有着很高的专业素养,就不做科普了。反正策略核心在这里就是尽量被别人成交从而赚负手续费的返佣。
一、AS模型
本人的策略起源来自于AS模型,就是下面这个东东:
但是,上面这些都不重要,反正最后可以得到近似解如下:
这个也不重要,核心逻辑就是,在基准价格两端分别挂买单和卖单等着被人成交。挂单的位置和以下几个因素有关系:
1、价位被市价单击穿的概率;
2、市场波动;
3、盘口厚度;
4、当前库存持仓量;
剩下的都是些经验参数。
从市场的观察也确实大家都是如此操作:
低波动的大币种,挂单集中于盘口,以下为ETH盘口:
大波动的小币种,则挂单明显具体盘口较远,以下为SOL盘口:
本着方便操作的原则,本人的原始方案是在AS模型基础上进一步简化:
基于taker积累的因子,对未来中间价的价格进行预测,得到预测价格Y_bar;在Y_bar的两端基于价格波动率和持仓量进行偏离挂单。同时这是最大单边持仓等风控条件。
这样寄希望于taker因子可以包含除了盘口波动、盘口厚度以外的其他信息,更综合定价。同时,价格波动率大的时候挂远一点,调整交易频率、单向持仓过多时挂单整体向反向偏离,增大库存消化的概率。构思好后,想想都要笑出声,简直完美啊。毕竟,taker因子我干不赢正手续费,但是预测能力摆在那里,负手续费我还搞不定你?
但是可以预料的,我还是太年轻。
二、逆向选择
所谓的逆向选择,通俗来讲,就是能被我成交的挂单,大概率是亏钱的订单,赚钱的订单都被别人抢走了,自己成了市场上的大傻子。对于逆向选择,taker策略还没啥感受,毕竟本来就不能稳定干赢手续费,而且主动成交在互联网行情下后续不一定处于绝对劣势。切换到maker策略以后,逆向选择的体验一下子爆棚了。
然而,在切换了各种因子组合、各个品种依然无果后,某一天突然峰回路转。某一天因为参数设置的bug!所有的因子权重都成了0!!于是挂单的基准价格成了不加任何预测的中间价!!!而这样以后竟然开始了稳定盈利!!!!
黑人问号???这简直是一种嘲讽,让人难以相信。不够经过了一阵子测试,还是接受了这个事实。于是就在这个基础上,稍作改进,就得到了文章最开始那段收益曲线。
事后总结分析,原因主要有以下几个方面:
1、前面提到,taker因子有效期较短,而maker策略相对来说持仓周期较长且靠被动成交,存在一定的不适配,更容易发生逆向选择。
2、因子变动较快,造成预测的基准价格变化过快。而挂单价格会因为基准价格变化过快而频繁报撤单,使得订单在市场存续时间过短,因而不利于订单被成交。更倾向于在单边趋势的订单流中被逆势成交。
三、后续改进方向
首先先记录几个方向的尝试:
1、尝试增加因子专门来避免被逆向成交:不再是买卖双边挂单同时调整,而是仅仅拉远与预测逆向的方向的订单。结论:失败,降低成交率。
2、对市场波动率进行更精细的预测,不同周期叠加。结论:感觉区别不大,不如碰到一个正好和市场吻合的参数。
3、当持仓量过大时,进入风控操作,一次性挂单减仓。结论:看运气,但是经常平早了。
4、强制控制订单成交频率,即:成交后一段时间内不挂单。结论:有效!可以有效防止单边被持续逆向成交。少亏就是赚。
5、有时候市场波动率骤降,造成持仓长期无法平仓。超过持仓时间阈值,强制平仓。结论:负收益贡献居多。
6、短期急剧单向波动时,撤单不挂单,待市场平复。结论:可能有用,不过这种时候一般都很卡,有没有用看命。
......
之前还做过一个大版本的调整,taker因子预测和maker负手续费想兼得之心不死:
基于taker策略的预测和交易模式,触发阈值则单边挂单至盘口。当然结果还是无悬念被逆向。
以上仅是暂时想起来的一些改进,还有好多改进忘记了,反正无用不提也罢。
四、maker小结
总体而言,我的做市策略出道即颠峰。后续因为市场波动变化、手续费调整,整体是个不温不火赚赚亏亏的状态,现在也就是设置成很小的挂单手数自动跑着。说不定那天行情又来了呢
后续的改进也是修修补补的状态。
真要从现在这种无差别做市模式切换为增加行情响应的模式,我个人觉得高频信号先不需要考虑了。但是还是需要加入低频的择时信号。毕竟做事策略和期权做空波动率本质还是很类似的,都是short vol属性,最怕波动率抬升,最怕被逆向。
所以反而觉得低频的CTA信号会更合适:在不增加报撤单频率的同时,对行情进行响应,同时用short vol的高胜率低盈亏比,叠加CTA的低胜率高盈亏比,说不定会发生1+1>2的效果。
其他
交易执行代码啥的,其实也有很多坑。包括各种错误处理代码处理呀、报撤单超频处理呀、仓位和订单校验呀、post_only、reduced_only等订单的运用呀......总之,只能说多测试运行,多看API文档。什么都准备着,万一啥时候风来了呢。