Binance Square

浮点量化

穿越迷雾与幻象,洞见量化交易的技术与真相 【公众号、推特同名】|| 中低频量化交易机器人开发
8 关注
85 粉丝
28 点赞
9 分享
全部内容
--
我的饼圈套利策略与技巧公开(真干货)最近看了 babyquant 的《大饼圈的套利策略简析》写了各种套利策略,我也来谈谈自己之前差不多实盘运行了2年左右的数字货币套利策略。 之所有公开,一是因为我现在已经不运行这些策略了,写一写自己也总结一下;二是套利策略的逻辑本来就不神秘。这一行比拼的是执行力,也就是写代码的能力,特别是高频交易方面。交易的频率可能并不是很高,但必须反应速度快,波动来了,立马入场。当然还有对事情的专研能力,因为套利的竞争还是比较激烈的,后期的竞争更是惨烈。还得有一定的资金筹集能力,毕竟套利的盈利率有限,资金充足一点才可能有比较可观的利润,至少要超过打工收入吧,才值得全职去做。当然加入机构团队也是一个办法。 这里公开并不意味着这些策略现在完全无效,大概可能还是有效的,只是效率可能不是太高了。意思就是风险大赚钱可能并不多,还有前面提到的竞争惨烈,玩的人越来越多,而且团队作战。 更重要的是,相比于其他策略而言,单纯套利吸引力不大,虽然可能比较稳。最终还是得拥有风险敞口的策略才能更赚钱,当然风险也更大,盈亏同源嘛。以前就是,行情来了,虽然我也赚钱,但是相比于别人的持仓策略,别人在吃肉,我顶多算喝到一口汤。当然,持仓策略方向做反了的时候,我也没有跟着挨打,只能这样安慰自己了。 先讲讲我最稳定赚钱的套利策略之一,也就是俗称的“搬砖”。 搬砖套利是最适合币圈的策略。因为这些币是数字化的,都在链上,这个大饼和那个大饼之间完全同质化(不同质化的话就成 NFT 了)。这样在不同交易所之间交易的大饼二饼,完全一模一样,天然适合搬砖。不像其他实体品种,比如农产品,虽然他们名称可能一样,比如都是小麦,但是一来运输麻烦,还得算仓储成本,二来在不同国家地区、周期的小麦可能蛋白质之类的含量也不一样,定价肯定也不同了,很容易被反套。 不可控的因素更多,风险就加大了。 所谓的“搬砖”就是在币圈有很多交易所,那么每个交易所的大饼二饼的价格其实是本交易所的账户之间博弈出来的,这样不同所之间肯定就有差别。普通用户感觉到每个交易所的价格几乎都是同步的,这就是套利策略的贡献,当然做市商的策略也有贡献。 总之,套狗们是抹平交易所差价的最大功臣。 具体策略 策略逻辑非常简单。 简单到,当年我在还不知道交易中买卖的英文单词是 bid ask 的时候,代码写出来都能赚钱。当初在 API 文档里到处翻找 buy sell,发现居然找不到,记忆犹新,只有 bid ask long short 之类。所以说隔行如隔山。其中隔离的障碍之一,就是每一个行业自带的“黑话”。 策略的大致逻辑就是,一个所的卖一价低于另外一个所的买一价,那么条件就满足了。说明有人在低价卖,另外有人高价买。你在第一个所买入二者挂单的公约数量,然后在另外一个所卖出,就是这么简单!激进一点,你也可以全吃了,然后剩下的再慢慢出货。 两边都做 taker,只做软搬砖的话(就是两个交易所都有资金或者币,并不真的把币买了再转到另外一个所卖,这样太慢,按这操作黄花菜都凉了)几乎没有持仓,同时成交,利润立马到手。没有比这更简单更稳定的策略了。 但是现实肯定没有这么容易的事情。知道跟真正做到之间往往隔着天堑。实操总有意外发生。 下面讲讲我当年遇到的问题和应对之道,说不定对后来者有一定启发。 问题一,没有价差。 这个问题应对方法很简单,那就是等。不要轻易乱动。 后期我加入了一点 maker 逻辑,主动去 orderbook 守株待兔,这样就类似做市商了,逻辑稍微复杂一些。 总之就是得等。你如果不想等,那就得像上面提到的那样变换策略。饼圈之前机会非常多,波动充足,几乎每天都有几次小机会,每周都有几次大机会。做 taker 就是得等机会出现。 真正需要担心的是,下雨了,你接水的桶够不够多,够不够大。不过这些只有你等你真正见识到了,才会明白。 问题二,抢不到。 这是最大的问题了。 你的代码监控到卖一买一价差有利可图,但是转瞬即逝,这总情况不是别人撤单,就是被人捷足先登了。你如果没有发单还好,单纯就是一个看客。或者发单了,但是没有成交,挂 orderbook 上了,也还好,大不了就是撤单。(当初还没有 IOC,FOK 这样的算法单,就是不成交立即自动撤单,不会挂着被吃,而只有普通的限价、市价单,特别是小所)麻烦的是,单腿成交了,这个后面再谈。 抢不到单子的应对。 因为是两个(甚至多个)交易所之间套利,那么单所的反应速度就没有那么重要,当年还没有 colo 这些设施,更没有 FPGA 这些大杀器,其实大家还比较公平,而且套利算法也极其简单,没有计算速度要求。所以关键就是在两个所之间的综合速度了。 当年的主流交易所服务器主要分布在东京(B安)、香港(ok)还有就是欧洲的都柏林、法兰克福和瑞士等等。 所以你总不可能把自己的实盘代码跑在北美的服务器吧。 下图是一张简单的海底光缆图。你可以根据自己套利的交易所,寻找到达他们共同都比较快的大致位置。特别是对于那些跨洲的套利,信号在光缆上单趟跑一次就得上百 ms 了。 这里的诀窍呢,就是可以首先考虑流动性没那么好的交易所,也就是小所,最好有代码和它在同一个云服务器供应商,同一个区。这样能够抢先拿下小所的挂单,然后再到流动性好的交易所去出货。 lead-lag,先对 lag 一侧动手。所谓的 take slow mover 策略。吃还没有意识到价格在激烈变化的挂单。 搬砖套利的一个要点就是,最好是一个大所和一个小所接合,这样才更容易获利,两个大所之间的竞争早就白刃化了。 然后另外一个窍门是,管他3721,两边都布置自己的代码,然后在他们的中间地带有可能也布置上,这样增加抢到的概率。到最后,很有可能发现其实是自己在跟自己的交易机器人抢,这样最好。 在当年,只要你的代码是异步的,然后用上了 websocket 获取行情,就足够快了,上得了牌桌,可以一战。 问题三,抢到单腿。 怕的是,一条腿成交了,另外一条还挂在那里,那么你就有了敞口,而且这种时候大都是被逆向选择了。也就是,价格在涨,你卖出了,另外一侧没买到对冲;价格在暴跌,恭喜你,你成功接到货了,但是卖单没有成交。 这个时候就看你的策略了。如果是币币套利,也就是 quote base 都是饼,例如 ETH/BTC 交易对,那么问题就不大,因为反正都是饼,涨跌幅度一般不太大。 但是如果是 usdt,那么价格波动可能就大了。这时你可以等等看,也可以认栽出货,也可以看看是不是在小时线布林带上下轨之外的危险区之类的,最好及早止损。 我之前有一个 6 秒持仓限制,一般单腿情况如果超过 6 秒,我就平仓走人了。好在一般胜率都比较高,这样的情况有限。 总之,看你的风险偏好。套利有时候也是会亏损的,虽然做得好的能够在大部分时候避免。 问题四,单所满仓。 大行情下,你在跌得慢的一侧全卖成了 usdt,跌得厉害价格更低的一侧,应该全是接到对应的币了。这里并不是真正的满仓,因为你手里的饼和钱的数量其实并没有变化,只是它们所在的交易所变了,然后数量多了一丢丢。 如果行情继续,价差持续,基本上你只有相互转币,这样就是真正的“搬砖”了。当然你也可以等反弹,有时候价格一旦反弹,价差就会倒挂,这样又可以交易一波。一来一回,如果你币种比较多的话,当天可能就能满仓赚 1 个点,甚至更多,因为币种之间行情的切换会提高资金利用率,当然你的策略也要设计得当,这也是挑战之一。比如利用跨所的三角套利,在可能不亏钱的情况下,软转移币,然后继续套。 到了我套利的后期,套利的人多了,只有在很大的行情下,才有这样的机会满仓。人多了,资金多了,流动性就上来了,特别是爆炸头 sbf 他们这些机构入场之后,把持了主要的机会,很多套狗都转做其他策略了。 现在做市的人越来越多,套利的人也越来越多,机构入场,还有期权交易增加,312 这样的史诗行情真的很难再现。那天真的是一场狂欢,历历在目。 其他技巧 我记得当初最大的单笔单子差不多150w左右(rmb计算)。 我设计了两种模式,也就是有人监督模式,无人监督模式。 很简单,无人监督的时候,例如晚上睡觉了,就低调点,单子小些,限额,慢慢吃单。一定要上一笔双腿都成交了,再执行下一笔。控制好仓位。机会错过就错过了。而且所有交易对要控制总仓位,控制全账户风险。 有人监督的时候,那么就可以开启大炮模式,一口把低流动一侧的单子吃了,甚至直接吃大单,然后到几个流动性好的大所慢慢出货。如果突然转向,那么赶紧人工介入处理一下。采用之前提到过的处理方式应对。 我记得当时《硅谷》美剧上映,我也用了里面那个加拿大程序员采用的音乐,作为有大单成交的提醒,每次听到都很兴奋,赶紧去查看情况,不要出了纰漏。 还有一个处理竞争的技巧。就是最好能够垄断一个小交易所的一些交易对。现货的手续费一般千一左右,那么一进一出就是千二(还有一点转币费用,如果资金少,那么也得计算在内)所以至少要有千分之二的差价才有得赚。 如果这个小交易所的交易对,例如 EOS/ETH 只有你在交易,你就可以任凭它的价差到千三才动手,甚至更高一点。当然太高也不好,这样会引来竞争对手。市场上大家时时刻刻都在扫描监控各个交易所的价差。人家看到这个交易对怎么价差这么高,就会过来跃跃欲试。但是如果看到价差不大,很快消失,同行就知道这里已经有主了,要过来搞事情得下更多功夫,大概得和人硬碰硬,就不一定来了。 如果真的有头铁的同行过来搞事,那么你就得应战。 来的是 maker 无所谓,因为这个策略只做 taker, 和 maker 策略正好互补,他要是个菜鸡,代码反应速度慢,你正好可以吃他。 怎么应战?就是在行情刚启动的时候就把单子吃了,之前是千三,那么对手进来可能千分之2.5就动手了,你连续错过几单就知道有人进来在做同样的事情。这时候,你就得牺牲利润,可能千2就动手,抢跑。千2其实大家都还有利润,因为交易量大的,手续费有折扣,所以大家会一直试探到千一左右。这个时候,你就得壮士断腕,不要利润,甚至倒贴一点也得上了。比如万五左右就动手。 这里就是拼心理了。因为对手是刚来这里,那么他心态其实就是来试试,有枣没枣打一杆子那种,看到不赚钱很快就会撤。这种套利,我之前说了,你要搞得好,就得多处布置服务器,还得充币,占用资金。还得专人监控。一句话,就是有成本的。一旦不赚钱,新来的就会撤。一般就是1个星期这样。对方可能向他老板报告,这个交易对不赚钱,那么他们就可能转战其他地方了。遇到硬茬,那么就拿出半个月的利润来跟他耗,新来的基本都扛不住。 我自己去别的地方也被人这样搞过。别人为了守住自己的地盘,会不惜和你一战。所以道理大家都懂。 最后,竞争对手走了,那么你就继续加价,千三才动手。这其实跟线下菜市场的那些小贩策略一样。毕竟都是交易,没谁更高大上。 所以,这行其实也挺累的,大家不断相互防着。有时候还有专门收割套利策略的交易机器人,诱发你出手交易。这个就复杂了,不在这里表述。总之要防的东西不少,得时刻警惕。盯盘是常事,几天不盯盘,不看看盘口变化,修改配置参数,甚至源代码,利润就会下降。 总之都是辛苦钱。 潜在风险 套利策略其实并不是全无风险。策略本身风险并不大。套到单腿,及时退出就可以了,大不了少赚一点。 风险就是币圈的结构性风险。一是交易所跑路,倒闭,提不出币,比如 cz 要是被 FBI/CIA 之类的长臂执法了,你的币不一定拿得到;二是 USDT 或者其他币本身突然暴雷了。 当年交易所之间的头部效应还不是非常显著,小所还是有人去交易的。不像现在,经历过几次交易所跑路之后,还有 ftx 挪用资金暴雷,大家都只去头部交易所交易了。 所以,普通套利不一定是一个好的策略。如果你会其他交易,比如 CTA,怎么都比套利强,资金利用率更高。之前的套狗,能力强的,基本都转高频做市、趋势交易了。 最后 以前真的是好时代,机会太多了。有的时候行情来了,其实用手下单都可以套利。真的大行情下,还能不断在交易所之间转币套,因为价差一直在。听说还有人肉搬砖到韩国去套的,不过那段行情我没有赶上。 我的初版代码是 JavaScript 写的。测试代码主要就几十行,想着先投入几天时间和精力,还有几十刀资金试试看,赚钱就继续,不然赶紧干别的去。没想到第一天测试就开始赚钱。当时几天就调好了最初的代码,想着只要第一天赚到鸡腿钱就继续,因为毕竟只有几十刀本金,结果一开始就赚到了盒饭加咖啡,然后就一发不可收拾,一路修改代码,修改模型,打怪升级。 比较遗憾的是,因为自己套利实在太顺滑了,没有动力去升级其他更赚钱的策略。主要是其他策略都是有回撤的,套利习惯了,实在忍受不了赚到的钱还要亏回去这种情况,心态接受不了,所以一直没有成功。另外,其他赚钱的策略其实难度更高。反观那些早早套利不赚钱的套狗,及时转战高频或者 CTA 之类的策略,好多转型成功,赶上之前的牛市,成功一波暴发。 总之,套利的逻辑很简单,不需要大聪明,只需要集合很多小聪明,小创意,做得比别人更用心就好,重在执行。但要做好真正的交易,就是有敞口,有持仓,就得理解交易的本质了,策略设计、回测、实盘执行,一个环节都不能落下。 这次就先分享这些。

我的饼圈套利策略与技巧公开(真干货)

最近看了 babyquant 的《大饼圈的套利策略简析》写了各种套利策略,我也来谈谈自己之前差不多实盘运行了2年左右的数字货币套利策略。

之所有公开,一是因为我现在已经不运行这些策略了,写一写自己也总结一下;二是套利策略的逻辑本来就不神秘。这一行比拼的是执行力,也就是写代码的能力,特别是高频交易方面。交易的频率可能并不是很高,但必须反应速度快,波动来了,立马入场。当然还有对事情的专研能力,因为套利的竞争还是比较激烈的,后期的竞争更是惨烈。还得有一定的资金筹集能力,毕竟套利的盈利率有限,资金充足一点才可能有比较可观的利润,至少要超过打工收入吧,才值得全职去做。当然加入机构团队也是一个办法。

这里公开并不意味着这些策略现在完全无效,大概可能还是有效的,只是效率可能不是太高了。意思就是风险大赚钱可能并不多,还有前面提到的竞争惨烈,玩的人越来越多,而且团队作战。

更重要的是,相比于其他策略而言,单纯套利吸引力不大,虽然可能比较稳。最终还是得拥有风险敞口的策略才能更赚钱,当然风险也更大,盈亏同源嘛。以前就是,行情来了,虽然我也赚钱,但是相比于别人的持仓策略,别人在吃肉,我顶多算喝到一口汤。当然,持仓策略方向做反了的时候,我也没有跟着挨打,只能这样安慰自己了。

先讲讲我最稳定赚钱的套利策略之一,也就是俗称的“搬砖”。

