В процессе загрузки ресурсов... загрузка...

Подробное объяснение стратегии BitMEX в отношении ожидаемых заказов

Автор:Доброта, Создано: 2019-01-16 15:28:13, Обновлено: 2019-01-22 14:16:48

BitMEX стала предпочтительной платформой для торговли криптовалютами с использованием рычага, но ограничения на торговлю API являются строгими и заставляют автоматических трейдеров чувствовать себя очень смущенными.

1. Особенности BitMEX

Наиболее значительным преимуществом является то, что ликвидность торговли очень активна, особенно в биткойн вечный контракт, сумма транзакции в минуту часто превышает один миллион или даже десять миллионов долларов США; BitMEX ожидания торговых заказов имеют политику возврата комиссии, хотя это не много, но привлекло большое количество рыночных торгов, что сделало глубину цены очень богатым. последняя цена покупки и продажи часто имеют более одного миллиона долларов стоимостью ожидания заказов; из-за этого момента цена транзакции часто колеблется вокруг минимальной единицы изменения в $ 0,50.

2.Ограничение частоты API BitMEX

Частота запросов API REST ограничена 300 раз в 5 минут, почти равна 1 раз в секунду, этот лимит можно сказать очень строгим по сравнению с другими торговыми платформами. После превышения лимита будет запрошен Rate limit exceeded. Если вы продолжаете превышать лимит, IP может быть отключен на один час. Несколько отключений в короткое время приведут к неделе отключения. Для каждого запроса API BitMEX вернет данные заголовка, данные заголовка используются для просмотра текущего количества оставшихся запросов. На самом деле, если API используется правильно, он не превысит лимит частоты и, как правило, не нуждается в проверке.

3.Использовать websocket для получения рыночной котировки

BitMEX REST API является более ограничительным. Официальная рекомендация заключается в том, чтобы использовать протокол websocket больше, и подталкивать больше типов данных, чем средний обмен. Обратите внимание на следующие пункты для конкретного использования:

Если время нагрузки данных глубины слишком длинное, произойдет ошибка, которая не соответствует реальной глубине. Подробная информация о заказах часто отсутствует и практически недоступна. Существует значительная задержка в отправке информации об аккаунте, предпочтительно с использованием API REST. Когда волатильность рынка слишком велика, задержка продвижения достигнет нескольких секунд. Следующий код использует протокол websocket для получения информации о рынке и счете в режиме реального времени, в основном для стратегий создания рынка.

var ticker  = {price:0, buy:0, sell:0, time:0} //Ticker information, the latest price, "buy one" price, "sell one" price, update time
//Account information, respectively, position, buying and selling price, buying and selling quantity, position status, order Id
var info = {position:0, buyPrice:0, sellPrice:0, buyAmount:0, sellAmount:0, buyState:0, sellState:0, buyId:0, sellId:0}
var buyListId = []//Global variables, pre-emptive buying id list, will described below
var sellListId = []
var APIKEY = 'your api id' //Need to fill in the BitMEX API ID here. Note that it is not a key, which is required for websocket protocol authentication.
var expires = parseInt(Date.now() / 1000) + 10
var signature = exchange.HMAC("sha256", "hex", "GET/realtime" + expires, "{{secretkey}}")//The secretkey will be automatically replaced at the bottom level and does not need to be filled in.
var bitmexClient = Dial("wss://www.bitmex.com/realtime", 60)
var auth = JSON.stringify({args: [APIKEY, expires, signature], op: "authKeyExpires"})//Authentication information, otherwise you cannot subscribe to the account
bitmexClient.write(auth)
bitmexClient.write('{"op": "subscribe", "args": ["position","execution","trade:XBTUSD"]}')//Subscribed to positions, order execution and perpetual contract real-time transaction
while(true){
    var data = bitmexClient.read()
    if(data){
        bitmexData = JSON.parse(data)
        if('table' in bitmexData && bitmexData.table == 'trade'){
            data = bitmexData.data
            ticker.price = parseFloat(data[data.length-1].price)//The latest transaction price, will push multiple transactions at a time, take one will be ok
            //You can get the "buy one" and "sell one" price according to the direction of the latest transaction, without subscribing to the depth.
            if(data[data.length-1].side == 'Buy'){
                ticker.sell = parseFloat(data[data.length-1].price)
                ticker.buy = parseFloat(data[data.length-1].price)-0.5
            }else{
                ticker.buy = parseFloat(data[data.length-1].price)
                ticker.sell = parseFloat(data[data.length-1].price)+0.5
            }
            ticker.time =  new Date(data[data.length-1].timestamp);//Update time, can be used to determine the delay
        }
    }else if(bitmexData.table == 'position'){
        var position = parseInt(bitmexData.data[0].currentQty)  
        if(position != info.position){
            Log('Position change: ', position, info.position, '#FF0000@')//Position change Log, and pushed to WeChat, remove @ means Do not push
            info.position = position  
        }
        info.position  = parseInt(bitmexData.data[0].currentQty)  
    }
}

