比特币定投日记第54天:EOS韭菜收割机原理


(交流比特币定投经验、参与小码哥定投系统内测,可私信留言)
昨天分享了一个别人的EOS套利方法,今天再来分享一个别人的『韭菜收割机』,更好玩。
小码哥一直说,在botvs里能挖到宝,不知道各位有没有行动起来。
今天来读一份别人的代码,重点是分析原理,了解别人的思路。币圈的机会很多,套利方法多种多样,但万变不离其宗,搞明白了本质的东西才是王道。
原文说明在:https://github.com/richox/okcoin-leeks-reaper
这是一个用Groovy写的,在OKCoin比特币交易平台上的高频交易机器人程序,从2016年6月策略基本定型,到2017年1月中旬,这个策略成功的把最初投入的6000块钱刷到了250000。最后由于央行对比特币实行高压政策,各大平台都停止了配资,并且开始征收交易费,作者宣称该策略实际上已经失效了,然后公开了代码(小码哥认为,同样的思路应该还是有机会的)。
策略的分两部分:
趋势策略:在价格发生趋势性的波动时,及时下单跟进,即俗话说的追涨杀跌。
平衡策略:仓位偏离50%时,放出小单使仓位逐渐回归50%,防止趋势末期的反转造成回撤,即收益落袋,不吃鱼尾。
听上去有些道理,接下来,我们一起读代码,看看到底是咋实现的。
botvs的老大Zero把策略移植成了js,可以直接回测,更方便,我们看这个版本。
https://www.botvs.com/strategy/34388
主函数,里面就干一件事情:LeeksReaper——"割韭菜"
function main() {
var reaper = LeeksReaper()
while (true) {
reaper.poll()
Sleep(TickInterval)
}
}
LeeksReaper对象有几个方法,分别作用是:
updateTrades() //获取最近的成交记录
updateOrderBook() //更新当前的盘口(深度)数据
balanceAccount() //平衡,即上面说的,收益落袋,不吃鱼尾
poll() //轮询入口
然后我们再来看每个方法里面都是怎么实现的:
updateTrades() 里面的实现比较简单。
最近15条交易的价格,更新到数组self.prices里:
if (self.prices.length == 0) {
while (trades.length == 0) {
trades = trades.concat(_C(exchange.GetTrades))
}
for (var i = 0; i < 15; i++) {
self.prices[i] = trades[trades.length - 1].Price
}
}
然后是交易量做了加权平滑,上次交易量权重70%,加上最近的交易量权重30%,这个权重不确定是怎么定出来的,应该是经验值。更新到self.vol里:
self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function(mem, trade) {
// Huobi not support trade.Id
if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
self.lastTradeId = Math.max(trade.Id == 0 ? trade.Time : trade.Id, self.lastTradeId)
mem += trade.Amount
}
return mem
}, 0)
updateOrderBook() 里面的逻辑也很简单,就是把盘口数据在加到价格数组里(后面用来判断短期趋势的),但是这几个经验参数都不确定来由,注:0.618是数学黄金分割。
self.bidPrice = orderBook.Bids[0].Price * 0.618 + orderBook.Asks[0].Price * 0.382 + 0.01
self.askPrice = orderBook.Bids[0].Price * 0.382 + orderBook.Asks[0].Price * 0.618 - 0.01
balanceAccount() 计算当前仓位,目标是50%,如果大于0.52,或小于0.48,就触发平衡。下单也是网格下单,分3个价位的网格,每单交易0.01BTC,比如:
exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01)
exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01)
exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01)
下单完后,等BalanceTimeout的时间,取消所有未成交订单,下次再平衡。这是通常的做法,不为当下过大的单向移动付出溢价,保证收益。小码哥目前的自动定投也是用类似方式处理。
poll() 轮询入口,这里面是主要逻辑。
if (self.numTick > 2 && (
self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -1)) > burstPrice ||
self.prices[self.prices.length-1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length-1] > self.prices[self.prices.length-2]
)) {
bull = true
tradeAmount = self.cny / self.bidPrice * 0.99
} else if (self.numTick > 2 && (
self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -1)) < -burstPrice ||
self.prices[self.prices.length-1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length-1] < self.prices[self.prices.length-2]
)) {
bear = true
tradeAmount = self.btc
}
这里是割韭菜的重点,主要逻辑是根据近期的成交历史,判断当前是『牛』(bull)还是『熊』(bear),简单的来说,就是判断短期内的趋势是『涨』还是『跌』,接下去就该『追涨杀跌』了。
所以,看明白策略的原理,就像昨天发的套利EOS的文章一样,都是根据最近一段时间市场上交易的数据(趋势、动能)来预测未来一段时间的涨跌,作为入市的依据。而韭菜收割机的退出策略更为谨慎,相当于用多次『香农网格』的平衡,完成退出,锁定利润。对于高频策略来说,这是非常重要的,不是去搏一个大的胜利,而是滚雪球,用无数的小胜利加在一起,复利的效应是巨大的。
那么分析完了原理,我们可以再反问一下,这样的机会真的消失了吗?交易所收取手续费,无非是大大抬高了高频的成本。从理论上来说,对于一个数学期望为正的交易策略,赚钱的结论依然是成立的。只是代码里有非常多的经验值参数,都是需要实践中花费不少学费去摸索出来最优值(高频策略的回测结果通常不具代表性,实盘很重要)。
这次的代码解读非常的粗略,因为小码哥只想抛砖引玉。对于所有会写代码的技术同学,小码哥强烈建议去读botvs上别人共享出来的代码,理解别人的思路,分析他们每行代码背后想要解决的问题,或者遇到的坑。然后,我们可以一起讨论,一起修改,一起躺赚比特币。