搬砖套利是最适合币圈的策略。因为这些币是数字化的,都在链上,这个大饼和那个大饼之间完全同质化(不同质化的话就成 NFT 了)。这样在不同交易所之间交易的大饼二饼,完全一模一样,天然适合搬砖。不像其他实体品种,比如农产品,虽然他们名称可能一样,比如都是小麦,但是一来运输麻烦,还得算仓储成本,二来在不同国家地区、周期的小麦可能蛋白质之类的含量也不一样,定价肯定也不同了,很容易被反套。

不可控的因素更多,风险就加大了。

所谓的“搬砖”就是在币圈有很多交易所,那么每个交易所的大饼二饼的价格其实是本交易所的账户之间博弈出来的,这样不同所之间肯定就有差别。普通用户感觉到每个交易所的价格几乎都是同步的,这就是套利策略的贡献,当然做市商的策略也有贡献。

总之,套狗们是抹平交易所差价的最大功臣。

具体策略

策略逻辑非常简单。

简单到,当年我在还不知道交易中买卖的英文单词是 bid ask 的时候,代码写出来都能赚钱。当初在 API 文档里到处翻找 buy sell,发现居然找不到,记忆犹新,只有 bid ask long short 之类。所以说隔行如隔山。其中隔离的障碍之一,就是每一个行业自带的“黑话”。

策略的大致逻辑就是,一个所的卖一价低于另外一个所的买一价,那么条件就满足了。说明有人在低价卖,另外有人高价买。你在第一个所买入二者挂单的公约数量,然后在另外一个所卖出,就是这么简单!激进一点,你也可以全吃了,然后剩下的再慢慢出货。

两边都做 taker,只做软搬砖的话(就是两个交易所都有资金或者币,并不真的把币买了再转到另外一个所卖,这样太慢,按这操作黄花菜都凉了)几乎没有持仓,同时成交,利润立马到手。没有比这更简单更稳定的策略了。

但是现实肯定没有这么容易的事情。知道跟真正做到之间往往隔着天堑。实操总有意外发生。

下面讲讲我当年遇到的问题和应对之道,说不定对后来者有一定启发。

问题一,没有价差。

这个问题应对方法很简单,那就是等。不要轻易乱动。

后期我加入了一点 maker 逻辑,主动去 orderbook 守株待兔,这样就类似做市商了,逻辑稍微复杂一些。

总之就是得等。你如果不想等,那就得像上面提到的那样变换策略。饼圈之前机会非常多,波动充足,几乎每天都有几次小机会,每周都有几次大机会。做 taker 就是得等机会出现。

真正需要担心的是,下雨了,你接水的桶够不够多,够不够大。不过这些只有你等你真正见识到了,才会明白。

问题二,抢不到。

这是最大的问题了。

你的代码监控到卖一买一价差有利可图,但是转瞬即逝,这总情况不是别人撤单,就是被人捷足先登了。你如果没有发单还好,单纯就是一个看客。或者发单了,但是没有成交,挂 orderbook 上了,也还好,大不了就是撤单。(当初还没有 IOC,FOK 这样的算法单,就是不成交立即自动撤单,不会挂着被吃,而只有普通的限价、市价单,特别是小所)麻烦的是,单腿成交了,这个后面再谈。

抢不到单子的应对。

因为是两个(甚至多个)交易所之间套利,那么单所的反应速度就没有那么重要,当年还没有 colo 这些设施,更没有 FPGA 这些大杀器,其实大家还比较公平,而且套利算法也极其简单,没有计算速度要求。所以关键就是在两个所之间的综合速度了。

当年的主流交易所服务器主要分布在东京(B安)、香港(ok)还有就是欧洲的都柏林、法兰克福和瑞士等等。

所以你总不可能把自己的实盘代码跑在北美的服务器吧。

下图是一张简单的海底光缆图。你可以根据自己套利的交易所,寻找到达他们共同都比较快的大致位置。特别是对于那些跨洲的套利,信号在光缆上单趟跑一次就得上百 ms 了。

这里的诀窍呢,就是可以首先考虑流动性没那么好的交易所,也就是小所,最好有代码和它在同一个云服务器供应商,同一个区。这样能够抢先拿下小所的挂单,然后再到流动性好的交易所去出货。

lead-lag,先对 lag 一侧动手。所谓的 take slow mover 策略。吃还没有意识到价格在激烈变化的挂单。

搬砖套利的一个要点就是,最好是一个大所和一个小所接合,这样才更容易获利,两个大所之间的竞争早就白刃化了。

然后另外一个窍门是,管他3721,两边都布置自己的代码,然后在他们的中间地带有可能也布置上,这样增加抢到的概率。到最后,很有可能发现其实是自己在跟自己的交易机器人抢,这样最好。

在当年,只要你的代码是异步的,然后用上了 websocket 获取行情,就足够快了,上得了牌桌,可以一战。

问题三,抢到单腿。

怕的是,一条腿成交了,另外一条还挂在那里,那么你就有了敞口,而且这种时候大都是被逆向选择了。也就是,价格在涨,你卖出了,另外一侧没买到对冲;价格在暴跌,恭喜你,你成功接到货了,但是卖单没有成交。

这个时候就看你的策略了。如果是币币套利,也就是 quote base 都是饼,例如 ETH/BTC 交易对,那么问题就不大,因为反正都是饼,涨跌幅度一般不太大。

但是如果是 usdt,那么价格波动可能就大了。这时你可以等等看,也可以认栽出货,也可以看看是不是在小时线布林带上下轨之外的危险区之类的,最好及早止损。

我之前有一个 6 秒持仓限制,一般单腿情况如果超过 6 秒,我就平仓走人了。好在一般胜率都比较高,这样的情况有限。

总之,看你的风险偏好。套利有时候也是会亏损的,虽然做得好的能够在大部分时候避免。

问题四,单所满仓。

大行情下,你在跌得慢的一侧全卖成了 usdt,跌得厉害价格更低的一侧,应该全是接到对应的币了。这里并不是真正的满仓,因为你手里的饼和钱的数量其实并没有变化,只是它们所在的交易所变了,然后数量多了一丢丢。

如果行情继续,价差持续,基本上你只有相互转币,这样就是真正的“搬砖”了。当然你也可以等反弹,有时候价格一旦反弹,价差就会倒挂,这样又可以交易一波。一来一回,如果你币种比较多的话,当天可能就能满仓赚 1 个点,甚至更多,因为币种之间行情的切换会提高资金利用率,当然你的策略也要设计得当,这也是挑战之一。比如利用跨所的三角套利,在可能不亏钱的情况下,软转移币,然后继续套。

到了我套利的后期,套利的人多了,只有在很大的行情下,才有这样的机会满仓。人多了,资金多了,流动性就上来了,特别是爆炸头 sbf 他们这些机构入场之后,把持了主要的机会,很多套狗都转做其他策略了。

现在做市的人越来越多,套利的人也越来越多,机构入场,还有期权交易增加,312 这样的史诗行情真的很难再现。那天真的是一场狂欢,历历在目。

其他技巧

我记得当初最大的单笔单子差不多150w左右(rmb计算)。

我设计了两种模式,也就是有人监督模式,无人监督模式。

很简单,无人监督的时候,例如晚上睡觉了,就低调点,单子小些,限额,慢慢吃单。一定要上一笔双腿都成交了,再执行下一笔。控制好仓位。机会错过就错过了。而且所有交易对要控制总仓位,控制全账户风险。

有人监督的时候,那么就可以开启大炮模式,一口把低流动一侧的单子吃了,甚至直接吃大单,然后到几个流动性好的大所慢慢出货。如果突然转向,那么赶紧人工介入处理一下。采用之前提到过的处理方式应对。

我记得当时《硅谷》美剧上映,我也用了里面那个加拿大程序员采用的音乐,作为有大单成交的提醒,每次听到都很兴奋,赶紧去查看情况,不要出了纰漏。

还有一个处理竞争的技巧。就是最好能够垄断一个小交易所的一些交易对。现货的手续费一般千一左右,那么一进一出就是千二(还有一点转币费用,如果资金少,那么也得计算在内)所以至少要有千分之二的差价才有得赚。

如果这个小交易所的交易对,例如 EOS/ETH 只有你在交易,你就可以任凭它的价差到千三才动手,甚至更高一点。当然太高也不好,这样会引来竞争对手。市场上大家时时刻刻都在扫描监控各个交易所的价差。人家看到这个交易对怎么价差这么高,就会过来跃跃欲试。但是如果看到价差不大,很快消失,同行就知道这里已经有主了,要过来搞事情得下更多功夫,大概得和人硬碰硬,就不一定来了。

如果真的有头铁的同行过来搞事,那么你就得应战。

来的是 maker 无所谓,因为这个策略只做 taker, 和 maker 策略正好互补,他要是个菜鸡,代码反应速度慢,你正好可以吃他。

怎么应战?就是在行情刚启动的时候就把单子吃了,之前是千三,那么对手进来可能千分之2.5就动手了,你连续错过几单就知道有人进来在做同样的事情。这时候,你就得牺牲利润,可能千2就动手,抢跑。千2其实大家都还有利润,因为交易量大的,手续费有折扣,所以大家会一直试探到千一左右。这个时候,你就得壮士断腕,不要利润,甚至倒贴一点也得上了。比如万五左右就动手。

这里就是拼心理了。因为对手是刚来这里,那么他心态其实就是来试试,有枣没枣打一杆子那种,看到不赚钱很快就会撤。这种套利,我之前说了,你要搞得好,就得多处布置服务器,还得充币,占用资金。还得专人监控。一句话,就是有成本的。一旦不赚钱,新来的就会撤。一般就是1个星期这样。对方可能向他老板报告,这个交易对不赚钱,那么他们就可能转战其他地方了。遇到硬茬,那么就拿出半个月的利润来跟他耗,新来的基本都扛不住。

我自己去别的地方也被人这样搞过。别人为了守住自己的地盘,会不惜和你一战。所以道理大家都懂。

最后,竞争对手走了,那么你就继续加价,千三才动手。这其实跟线下菜市场的那些小贩策略一样。毕竟都是交易,没谁更高大上。

所以,这行其实也挺累的,大家不断相互防着。有时候还有专门收割套利策略的交易机器人,诱发你出手交易。这个就复杂了,不在这里表述。总之要防的东西不少,得时刻警惕。盯盘是常事,几天不盯盘,不看看盘口变化,修改配置参数,甚至源代码,利润就会下降。

总之都是辛苦钱。

潜在风险

套利策略其实并不是全无风险。策略本身风险并不大。套到单腿,及时退出就可以了,大不了少赚一点。

风险就是币圈的结构性风险。一是交易所跑路,倒闭,提不出币,比如 cz 要是被 FBI/CIA 之类的长臂执法了,你的币不一定拿得到;二是 USDT 或者其他币本身突然暴雷了。

当年交易所之间的头部效应还不是非常显著,小所还是有人去交易的。不像现在,经历过几次交易所跑路之后,还有 ftx 挪用资金暴雷,大家都只去头部交易所交易了。

所以,普通套利不一定是一个好的策略。如果你会其他交易,比如 CTA,怎么都比套利强,资金利用率更高。之前的套狗,能力强的,基本都转高频做市、趋势交易了。

最后

以前真的是好时代,机会太多了。有的时候行情来了,其实用手下单都可以套利。真的大行情下,还能不断在交易所之间转币套,因为价差一直在。听说还有人肉搬砖到韩国去套的,不过那段行情我没有赶上。

我的初版代码是 JavaScript 写的。测试代码主要就几十行,想着先投入几天时间和精力,还有几十刀资金试试看,赚钱就继续,不然赶紧干别的去。没想到第一天测试就开始赚钱。当时几天就调好了最初的代码,想着只要第一天赚到鸡腿钱就继续,因为毕竟只有几十刀本金,结果一开始就赚到了盒饭加咖啡,然后就一发不可收拾,一路修改代码,修改模型,打怪升级。

比较遗憾的是,因为自己套利实在太顺滑了,没有动力去升级其他更赚钱的策略。主要是其他策略都是有回撤的,套利习惯了,实在忍受不了赚到的钱还要亏回去这种情况,心态接受不了,所以一直没有成功。另外,其他赚钱的策略其实难度更高。反观那些早早套利不赚钱的套狗,及时转战高频或者 CTA 之类的策略,好多转型成功,赶上之前的牛市,成功一波暴发。

总之,套利的逻辑很简单,不需要大聪明,只需要集合很多小聪明,小创意,做得比别人更用心就好,重在执行。但要做好真正的交易,就是有敞口,有持仓,就得理解交易的本质了,策略设计、回测、实盘执行,一个环节都不能落下。

这次就先分享这些。
币安逐笔交易记录(aggTrades)下载、整理和使用(一)昨晚大饼二饼的这一波行情来得真是及时,好久没有这么顺畅的趋势了。 这次说说如何使用 B 安的逐笔历史交易记录。 B安官方已经把很多交易数据共享了出来。有 Github 页面可以详细查看有哪些类别的数据以及如何下载。我这里主要介绍聚合交易记录 aggTrades 的下载、整理和使用。 aggTrades 就是聚合之后的逐笔交易记录,也就是币安把连续的几笔在同一时间、同一方向、同一价位成交的交易聚合成一笔记录,类似 k 线的一根,但是只有一个价格,没有最高最低价之类。比如盘口挂了一笔大单,很多小订单去吃它,那么这些在很短时间内(毫秒级)同时到达的订单,就会被聚合在一起。或者可能就是撮合引擎一次能够撮合的订单。 aggTrades 数据的好处就是可以有毫秒级别的交易记录,但是又不像纯逐笔 trades (就是最原始的数据,没有按照同一价格聚合)记录那样大的数据量,是一个不错的高频数据折中方案。 一般就是准高频策略使用这样的聚合数据。那些真正的高频一般都是用 trades 以及加上 orderbook 的数据,数据量非常大,处理起来也很不方便,如果用不上就没有必要。不仅消耗资源,也增加编程的难度。 aggTrades 的用处可以是用来合成任意级别的短 k 线,例如 5、10、15 秒的短 k 线,这样的 k 线用来做一些日内交易策略也还是有可能的。 譬如下面是之前贴过的 1 秒级别 k 线。 还有高频套利,现在普通套利已经很难赚钱了,非常卷,频率高一点的话可能还有些许机会。 这种逐笔数据还可以用来合成另类的 k 线,例如等量 bar 之类的,用 aggTrades 比用分钟 k 线合成出来要精确得多,这样做出来的 CTA 策略可能和普通 k 线策略比较互补。后面几篇我可能会写如何合成这种 bar。 下面就是代码介绍(大部分代码见附件,因为太多太长,就不在正文中贴了)。下载代码是币安的例子,不过稍微有一些改动,还有就是我的加工整理代码。 这里是以月度数据为例(币安也提供了日数据)。代码都是单线程、同步执行,没有搞异步、多线程之类。因为这样的下载都是一个月或者 n 天执行一次,稍微等等就行了,用不着搞得很复杂。 基本的回测用旧一点的数据一般没有什么问题,因为高频数据回测也就主要是起到一些分析作用,主要还是得看实盘,因为滑点可能很大,或者挂单不成交,追单没追到,交易所延迟等等。 不过后面我也有下载即时数据的代码,就是下载当天的 aggTrades 数据,即时验证错过的行情。币安的日数据都是滞后几天才有的。要急着用的话,就得自己用交易所 api 爬取了。 一 下载 第一部分代码就是 agg.py 和 utility.py 两个文件,然后使用 python3 agg.py -y 2022 -m 6 -t um -folder /你的指定路径 这里就是一个下载 2022 年 6 月份的所有永续合约 aggTrades 数据的命令例子。一般十来分钟就可以下载完成。数据下载下来是压缩过的,所以下一步就是解压缩。 二 解压 解压就是使用 unzip.py 这个文件,非常短的代码,就两个函数,一个解压月度数据,一个解压日数据。 zip 文件解压出来之后是 csv 文件。csv 文件的问题是比较占硬盘,而且加载速度会比较慢。所以就是下一步,把 csv 文件转换为 pickle 文件。你可以根据自己的情况压缩和不压缩。如果你硬盘大,建议不用压缩,一般永续数据一个月大概 50GB 左右,所以看自己情况。一般可以买一个速度快一点的外置 SSD 硬盘,现在 1TB 也就几百块,早就白菜价了,回测时加载也挺快。 三 压缩转为 pickle 转换的代码就在 csv_to_pkl.py。如上所述,转换之后更容易保存使用。 转换之后我就是手动把 csv 文件删除,不然占硬盘。这一步就没有代码实现了。之前说了,都是很低频的操作,不用完全自动化。我在例子代码里使用的是 gzip 2 级压缩,一般一个月的数据压缩后也就不到 10GB。 csv 不仅占用空间,加载还慢。建议采用 pickle 格式。综合来看,它的性能不错,关键是兼容性好。如果你要用云服务器,或者很多其他开源包,比 feather 之类更兼容。 好了,到这一步数据就算准备妥当了,可以开始研究策略了。 四 即时数据下载 之前提到,因为币安的数据服务器上的数据都是滞后一两天的。如果你需要验证你的策略在当前的行情下会怎么样,而又没及时上某个币的实盘,那么可以通过下面代码下载回溯到指定时间的 aggTrades。我一般就是用来下载当前 12 小时的数据,看看策略可能的表现会怎样。 下面代码使用的话,需要修改为最近的开始时间。 下载下来的数据是这样。可以对照币安的文档,近期成交(归集)看看他们的具体意义。 有了这样的原始数据,你可以使用 df.resample(bar_size).agg() 把它们聚合成你需要的任何级别 k 线,更随心所欲。 最后 基本上这就是我之前用到的 aggTrades 数据的准备了。现在的策略是越来越卷,使用更细致的数据可以开发更多类别的策略。策略之间互补才是多策略的王道。 如果你需要以上代码,可以联系领取。

