Трансплантация OKCoin для капустного комбайна

Автор:Нуль, Дата: 2017-01-30 19:38:25
Тэги:Высокочастотные

Пересадка:https://github.com/richox/okcoin-leeks-reaper

Я просто сделал трансплантацию, не тестировался на диске, заинтересован в изучении. Изобретатели количественного Tick-уровневого ретроспективного воспроизведения поддерживают воспроизведение Deepth и Trades, что позволяет непосредственно ретроспективно изучать стратегическую логику.

Ниже приведены оригинальные описания

OKCoin салатный комбайн

Это высокочастотный торговый робот на криптовалютной торговой платформе OKCoin, который с июня 2016 года был продемонстрирован, а к середине января 2017 года был успешно очищен от первоначального вложения 6000 до 250000. В результате недавней политики высокого давления на биткоин со стороны центрального банка, основные платформы прекратили финансирование и начали взимать сборы за транзакции. Эта стратегия фактически не сработала.

image

Эта робот-программа основана на двух основных стратегиях:

  1. Тенденционная стратегия: своевременное размещение заказов и последующее последующее наблюдение за тенденционными колебаниями цен, как говорится в пословице.Преследование и гибель
  2. Стратегия сбалансирования: когда позиция отклоняется на 50%, выпускается бумага, которая постепенно возвращает позицию на 50% и предотвращает обратный конец тренда, который приводит к регрессу, т.е.Покупки в пакеты, не ешьте рыбьих хвостов

Эта процедура требует сбалансированной позиции, т.е. (капитал + финансирование = денежные средства), чтобы при позиции 50% чистые активы не колебались с ценой, а также гарантировали, что в случае возникновения тенденционных колебаний.Взрыв.

Мы хотим поблагодарить вас за следующие два проекта:

Спасибо OKCoin:

BTC: 3QFn1qfZMhMQ4FhgENR7fha3T8ZVw1bEeU


/*backtest
start: 2019-09-05 00:00:00
end: 2019-09-05 22:00:00
period: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT","fee":[0,0]}]
mode: 1
*/

function LeeksReaper() {
    var self = {}
    self.numTick = 0
    self.lastTradeId = 0
    self.vol = 0
    self.askPrice = 0
    self.bidPrice = 0
    self.orderBook = {Asks:[], Bids:[]}
    self.prices = []
    self.tradeOrderId = 0
    self.p = 0.5
    self.account = null
    self.preCalc = 0
    self.preNet = 0

    self.updateTrades = function() {
        var trades = _C(exchange.GetTrades)
        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
            }
        }
        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)

    }
    self.updateOrderBook = function() {
        var orderBook = _C(exchange.GetDepth)
        self.orderBook = orderBook
        if (orderBook.Bids.length < 3 || orderBook.Asks.length < 3) {
            return
        }
        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
        self.prices.shift()
        self.prices.push(_N((orderBook.Bids[0].Price + orderBook.Asks[0].Price) * 0.35 +
            (orderBook.Bids[1].Price + orderBook.Asks[1].Price) * 0.1 +
            (orderBook.Bids[2].Price + orderBook.Asks[2].Price) * 0.05))
    }
    self.balanceAccount = function() {
        var account = exchange.GetAccount()
        if (!account) {
            return
        }
        self.account = account
        var now = new Date().getTime()
        if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {
            self.preCalc = now
            var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
            if (net != self.preNet) {
                self.preNet = net
                LogProfit(net)
            }
        }
        self.btc = account.Stocks
        self.cny = account.Balance
        self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
        var balanced = false
        
        if (self.p < 0.48) {
            Log("开始平衡", self.p)
            self.cny -= 300
            if (self.orderBook.Bids.length >0) {
                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)
            }
        } else if (self.p > 0.52) {
            Log("开始平衡", self.p)
            self.btc -= 0.03
            if (self.orderBook.Asks.length >0) {
                exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01)
                exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01)
            }
        }
        Sleep(BalanceTimeout)
        var orders = exchange.GetOrders()
        if (orders) {
            for (var i = 0; i < orders.length; i++) {
                if (orders[i].Id != self.tradeOrderId) {
                    exchange.CancelOrder(orders[i].Id)
                }
            }
        }
    }

    self.poll = function() {
        self.numTick++
        self.updateTrades()
        self.updateOrderBook()
        self.balanceAccount()
        
        var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct
        var bull = false
        var bear = false
        var tradeAmount = 0
        if (self.account) {
            LogStatus(self.account, 'Tick:', self.numTick, ', lastPrice:', self.prices[self.prices.length-1], ', burstPrice: ', burstPrice)
        }
        
        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
        }
        if (self.vol < BurstThresholdVol) {
            tradeAmount *= self.vol / BurstThresholdVol
        }
        
        if (self.numTick < 5) {
            tradeAmount *= 0.8
        }
        
        if (self.numTick < 10) {
            tradeAmount *= 0.8
        }
        
        if ((!bull && !bear) || tradeAmount < MinStock) {
            return
        }
        var tradePrice = bull ? self.bidPrice : self.askPrice
        while (tradeAmount >= MinStock) {
            var orderId = bull ? exchange.Buy(self.bidPrice, tradeAmount) : exchange.Sell(self.askPrice, tradeAmount)
            Sleep(200)
            if (orderId) {
                self.tradeOrderId = orderId
                var order = null
                while (true) {
                    order = exchange.GetOrder(orderId)
                    if (order) {
                        if (order.Status == ORDER_STATE_PENDING) {
                            exchange.CancelOrder(orderId)
                            Sleep(200)
                        } else {
                            break
                        }
                    }
                }
                self.tradeOrderId = 0
                tradeAmount -= order.DealAmount
                tradeAmount *= 0.9
                if (order.Status == ORDER_STATE_CANCELED) {
                    self.updateOrderBook()
                    while (bull && self.bidPrice - tradePrice > 0.1) {
                        tradeAmount *= 0.99
                        tradePrice += 0.1
                    }
                    while (bear && self.askPrice - tradePrice < -0.1) {
                        tradeAmount *= 0.99
                        tradePrice -= 0.1
                    }
                }
            }
        }
        self.numTick = 0
    }
    return self
}

