리소스 로딩... 로딩...

BitMEX의 대기 주문 전략에 대한 자세한 설명

저자:선함, 2019-01-16 15:28:13, 업데이트: 2019-01-22 14:16:48

BitMEX는 암호화폐 레버리지 거래의 선택의 플랫폼이 되었지만 API 거래 제한은 엄격하며 자동 거래자가 매우 혼란스러워합니다. 이 기사는 주로 시장 제작 전략에 대한 FMZ 양적 거래 플랫폼에서 API 사용에 대한 몇 가지 팁을 공유합니다.

1. BitMEX의 특징

가장 중요한 장점은 거래 유동성이 매우 활발하다는 것입니다. 특히 비트코인 영구계약, 매분 거래 금액은 종종 100만 달러 또는 심지어 1천만 달러를 초과합니다. BitMEX 대기 주문 거래는 수익 수수료의 정책을 가지고 있지만, 많은 것은 아니지만 많은 수의 시장을 만드는 거래를 유치하여 가격 깊이를 매우 풍부하게 만들었습니다. 최신 구매 및 판매 가격은 종종 백만 달러 이상의 가치가 있습니다. 대기 주문; 이 점 때문에 거래 가격은 종종 최소 변화 단위인 $0.50 주위를 변동합니다.

2.BitMEX API 주파수 제한

REST API의 요청 빈도는 5분마다 300번으로 제한되어 있으며, 거의 1초에 1번과 같으며, 이 제한은 다른 거래 플랫폼에 비해 매우 엄격하다고 할 수 있다. 제한을 초과한 후, Rate limit exceeded이 요청된다. 제한을 계속 초과하면 IP가 1시간 동안 비활성화 될 수 있다. 짧은 시간에 여러 번 비활성화하면 일주일 동안 비활성화 될 수 있다. 각 API 요청에 대해 BitMEX는 헤더 데이터를 반환하고, 헤더 데이터는 남은 요청의 현재 수를 보기 위해 사용된다. 사실, API가 올바르게 사용된다면, 빈도 제한을 초과하지 않으며 일반적으로 확인할 필요가 없다.

3.시장 코트를 얻기 위해 웹소켓을 사용하십시오.

BitMEX REST API는 더 제한적입니다. 공식적인 권장 사항은 웹소켓 프로토콜을 더 많이 사용하고 평균 교환보다 더 많은 데이터 유형을 푸시하는 것입니다. 특정 사용을 위해 다음 점에 주의하십시오.

깊이 데이터 푸시 시간이 너무 길다면 실제 깊이와 일치하지 않는 오류가 발생할 것입니다. 푸시에서 너무 많은 깊이 변화가 있고 방치가 있다고 추정되지만 일반적으로 뛰어난 유동성으로 인해 ticker 또는 trades에 가입 할 수 있습니다. 주문 세부사항은 거의 없습니다. 계정 정보 전달에 상당한 지연이 있습니다. REST API를 사용하는 것이 좋습니다. 시장의 변동성이 너무 커지면, 푸시 지연은 몇 초에 도달합니다. 다음 코드는 웹소켓 프로토콜을 사용하여 시장 및 계정 정보를 실시간으로 얻으며, 주로 시장 제작 전략을 위해 사용합니다. 특정 사용은 메인 () 기능에서 수행해야합니다.

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 실시간 감사, 위험 검사, 마진 계산 및 시공으로 인해 량 주문을 더 빠르게 실행할 수 있습니다. 따라서 량 주문의 빈도는 정상적인 빈도의 10분의 1로 계산됩니다. 또한, 우리의 주문 작업은 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의 서버는 아일랜드 더블린에 있는 아마존의 서버에 있습니다. 더블린에 있는 AWS 클라우드 서버를 선택할 때 서버 실행 전략 핑은 1ms 미만이지만, 여전히 푸싱에 지연이 있을 때 과부하 문제가 해결될 수 없습니다. 또한, 계정이 로그인 될 때, 서버 에이전트는 미국 및 암호화폐 거래가 허용되지 않는 다른 곳에서 위치할 수 없습니다. 규제로 인해 계정은 금지 될 것입니다.

이 문서의 코드는 내 개인적인 전략에서 수정되었으며 참조를 위해 완전히 정확 할 수 있다고 보장되지 않습니다. 시장 코드의 특정 사용은 주요 함수에서 실행되어야하며, 거래 관련 코드는 주요 함수 이전에 배치되며, 거래 () 함수는 푸시 시장 코트에 배치됩니다.


더 많은

gmgphilWS 커넥터에서 오류가 발생했습니다. 참조 오류: 식별자 '데이터'는 정의되지 않았습니다...

초목코드 오류, 문제 해결