币安逐笔交易记录(aggTrades)下载、整理和使用(一)

昨晚大饼二饼的这一波行情来得真是及时,好久没有这么顺畅的趋势了。

这次说说如何使用 B 安的逐笔历史交易记录。

B安官方已经把很多交易数据共享了出来。有 Github 页面可以详细查看有哪些类别的数据以及如何下载。我这里主要介绍聚合交易记录 aggTrades 的下载、整理和使用。

aggTrades 就是聚合之后的逐笔交易记录,也就是币安把连续的几笔在同一时间、同一方向、同一价位成交的交易聚合成一笔记录,类似 k 线的一根,但是只有一个价格,没有最高最低价之类。比如盘口挂了一笔大单,很多小订单去吃它,那么这些在很短时间内(毫秒级)同时到达的订单,就会被聚合在一起。或者可能就是撮合引擎一次能够撮合的订单。

aggTrades 数据的好处就是可以有毫秒级别的交易记录,但是又不像纯逐笔 trades (就是最原始的数据,没有按照同一价格聚合)记录那样大的数据量,是一个不错的高频数据折中方案。

一般就是准高频策略使用这样的聚合数据。那些真正的高频一般都是用 trades 以及加上 orderbook 的数据,数据量非常大,处理起来也很不方便,如果用不上就没有必要。不仅消耗资源,也增加编程的难度。

aggTrades 的用处可以是用来合成任意级别的短 k 线,例如 5、10、15 秒的短 k 线,这样的 k 线用来做一些日内交易策略也还是有可能的。

譬如下面是之前贴过的 1 秒级别 k 线。

还有高频套利,现在普通套利已经很难赚钱了,非常卷,频率高一点的话可能还有些许机会。

这种逐笔数据还可以用来合成另类的 k 线,例如等量 bar 之类的,用 aggTrades 比用分钟 k 线合成出来要精确得多,这样做出来的 CTA 策略可能和普通 k 线策略比较互补。后面几篇我可能会写如何合成这种 bar。

下面就是代码介绍(大部分代码见附件,因为太多太长,就不在正文中贴了)。下载代码是币安的例子,不过稍微有一些改动,还有就是我的加工整理代码。

这里是以月度数据为例(币安也提供了日数据)。代码都是单线程、同步执行,没有搞异步、多线程之类。因为这样的下载都是一个月或者 n 天执行一次,稍微等等就行了,用不着搞得很复杂。

基本的回测用旧一点的数据一般没有什么问题,因为高频数据回测也就主要是起到一些分析作用,主要还是得看实盘,因为滑点可能很大,或者挂单不成交,追单没追到,交易所延迟等等。

不过后面我也有下载即时数据的代码,就是下载当天的 aggTrades 数据,即时验证错过的行情。币安的日数据都是滞后几天才有的。要急着用的话,就得自己用交易所 api 爬取了。

一 下载

第一部分代码就是 agg.py 和 utility.py 两个文件,然后使用

python3 agg.py -y 2022 -m 6 -t um -folder /你的指定路径

这里就是一个下载 2022 年 6 月份的所有永续合约 aggTrades 数据的命令例子。一般十来分钟就可以下载完成。数据下载下来是压缩过的,所以下一步就是解压缩。

二 解压

解压就是使用 unzip.py 这个文件,非常短的代码,就两个函数,一个解压月度数据,一个解压日数据。

zip 文件解压出来之后是 csv 文件。csv 文件的问题是比较占硬盘,而且加载速度会比较慢。所以就是下一步,把 csv 文件转换为 pickle 文件。你可以根据自己的情况压缩和不压缩。如果你硬盘大,建议不用压缩,一般永续数据一个月大概 50GB 左右,所以看自己情况。一般可以买一个速度快一点的外置 SSD 硬盘,现在 1TB 也就几百块,早就白菜价了,回测时加载也挺快。

三 压缩转为 pickle

转换的代码就在 csv_to_pkl.py。如上所述,转换之后更容易保存使用。

转换之后我就是手动把 csv 文件删除,不然占硬盘。这一步就没有代码实现了。之前说了,都是很低频的操作,不用完全自动化。我在例子代码里使用的是 gzip 2 级压缩,一般一个月的数据压缩后也就不到 10GB。

csv 不仅占用空间,加载还慢。建议采用 pickle 格式。综合来看,它的性能不错,关键是兼容性好。如果你要用云服务器,或者很多其他开源包,比 feather 之类更兼容。

好了,到这一步数据就算准备妥当了,可以开始研究策略了。

四 即时数据下载

之前提到,因为币安的数据服务器上的数据都是滞后一两天的。如果你需要验证你的策略在当前的行情下会怎么样,而又没及时上某个币的实盘,那么可以通过下面代码下载回溯到指定时间的 aggTrades。我一般就是用来下载当前 12 小时的数据,看看策略可能的表现会怎样。

下面代码使用的话,需要修改为最近的开始时间。

下载下来的数据是这样。可以对照币安的文档,近期成交(归集)看看他们的具体意义。

有了这样的原始数据,你可以使用 df.resample(bar_size).agg() 把它们聚合成你需要的任何级别 k 线,更随心所欲。

最后

基本上这就是我之前用到的 aggTrades 数据的准备了。现在的策略是越来越卷,使用更细致的数据可以开发更多类别的策略。策略之间互补才是多策略的王道。

如果你需要以上代码,可以联系领取。
多策略组合 - 自动化实盘细节与思考(四 行情中心)接前面三篇关于程序化交易实盘代码的文章: 硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点) 量化交易系统 - 自动化实盘细节与思考(二 实盘宗旨) 量化交易系统 - 自动化实盘细节与思考(三 处理技巧) 这里再继续说说多策略交易系统,实盘代码总体架构里的行情中心。 前言 交易这个行业,特别是期货合约,每隔一段时间就会有几个高杠杆交易大神闪现,十万本金轻松翻到上千万。但是,这些人几乎都如流星划过夜空,短暂的绚烂夺目之后,就沉寂消失不见。 而另外一群长期做交易的老帮菜,整日唯唯诺诺,嘴里念叨着什么未来不可知,敬畏市场,黑天鹅随时降临之类的丧气话,同时用着很低的杠杆来回开仓试错,方向犹如墙头草,左右摇摆,一点也没有高手的决绝与勇气。但不知为何,这一帮人却一直在市场上活跃着,杠杆虽低,但是仓位还不小。 在交易世界这个人性的修罗场,明星易得,寿星难寻。 作为一名活下来的量化交易员,我认为交易中比较重要的一点,就是意识到多策略的必要性。主观交易要实现多策略还是比较难的,因为人力有限(除非像机构那样雇佣多名交易员)7*24 小时运行的市场也容易错过入场点。但是程序化交易,还是比较容易实现的。程序化失去了人脑人眼对价格走势形态的识别能力,但是执行力更强,复制策略分散仓位的能力也更强,有利有弊。 多标的多策略多参数,资金仓位自然而然就分散开来。单次盈亏不再有刺激的大开大合,而是追求资金曲线尽量平滑。 总览 下图就是我的一组实盘代码的大致架构图。 整个架构分为两块。一块是独立的行情中心,另外一块就是负责策略逻辑实现的交易程序。 通常我是以一个账号启动一个程序,它们的策略参数和账号 key 以配置文件区别,这样就可以完全共享代码,代码版本也更容易管理。策略的一些参数,可以略有不同,主要是为了错开某些操作,不用突然同时运行。 之前策略少的时候,我以每一个子策略启动一个 Python 程序,到了后期发现服务器内存不够用了。因为一个 Python 程序,光自身就占用了大概 60M 内存,如果策略多一点,再加上复制到几个账号,那么很快就会占用大量内存。虽然可以加钱上更强大的服务器,但是这样管理维护也比较麻烦。最终就改成了现在这样,以账号分,同类策略在不同的币上(多币种多参数)为一组,然后一组策略为一个 Python app。运行下来感觉这个组合模式对于多账号多策略的布局很不错,代码管理,实盘运维都很方便。 一个子策略就一个 Python app 的模式好处是,代码可以简单很多。但是,试想,如果你的策略运行到排名前 40 名的大币上,然后每个币运行 3 个不同的策略,那么就是 120 个子策略,如果再来三个账号,就是 360 个子策略,这种模式就难以为继。 app 少的时候,可以先采用 tmux 这类终端让 log 信息实时输出,在程序运行初期监控就非常方便。后期代码稳定了,再采用 pm2 这类运维软件管理。以后定期分析 log 文件就行。 多标的多策略的情况下,独立的行情中心就得是标配了。获取的各种市场信息,可以在多个交易程序之间共享,也就是上图左边的那些策略模块。 行情中心 下图是一张更详细一点的行情中心模块图。 首先,可以通过配置文件,设定需要获取的 k 线 symbols,这样以后方便更换品种。 如果是多周期的,那么可以获取它们的公约数周期 k 线,然后各个策略根据自己的需求再 resample 就可以了。 如果要简化一点,一劳永逸,那么直接获取 15 分钟的 k 线最好,因为中低频策略,特别是趋势跟随这类,周期低于 15 分钟的,长期来看基本很难赚钱。 例如,你有 15 分钟,1 小时,4 小时的策略,那么行情中心仅仅获取 15 分钟的 k 线就行了。如果 resample 之后大周期的 k 线长度不够,那么就得在启动时刻,把 15 分钟的 k 线在数据库中多保存一些。 因为 websocket 只是推送最近更新的 k 线信息,如果你的策略用到的 k 线周期比较大,而且回溯时间又长的话,例如 4 小时的 ma150,那么就是 600 个小时(25天)的数据,15 分钟一根 k 线的话,需要 2400 根。这个得靠在行情中心启动的时候,通过 rest api 一次性获取保存,作为之后不断更新的基础。 整个行情中心,我分了两个 app。其实也可以合在一个 app,但是分开更加 robust。先说次要的 PlanB。 PlanB 之前几篇文章说过,这个主要是防止 PlanA 的 websocket 掉链子的情况,用来临时备用的,特别是策略的出场时刻,避免价格都已经反向走出一段距离了,该退出仓位还没退出,造成意外的更多亏损。 PlanB 非常简单,主要就是利用 public_get_ticker_price 这个函数,一次性获取所有永续合约的最新价格。这也是B安自己聚合好的最新价格信息。 目前B安大概有 200 多个永续合约,如果一个一个单独获取最新价格的话,要保证每个品种价格 3 秒更新一次,一分钟内大概就要调用超过 4000 次 api,肯定超过限制了,不可能实现。但是前面提到的那个函数 api 权重只有 2,如果 3 秒一次,每分钟也才耗费 40 次 api quota,完全不用担心超标。 经过我的测验,基本上币安就是 1~2 秒左右聚合一次所有合约的价格,所以对于中低频策略的备用价格,5 秒左右的延迟完全够用了。 如果要求不高,你甚至可以用它来合成所有合约的粗糙 k 线,完全避开采用 websocket 的方案。这种 k 线就算不能用来交易,也可以用在诸如全市场信息扫描上,然后根据自己设计的策略算法,例如什么均线发散、收敛,简单的形态识别等等,给主观交易员提供入场信号。不然,那么多币,怎么看得过来。如果有水平高的日内交易员,这种工具可能就会有用,辅助交易。我之前就给别人写过类似工具,行情好的时候确实不错,不过最近没啥行情了。 当然,只有在交易很多币的时候这个方案才有实际用处。不然就直接获取各个品种的盘口 BBO 价格更好。 还有注意,备用价格信息也得在主代码中常常使用才行,比如用来计算仓位对应的法币资金额,大致盈亏率这类不需要很精确的数据。因为,不经常使用的代码片段和信息,早就崩坏了你可能还不知道,直到用时才发现就晚了。代码写多了的都知道,这种阑尾代码很容易意外改坏而不自知。 PlanA 行情中心的主代码。这个 app 主要有 4 个功能。 获取历史基础 k 线。就是文章前面提到的,每次启动,要保证所有策略需要的每根 k 线都在。 websocket 管理。这一个模块稍微复杂一点,需要处理各种掉线情况,还有重连等等。每次交易所推送了新的 k 线数据,就更新数据库中 k 线最新那一根 bar 的数据。 除了 k 线数据,我还把每个品种的精度信息更新也放在行情中心。也就是 public_get_exchangeinfo 这个函数获取的各种下单价格,下单数量的最小精度,再转换成方便使用的字典类型。这样所有策略可以共享。 最后就是检查,简单的 sanity check 就够了。获取的 k 线是否连续,没有遗漏,然后再定期与 rest api 获取的 k 线进行一一对比,与 PlanB 获取的价格是否差距过大等等。总之,就是多对比检查,有错误早发现。 这些大概就是我的中低频策略行情中心架构。如果需要,还可以把账号的更新信息通过 websocket 进行获取。但是这样做稍微麻烦一点,大多数时候用不到。

多策略组合 - 自动化实盘细节与思考(四 行情中心)

接前面三篇关于程序化交易实盘代码的文章:

硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点)

量化交易系统 - 自动化实盘细节与思考(二 实盘宗旨)

量化交易系统 - 自动化实盘细节与思考(三 处理技巧)

这里再继续说说多策略交易系统,实盘代码总体架构里的行情中心。

前言

交易这个行业,特别是期货合约,每隔一段时间就会有几个高杠杆交易大神闪现,十万本金轻松翻到上千万。但是,这些人几乎都如流星划过夜空,短暂的绚烂夺目之后,就沉寂消失不见。

而另外一群长期做交易的老帮菜,整日唯唯诺诺,嘴里念叨着什么未来不可知,敬畏市场,黑天鹅随时降临之类的丧气话,同时用着很低的杠杆来回开仓试错,方向犹如墙头草,左右摇摆,一点也没有高手的决绝与勇气。但不知为何,这一帮人却一直在市场上活跃着,杠杆虽低,但是仓位还不小。

在交易世界这个人性的修罗场,明星易得,寿星难寻。

作为一名活下来的量化交易员,我认为交易中比较重要的一点,就是意识到多策略的必要性。主观交易要实现多策略还是比较难的,因为人力有限(除非像机构那样雇佣多名交易员)7*24 小时运行的市场也容易错过入场点。但是程序化交易,还是比较容易实现的。程序化失去了人脑人眼对价格走势形态的识别能力,但是执行力更强,复制策略分散仓位的能力也更强,有利有弊。

多标的多策略多参数,资金仓位自然而然就分散开来。单次盈亏不再有刺激的大开大合,而是追求资金曲线尽量平滑。

总览

下图就是我的一组实盘代码的大致架构图。

整个架构分为两块。一块是独立的行情中心,另外一块就是负责策略逻辑实现的交易程序。

通常我是以一个账号启动一个程序,它们的策略参数和账号 key 以配置文件区别,这样就可以完全共享代码,代码版本也更容易管理。策略的一些参数,可以略有不同,主要是为了错开某些操作,不用突然同时运行。

