BitMEXの待機注文戦略の詳細な説明

作者: リン・ハーン優しさ, 作成日:2019-01-16 15:28:13, 更新日:2019-01-22 14:16:48

BitMEXは仮想通貨レバレッジ取引の好みのプラットフォームとなっていますが,API取引の制限は厳しく,自動トレーダーは非常に混乱しています.この記事は主にFMZ定量取引プラットフォームにおけるAPIの使用に関するいくつかのヒントをシェアしています.主にマーケットメーキング戦略のために.

1. BitMEX の特徴

最も重要な利点は,取引流動性が非常に活発であること,特にビットコイン永続契約では,毎分取引額が100万ドル,あるいは1000万米ドルを超えることが多い.BitMEXの待機注文取引には返金手数料のポリシーがありますが,それはあまり多くありませんが,多くの市場作取引を惹き付け,価格深度が非常に豊かになりました.最新の買い売り価格にはしばしば100万ドル以上の待機注文があります.この点のために,取引価格はしばしば0.50ドルの最低変更単位の周りに変動します.

2.BitMEX API の周波数制限

REST APIのリクエスト頻度は,5分ごとに300回に制限されており,ほぼ1秒に1回に等しい.この制限は他の取引プラットフォームと比較して非常に厳格であると言えます.制限を超えると,Rate limit exceededが提示されます.制限を超え続けると,IPが1時間停止する可能性があります.短時間で複数の無効化により,1週間無効になります.各APIリクエストに対して,BitMEXはヘッダーデータを返します.ヘッダーデータは残りのリクエストの現在の数を表示するために使用されます.実際には,APIが正しく使用されれば,周波数制限を超えておらず,一般的にチェックする必要はありません.

3.Webソケットを使って市場価格を入手

BitMEX REST API はより制限的です.公式の推奨は,ウェブソケットプロトコルをより多く使用し,平均的な交換よりも多くのデータタイプをプッシュすることです.特定の使用のために以下のポイントに注意してください:

深度データプッシュ時間が長すぎると,実際の深さとは一致しないエラーが発生します.深度変更が多すぎると推定され,プッシュには省略がありますが,一般的に,優れた流動性により,tickerまたはtradesに購読することができます. 注文の詳細は 欠落し ほとんど利用できません アカウント情報のプッシュにはかなりの遅延があり,REST API を使用することが望ましい. 市場の変動が大きすぎると プッシュ遅延は数秒に達します 次のコードは,主にマーケットメーキング戦略のために,リアルタイムで市場およびアカウント情報を取得するために,webソケットプロトコルを使用しています. 特定の使用はメインの機能で実行する必要があります.

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分の"として計算されます.さらに,私たちの注文操作は,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のサーバーにあります.AWSのクラウドサーバをダブリンで選択すると,サーバーの実行戦略ピングは1ms未満ですが,まだプッシュに遅れがある場合,オーバーロード問題は解決できません.また,アカウントがログインされたとき,サーバーエージェントは,仮想通貨取引を許可しない米国および他の場所には位置することができません.規制により,アカウントは禁止されます.

この記事のコードは,私の個人的な戦略から修正され,参照のために完全に正確であることを保証されません. 市場のコードの特定の使用は,メイン機能で実行され,取引に関連するコードはメイン機能の前に置かれ,トレード() 機能はプッシュマーケットのコートに置かれます.


もっと

gmgphilWSコンネクタがエラーを出しています. ReferenceError: 識別子 'data' は定義されていない...

小草コードエラー,問題解決