function main() {
    var reaper = LeeksReaper()
    while (true) {
        reaper.poll()
        Sleep(TickInterval)
    }
}

Связанные

Больше

Король хип-хапаЭта стратегия не сработала, и прибыль была получена за счет высокочастотного дохода с нулевой оплатой.

Кунгбай979 self.vol到底是个啥?是一个ticker期间内所有交易量的总和吗?

деньTrader2018for (var i = 0; i < 15; i++) { self.prices[i] = trades[trades.length - 1].Price }; Есть ли здесь какая-то проблема, так что каждый элемент в массиве prices является последней ценой сделки?

Коую 7035У меня есть несколько обменных пунктов, где я могу работать без оплаты. Можно попробовать эту стратегию?

БиджасуоОчень круто, к сожалению, не работает.

СкайффайрПримечание: продажа: 2000 экземпляров, неофициальный, имеется связь

РаджаякКто-нибудь из тех, кто пробовал, вышел и обсудил результаты?

ВаленнКогда появится аннотация?

УцзяньминКак можно работать на биржах без поддержки botvs, где можно торговать бесплатно, как написать API биржи?

JСпасибо, что поделились такой хорошей стратегией! exchange.CancelOrder ((orders[i].Id) код отмены здесь немного проблемен, постоянно отменяется при проверке. Посмотрев на исходную версию кода, вы должны были отменить заявку через 10 секунд. В общем-то, все остальное в принципе нормально, и после того, как я его изменил, я начал работать на бирже, которая не платит за обслуживание, и это хорошо.

Киль-студия 66行prices需加.length

снежный горошекКакой это язык?

Нуль 平衡那里下单忘加上Price属性了。。已更正,有发现bug请及时提交.

ВодолеиПо-видимому, есть тактики, чтобы заработать деньги, или не продавать, и оставить себе деньги.

1213761768Не выпускать раньше.

Чан НихиНет, цена предложения должна быть меньше, чем цена спроса, одна из которых - цена покупки, одна - цена продажи.

БвксяокПожалуйста, когда вы рассчитываете bidprice и askprice, вы делаете заказ так, как если бы не судили, что bidprice больше askprice, так что если купить или продать очень близко, вы вычисляете, что это скорее всего, что вы покупаете или продаете, будет ли это проблема?

Я люблю луковицу.Я написал аннотацию, в которой говорится, что все должны иметь возможность добавлять свой твит Hoo_tongxue, и самое главное - бесплатно.

Я люблю луковицу.На самом деле, кожа достаточно толстая, чтобы быть одетой.

Маленький угольный шарКакие биржи?

НульЭто должно быть инициировано как последняя цена, за которой следует операция Shift.

Перезагрузка - чудоЭто уже давно провалилось. Сейчас все боевые роботы.

сускиДа, да, я думаю, что это будет лучше.

СкайффайрПусть продавец продает, и пусть покупатель покупает, и не спорят с тобой.

И невесты тоже.Все выпустили исходный код, а вы комментируете, продать 2000?

Аккк 请问zaif.jp现在还是免手续费吗?怎么通过认证呢

Хиаохуань001Посмотрите на ID.

J 在Zaif.jp上测试,买一卖一间经常就没有空间,用这个策略有什么问题吗?

JЭто правда? Выходите и дайте им урок.

Хиаохуань001Удивительный автор

JХорошо, есть еще вопросы, пожалуйста, и есть еще одна статья: https://www.botvs.com/bbs-topic/677

НульЕсли у вас есть какие-либо вопросы или пожелания по поводу этой стратегии, пожалуйста, разместите их на форуме.

НульСпасибо за предложение, я добавил параметр, балансировать время ожидания ордера, если вы хотите одновременную обработку, вы можете записать ID каждого ордера с временем размещения ордера, а затем избирательно отменить, что уменьшит задержку, но логически, должен быть балансировать снова открыть первым, поскольку не все биржи поддерживают свойство времени получения ордера, поэтому платформа не добавляет это свойство в ордера, требуя собственных статистических данных.

Хиаохуань001Мне кажется, эта стратегия странная, мне нравится ((*^__^*)

НульЯ никогда не пытался это сделать, но вам нужно будет изучить это сами.

Орион 1708Очень сложно перенести Z. Пожалуйста, изменить параметры политики по умолчанию, что может сильно повлиять на политику?

НульХа-ха, спасибо, добавлено.

НульJavaScript

НульВысокая частота сделок

Маленькие мечтыАвтор также был опубликован только в те дни, когда он взимал плату за регистрацию.

Хиаохуань001Почему трендовые стратеги боятся ударных затрат?