之前策略少的时候,我以每一个子策略启动一个 Python 程序,到了后期发现服务器内存不够用了。因为一个 Python 程序,光自身就占用了大概 60M 内存,如果策略多一点,再加上复制到几个账号,那么很快就会占用大量内存。虽然可以加钱上更强大的服务器,但是这样管理维护也比较麻烦。最终就改成了现在这样,以账号分,同类策略在不同的币上(多币种多参数)为一组,然后一组策略为一个 Python app。运行下来感觉这个组合模式对于多账号多策略的布局很不错,代码管理,实盘运维都很方便。

一个子策略就一个 Python app 的模式好处是,代码可以简单很多。但是,试想,如果你的策略运行到排名前 40 名的大币上,然后每个币运行 3 个不同的策略,那么就是 120 个子策略,如果再来三个账号,就是 360 个子策略,这种模式就难以为继。

app 少的时候,可以先采用 tmux 这类终端让 log 信息实时输出,在程序运行初期监控就非常方便。后期代码稳定了,再采用 pm2 这类运维软件管理。以后定期分析 log 文件就行。

多标的多策略的情况下,独立的行情中心就得是标配了。获取的各种市场信息,可以在多个交易程序之间共享,也就是上图左边的那些策略模块。

行情中心

下图是一张更详细一点的行情中心模块图。

首先,可以通过配置文件,设定需要获取的 k 线 symbols,这样以后方便更换品种。

如果是多周期的,那么可以获取它们的公约数周期 k 线,然后各个策略根据自己的需求再 resample 就可以了。

如果要简化一点,一劳永逸,那么直接获取 15 分钟的 k 线最好,因为中低频策略,特别是趋势跟随这类,周期低于 15 分钟的,长期来看基本很难赚钱。

例如,你有 15 分钟,1 小时,4 小时的策略,那么行情中心仅仅获取 15 分钟的 k 线就行了。如果 resample 之后大周期的 k 线长度不够,那么就得在启动时刻,把 15 分钟的 k 线在数据库中多保存一些。

因为 websocket 只是推送最近更新的 k 线信息,如果你的策略用到的 k 线周期比较大,而且回溯时间又长的话,例如 4 小时的 ma150,那么就是 600 个小时(25天)的数据,15 分钟一根 k 线的话,需要 2400 根。这个得靠在行情中心启动的时候,通过 rest api 一次性获取保存,作为之后不断更新的基础。

整个行情中心,我分了两个 app。其实也可以合在一个 app,但是分开更加 robust。先说次要的 PlanB。

PlanB

之前几篇文章说过,这个主要是防止 PlanA 的 websocket 掉链子的情况,用来临时备用的,特别是策略的出场时刻,避免价格都已经反向走出一段距离了,该退出仓位还没退出,造成意外的更多亏损。

PlanB 非常简单,主要就是利用 public_get_ticker_price 这个函数,一次性获取所有永续合约的最新价格。这也是B安自己聚合好的最新价格信息。

目前B安大概有 200 多个永续合约,如果一个一个单独获取最新价格的话,要保证每个品种价格 3 秒更新一次,一分钟内大概就要调用超过 4000 次 api,肯定超过限制了,不可能实现。但是前面提到的那个函数 api 权重只有 2,如果 3 秒一次,每分钟也才耗费 40 次 api quota,完全不用担心超标。

经过我的测验,基本上币安就是 1~2 秒左右聚合一次所有合约的价格,所以对于中低频策略的备用价格,5 秒左右的延迟完全够用了。

如果要求不高,你甚至可以用它来合成所有合约的粗糙 k 线,完全避开采用 websocket 的方案。这种 k 线就算不能用来交易,也可以用在诸如全市场信息扫描上,然后根据自己设计的策略算法,例如什么均线发散、收敛,简单的形态识别等等,给主观交易员提供入场信号。不然,那么多币,怎么看得过来。如果有水平高的日内交易员,这种工具可能就会有用,辅助交易。我之前就给别人写过类似工具,行情好的时候确实不错,不过最近没啥行情了。

当然,只有在交易很多币的时候这个方案才有实际用处。不然就直接获取各个品种的盘口 BBO 价格更好。

还有注意,备用价格信息也得在主代码中常常使用才行,比如用来计算仓位对应的法币资金额,大致盈亏率这类不需要很精确的数据。因为,不经常使用的代码片段和信息,早就崩坏了你可能还不知道,直到用时才发现就晚了。代码写多了的都知道,这种阑尾代码很容易意外改坏而不自知。

PlanA

行情中心的主代码。这个 app 主要有 4 个功能。

获取历史基础 k 线。就是文章前面提到的,每次启动,要保证所有策略需要的每根 k 线都在。

websocket 管理。这一个模块稍微复杂一点,需要处理各种掉线情况,还有重连等等。每次交易所推送了新的 k 线数据,就更新数据库中 k 线最新那一根 bar 的数据。

除了 k 线数据,我还把每个品种的精度信息更新也放在行情中心。也就是 public_get_exchangeinfo 这个函数获取的各种下单价格,下单数量的最小精度,再转换成方便使用的字典类型。这样所有策略可以共享。

最后就是检查,简单的 sanity check 就够了。获取的 k 线是否连续,没有遗漏,然后再定期与 rest api 获取的 k 线进行一一对比,与 PlanB 获取的价格是否差距过大等等。总之,就是多对比检查,有错误早发现。

这些大概就是我的中低频策略行情中心架构。如果需要,还可以把账号的更新信息通过 websocket 进行获取。但是这样做稍微麻烦一点,大多数时候用不到。
查看原文
Expertise is knowing which mistakes to not make. - Taleb 专业知识就是知道那些错误不要犯 - 塔勒布
Expertise is knowing which mistakes to not make. - Taleb

专业知识就是知道那些错误不要犯 - 塔勒布
前段时间试了一把用莱特币充值量化交易的服务器费用。纯粹是为了实验。滑点还真不大。数字货币大有可为!
前段时间试了一把用莱特币充值量化交易的服务器费用。纯粹是为了实验。滑点还真不大。数字货币大有可为!
量化交易系统 - 自动化实盘细节与思考(三 处理技巧)接前面两篇关于程序化交易实盘注意事项的文章: 硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点) 量化交易系统 - 自动化实盘细节与思考(二 实盘宗旨) 这里再继续说说一些代码设计上的细节处理技巧。 数据库 前两篇讲过,复杂一点的策略组合的状态记录很重要,需要用到数据库。 其实,大多数编程业务都可以被归纳为 CRUD 类别,也就是核心流程就是对数据库的增删改查罢了。交易代码也不例外。中低频的二级市场交易行为,其实和大家去某宝购物区别不大,都是买卖,自动化交易的实现重点就在对策略状态的管理上。 如果你不是已经用熟了 SQL 这种关系型数据库,那么建议你直接学习使用 Redis 这类 NoSQL 内存性数据库。它的优点就是上手简单,性能卓越,天生单线程,不用去考虑读写的时候需要锁住数据之类的底层操作。不过缺点就是没有主键,不能自动实现编号自增之类的功能。需要的话,得自己写代码实现。不过这个功能,我自己从事自动化交易这么久时间,也没有怎么用到过。 还有一个不重要的问题就是,内存数据库,如果需要存的数据量比较大的话,那么服务器内存就得大一点,不过一般的量化交易实盘,4G,甚至 2G 内存都已经足够了,用不着保存那么多数据。 Redis 在实盘中的功能真的很强大,如果你的策略有一点高频的需求,它还能实现 pub/sub 的消息订阅模式,用不着再加入额外的各种 MQ 模块。如果使用 MySQL 这种关系型数据库,就像前面提到的那样,只要不是之前已经上手实战过了,那么就得再投入时间精力学习一门比较恶心难懂的编程语言 SQL。注意,大家是来做量化交易的,不是来学习写代码的,尽量采用简单一点的方案。 另外,如果要做行情中心,考虑到性能,也是采用 Redis 数据库,再配合消息队列方便。方案简单,适用绝大多数场景。一台服务器(或者多台)都能用上。 代码设计 基本上,写代码,核心数据结构最重要。数据结构设计不够合理,代码会怎么写怎么别扭,因为会导致各个模块之间无法避免地耦合在一起,修改起来很麻烦。但是要设计合理,就得有点交易经验了,也就是业务经验。这些都是关于怎么写代码的了,没啥说头。每个人的策略也不一样,不能等同对待。不过,有些道理大概是相通的。 举个例子,单子提交之后,是不能保证成功的,就算是市价单也一样,因为有可能被交易所拒绝。例如交易所太忙,或者临时网络数据掉包之类。那么,最好设计一些二阶段提交(2 Phase Commit)类似的中间态,不成功就一直 try(当然不能太高频率,不然超过限制被 ban,有专门 retry decorator 干这事),或者再加入多次矫正错误状态的方法。 一般情况下,就算交易所宕机了,短时间都会恢复。不恢复,那么总有一方是完全挂了,不是交易所,就是你自己的代码服务器。这点得做好监控,告警。自动化代码是不可能面面俱到的,真不能自动处理了就发出告警,人工介入吧。人工没有及时处理,只要不继续开仓增加敞口,问题就不会太大,因为还有算法止损单兜底。 下面是我自己梳理的一个策略开仓逻辑: 基本上,画一个类似的流程图,代码写起来就会有条理得多,潜在 bug 也会减少。所以,写代码前,最好先画流程图,或者边写边梳理,这样才会逻辑清晰,心中有数。 关仓逻辑比这个复杂很多,因为关仓的条件也多一些,止盈止损,各种策略退场信号,都会触发平仓。总之,出场的重要性是高于入场的,实盘上也麻烦一点。 因为大家策略逻辑肯定不一样,这里也就不多说了。主要就是理顺你的策略逻辑,防止各种可能错误的发生。 但是,这些也就看着复杂而已,不过都是一堆 if else 罢了(Python 连 switch 语句都没有)。符合条件,就进行下一步,不行就退出,没啥大的问题。 时间控制 做交易,时间点的掌握毫无疑问非常重要。这里再分享一点我的时间控制技巧。 一般编程,如果有需要定时执行的任务,那么通常采用诸如 apscheduler 这样的 cron job package。例如计划整点时刻一到就检测 k 线价格是否需要开仓、关仓的定时任务。 这种包其实就是在设定的时间(可以精确到秒级),立马新开一个线程,然后执行指定的任务,问题就是如果这个任务执行时间太长,那么下一个任务又接着开始,这时就会有问题,虽然可以解决,但是比较麻烦。 我一般是在需要定时输出 log 信息,程序自纠自检的时候使用这样的定时任务,也就是一些低频而又可以快速完成的功能。这些功能都是对数据库里的数据只读,没有写、更新操作,所以让 apscheduler 另开线程处理也无妨。 然而,那种需要不断较高频率查询市场价格,或者本地策略状态的逻辑,就不适合这样的定时包,需要采用 while 循环来控制。 比如策略使用了 k 线的 bar 内信号,就意味着信号可能随时会出现,就需要不停地检查标的价格或者交易量,判断是否需要执行相应的操作。如果这个时候你还需要比较精确的时间控制,例如只在 k 线整点结束前 10 秒才执行开仓的系列逻辑。那么如何简单判断是最后 10 秒呢? 我是通过使用时间 timestamp 对 3600 取余数。 (如果你不熟悉计算机上的 timestamp,也就是时间戳,它是从格林威治标准时间 1970.1.1 开始算起,比如现在大概是第 1691240298 秒,电脑上准确到微秒级都没有问题。) 对 3600 取余之后,如果余数大于 3590 秒就是最后十秒了。误差可以到毫秒级别。之前讲过,主要交易操作最好是在一个线程里,顺序执行,那么就可以通过这样的方式来大致控制执行的时间,或者模糊一点,时间段,这样就更没问题了。 这种控制,需要你自己服务器的时间设置与标准时间误差不大就行。不过这种控制也不会非常精确,只能到秒级吧。但是 Python 里本来就不能非常精确控制时间,那些 sleep 函数都会导致大概微秒级误差的。 减少 API 访问频率 如果已经采用了基于 websocket 的独立行情中心,在不同策略,甚至不同交易代码之间共享 k 线这类市场公开信息,那么在这方面就没有 API 频率限制的顾虑。 但是我们还需要及时获取账户信息,也就是资金、仓位、订单这三类信息。账户信息虽然也可以使用 websocket,等待交易所服务器主动推送过来,但是,因为三点原因,还是直接采用 rest api 比较简单一点。 第一,websocket 推送的账户信息,交易所为了减轻负担,要求每隔一段时间就得重新链接或者更新 listenKey(币安是60分钟)。这种情况显然维护比较麻烦。虽然也没有麻烦多少,但是如果做了 API 托管,同时交易多个账户,那么就得又启用单独的程序来保证信息的即时准确,逻辑复杂了不少。 第二,有的交易所并没有账户信息更新的 websocket 推送,这样的话,交易逻辑不通用,实盘代码在不同交易所之间切换更麻烦。当然,一般人不会交易多个交易所,碰不到这样的情况。 第三,websocket 如果链接断了,或者遇到前面讲的 listenKey 更新,或者到期之类的问题,如果程序没有及时发现,而这个时候恰好又有交易,那么如果仅仅依赖 websocket,就会造成比较大的问题,因为错过的账户更新信息不会再次推送。要规避这类潜在问题发生的可能性,也得依赖 rest api 获取确定的账户信息。那么最后总得依赖 rest api,岂不是多此一举? 综上,对于中低频交易,还不如直接采用 rest api 获取账户信息。重要数据源,最好奉行 SSOT(Single Source Of Truth 可信单一数据源),不然可能造成潜在混乱,这个概念可以自行谷歌,在依靠数据处理的编程中非常有用。 那么,如果只采用 rest api 获取账户信息,可以在本地代码内存里维护一个临时账户信息表,特别是可用资金,这样可以减少频繁访问交易所,关键是快,可以把单子一次性都发出去,类似批量下单,然后再慢慢处理更新后面的逻辑,下单快了,滑点自然就小一点。 另外,要判断算法止损单是否成交,可以使用近期的 high low 价格,而不是直接去获取挂单的状态,因为判断单子是否成交,需要不断去 poll,比较频繁,会造成很多无效 api 访问。而 websocket 的 k 线价格更新是非常及时的,而且不占用 api 频率限制。 同理,一些退场单子也可以如此。如果你的退场信号是依靠 bar 内的价格,那么采用近期 high low 价格可能更好。因为有的时候价格触发了,又会立即回归,如果你的检查频率不是太高,那么就有可能错过。为了保证交易策略的一致性,检查 high low 这样的价格就不会错过。这样处理还有额外好处,就是实际成交价格可能会更有利,相比于真正的触发价格。 不知道上面两点容不容易理解。可能需要一点实盘经验才行。 分享一点自己实盘代码开发中的心得体会,希望对大家有所帮助。

量化交易系统 - 自动化实盘细节与思考(三 处理技巧)

接前面两篇关于程序化交易实盘注意事项的文章:

硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点)

量化交易系统 - 自动化实盘细节与思考(二 实盘宗旨)

这里再继续说说一些代码设计上的细节处理技巧。

数据库

前两篇讲过,复杂一点的策略组合的状态记录很重要,需要用到数据库。

其实,大多数编程业务都可以被归纳为 CRUD 类别,也就是核心流程就是对数据库的增删改查罢了。交易代码也不例外。中低频的二级市场交易行为,其实和大家去某宝购物区别不大,都是买卖,自动化交易的实现重点就在对策略状态的管理上。

如果你不是已经用熟了 SQL 这种关系型数据库,那么建议你直接学习使用 Redis 这类 NoSQL 内存性数据库。它的优点就是上手简单,性能卓越,天生单线程,不用去考虑读写的时候需要锁住数据之类的底层操作。不过缺点就是没有主键,不能自动实现编号自增之类的功能。需要的话,得自己写代码实现。不过这个功能,我自己从事自动化交易这么久时间,也没有怎么用到过。

还有一个不重要的问题就是,内存数据库,如果需要存的数据量比较大的话,那么服务器内存就得大一点,不过一般的量化交易实盘,4G,甚至 2G 内存都已经足够了,用不着保存那么多数据。