4. Умение отдавать приказы

BitMEX официально рекомендует использовать объемный заказ и модификацию заказа для размещения заказа. объемный заказ может быть выполнен быстрее из-за аудита в режиме реального времени BitMEX, проверки рисков, расчета маржи и ввода в эксплуатацию. Поэтому частота объемного заказа рассчитывается как одна десятая от нормальной частоты. Кроме того, наша операция заказа должна использовать метод объемного заказа и модификации заказа для минимизации использования API. Статус заказа запроса также должен потреблять API с использованием частоты. Он может судить о статусе заказа в соответствии с изменением или неудачей позиции заказа модификации.

объемный заказ не ограничивает количество заказов (не может быть слишком много), на самом деле, один заказ также может использовать интерфейс объемный заказ. Из-за операции модификации заказа мы можем предварительный заказ некоторых заказов, где цена сильно отклоняется, эти заказы не будут выполнены, но когда нам нужно разместить заказ, нам нужно только изменить цену и количество размещенного заказа. когда при изменении заказа происходит сбой, он также может быть использован в качестве сигнала для выполнения заказа.

Ниже приводится конкретный код реализации:

// Cancel all orders and reset global variables
function cancelAll(){
    exchange.IO("api","DELETE","/api/v1/order/all","symbol=XBTUSD")//Call IO extension revocation
    info = {position:0, buyPrice:0, sellPrice:0, buyAmount:0, sellAmount:0, buyState:0, sellState:0, buyId:0, sellId:0}
    buyListId = []
    sellListId = []
}
//placing alternate order
function waitOrders(){
    var orders = []
    if(buyListId.length<4){
        //When the number of inspections is insufficient, place another "bulk"
        for(var i=0;i<7;i++){
            //Due to BitMEX restrictions, the price can not be excessively excessive, the order quantity can not be too small, and the "execInst" parameter guarantees that only the market making transaction can be executed.
            orders.push({symbol:'XBTUSD', side:'Buy', orderQty:100, price:ticker.buy-400+i, execInst:'ParticipateDoNotInitiate'})
        }
    }
    if(sellListId.length<4){
        for(var i=0;i<7;i++){
            orders.push({symbol:'XBTUSD', side:'Sell', orderQty:100, price:ticker.buy+400+i, execInst:'ParticipateDoNotInitiate'})
        }
    }
    if(orders.length>0){
        var param = "orders=" + JSON.stringify(orders);
        var ids = exchange.IO("api", "POST", "/api/v1/order/bulk", param);//Bulk orders submitted here
        for(var i=0;i<ids.length;i++){
            if(ids.side == 'Buy'){
                buyListId.push(ids.orderID)
            }else{
                sellListId.push(ids.orderID)
            }
        }
    }
}
//Modify order function
function amendOrders(order, direction, price, amount, id){
    var param = "orders=" + JSON.stringify(order);
    var ret = exchange.IO("api", "PUT", "/api/v1/order/bulk", param);//Modify one order at a time
    //Modification occurs error
    if(!ret){
        var err = GetLastError()
        //overloaded unmodified strategy, need to recycle the order id
        if(err.includes('The system is currently overloaded')){
            if(id){
                if(direction == 'buy'){
                    buyListId.push(id)
                }else{
                    sellListId.push(id)
                }
            }
            Sleep(1000)
            return
        }
        //Illegal order status, indicating that the order to be modified has been completely executed
        else if(err.includes('Invalid ordStatus')){
            Log(order, direction)
            if(direction == 'buy'){
                info.buyId = 0
                info.buyState = 0
                info.buyAmount = 0
                info.buyPrice = 0
            }else{
                info.sellId = 0
                info.sellState = 0
                info.sellAmount = 0
                info.sellPrice = 0
            }
            //Since the push is not timely, update the position with the "rest" protocol here.
            pos = _C(exchange.GetPosition)
            if(pos.length>0){
                info.position = pos[0].Type == 0 ? pos[0].Amount : -pos[0].Amount
            }else{
                info.position = 0
            }
        }
        //Unknown error cannot be modified, all orders are cancelled, reset once
        else if(err.includes('Invalid orderID')){
            cancelAll()
            Log('Invalid orderID,reset once')
        }
        //Exceed the frequency limit, you can continue to try after hibernation
        else if(err.includes('Rate limit exceeded')){
            Sleep(2000)
            return
        }
        //The account is banned, all orders are revoked, and sleep is awaiting recovery for a long time.
        else if(err.includes('403 Forbidden')){
            cancelAll()
            Log('403,reset once')
            Sleep(5*60*1000)
        }
    }else{
        //Modify order successfully
        if(direction == 'buy'){
            info.buyState = 1
            info.buyPrice = price
            info.buyAmount = amount
        }else{
            info.sellState = 1
            info.sellPrice = price
            info.sellAmount = amount
        }
    }
}
//0.5 price change
function fixSize(num){
    if(num>=_N(num,0)+0.75){
        num = _N(num,0)+1
    }else if(num>=_N(num,0)+0.5){
        num=_N(num,0)+0.5
    }else{
        num=_N(num,0)
    }
    return num
}
//Trading function
function trade(){
    waitOrders()//Check if you need a replacement order
    var buyPrice = fixSize(ticker.buy-5) //For demonstration purposes only, specific transactions should be written by yourself.
    var sellPrice = fixSize(ticker.sell+5)
    var buyAmount =  500
    var sellAmount = 500
    //Modify from an alternate order when there is no order
    if(info.buyState == 0  && buyListId.length > 0){
        info.buyId = buyListId.shift()
        amendOrders([{orderID:info.buyId, price:buyPrice, orderQty:buyAmount}],'buy', group, buyPrice, buyAmount, info.buyId)
    }
    if(info.sellState == 0 && sellListId.length > 0){
        info.sellId = sellListId.shift()
        amendOrders([{orderID: info.sellId, price:sellPrice, orderQty:sellAmount}],'sell', group, sellPrice, sellAmount, info.sellId )
    }
    //Existing orders need to change price
    if(buyPrice !=  info.buyPrice && info.buyState == 1){
        amendOrders([{orderID:info.buyId, price:buyPrice, orderQty:buyAmount}],'buy', group, buyPrice, buyAmount)
    }
    if(sellPrice != info.sellPrice && info.sellState == 1){
        amendOrders([{orderID:info.sellId, price:sellPrice, orderQty:sellAmount}],'sell', group, sellPrice, sellAmount)
    }
}

5. Другие

Сервер BitMEX находится на сервере Amazon в Дублине, Ирландия. Пинг сервера менее 1 мс, когда вы выбираете облачный сервер AWS в Дублине, но когда все еще есть задержка в продвижении, проблема перегрузки не может быть решена. Кроме того, когда учетная запись вводится, агент сервера не может быть расположен в Соединенных Штатах и других местах, где не разрешается торговля криптовалютами. Из-за регулирования учетная запись будет запрещена.

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


Больше

gmgphilКоннектор WS дает ошибку: Ошибка ссылки: идентификатор "данные" не определен в...

ТраваОшибка кода, проблема решена.