Redis 在实盘中的功能真的很强大,如果你的策略有一点高频的需求,它还能实现 pub/sub 的消息订阅模式,用不着再加入额外的各种 MQ 模块。如果使用 MySQL 这种关系型数据库,就像前面提到的那样,只要不是之前已经上手实战过了,那么就得再投入时间精力学习一门比较恶心难懂的编程语言 SQL。注意,大家是来做量化交易的,不是来学习写代码的,尽量采用简单一点的方案。

另外,如果要做行情中心,考虑到性能,也是采用 Redis 数据库,再配合消息队列方便。方案简单,适用绝大多数场景。一台服务器(或者多台)都能用上。

代码设计

基本上,写代码,核心数据结构最重要。数据结构设计不够合理,代码会怎么写怎么别扭,因为会导致各个模块之间无法避免地耦合在一起,修改起来很麻烦。但是要设计合理,就得有点交易经验了,也就是业务经验。这些都是关于怎么写代码的了,没啥说头。每个人的策略也不一样,不能等同对待。不过,有些道理大概是相通的。

举个例子,单子提交之后,是不能保证成功的,就算是市价单也一样,因为有可能被交易所拒绝。例如交易所太忙,或者临时网络数据掉包之类。那么,最好设计一些二阶段提交(2 Phase Commit)类似的中间态,不成功就一直 try(当然不能太高频率,不然超过限制被 ban,有专门 retry decorator 干这事),或者再加入多次矫正错误状态的方法。

一般情况下,就算交易所宕机了,短时间都会恢复。不恢复,那么总有一方是完全挂了,不是交易所,就是你自己的代码服务器。这点得做好监控,告警。自动化代码是不可能面面俱到的,真不能自动处理了就发出告警,人工介入吧。人工没有及时处理,只要不继续开仓增加敞口,问题就不会太大,因为还有算法止损单兜底。

下面是我自己梳理的一个策略开仓逻辑:

基本上,画一个类似的流程图,代码写起来就会有条理得多,潜在 bug 也会减少。所以,写代码前,最好先画流程图,或者边写边梳理,这样才会逻辑清晰,心中有数。

关仓逻辑比这个复杂很多,因为关仓的条件也多一些,止盈止损,各种策略退场信号,都会触发平仓。总之,出场的重要性是高于入场的,实盘上也麻烦一点。

因为大家策略逻辑肯定不一样,这里也就不多说了。主要就是理顺你的策略逻辑,防止各种可能错误的发生。

但是,这些也就看着复杂而已,不过都是一堆 if else 罢了(Python 连 switch 语句都没有)。符合条件,就进行下一步,不行就退出,没啥大的问题。

时间控制

做交易,时间点的掌握毫无疑问非常重要。这里再分享一点我的时间控制技巧。

一般编程,如果有需要定时执行的任务,那么通常采用诸如 apscheduler 这样的 cron job package。例如计划整点时刻一到就检测 k 线价格是否需要开仓、关仓的定时任务。

这种包其实就是在设定的时间(可以精确到秒级),立马新开一个线程,然后执行指定的任务,问题就是如果这个任务执行时间太长,那么下一个任务又接着开始,这时就会有问题,虽然可以解决,但是比较麻烦。

我一般是在需要定时输出 log 信息,程序自纠自检的时候使用这样的定时任务,也就是一些低频而又可以快速完成的功能。这些功能都是对数据库里的数据只读,没有写、更新操作,所以让 apscheduler 另开线程处理也无妨。

然而,那种需要不断较高频率查询市场价格,或者本地策略状态的逻辑,就不适合这样的定时包,需要采用 while 循环来控制。

比如策略使用了 k 线的 bar 内信号,就意味着信号可能随时会出现,就需要不停地检查标的价格或者交易量,判断是否需要执行相应的操作。如果这个时候你还需要比较精确的时间控制,例如只在 k 线整点结束前 10 秒才执行开仓的系列逻辑。那么如何简单判断是最后 10 秒呢?

我是通过使用时间 timestamp 对 3600 取余数。

(如果你不熟悉计算机上的 timestamp,也就是时间戳,它是从格林威治标准时间 1970.1.1 开始算起,比如现在大概是第 1691240298 秒,电脑上准确到微秒级都没有问题。)

对 3600 取余之后,如果余数大于 3590 秒就是最后十秒了。误差可以到毫秒级别。之前讲过,主要交易操作最好是在一个线程里,顺序执行,那么就可以通过这样的方式来大致控制执行的时间,或者模糊一点,时间段,这样就更没问题了。

这种控制,需要你自己服务器的时间设置与标准时间误差不大就行。不过这种控制也不会非常精确,只能到秒级吧。但是 Python 里本来就不能非常精确控制时间,那些 sleep 函数都会导致大概微秒级误差的。

减少 API 访问频率

如果已经采用了基于 websocket 的独立行情中心,在不同策略,甚至不同交易代码之间共享 k 线这类市场公开信息,那么在这方面就没有 API 频率限制的顾虑。

但是我们还需要及时获取账户信息,也就是资金、仓位、订单这三类信息。账户信息虽然也可以使用 websocket,等待交易所服务器主动推送过来,但是,因为三点原因,还是直接采用 rest api 比较简单一点。

第一,websocket 推送的账户信息,交易所为了减轻负担,要求每隔一段时间就得重新链接或者更新 listenKey(币安是60分钟)。这种情况显然维护比较麻烦。虽然也没有麻烦多少,但是如果做了 API 托管,同时交易多个账户,那么就得又启用单独的程序来保证信息的即时准确,逻辑复杂了不少。

第二,有的交易所并没有账户信息更新的 websocket 推送,这样的话,交易逻辑不通用,实盘代码在不同交易所之间切换更麻烦。当然,一般人不会交易多个交易所,碰不到这样的情况。

第三,websocket 如果链接断了,或者遇到前面讲的 listenKey 更新,或者到期之类的问题,如果程序没有及时发现,而这个时候恰好又有交易,那么如果仅仅依赖 websocket,就会造成比较大的问题,因为错过的账户更新信息不会再次推送。要规避这类潜在问题发生的可能性,也得依赖 rest api 获取确定的账户信息。那么最后总得依赖 rest api,岂不是多此一举?

综上,对于中低频交易,还不如直接采用 rest api 获取账户信息。重要数据源,最好奉行 SSOT(Single Source Of Truth 可信单一数据源),不然可能造成潜在混乱,这个概念可以自行谷歌,在依靠数据处理的编程中非常有用。

那么,如果只采用 rest api 获取账户信息,可以在本地代码内存里维护一个临时账户信息表,特别是可用资金,这样可以减少频繁访问交易所,关键是快,可以把单子一次性都发出去,类似批量下单,然后再慢慢处理更新后面的逻辑,下单快了,滑点自然就小一点。

另外,要判断算法止损单是否成交,可以使用近期的 high low 价格,而不是直接去获取挂单的状态,因为判断单子是否成交,需要不断去 poll,比较频繁,会造成很多无效 api 访问。而 websocket 的 k 线价格更新是非常及时的,而且不占用 api 频率限制。

同理,一些退场单子也可以如此。如果你的退场信号是依靠 bar 内的价格,那么采用近期 high low 价格可能更好。因为有的时候价格触发了,又会立即回归,如果你的检查频率不是太高,那么就有可能错过。为了保证交易策略的一致性,检查 high low 这样的价格就不会错过。这样处理还有额外好处,就是实际成交价格可能会更有利,相比于真正的触发价格。

不知道上面两点容不容易理解。可能需要一点实盘经验才行。

分享一点自己实盘代码开发中的心得体会,希望对大家有所帮助。
最近市场主流币没有大一点的波动,CTA 不断回撤中,有的朋友交易策略都开始缩仓了😂 不容易啊 坚持一下,行情可能近在眼前 ------------------------------------------------ 欢迎关注本号,专注中长线量化趋势策略
最近市场主流币没有大一点的波动,CTA 不断回撤中,有的朋友交易策略都开始缩仓了😂

不容易啊

坚持一下,行情可能近在眼前

------------------------------------------------

欢迎关注本号,专注中长线量化趋势策略
量化交易系统 - 自动化实盘细节与思考(二 实盘宗旨)前一篇硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点)讲了一点币圈实盘的基本难题。这一篇说说实盘的主要宗旨。 我认为主要有四个: 一. 贯彻策略的既定逻辑 这一点毋庸置疑。在有信号的时候必须做出相应的操作,开仓,平仓。这一点就要求尽量不要用限价单,不然成交不了还得追单,可能价格都已经飞远了,最后到底要不要追也是个问题。 长期来看,采用市价单产生的滑点和偶尔错过限价单,但又追单产生的滑点总量大致类似,所以还不如直接市价进出场,除非你的策略很特殊。 另外,使用限价单的话,你的代码更复杂,因为要管理没有成交的限价单,再去追单。还有如果限价单只成交了一部分又怎么办?是余下的限价单一直挂着呢?还是错过部分再另外发市价单?这种一步操作却又产生多笔成交订单,后期复盘也麻烦,容易搞混。所以,不如直接用市价单算了,只要提交成功,基本上就会保证成交。如果确实是滑点敏感的策略,那么只做流动性好的标的吧。 还有,合约的话,杠杆也不要随意变动,最好是回测的理想杠杆再打八折。不要人为主观去预测行情,手动调整杠杆。仓位变来变去也是自动化交易的大忌。 仓位最好是自动赢冲输缩,回撤到一定程度就要降低杠杆,而不要反其道而行之,以为马上风就要来了,加大杠杆(不过可以加本金、降杠杆)。账户活命最重要,先求不败。可以等资金曲线度过回撤期,再加回杠杆。不过如果是采用复利模式,就已经是简单的自动赢冲输缩了。 二. 尽量减少滑点 这点前一篇已经说了。滑点是消除不了的,只能缓解。这需要你能在第一时间获取市场价格信息,交易所账号里的各种资金、仓位信息,才能做到快速反应。 实盘总体架构上,子策略多,又要求获取各类信息及时,就要有一个专门的 websocket 行情中心来分担任务。再配一个 Restful 的 Plan B 行情中心做备份。这样万一 websocket 掉线连接不上的时候,还有一个比较新的价格来判断是否需要离场。跑路的时候要快,宁愿跑错,也比被堵在里面,不知未来如何要强。 三. 长久运行 这一点前一篇也已经说过。币圈是 7*24 运行,你的代码是不能停机的。这就要求代码不会被抛出的各种异常中断,得有处理各种意外情况的代码。还有不能带有内存泄露这种 bug,不然时间长了,程序会崩溃,甚至整个服务器都被拖垮。好在 Python 不容易导致这类问题,它有内存自动回收机制。实在不行,每天或者几天手动重启一下交易程序也可以,反正都是中低频交易。这些都是基本的后端代码开发要求,容易达成。 一般量化交易都是采用 Python。Python 这种脚本语言一大特点就是动态编译,运行效率稍低,因为一边编译一边执行(不过完全不会影响到中低频交易)不容易调试。如果代码逻辑上暗含问题,可能不太容易被发现。 譬如有 100 行代码,第99 行有问题,但是每次都只运行到 95 行,那这个问题就不会被发现,因为必须运行到第 99 行,触发了相关代码,才能发现错误,但是这时候可能为时已晚,程序会直接崩溃,如果你没有 try catch exception 的话。 另外一个特点,其实已经包含在上面提到的问题里了。因为 Python 算是强类型,很少隐式转换类型。如果你太信任服务器传来的数据类型,特别是那些数字,那么很可能会吃亏,因为有的时候数字会变成字符串。交易所不同的币种,不同 API 版本,websocket 和 rest 传来的同一种返回数据,都有可能是不同类型。所以原则上,每次都必须强制转型一下,或者先判断需不需要转。 还有就是,各个策略之间开关仓不要搞混了,特别是一个币种的,做好隔离。不然在一些极端行情下,a 策略把 b 策略的仓位平了,最后导致对不上,可能得停掉实盘再重新开局,这样就不连贯了,也可能错过关键行情。 一句话,一切为了实盘的长期全自动化无干预运行。 然而,如果策略太过复杂,要做到完全无需干预,也不是那么容易的。简化策略也是一个入手点,别搞太复杂了。例如少用 OBV 这类信号,因为 OBV 需要追溯很久远的价量信息,实盘需要维护太多数据了,每次中断,重启都是一个麻烦事。不得已,避免这样的因子。 四. 风控 这点是实盘要求的重中之重。 其中最危险的,莫过于不能平仓。行情反向了,而且还在继续暴走,结果你的出场代码失控,不管什么原因,不止损平仓了。在币圈,山寨币短时间内是可能涨几倍的。所以,在做空的情况下,就算你没有使用杠杆,还半仓,自以为高枕无忧,结果早上起来仓位可能已经爆干净了。 所以,要保证退出机制一定生效。开仓机会如果错过至少不会致命,踏空了顶多惋惜,但是错过平仓是要出大问题的。 这里简单说两个解决方案,后面有空再详细讲讲。 第一点,就是最好要有一个硬止损,就是类似固定亏损比例的止损。例如,大币亏损超过 10%,小币 15%,发生了立马平仓跑路。 硬止损这种方法在开仓时刻就应该定下止损价位了。所以开仓后应尽快提交算法止损单(有的也叫条件单),中途无须更改价格。这样交易所帮你负责监控实时价格,触发之后再帮你提交市价单退场。这样处理可能会有不少滑点,但是大概率比你自己搞的止损稳定可靠,而且就算出问题了,没有触发,你还可能找交易所维权索赔(所以得去头部大交易所)。 当然,这种止损就是用来兜底的,应该极少触发才对,最好还是由自己的策略来控制出场时机,这样回撤大概更小。 第二点,程序不会乱开仓。不要已经开了仓,但是却以为没有,连续开仓,结果开出一个很大敞口。短时间内价格没有波动还好,还有可能手动介入纠正,要是突然反向,就可能爆仓的,这取决于你到底开出了多少仓位。当然这种是低级错误,但是确实可能发生。特别是中途迭代升级了代码之后,有可能考虑不周。 这种就需要先放慢一点开仓的节奏,必须等待开仓结果的返回。还有开仓前一定要查询确认当时的账户信息,不要连续开仓,当然也可以在本地记录所有操作,那么就省却一点查询交易所自己账号情况的 API 请求次数和时间。 还有,更有效的是,可以事先限制交易所的最大杠杆。这个是可以自己调整的。币安默认 20 倍,你改为 3 倍,甚至 2 倍(当然,这要求你策略本身就不使用高杠杠,不然你该开高点的时候还开不出来)。那么代码再怎么发神经,也不可能在你睡觉的时候搞出来一个大敞口。这样就比较稳妥。 总之,实盘有时候不光是交易代码,还需要布局一道道其他防线,防止被黑天鹅事件一下击穿。任何时候都不能掉以轻心,尽量封住死角。

量化交易系统 - 自动化实盘细节与思考(二 实盘宗旨)

前一篇硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点)讲了一点币圈实盘的基本难题。这一篇说说实盘的主要宗旨。

我认为主要有四个:

一. 贯彻策略的既定逻辑

这一点毋庸置疑。在有信号的时候必须做出相应的操作,开仓,平仓。这一点就要求尽量不要用限价单,不然成交不了还得追单,可能价格都已经飞远了,最后到底要不要追也是个问题。

长期来看,采用市价单产生的滑点和偶尔错过限价单,但又追单产生的滑点总量大致类似,所以还不如直接市价进出场,除非你的策略很特殊。

另外,使用限价单的话,你的代码更复杂,因为要管理没有成交的限价单,再去追单。还有如果限价单只成交了一部分又怎么办?是余下的限价单一直挂着呢?还是错过部分再另外发市价单?这种一步操作却又产生多笔成交订单,后期复盘也麻烦,容易搞混。所以,不如直接用市价单算了,只要提交成功,基本上就会保证成交。如果确实是滑点敏感的策略,那么只做流动性好的标的吧。

还有,合约的话,杠杆也不要随意变动,最好是回测的理想杠杆再打八折。不要人为主观去预测行情,手动调整杠杆。仓位变来变去也是自动化交易的大忌。

仓位最好是自动赢冲输缩,回撤到一定程度就要降低杠杆,而不要反其道而行之,以为马上风就要来了,加大杠杆(不过可以加本金、降杠杆)。账户活命最重要,先求不败。可以等资金曲线度过回撤期,再加回杠杆。不过如果是采用复利模式,就已经是简单的自动赢冲输缩了。

二. 尽量减少滑点

这点前一篇已经说了。滑点是消除不了的,只能缓解。这需要你能在第一时间获取市场价格信息,交易所账号里的各种资金、仓位信息,才能做到快速反应。

实盘总体架构上,子策略多,又要求获取各类信息及时,就要有一个专门的 websocket 行情中心来分担任务。再配一个 Restful 的 Plan B 行情中心做备份。这样万一 websocket 掉线连接不上的时候,还有一个比较新的价格来判断是否需要离场。跑路的时候要快,宁愿跑错,也比被堵在里面,不知未来如何要强。

三. 长久运行

这一点前一篇也已经说过。币圈是 7*24 运行,你的代码是不能停机的。这就要求代码不会被抛出的各种异常中断,得有处理各种意外情况的代码。还有不能带有内存泄露这种 bug,不然时间长了,程序会崩溃,甚至整个服务器都被拖垮。好在 Python 不容易导致这类问题,它有内存自动回收机制。实在不行,每天或者几天手动重启一下交易程序也可以,反正都是中低频交易。这些都是基本的后端代码开发要求,容易达成。

一般量化交易都是采用 Python。Python 这种脚本语言一大特点就是动态编译,运行效率稍低,因为一边编译一边执行(不过完全不会影响到中低频交易)不容易调试。如果代码逻辑上暗含问题,可能不太容易被发现。 譬如有 100 行代码,第99 行有问题,但是每次都只运行到 95 行,那这个问题就不会被发现,因为必须运行到第 99 行,触发了相关代码,才能发现错误,但是这时候可能为时已晚,程序会直接崩溃,如果你没有 try catch exception 的话。

另外一个特点,其实已经包含在上面提到的问题里了。因为 Python 算是强类型,很少隐式转换类型。如果你太信任服务器传来的数据类型,特别是那些数字,那么很可能会吃亏,因为有的时候数字会变成字符串。交易所不同的币种,不同 API 版本,websocket 和 rest 传来的同一种返回数据,都有可能是不同类型。所以原则上,每次都必须强制转型一下,或者先判断需不需要转。

还有就是,各个策略之间开关仓不要搞混了,特别是一个币种的,做好隔离。不然在一些极端行情下,a 策略把 b 策略的仓位平了,最后导致对不上,可能得停掉实盘再重新开局,这样就不连贯了,也可能错过关键行情。

一句话,一切为了实盘的长期全自动化无干预运行。

然而,如果策略太过复杂,要做到完全无需干预,也不是那么容易的。简化策略也是一个入手点,别搞太复杂了。例如少用 OBV 这类信号,因为 OBV 需要追溯很久远的价量信息,实盘需要维护太多数据了,每次中断,重启都是一个麻烦事。不得已,避免这样的因子。

四. 风控

这点是实盘要求的重中之重。

其中最危险的,莫过于不能平仓。行情反向了,而且还在继续暴走,结果你的出场代码失控,不管什么原因,不止损平仓了。在币圈,山寨币短时间内是可能涨几倍的。所以,在做空的情况下,就算你没有使用杠杆,还半仓,自以为高枕无忧,结果早上起来仓位可能已经爆干净了。

所以,要保证退出机制一定生效。开仓机会如果错过至少不会致命,踏空了顶多惋惜,但是错过平仓是要出大问题的。

这里简单说两个解决方案,后面有空再详细讲讲。

第一点,就是最好要有一个硬止损,就是类似固定亏损比例的止损。例如,大币亏损超过 10%,小币 15%,发生了立马平仓跑路。

硬止损这种方法在开仓时刻就应该定下止损价位了。所以开仓后应尽快提交算法止损单(有的也叫条件单),中途无须更改价格。这样交易所帮你负责监控实时价格,触发之后再帮你提交市价单退场。这样处理可能会有不少滑点,但是大概率比你自己搞的止损稳定可靠,而且就算出问题了,没有触发,你还可能找交易所维权索赔(所以得去头部大交易所)。

当然,这种止损就是用来兜底的,应该极少触发才对,最好还是由自己的策略来控制出场时机,这样回撤大概更小。

第二点,程序不会乱开仓。不要已经开了仓,但是却以为没有,连续开仓,结果开出一个很大敞口。短时间内价格没有波动还好,还有可能手动介入纠正,要是突然反向,就可能爆仓的,这取决于你到底开出了多少仓位。当然这种是低级错误,但是确实可能发生。特别是中途迭代升级了代码之后,有可能考虑不周。

这种就需要先放慢一点开仓的节奏,必须等待开仓结果的返回。还有开仓前一定要查询确认当时的账户信息,不要连续开仓,当然也可以在本地记录所有操作,那么就省却一点查询交易所自己账号情况的 API 请求次数和时间。

还有,更有效的是,可以事先限制交易所的最大杠杆。这个是可以自己调整的。币安默认 20 倍,你改为 3 倍,甚至 2 倍(当然,这要求你策略本身就不使用高杠杠,不然你该开高点的时候还开不出来)。那么代码再怎么发神经,也不可能在你睡觉的时候搞出来一个大敞口。这样就比较稳妥。

总之,实盘有时候不光是交易代码,还需要布局一道道其他防线,防止被黑天鹅事件一下击穿。任何时候都不能掉以轻心,尽量封住死角。
硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点)这里主要讲的是,中低频交易策略的程序化实盘代码实现。 策略 一个量化交易策略的诞生,一般是经由对市场的观察了解,产生策略 idea,然后设计策略的具体细节,再回测多品种的数据,从而获取、验证具体参数数值的效果。如果效果可以,具有普适性,那么下一步就是上实盘小资金测试。样本外实盘可行,最终就可以加大资金并长期运行。 为了防杠精,说明一下,当然也有其他方法产生策略,比如数据挖掘,挖呀挖呀挖因子。还有机器学习、强化学习这类自动生成因子。不过,这类黑盒方法,在策略回撤期很难坚持运行,因为你不知道这些挖出来的因子,什么时候失效,为什么失效。而做量化交易,最重要的一点就是要坚持实盘,行情不好,你可以缩仓,但是不能停机。没有人能知道大行情什么时候爆发。错过了,你之前的回撤就是白瞎。 一个类比,策略的设计、回测,就相当于《孙子兵法》上说的“庙算”,“夫未战而庙算胜者,得算多也;未战而庙算不胜者,得算少也。多算胜,少算不胜,而况于无算乎!” 所以,交易策略在最初的设计上就得谋划好,计算周密,不然还没实盘其实就已经输了。这一步是最难的,后面的实盘代码虽然也不容易,但不过大部分只是繁琐而已,多花花时间精力,总能做好的。实盘的关键还是在风控。 交易策略,或者叫交易规则,就是让我们 “做正确的事”,具体的实盘落地,就是“正确地做事”。很多时候,知道正确的方向,远远要比走完路程要难。就如那个维修设备的段子,画一条线收费一千块。画线本身只值 1 块,但是知道在哪里画收费 999。 策略+实盘共同组成交易系统。关于交易系统的设计,可以参看之前这篇:完备交易系统的七要素。这里的实盘其实就是交易系统的后面 4 步“进出盈损”的具体操作。前面 3 步,在策略设计完成时,就基本已经确定了。 但是,就算策略不错,如果实盘执行不到位,那么效果也会大打折扣,甚至导致停掉本来还不错的潜力策略。研究出一个好策略是很不容易的事情,不要倒在执行这一关。好的想法,要最终稳妥落地才行。 问题 1. 突然的行情 这种是有 bar 内信号的策略才会遇到。bar 内就是没有采用某根 k 线的关仓价或者开仓价,而是盘中的价格来触发信号。 这里以几天前实盘遇到的一个问题为例。一个交易市场的微观例子。在币圈挺普遍的。 下图是前几天(2023.7.10 17:21) BNB 永续合约的 10 秒 k 线(就是一根 bar 是 10 秒内的交易数据聚合出 OHLCV 的意思)。 可以看到,那根大阳线振幅 3.53%,成交了大概 3 千万刀左右。10 秒内完成。在这次行情启动前,走势几乎毫无波澜。 再看下图是当时的 1 秒 k 线,可以得到更多的细节。 基本上 4 秒左右就完全涨到位了。第 1 秒涨了大概2 个多点。这些,基本都是那些高频策略(事件驱动,高频趋势,做市等)还有可能事先布置的算法单之类的博弈结果。 再来看 BNB 的 4 小时 k 线。最大那根阳线就是当时消息出来的时间段。振幅 4.05%。 对比一下这几个周期的 k 线就可以看出,这种消息驱动的波动(这次消息为币安新IEO,ARKM),一般都是瞬间完成的。4 小时的涨幅居然和 10 秒相差并不太多,而真正的启动,也就 4 秒左右。这种战场,是属于那些武装到牙齿的高频策略的。但是,它也可能会影响到中低频策略,造成更大的滑点。 这里不研究高频策略,对于中低频,说明什么问题呢?我想到的主要有两点: 1. 有的趋势爆发非常突然,而且是在很短时间内完成,所以不能随便暂停策略。在币圈的实盘要保证 24 小时在线,特别是有仓位的情况下,不能掉线。 2. 实盘的滑点有可能达到 2 个百分点级别。看上面的 1 秒 k 线,如果你的买入信号是以某个价格为基准,这个价格又正好在大 k 线的下部出来,那么不管怎样,你进场后的价格大概都可能是滑出 2~3 个百分点。最差能到 4 个百分点,那些在针尖成交的买单就是。不过,如果你是卖单,那么就会获取超出预期的利润。但是,根据墨菲法则,落下的面包总是涂着黄油的一面着地。长期来看,大概率是滑点更多。 不过,好的是,这种情况发生的次数有限。只要策略没问题,滑点大一点,只是盈利回吐而已,不影响长期正收益。就当多承受了一次震荡磨损。 缓解的一个办法,就是采用 websocket 获取最新价格,文档说 250 毫秒更新一次,但是有的时候其实更新更快,这样就有可能在第一时间反应了。websocket 的另外一个优点,是不占用交易所 Restful API 的频率限制。这个后面有详细提到。 2. 整点行情 这种是很多趋势策略会遇到,因为大都是采用开关仓价格来计算进出场的信号。那么整点一过,各自纷纷启动。 整点时刻,特别是 8 的倍数,因为无论你的策略是什么周期,这三个点应该都遇到公约数时间了,可能大家的自动化策略都会有动作,高中低频挤在一起产生各自的信号,互为对手盘。 另外,这个时候,交易所还需要结算交割。虽然永续合约不交割,但是要计算交割资金费,可能还有其他操作。在 0/8/16 这三个整点之后的开始 6 秒钟左右,币安的 websocket 是不推送 k 线信息的,它停了!就问你怎么办?现实情况,很多时候就是没有办法。 更严重的是,行情会共振,特别是下跌行情,恐慌的传染性更强烈。交易所的服务器更忙了,很多行情激烈的小币直接就宕机,下单是下不进去的,全是 1001 错误。等你忙不迭地下单成功了,可能针尖上成交的那些单子就是你的。 所以,滑点真的是避免不了的,都是命,接受它吧,过分优化代码也没太大用处。就如前面说的,就当多止损了一次。 不过,也有一些小技巧分享。 可以在整点前 n 秒提前计算信号跑路,那个时候还没开始拥挤,因为可能大多数自动化策略都是等到整点 k 线关仓价出来之后,才开始计算信号的。不过这样操作带来的问题就是,可能会产生错误信号,例如价格马上又回去了,本来不该有信号的,false positive 发生了。这时就看你的取舍了,要不要这么干。不过,可以再加一定阈值,超过了才触发,这样防止短时间价格回归造成的误发信号。滑点能减少一点是一点吧。 还有就是采用时间 offset 或者 shift k 线这类偏移信号的方法,不在整点产生信号,不跟别人卷到一起去,更好地避开拥挤。还有就是 TWAP 等等方式。 不过,这些都需要一些技巧,会加大实盘代码的难度。 实盘 初级的中低频 CTA 策略,一般来说实盘代码非常简单。一个品种只有一个策略,而且没有加减仓,没有交叉信息混淆在一起。那么本地代码可以不维护任何状态,因为交易所帮你记录了一切。是否有仓位,保证金多少,单子是否成交等等。因为是中低频,需要的时候可以随时查询交易所的账户信息,而且这个是最即时准确的。免去了本地使用数据库之类记录交易状态的麻烦。 这种简单策略其实也是可行的,但是问题就是可能回撤会大一点,不够分散,风险高。单品种可能一直没行情,震荡回撤不见回头,或者遇到极端行情,资金曲线上又会来一个大坑。严重点,扛不住就会被吓得停策略,轻一点,交易体验会差很多。注意,这些说的都是在合理仓位的条件下。不然仓位太轻,回撤是小了,但是收益也降低了,盈亏同源,机会错过也可惜;太重,就是错误,迟早要完蛋的。 不过,建议新手可以先搞一个这种策略实盘跑起来。实践才能快速提高自己的交易水平。但是注意一定要轻仓,然后杠杆要低一点,最好是不用杠杠,这样可以坚持更长时间。 如果要做得更专业一点,降低单点风险,资金曲线更平滑,实盘的时候更少担心(如前所述,合理仓位下,这点其实挺重要,因为更容易坚持运行策略,等到风来)一般都是多品种多策略多参数的模式,然后还有加减仓。不一定是在一个策略上的加减仓,也可以是多个子策略实现加减仓的效果。不过,这样的话,策略就会比较拥挤,如果还想尽量降低开平仓滑点,那么代码复杂度就会直线上升。 下面说说这种多品种多策略多参数模式带来的难题。 难点 1. API 频率限制 多策略的第一个难题就是 API 频率限制。品种多了,策略多了,为了获得即时的价格、仓位、下单等信息,就得不停去访问交易所。像前面讲的,频率低了,慢了,那么获得价格就可能不是最新的,滑点就可能大不少。 交易所的服务器资源有限,那么就产生了 API 的访问频率限制。币安的限制是每分钟 2400,然后还有 10 秒的限制,然后还有其他所谓机器学习探测恶意行为的模式,反正就是太频繁肯定不行,至于怎么不行,交易所说了算,这种你懂的,没有定式。 虽然说是 2400,但是我用并发随便测试了一下,如果是请求 k 线,一次就算是最短的 99 根(API 权重为 1)那么,一起请求 75 个币左右就会被 ban 几分钟。所以,不能轻易去挑战极限的。 违反了,就是收到 429, 418 错误,IP 被封禁几分钟到几天,这个时候,如果你有仓位就惨了(下单,特别是出清已有仓位不受限制,但是你没有价格信息了,除非还有 websocket) 这个问题的解决,就是使用 websocket 获取数据,这样交易所主动推过来,时间及时又不占用 API。可以减少一些滑点。带来的问题,就是你得再维护一套基于 websocket 的行情中心。实盘代码难度上升了,变复杂了。要 24 小时不掉线,断线了要及时自动重连等等。 2. 策略状态 前面说了,策略多了,复杂了,就不得不记录每个策略的状态,不然交易所的仓位也不知道是哪个策略开的,每个开的多少之类。而且后面要复盘的话,也得记录更多数据。 这个时候就得引入数据库了(当然,用文件记录也行,一个意思)。 引入了数据库,就带来数据库的那些问题。不过这和其他行业的软件开发类似,没有新意。特别是电商行业,因为都是资金余额,订单管理这些类似的东西,没有经验的可以看看这类书籍文章。 要注意的就是,很多步骤要达到类似数据库事务的原子化操作,就是一组操作要么就是全部成功,一旦某一步失败,就得什么都不干,回滚到最初状态。 然后,因为毕竟是真金白银的交易,对于下单信息的数据库操作,最好是采用 4 个隔离级别的最高级,串行化 Serializable,杜绝所有脏读、不可重复读、幻读的可能性。也就是不采用任何并发,多线程,甚至异步去读写数据库的关键信息,所有操作在一个线程内完成。实现操作的冥等。 不要轻易去挑战并发编程。这种系统出了问题大概都无从下手,属于软件开发里最难发现的 bug。能把这类活完成得干净利落的,都是 5 万+月薪级别的程序员。 我能想到的不多的采用多线程或者异步(多线程和异步,建议采用多线程,因为异步在 Python 里就跟传染病似的,一旦用了,一条调用链上都得用它才行)确实有益处的地方,就是发送钉钉告警信号之类。因为钉钉服务在中国,而币圈交易所服务器又都在海外,你的代码服务器应该布置在海外,更靠近交易所,所以发送钉钉,有时候要等好几秒才返回,有时候甚至阻塞十几秒都有。 最后 其实很多事情做不到也不要紧。只要有接受大一点滑点的觉悟,也就是可能吐出差不多 1/5 甚至更多的利润出来。重要的还是策略,收益正期望,能够不停机一直运行才是王道。 总之,实盘的第一要务是持续稳定执行策略的既定逻辑。滑点是交易的一部分,尽力减少就行了,只要不伤筋动骨。 一流策略,2、3 流实盘实现,问题不大。但是如果策略不过关,顶级实盘代码也无济于事,该亏也还是得亏。所以光是代码写得好,是做不好量化交易的。策略好,实盘代码也健壮,当然是最好的。不过,在时间有限的情况下,要把主要精力放在策略上。 To be continued

硬核干货 - 量化交易系统的自动化实盘细节与思考(一 问题与难点)

这里主要讲的是,中低频交易策略的程序化实盘代码实现。

策略

一个量化交易策略的诞生,一般是经由对市场的观察了解,产生策略 idea,然后设计策略的具体细节,再回测多品种的数据,从而获取、验证具体参数数值的效果。如果效果可以,具有普适性,那么下一步就是上实盘小资金测试。样本外实盘可行,最终就可以加大资金并长期运行。

为了防杠精,说明一下,当然也有其他方法产生策略,比如数据挖掘,挖呀挖呀挖因子。还有机器学习、强化学习这类自动生成因子。不过,这类黑盒方法,在策略回撤期很难坚持运行,因为你不知道这些挖出来的因子,什么时候失效,为什么失效。而做量化交易,最重要的一点就是要坚持实盘,行情不好,你可以缩仓,但是不能停机。没有人能知道大行情什么时候爆发。错过了,你之前的回撤就是白瞎。

一个类比,策略的设计、回测,就相当于《孙子兵法》上说的“庙算”,“夫未战而庙算胜者,得算多也;未战而庙算不胜者,得算少也。多算胜,少算不胜,而况于无算乎!”

所以,交易策略在最初的设计上就得谋划好,计算周密,不然还没实盘其实就已经输了。这一步是最难的,后面的实盘代码虽然也不容易,但不过大部分只是繁琐而已,多花花时间精力,总能做好的。实盘的关键还是在风控。

交易策略,或者叫交易规则,就是让我们 “做正确的事”,具体的实盘落地,就是“正确地做事”。很多时候,知道正确的方向,远远要比走完路程要难。就如那个维修设备的段子,画一条线收费一千块。画线本身只值 1 块,但是知道在哪里画收费 999。

策略+实盘共同组成交易系统。关于交易系统的设计,可以参看之前这篇:完备交易系统的七要素。这里的实盘其实就是交易系统的后面 4 步“进出盈损”的具体操作。前面 3 步,在策略设计完成时,就基本已经确定了。

但是,就算策略不错,如果实盘执行不到位,那么效果也会大打折扣,甚至导致停掉本来还不错的潜力策略。研究出一个好策略是很不容易的事情,不要倒在执行这一关。好的想法,要最终稳妥落地才行。

问题

1. 突然的行情

这种是有 bar 内信号的策略才会遇到。bar 内就是没有采用某根 k 线的关仓价或者开仓价,而是盘中的价格来触发信号。

这里以几天前实盘遇到的一个问题为例。一个交易市场的微观例子。在币圈挺普遍的。

下图是前几天(2023.7.10 17:21) BNB 永续合约的 10 秒 k 线(就是一根 bar 是 10 秒内的交易数据聚合出 OHLCV 的意思)。

可以看到,那根大阳线振幅 3.53%,成交了大概 3 千万刀左右。10 秒内完成。在这次行情启动前,走势几乎毫无波澜。

再看下图是当时的 1 秒 k 线,可以得到更多的细节。

基本上 4 秒左右就完全涨到位了。第 1 秒涨了大概2 个多点。这些,基本都是那些高频策略(事件驱动,高频趋势,做市等)还有可能事先布置的算法单之类的博弈结果。

再来看 BNB 的 4 小时 k 线。最大那根阳线就是当时消息出来的时间段。振幅 4.05%。

对比一下这几个周期的 k 线就可以看出,这种消息驱动的波动(这次消息为币安新IEO,ARKM),一般都是瞬间完成的。4 小时的涨幅居然和 10 秒相差并不太多,而真正的启动,也就 4 秒左右。这种战场,是属于那些武装到牙齿的高频策略的。但是,它也可能会影响到中低频策略,造成更大的滑点。

这里不研究高频策略,对于中低频,说明什么问题呢?我想到的主要有两点:

1. 有的趋势爆发非常突然,而且是在很短时间内完成,所以不能随便暂停策略。在币圈的实盘要保证 24 小时在线,特别是有仓位的情况下,不能掉线。

2. 实盘的滑点有可能达到 2 个百分点级别。看上面的 1 秒 k 线,如果你的买入信号是以某个价格为基准,这个价格又正好在大 k 线的下部出来,那么不管怎样,你进场后的价格大概都可能是滑出 2~3 个百分点。最差能到 4 个百分点,那些在针尖成交的买单就是。不过,如果你是卖单,那么就会获取超出预期的利润。但是,根据墨菲法则,落下的面包总是涂着黄油的一面着地。长期来看,大概率是滑点更多。

不过,好的是,这种情况发生的次数有限。只要策略没问题,滑点大一点,只是盈利回吐而已,不影响长期正收益。就当多承受了一次震荡磨损。

缓解的一个办法,就是采用 websocket 获取最新价格,文档说 250 毫秒更新一次,但是有的时候其实更新更快,这样就有可能在第一时间反应了。websocket 的另外一个优点,是不占用交易所 Restful API 的频率限制。这个后面有详细提到。

2. 整点行情

这种是很多趋势策略会遇到,因为大都是采用开关仓价格来计算进出场的信号。那么整点一过,各自纷纷启动。

整点时刻,特别是 8 的倍数,因为无论你的策略是什么周期,这三个点应该都遇到公约数时间了,可能大家的自动化策略都会有动作,高中低频挤在一起产生各自的信号,互为对手盘。

另外,这个时候,交易所还需要结算交割。虽然永续合约不交割,但是要计算交割资金费,可能还有其他操作。在 0/8/16 这三个整点之后的开始 6 秒钟左右,币安的 websocket 是不推送 k 线信息的,它停了!就问你怎么办?现实情况,很多时候就是没有办法。

更严重的是,行情会共振,特别是下跌行情,恐慌的传染性更强烈。交易所的服务器更忙了,很多行情激烈的小币直接就宕机,下单是下不进去的,全是 1001 错误。等你忙不迭地下单成功了,可能针尖上成交的那些单子就是你的。

所以,滑点真的是避免不了的,都是命,接受它吧,过分优化代码也没太大用处。就如前面说的,就当多止损了一次。

不过,也有一些小技巧分享。

可以在整点前 n 秒提前计算信号跑路,那个时候还没开始拥挤,因为可能大多数自动化策略都是等到整点 k 线关仓价出来之后,才开始计算信号的。不过这样操作带来的问题就是,可能会产生错误信号,例如价格马上又回去了,本来不该有信号的,false positive 发生了。这时就看你的取舍了,要不要这么干。不过,可以再加一定阈值,超过了才触发,这样防止短时间价格回归造成的误发信号。滑点能减少一点是一点吧。

还有就是采用时间 offset 或者 shift k 线这类偏移信号的方法,不在整点产生信号,不跟别人卷到一起去,更好地避开拥挤。还有就是 TWAP 等等方式。

不过,这些都需要一些技巧,会加大实盘代码的难度。

实盘

初级的中低频 CTA 策略,一般来说实盘代码非常简单。一个品种只有一个策略,而且没有加减仓,没有交叉信息混淆在一起。那么本地代码可以不维护任何状态,因为交易所帮你记录了一切。是否有仓位,保证金多少,单子是否成交等等。因为是中低频,需要的时候可以随时查询交易所的账户信息,而且这个是最即时准确的。免去了本地使用数据库之类记录交易状态的麻烦。

这种简单策略其实也是可行的,但是问题就是可能回撤会大一点,不够分散,风险高。单品种可能一直没行情,震荡回撤不见回头,或者遇到极端行情,资金曲线上又会来一个大坑。严重点,扛不住就会被吓得停策略,轻一点,交易体验会差很多。注意,这些说的都是在合理仓位的条件下。不然仓位太轻,回撤是小了,但是收益也降低了,盈亏同源,机会错过也可惜;太重,就是错误,迟早要完蛋的。

不过,建议新手可以先搞一个这种策略实盘跑起来。实践才能快速提高自己的交易水平。但是注意一定要轻仓,然后杠杆要低一点,最好是不用杠杠,这样可以坚持更长时间。

如果要做得更专业一点,降低单点风险,资金曲线更平滑,实盘的时候更少担心(如前所述,合理仓位下,这点其实挺重要,因为更容易坚持运行策略,等到风来)一般都是多品种多策略多参数的模式,然后还有加减仓。不一定是在一个策略上的加减仓,也可以是多个子策略实现加减仓的效果。不过,这样的话,策略就会比较拥挤,如果还想尽量降低开平仓滑点,那么代码复杂度就会直线上升。

下面说说这种多品种多策略多参数模式带来的难题。

难点

1. API 频率限制

多策略的第一个难题就是 API 频率限制。品种多了,策略多了,为了获得即时的价格、仓位、下单等信息,就得不停去访问交易所。像前面讲的,频率低了,慢了,那么获得价格就可能不是最新的,滑点就可能大不少。

交易所的服务器资源有限,那么就产生了 API 的访问频率限制。币安的限制是每分钟 2400,然后还有 10 秒的限制,然后还有其他所谓机器学习探测恶意行为的模式,反正就是太频繁肯定不行,至于怎么不行,交易所说了算,这种你懂的,没有定式。

虽然说是 2400,但是我用并发随便测试了一下,如果是请求 k 线,一次就算是最短的 99 根(API 权重为 1)那么,一起请求 75 个币左右就会被 ban 几分钟。所以,不能轻易去挑战极限的。

违反了,就是收到 429, 418 错误,IP 被封禁几分钟到几天,这个时候,如果你有仓位就惨了(下单,特别是出清已有仓位不受限制,但是你没有价格信息了,除非还有 websocket)

这个问题的解决,就是使用 websocket 获取数据,这样交易所主动推过来,时间及时又不占用 API。可以减少一些滑点。带来的问题,就是你得再维护一套基于 websocket 的行情中心。实盘代码难度上升了,变复杂了。要 24 小时不掉线,断线了要及时自动重连等等。

2. 策略状态

前面说了,策略多了,复杂了,就不得不记录每个策略的状态,不然交易所的仓位也不知道是哪个策略开的,每个开的多少之类。而且后面要复盘的话,也得记录更多数据。

这个时候就得引入数据库了(当然,用文件记录也行,一个意思)。

引入了数据库,就带来数据库的那些问题。不过这和其他行业的软件开发类似,没有新意。特别是电商行业,因为都是资金余额,订单管理这些类似的东西,没有经验的可以看看这类书籍文章。

要注意的就是,很多步骤要达到类似数据库事务的原子化操作,就是一组操作要么就是全部成功,一旦某一步失败,就得什么都不干,回滚到最初状态。

然后,因为毕竟是真金白银的交易,对于下单信息的数据库操作,最好是采用 4 个隔离级别的最高级,串行化 Serializable,杜绝所有脏读、不可重复读、幻读的可能性。也就是不采用任何并发,多线程,甚至异步去读写数据库的关键信息,所有操作在一个线程内完成。实现操作的冥等。

不要轻易去挑战并发编程。这种系统出了问题大概都无从下手,属于软件开发里最难发现的 bug。能把这类活完成得干净利落的,都是 5 万+月薪级别的程序员。

我能想到的不多的采用多线程或者异步(多线程和异步,建议采用多线程,因为异步在 Python 里就跟传染病似的,一旦用了,一条调用链上都得用它才行)确实有益处的地方,就是发送钉钉告警信号之类。因为钉钉服务在中国,而币圈交易所服务器又都在海外,你的代码服务器应该布置在海外,更靠近交易所,所以发送钉钉,有时候要等好几秒才返回,有时候甚至阻塞十几秒都有。

最后

其实很多事情做不到也不要紧。只要有接受大一点滑点的觉悟,也就是可能吐出差不多 1/5 甚至更多的利润出来。重要的还是策略,收益正期望,能够不停机一直运行才是王道。

总之,实盘的第一要务是持续稳定执行策略的既定逻辑。滑点是交易的一部分,尽力减少就行了,只要不伤筋动骨。

一流策略,2、3 流实盘实现,问题不大。但是如果策略不过关,顶级实盘代码也无济于事,该亏也还是得亏。所以光是代码写得好,是做不好量化交易的。策略好,实盘代码也健壮,当然是最好的。不过,在时间有限的情况下,要把主要精力放在策略上。

To be continued
完备交易系统的七要素本文主要讨论量化交易系统,对于主观交易,因为盘感、形态之类很难量化,也就很难系统化、自动化,所以不在讨论之列。 何为系统 交易系统,如同现实中的交通系统、工程系统、法律系统一样,通过建立一系列规则,帮助我们在不确定的世界中更好地活着。交易系统陪着你征战各个二级市场,是你最赖以生存的护身符,保护着你的仓位,让其在交易所的撮合引擎中不断穿梭,最终资金曲线震荡向上。 系统可以是不完美的,因为任何真实世界中实际运行的“系统”都是各种权衡、取舍的结果,不可能完美无瑕,不要迷失在追求完美的幻境中。但是系统必须完备。完备在这里的意思就是该有的都有了,而且没有死角,是反脆弱的,不能说随便一点波动就被带走。 我认为,一个完备的交易系统必须具有七大基本要素,它们就是:标的、目标行情、仓位杠杆或者叫资金管理,然后就是交易逻辑的四个基本操作:进出盈损。其中前三项一般由交易员通过经验综合选择,然后再回测确认是否合理有效,最终量化出交易逻辑的各个参数,最后由实盘代码根据量化回测出来的各个参数,机械地按规则自动执行。 下面一一解释。 1. 标的: 首先要选定你打算交易的标的品种。 这个可以是任何方便交易的标的,当然也可以同时交易多个标的,看具体策略情况。 当今世界的五大公开投机 du 场:股票(股指)、债市、商品期货、外汇,还有新进的数字货币(其实还有各种 betting site,比如世界杯,你懂的,不过比较小众,交易量比较小,老板们也不太讲武德,动不动就跑路)。 因为是要建立量化交易系统,所以最好是有交易所或者券商之类提供历史数据和 API 的品种,这样方便量化回测和程序化自动执行。 至于到底如何选择,主要是看你喜欢什么样的波动,或者说是对手盘。 容易的,可能就是数字货币,因为波动确实大,而且场内的人极易 fomo,情绪化,所以经常有比较持续的趋势。其实控盘比特币也不容易,因为你不知道是不是在世界上的某一个角落,突然有一个或者几个大鲸鱼正好要买(卖),你去随意拉砸,说不定就正中别人的下怀。 最难的,应该就是原油之类的大宗商品,因为有地缘政治之类的博弈,而不是单纯的交易市场里的资金博弈,k 线上更难寻踪觅迹。 原则上,尽量选择对手盘弱的市场,不然放眼望去,如果你是牌桌上最弱的那个,最终结果可想而知。交易毕竟是零和博弈,一个人的利润只能是另一人的亏损。选标的就是选牌桌。 2. 行情: 这个就是你的交易策略主要是想抓什么样的行情。这个行情也可以是周期的意思。大周期的震荡可能就是小周期的趋势。 首先别指望什么行情或者波动都能赚钱,一个系统必须只专注一点,不然基本上做不好,容易顾此失彼。 另外,行情也可以是指诸如要做均值回归还是趋势跟随一类,或者套利,高频做市等等。是做单个标的还是多个标的的对冲,或者是截面的回归或者趋势种种。 想要多种行情,就得多种系统,或者形成系统体系,就像私募基金一样运作,不过这种都是团队化作战了,各自分工。 原则上,系统不该赚钱的时候赚钱就是一种错误。你的系统目标定错了,最终结果只能南辕北辙。 3. 仓位: 这一项就是你打算分配多少资金到这个系统,特别是如果你有多个交易系统的话。对于那些采用保证金模式的交易标的,打算采用的杠杆是多少。 还有就是资金管理。总之就是动用多少仓位的问题。 初学者喜欢打听你用的什么点位和指标进场,稍有经验的最多还问问你怎么出场,止盈止损怎么设置,只有经历过市场毒打的人才会把重点放在资金管理上。 资金管理相当于在系统的交易逻辑上增加了一个维度,不再是单纯的进场出场一个维度,而是每次进场出场之外还有资金量大小的区别,类似于上升到二维空间了,这样策略才能玩出更多花来。指标终归是趋同的,因为都是量价的各种数学变换而已,大概也就是滞后性不太相同,最后起到一定的过滤作用罢了。 资金管理才是高级玩法。 4. 进场: 就是什么情况下进场,以及进场的方向。我主要是做趋势跟踪,个人认为进场信号其实没有那么重要,至少没有出场逻辑重要,因为未来的不可预测,你怎么做都不会比随机抛硬币好太多的,准确性提升有限。但是作为自动化交易,必须也得规则化。 如果是分开多次进场,其实就是加仓了。加仓相当于是多个策略融合在一起,起到分散仓位的作用。 趋势跟随的话一般都是浮盈加仓,很少见到浮亏加仓的操作。 加仓之后,一般交易系统的胜率会降低,但是盈亏比会增大,看各自的取舍了。 加仓的话,回测起来就麻烦一些,不光是代码更复杂一点,还有各种策略变化之间难于对比,因为加仓方式不同,仓位和杠杆就不同,那么对比他们的收益和回撤就没那么直观简洁(当然卡玛比率 Calmar ratio 是一个选择),给参数选择造成一定的难度。 5. 出场: 这里的出场是指依据交易策略信号的退场。比如持有多仓的时候出现做空的信号。不过这种永远持仓(不是多就是空)的模式一般回撤会比较大,所以一般都会配合上主动止盈,这样利润会回吐少一点,但是必须得承担一定的回撤才有可能抓住大一点的趋势,不然就是轻易被震出场,抓不住大趋势。 曾经有人做过回测,就是随机信号进场,但是只要出场是符合交易逻辑的,也就是“截断亏损,让利润奔跑”,那么也能建立起一套正期望值的交易系统。所以,不要被轻易震出场,用浮盈回吐去抓大趋势几乎是最划算的买卖。 后面还有两种出场方式。可见出场比入场要重要且关键得多。 6. 止盈: 这里的止盈主要是指各种主动止盈。比如各种固定止盈、浮动止盈、追踪止盈。个人认为,只要浮盈足够,也就是达到了一定的盈亏比,就可以无脑止盈一部分,这样让资金曲线走势更平滑,并不一定要让所有利润奔跑到底。 但是也别刚开始盈利就执行所谓的平半,或者平仓一部分,用来锁定利润。我观察很多带单老师喜欢这么干,因为这样看起来胜率高啊,顺着人性,用户体验好。 但是真实道理是,如果有一点盈利就跑,走太早,没有超过一定盈亏比的盈利,你这部分资金相当于就一直在亏钱,原因是吃肉的时候舔到一口你就跑了,挨打的时候可一板子没少,次次挺到止损。就算最终赚钱,也是另外一部分没提前跑的资金在替全部仓位负重前行。 所以太早锁定利润会大大影响你全仓赚钱的效率。 止盈要保证足够盈亏比,而不要单看胜率。 7. 止损: 止损是一个交易系统必须要有的。一般一个交易系统一旦加上比较紧凑的止损,性能大概会下降不少,也就是收益降低,回撤可能也同时增大,回测数据就会不太好看。所以有些还没有吃过亏的交易员,系统没有设计止损,而仅仅是等反向信号出来再退场,很有可能会一次亏一把大的,从而资金和信心都大受打击,一蹶不振。 一般止损有两种,一种是固定比例止损,就是价格反向了 8 个点,10 个点这类,只要价格扎到就算法单自动市价退出。这种最好,因为最可控,至多再额外加一些滑点。其他的,例如利用标记价格,可能更难触发到止损,但是一旦触发,可能已经反向 15 个点了,造成更大亏损。主要问题还是可能超过太多预期。 还有的就是利用几倍 ATR 止损这类,这类的问题也是不太可控,因为在极端情况,ATR 可能变得非常大,特别是大周期,那么也可能一次性亏损很多,其实本来早就该离场的。 对于全自动化运行的交易系统,止损必须考虑得非常细致才行,止盈可以稍微随意一点。 另外一种就是利用 k 线的关仓价格,这样的止损方式光看回测可能更稳定一些,比较诱惑人,但是同样也是不可控,因为显然一根 k 线在极端情况下可能会大幅变动,幅度可能是你在所有历史 k 线中没有见过的,不然怎么叫黑天鹅呢。 最后 有了完备的交易系统只是漫漫征途的开始,并不能保证让你从此高枕无忧,开始躺着赚钱。因为未来的不确定,每一个策略都会有它的不利期。 就算开始赚了钱,当系统连续亏损时,资金曲线不停回撤,我们依然会恐惧。我们不知道自己设计的交易模式是不是有回测没有发现的问题,是不是市场风格发生了某些不为人知的变化,策略"失效"了,是不是传说中那些虚无缥缈的“主力”和“庄家”在干着某些不为人知的勾当。 一切都会变成迷雾,挑战你最底层的交易认知。 其实市场中能够建立起自己交易系统的人并不少,但是能够在不利期冲击中挺过去的人寥寥无几。大多数人在几个月回撤走势的冲击下,恐惧开始支配大脑,开始犹豫怀疑,开始干预系统,甚至放弃自己的准则。最终系统被改得面目全非。 所以,最终更考验你的,是你的认知,是执行这套交易系统的决心,能不能战胜一路上的贪婪和恐惧。 最后,要详细了解如何建立交易系统,推荐《海龟交易法则》,它毫无保留的把一套完整的交易系统展示了出来,解剖得非常彻底,这是搞量化交易的必读书,不要嫌弃它已经有好几十年历史了。经典永不过时。

完备交易系统的七要素

本文主要讨论量化交易系统,对于主观交易,因为盘感、形态之类很难量化,也就很难系统化、自动化,所以不在讨论之列。

何为系统

交易系统,如同现实中的交通系统、工程系统、法律系统一样,通过建立一系列规则,帮助我们在不确定的世界中更好地活着。交易系统陪着你征战各个二级市场,是你最赖以生存的护身符,保护着你的仓位,让其在交易所的撮合引擎中不断穿梭,最终资金曲线震荡向上。

系统可以是不完美的,因为任何真实世界中实际运行的“系统”都是各种权衡、取舍的结果,不可能完美无瑕,不要迷失在追求完美的幻境中。但是系统必须完备。完备在这里的意思就是该有的都有了,而且没有死角,是反脆弱的,不能说随便一点波动就被带走。

我认为,一个完备的交易系统必须具有七大基本要素,它们就是:标的、目标行情、仓位杠杆或者叫资金管理,然后就是交易逻辑的四个基本操作:进出盈损。其中前三项一般由交易员通过经验综合选择,然后再回测确认是否合理有效,最终量化出交易逻辑的各个参数,最后由实盘代码根据量化回测出来的各个参数,机械地按规则自动执行。

下面一一解释。

1. 标的:

首先要选定你打算交易的标的品种。

这个可以是任何方便交易的标的,当然也可以同时交易多个标的,看具体策略情况。

当今世界的五大公开投机 du 场:股票(股指)、债市、商品期货、外汇,还有新进的数字货币(其实还有各种 betting site,比如世界杯,你懂的,不过比较小众,交易量比较小,老板们也不太讲武德,动不动就跑路)。

因为是要建立量化交易系统,所以最好是有交易所或者券商之类提供历史数据和 API 的品种,这样方便量化回测和程序化自动执行。

至于到底如何选择,主要是看你喜欢什么样的波动,或者说是对手盘。

容易的,可能就是数字货币,因为波动确实大,而且场内的人极易 fomo,情绪化,所以经常有比较持续的趋势。其实控盘比特币也不容易,因为你不知道是不是在世界上的某一个角落,突然有一个或者几个大鲸鱼正好要买(卖),你去随意拉砸,说不定就正中别人的下怀。

最难的,应该就是原油之类的大宗商品,因为有地缘政治之类的博弈,而不是单纯的交易市场里的资金博弈,k 线上更难寻踪觅迹。

原则上,尽量选择对手盘弱的市场,不然放眼望去,如果你是牌桌上最弱的那个,最终结果可想而知。交易毕竟是零和博弈,一个人的利润只能是另一人的亏损。选标的就是选牌桌。

2. 行情:

这个就是你的交易策略主要是想抓什么样的行情。这个行情也可以是周期的意思。大周期的震荡可能就是小周期的趋势。

首先别指望什么行情或者波动都能赚钱,一个系统必须只专注一点,不然基本上做不好,容易顾此失彼。

另外,行情也可以是指诸如要做均值回归还是趋势跟随一类,或者套利,高频做市等等。是做单个标的还是多个标的的对冲,或者是截面的回归或者趋势种种。

想要多种行情,就得多种系统,或者形成系统体系,就像私募基金一样运作,不过这种都是团队化作战了,各自分工。

原则上,系统不该赚钱的时候赚钱就是一种错误。你的系统目标定错了,最终结果只能南辕北辙。

3. 仓位:

这一项就是你打算分配多少资金到这个系统,特别是如果你有多个交易系统的话。对于那些采用保证金模式的交易标的,打算采用的杠杆是多少。

还有就是资金管理。总之就是动用多少仓位的问题。

初学者喜欢打听你用的什么点位和指标进场,稍有经验的最多还问问你怎么出场,止盈止损怎么设置,只有经历过市场毒打的人才会把重点放在资金管理上。

资金管理相当于在系统的交易逻辑上增加了一个维度,不再是单纯的进场出场一个维度,而是每次进场出场之外还有资金量大小的区别,类似于上升到二维空间了,这样策略才能玩出更多花来。指标终归是趋同的,因为都是量价的各种数学变换而已,大概也就是滞后性不太相同,最后起到一定的过滤作用罢了。

资金管理才是高级玩法。

4. 进场:

就是什么情况下进场,以及进场的方向。我主要是做趋势跟踪,个人认为进场信号其实没有那么重要,至少没有出场逻辑重要,因为未来的不可预测,你怎么做都不会比随机抛硬币好太多的,准确性提升有限。但是作为自动化交易,必须也得规则化。

如果是分开多次进场,其实就是加仓了。加仓相当于是多个策略融合在一起,起到分散仓位的作用。

趋势跟随的话一般都是浮盈加仓,很少见到浮亏加仓的操作。

加仓之后,一般交易系统的胜率会降低,但是盈亏比会增大,看各自的取舍了。

加仓的话,回测起来就麻烦一些,不光是代码更复杂一点,还有各种策略变化之间难于对比,因为加仓方式不同,仓位和杠杆就不同,那么对比他们的收益和回撤就没那么直观简洁(当然卡玛比率 Calmar ratio 是一个选择),给参数选择造成一定的难度。

5. 出场:

这里的出场是指依据交易策略信号的退场。比如持有多仓的时候出现做空的信号。不过这种永远持仓(不是多就是空)的模式一般回撤会比较大,所以一般都会配合上主动止盈,这样利润会回吐少一点,但是必须得承担一定的回撤才有可能抓住大一点的趋势,不然就是轻易被震出场,抓不住大趋势。

曾经有人做过回测,就是随机信号进场,但是只要出场是符合交易逻辑的,也就是“截断亏损,让利润奔跑”,那么也能建立起一套正期望值的交易系统。所以,不要被轻易震出场,用浮盈回吐去抓大趋势几乎是最划算的买卖。

后面还有两种出场方式。可见出场比入场要重要且关键得多。

6. 止盈:

这里的止盈主要是指各种主动止盈。比如各种固定止盈、浮动止盈、追踪止盈。个人认为,只要浮盈足够,也就是达到了一定的盈亏比,就可以无脑止盈一部分,这样让资金曲线走势更平滑,并不一定要让所有利润奔跑到底。

但是也别刚开始盈利就执行所谓的平半,或者平仓一部分,用来锁定利润。我观察很多带单老师喜欢这么干,因为这样看起来胜率高啊,顺着人性,用户体验好。

但是真实道理是,如果有一点盈利就跑,走太早,没有超过一定盈亏比的盈利,你这部分资金相当于就一直在亏钱,原因是吃肉的时候舔到一口你就跑了,挨打的时候可一板子没少,次次挺到止损。就算最终赚钱,也是另外一部分没提前跑的资金在替全部仓位负重前行。

所以太早锁定利润会大大影响你全仓赚钱的效率。

止盈要保证足够盈亏比,而不要单看胜率。

7. 止损:

止损是一个交易系统必须要有的。一般一个交易系统一旦加上比较紧凑的止损,性能大概会下降不少,也就是收益降低,回撤可能也同时增大,回测数据就会不太好看。所以有些还没有吃过亏的交易员,系统没有设计止损,而仅仅是等反向信号出来再退场,很有可能会一次亏一把大的,从而资金和信心都大受打击,一蹶不振。

一般止损有两种,一种是固定比例止损,就是价格反向了 8 个点,10 个点这类,只要价格扎到就算法单自动市价退出。这种最好,因为最可控,至多再额外加一些滑点。其他的,例如利用标记价格,可能更难触发到止损,但是一旦触发,可能已经反向 15 个点了,造成更大亏损。主要问题还是可能超过太多预期。

还有的就是利用几倍 ATR 止损这类,这类的问题也是不太可控,因为在极端情况,ATR 可能变得非常大,特别是大周期,那么也可能一次性亏损很多,其实本来早就该离场的。

对于全自动化运行的交易系统,止损必须考虑得非常细致才行,止盈可以稍微随意一点。

另外一种就是利用 k 线的关仓价格,这样的止损方式光看回测可能更稳定一些,比较诱惑人,但是同样也是不可控,因为显然一根 k 线在极端情况下可能会大幅变动,幅度可能是你在所有历史 k 线中没有见过的,不然怎么叫黑天鹅呢。

最后

有了完备的交易系统只是漫漫征途的开始,并不能保证让你从此高枕无忧,开始躺着赚钱。因为未来的不确定,每一个策略都会有它的不利期。

就算开始赚了钱,当系统连续亏损时,资金曲线不停回撤,我们依然会恐惧。我们不知道自己设计的交易模式是不是有回测没有发现的问题,是不是市场风格发生了某些不为人知的变化,策略"失效"了,是不是传说中那些虚无缥缈的“主力”和“庄家”在干着某些不为人知的勾当。

一切都会变成迷雾,挑战你最底层的交易认知。

其实市场中能够建立起自己交易系统的人并不少,但是能够在不利期冲击中挺过去的人寥寥无几。大多数人在几个月回撤走势的冲击下,恐惧开始支配大脑,开始犹豫怀疑,开始干预系统,甚至放弃自己的准则。最终系统被改得面目全非。

所以,最终更考验你的,是你的认知,是执行这套交易系统的决心,能不能战胜一路上的贪婪和恐惧。

最后,要详细了解如何建立交易系统,推荐《海龟交易法则》,它毫无保留的把一套完整的交易系统展示了出来,解剖得非常彻底,这是搞量化交易的必读书,不要嫌弃它已经有好几十年历史了。经典永不过时。
登录解锁更多内容
浏览最新的加密货币新闻
⚡️ 参与加密货币领域的最新讨论
💬 与喜爱的创作者互动
👍 查看感兴趣的内容
邮箱/手机号码

实时新闻

--
查看更多

热门文章

尧二六疯狂刷 Alpha
查看更多
网站地图
Cookie偏好设置
平台条款和条件