بائننس ملٹی کرنسیز آٹومیشن ٹریڈنگ حکمت عملی API آپریشن گائیڈ

مصنف:نیکی, تخلیق: 2019-01-22 10:34:09, تازہ کاری:

اگرچہBinance.comبی ٹی سی کو ایک طویل عرصے سے قائم نہیں کیا گیا ہے ، اس کی عمدہ ٹکنالوجی کی وجہ سے ، اے پی آئی مستحکم اور موثر ہے ، درخواست کی تعدد کی حد بھی نرمی ہے ، اور بہت سارے سکے اور فعال لین دین موجود ہیں ، جو پہلے ہی اسپاٹ ٹریڈنگ کا ترجیحی پلیٹ فارم ہے۔ فی الحال ، 150 سے زیادہ اقسام کی کرنسیاں ہیں جن کی قیمت بی ٹی سی کے ذریعہ ہے ، اور وہ اب بھی بڑھ رہی ہیں ، جس کی وجہ سے بہت ساری کرنسیوں کی قیمتوں اور کے لائن کو حاصل کرنا مشکل ہے۔ اس مضمون میں بنیادی طور پر ایف ایم زیڈ کی کوانٹیٹیٹیو ٹریڈنگ پلیٹ فارم پر ملٹی کرنسی کی حکمت عملیوں کو چلانے کا طریقہ متعارف کرایا جائے گا ، اور یہاں تک کہ تمام کرنسیوں کو بغیر کسی پریشانی کے چلانے کے لئے ، بنیادی طور پر ایک خاص علمی بنیاد والے صارفین کے لئے۔

1۔ مارکیٹ کی قیمت حاصل کریں

اگر آپ ایک ہی وقت میں 150 کرنسیوں کو چلانا چاہتے ہیں تو ، مارکیٹ کی قیمت حاصل کرنے کے لئے REST پروٹوکول کا استعمال کرنا ظاہر ہے کہ یہ مناسب نہیں ہے۔ پولنگ کے بعد یہ بہت زیادہ وقت ضائع کرے گا ، اور ویب ساکٹ ایک ہی وقت میں بہت ساری کرنسیوں کو سبسکرائب نہیں کرسکتا ہے۔Binance.comمارکیٹ کوٹ حاصل کرنے کے لئے کثیر قسم کی حکمت عملی کا مسئلہ سمجھتا ہے، اور ایک مجموعی مارکیٹ کوٹ انٹرفیس فراہم کرتا ہے.

جب براہ راست اس REST انٹرفیس (/api/v1/ticker/24hr) کا استعمال کرتے ہیں تو ، نوٹ کرنا ضروری ہے کہ اس کا وزن 40 ہے ، اس کا مطلب یہ ہے کہ ایک رسائی عام طور پر 40 بار تک رسائی کے برابر ہے ، یہاں تک کہ اگر آپ اس انٹرفیس تک 5 یا 6 سیکنڈ میں ایک بار رسائی حاصل کرتے ہیں تو ، حد سے تجاوز کرنا بھی ممکن ہے۔

لہذا ، ہمیں اس انٹرفیس کے ویب ساکٹ ورژن تک رسائی حاصل کرنے کی ضرورت ہے ، لیکن اس بات سے آگاہ رہیں کہ بڑی مقدار میں ڈیٹا کی وجہ سے ، اعداد و شمار کو مارکیٹ میں ہونے والی تبدیلیوں کے ساتھ اعداد و شمار کو آگے بڑھانے کے لئے صرف 1s کے لئے طے کیا جاتا ہے۔ کچھ غیر مقبول کرنسیوں کے لئے جو کچھ منٹ سے تجارت نہیں کی گئی ہے ، اسے طویل عرصے تک آگے نہیں بڑھایا جاسکتا ہے۔ فکسڈ پش اوقات اعلی تعدد کی حکمت عملی کے لئے موزوں نہیں ہیں ، لیکن عام ملٹی کرنسی کی حکمت عملی کے لئے کافی ہیں۔ مخصوص کوڈ مندرجہ ذیل ہے:

function main() {
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
    while (true){
        var data = client.read();
        var msg = JSON.parse(data);
        updateTicker(msg);//The updateTicker function handles market quotes and transactions, which will be introduced below.
    }
}

تجارت سے پہلے تیاری

بائننس میں تجارت ، کم سے کم ٹرانزیکشن ویلیو ، کم سے کم ٹرانزیکشن حجم ، قیمت کی درستگی ، اور ٹرانزیکشن حجم کی درستگی پر بہت سی پابندیاں ہیں۔ ان کو پہلے سے تیار کرنے کی ضرورت ہے۔

Defined global variables:

var totalbtc = 0;//Total value, not necessarily btc
var baseCoin = ['BTC', 'ETH', 'BNB', 'USDT'][baseCoin_select];//Base currency selection baseCoin_select is a parameter of the drop-down box
var exceptList = Except_list_string.split(',');//Excluded currency, Except_list_string is the strategy parameter
//K line cycle selects PERIOD_M1, PERIOD_M5 is FMZ default global variable
var period = [PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H1, PERIOD_D1][period_select]
var periodSecond = [60, 300, 900, 1800, 3600, 3600*24][period_select]//The number of seconds corresponding to each cycle
var lastPeriodTime = 0;//The most recent cycle time, used to update the K line
var updateProfitTime = 0//Recently updated earnings time to update revenue
var buyList = []//buying order list
var sellList = []//selling order list
var accountInfo = {};//Used to store transaction related data lists

اگلا مرحلہ اکاؤنٹ انفو کے مواد کو بہتر بنانا ہے ، اور ٹریڈنگ جوڑی سے متعلق تمام مواد اس میں محفوظ ہیں۔

if (!_G('accountInfo')){//If accountInfo is not stored in the database, reacquire the data.
    var exchangeInfo = JSON.parse(HttpQuery('https://api.binance.com/api/v1/exchangeInfo'));//Get transaction related data
    var ticker = JSON.parse(HttpQuery('https://api.binance.com/api/v1/ticker/24hr'));//First use the rest protocol to get a full amount of ticker
    var tradeSymbol = exchangeInfo.symbols.filter(function(x){return x.quoteAsset == baseCoin});//Filter the required trading pairs
    accountInfo[baseCoin] = {free:0, frozen:0, last:1, value:0};//Base currency information
    for (var i=0; i<tradeSymbol.length; i++){
        var info = tradeSymbol[i];
        if(exceptList.indexOf(info.symbol.slice(0,info.symbol.length-baseCoin.length)) >= 0){
            continue;//Filter out the currencies that was kicked out
        }
        for (var j=0; j<ticker.length; j++){
            var symbol = info.symbol.slice(0,info.symbol.length-baseCoin.length)//Currency name
            if(ticker[j].symbol.slice(ticker[j].symbol.length-baseCoin.length) == baseCoin && ticker[j].symbol == info.symbol){
                //The stored contents of the exchangeInfo and ticker
                accountInfo[symbol] = {
                    last:parseFloat(ticker[j].lastPrice), free:0, frozen:0, 
                    minQty:parseFloat(info.filters[2].minQty), minNotional:parseFloat(info.filters[3].minNotional)
                    tickerSize:parseFloat(info.filters[0].tickSize), stepSize:parseFloat(info.filters[2].stepSize),
                    ask:parseFloat(ticker[j].askPrice), bid:parseFloat(ticker[j].bidPrice), volume:parseFloat(ticker[j].quoteVolume), 
                    lowPrice:parseFloat(ticker[j].lowPrice), highPrice:parseFloat(ticker[j].highPrice),
                    priceChangePercent:parseFloat(ticker[j].priceChangePercent),
                    sellPrice:0, buyPrice:0, state:0, value:0, records:null
                }
                break;
            }
        }
    }
}else{
    accountInfo = _G('accountInfo');
}
//Automatically save accountInfo to the database when exiting
function onexit(){
    _G('accountInfo', accountInfo);
}

اکاؤنٹ اور K لائن کی معلومات کو اپ ڈیٹ کریں

اکاؤنٹ کی معلومات کی تقریب کو حقیقی وقت کی تازہ کاریوں کے بغیر اپ ڈیٹ کریں۔

function updateAccount(){
    account = exchange.GetAccount();
    if (!account){
        Log('time out');
        return;//Returning directly here is to save time, and the account information acquisition is not affected in time.
    }
    for (var i=0; i<account.Info.balances.length; i++){
        var symbol = account.Info.balances[i].asset
        //Are stored in accountInfo
        if (symbol in accountInfo){
            accountInfo[symbol].free = parseFloat(account.Info.balances[i].free);
            accountInfo[symbol].frozen = parseFloat(account.Info.balances[i].locked);
            accountInfo[symbol].value = (accountInfo[symbol].free + accountInfo[symbol].frozen)*accountInfo[symbol].last
        }
    }
}
//Update the current account total value in the selected base currency
function updateTotalBTC(){
    var btc = 0;
    for (var symbol in accountInfo){
        btc += accountInfo[symbol].value
    totalbtc = btc;
    }
}

Update the K line, the initial update can use the GetRecords function in stages, and the later update uses push data synthesis.

function initRecords(){    
    for (var symbol in accountInfo){
        if(symbol == baseCoin){continue}
        if(!accountInfo[symbol].records){
            var currency = symbol + '_' + baseCoin;
            //Switch trading pair
            exchange.IO("currency", currency)
            accountInfo[symbol].records = exchange.GetRecords(period)
            Log('Update', currency, 'K line', accountInfo[symbol].records[accountInfo[symbol].records.length-1])
            Sleep(250)//Update four per second, no limit will be reached
        }
        //Recent K-line time
        lastPeriodTime = Math.max(accountInfo[symbol].records[accountInfo[symbol].records.length-1].Time/1000, lastPeriodTime)
    }
}
//Update K line based on push ticker data
function updateRecords(msgTime){
    //If the current time is greater than the last updated cycle, it indicates that a new K line needs to be generated.
    if(parseFloat(msgTime)/1000 - lastPeriodTime > periodSecond){
        for (var symbol in accountInfo){
            if(symbol != baseCoin){
                //If the K line missing of a trading pair is too much, it will be re-acquired once, it may be that the transaction is not active, ticker did not push
                if(parseFloat(msgTime)/1000 - accountInfo[symbol].records[accountInfo[symbol].records.length-1].Time/1000 > 1.5*periodSecond){
                    var currency = symbol + '_' + baseCoin;
                    exchange.IO("currency", currency)
                    var records = exchange.GetRecords(period)
                    if(records){
                        accountInfo[symbol].records = exchange.GetRecords(period)
                    }
                    Log(symbol, 'K line is missing, regain')
                }else{
                    //Push a new K line
                    accountInfo[symbol].records.push({"Time":parseInt(lastPeriodTime + periodSecond)*1000, "Open":accountInfo[symbol].last, "High":accountInfo[symbol].last,
                    "Low":accountInfo[symbol].last, "Close":accountInfo[symbol].last, "Volume":0})
                }
            }
        }
        lastPeriodTime = lastPeriodTime + periodSecond
        Log(parseFloat(msgTime)/1000, 'Adding K line')
    }else{
        //If it is in the current K line cycle, update the current K line
        for (var symbol in accountInfo){
            if(symbol != baseCoin){
                var length = accountInfo[symbol].records.length
                accountInfo[symbol].records[length-1].Close = accountInfo[symbol].last
                accountInfo[symbol].records[length-1].Volume += accountInfo[symbol].volume
                if(accountInfo[symbol].last > accountInfo[symbol].records[length-1].High){
                    accountInfo[symbol].records[length-1].High = accountInfo[symbol].last 
                }
                else if(accountInfo[symbol].last < accountInfo[symbol].records[length-1].Low){
                    accountInfo[symbol].records[length-1].Low = accountInfo[symbol].last
                }
            }
        }
    }
}

4.Tradingمتعلقہ فنکشن

//Cancel current trading pair orders
function CancelPendingOrders() {
    var orders = _C(exchange.GetOrders);
    for (var j = 0; j < orders.length; j++) {
        exchange.CancelOrder(orders[j].Id, orders[j]);
    }
}
//Cancel all trading pair orders
function cancellAll(){
    try{
        var openOrders = exchange.IO('api', 'GET', '/api/v3/openOrders');
        for (var i=0; i<openOrders.length; i++){
            var order = openOrders[i];
            var currency = order.symbol.slice(0,order.symbol.length-baseCoin.length) + '_' + baseCoin;
            exchange.IO("currency", currency);
            exchange.CancelOrder(order.orderId);
        }
    }
    catch(err){
        Log('Cancel order failed');
    }
    for (var symbol in accountInfo){
        accountInfo[symbol].state = 0;
        accountInfo[symbol].buyprice = 0;
        accountInfo[symbol].sellPrice = 0;
    }
}
//Placing the buying long order 
function toBuy(){
    //The currencies you need to buy are stored in the buyList
    if (buyList.length == 0){
        return;
    }
    for (var i=0; i<buyList.length; i++){
        var symbol =  buyList[i];
        //Slippage is the "selling price 1" plus minimum trading unit, may not be completely executed immediately, you can modify it yourself
        var buyPrice = accountInfo[symbol].ask + accountInfo[symbol].tickerSize;
        buyPrice = _N(buyPrice, parseInt((Math.log10(1.1/accountInfo[symbol].tickerSize))));//Meet price accuracy
        var currency = symbol + '_' + baseCoin;
        exchange.IO("currency", currency);//Switch trading pair
        //If you have placed an order and the price is same as this one, do not operate.
        if (accountInfo[symbol].state && accountInfo[symbol].bid == accountInfo[symbol].buyprice){
            continue;
        }else{
            //Order placed first will be cancelled first
            if (accountInfo[symbol].state == 1){
                CancelPendingOrders();
                accountInfo[symbol].state = 0;
                accountInfo[symbol].buyprice = 0;
            }
            var amount = (accountInfo[symbol].free + accountInfo[symbol].frozen)*buyPrice; //Value of existing currency
            var needBuyBTC = HoldAmount - amount;//HoldAmount is a global parameter, which require value of the hold
            var buyAmount = needBuyBTC/buyPrice;
            buyAmount = _N(scale*buyAmount, parseInt((Math.log10(1.1/accountInfo[symbol].stepSize))));//Order quantity accuracy
            //Meet minimum transaction volume and minimum transaction value requirements
            if (buyAmount > accountInfo[symbol].minQty && buyPrice*buyAmount > accountInfo[symbol].minNotional){
                if (accountInfo[baseCoin].free < buyPrice*buyAmount){return;}//Have enough base currency to buy
                var id = exchange.Buy(buyPrice, buyAmount, currency);//Final order
                if(id){
                    accountInfo[symbol].buyprice = buyPrice;
                    accountInfo[symbol].state = 1;
                }
            }
        }
        //If the buying orders are too much, it need a pause, Binance allows 10 orders every 1s maximum
        if(buyList.length > 5){
            Sleep(200)
        }
    }
}
//Placing the selling orders principles are similar to the buying orders
function toSell(){
    if (sellList.length == 0){
        return;
    }
    for (var i=0; i<sellList.length; i++){
        var currency = symbol + '_' + baseCoin;
        exchange.IO("currency", currency);
        var sellPrice = accountInfo[symbol].bid - accountInfo[symbol].tickerSize;
        sellPrice = _N(sellPrice, parseInt((Math.log10(1.1/accountInfo[symbol].tickerSize))));
        if (accountInfo[symbol].state == 1 && accountInfo[symbol].bid != accountInfo[symbol].buyprice){
            CancelPendingOrders();
            accountInfo[symbol].state = 0;
            accountInfo[symbol].sellPrice = 0;
        }
        var sellAmount = accountInfo[symbol].free;
        sellAmount = _N(Math.min(scale*sellAmount,accountInfo[symbol].free), parseInt((Math.log10(1.1/accountInfo[symbol].stepSize))));
        if (sellAmount > accountInfo[symbol].minQty && sellPrice*sellAmount > accountInfo[symbol].minNotional){
            var id = exchange.Sell(sellPrice, sellAmount, currency);
            if(id){
                accountInfo[symbol].state = 1;
                accountInfo[symbol].sellPrice = sellPrice;
            }
        }
        if(sellList.length > 5){
            Sleep(200)
        }
    }
}

5.Tradingمنطق

تجارت بہت سادہ ہے، صرف خرید و فروخت کی کرنسی کو buyList اور sellList پر دھکیلیں.

function checkTrade(){
    buyList = []
    sellList = []
    for(var symbol in accountInfo){
        if(symbol == baseCoin){
            continue
        }
        var length = accountInfo[symbol].records.length
        //Simple moving average, this is a simple demonstration example, don't use it at the real market.
        var fast = TA.MA(accountInfo[symbol].records, FastPeriod)[length-1]
        var slow = TA.MA(accountInfo[symbol].records, SlowPeriod)[length-1]
        if(accountInfo[symbol].value > 2*accountInfo[symbol].minNotional && fast < 0.99*slow){
            sellList.push(symbol)
        }
        //HoldAmount strategy parameter
        if(accountInfo[symbol].value < 0.9*HoldAmount && fast > 1.01*slow){
            buyList.push(symbol)
        }
    }
}

روبوٹ انٹرفیس کی حیثیت اور ٹکر کو اپ ڈیٹ کریں

بہت ساری تجارتی کرنسیوں کو کیسے ظاہر کیا جائے یہ بھی ایک مسئلہ ہے۔ خوش قسمتی سے ، ایف ایم زیڈ کوانٹیٹیو پلیٹ فارم ایک مکمل ٹیبل فنکشن مہیا کرتا ہے۔ اسے نمبر کے لحاظ سے بھی ترتیب دیا جاسکتا ہے ، جو آسان اور آسان ہے۔ جب بھی ویب ساکٹ ٹکر کو آگے بڑھاتا ہے تو ، یہ ایونٹ سے چلنے والے ، لین دین اور مختلف اپ ڈیٹ منطق کی وجہ سے اپ ڈیٹ ہوجاتا ہے۔

function updateStatus(msgTime){
    //The specific data to be displayed can be defined by itself.
    var table = {type: 'table', title: 'Position information', 
             cols: ['Currency', 'Bid', 'Ask','Last', 'Lowest price','Highest price','Price Amplitude','Volume','buying price','Selling price', 'frozen','Available','Present value'],
             rows: []};
    for (var symbol in accountInfo){
        if(symbol == baseCoin){
            var infoList = [symbol,0, 0, 1,0, 0, 0,0, 0, 0, 0, _N(accountInfo[symbol].frozen,4),_N(accountInfo[symbol].free,4), _N(accountInfo[symbol].value,5)];
        }else{
            var infoList = [symbol,accountInfo[symbol].bid, accountInfo[symbol].ask, accountInfo[symbol].last,
                        accountInfo[symbol].lowPrice, accountInfo[symbol].highPrice, accountInfo[symbol].priceChangePercent,
                        _N(accountInfo[symbol].volume,2), accountInfo[symbol].buyPrice, accountInfo[symbol].sellPrice,
                        _N(accountInfo[symbol].frozen,4),_N(accountInfo[symbol].free,4), _N(accountInfo[symbol].value,5)];
        }
        table.rows.push(infoList);
    }
    var logString = _D() + ' Net value:' + _N(totalbtc,6) + (typeof(msgTime) == 'number' ? (', Latest market time: ' + _D(msgTime)) : '') + '\n';
    logString += 'The currency to be bought:' + buyList.join(',') + ' \n';
    logString += 'The currency to be sold:' + sellList.join(',') + ' \n';
    logString += 'Currently available'+ baseCoin + ':' + _N(accountInfo[baseCoin].free,6) + ',frozen:' + _N(accountInfo[baseCoin].frozen,6)  + '\n';
    LogStatus(logString + '`' + JSON.stringify(table) + '`');//Update to robot interface
}
//Every time pushes the ticker, it is updated because of the event-driven, transactional and various update logic.
function updateTicker(msg){
    var ticker = msg;
    var msgTime = 0;
    for (var i=0; i<ticker.length; i++){
        msgTime = Math.max(msgTime, ticker[i].E);
        var symbol = ticker[i].s.slice(0,ticker[i].s.length-baseCoin.length)
        if (ticker[i].s.slice(ticker[i].s.length-baseCoin.length) == baseCoin && parseFloat(ticker[i].c) && symbol in accountInfo){
            accountInfo[symbol].last = parseFloat(ticker[i].c);
            accountInfo[symbol].volume = _N(parseFloat(ticker[i].q),1);
            accountInfo[symbol].lowPrice = parseFloat(ticker[i].l);
            accountInfo[symbol].highPrice = parseFloat(ticker[i].h);
            accountInfo[symbol].ask = parseFloat(ticker[i].a);
            accountInfo[symbol].bid = parseFloat(ticker[i].b);
            accountInfo[symbol].priceChangePercent = parseFloat(ticker[i].P);
            accountInfo[symbol].value = (accountInfo[symbol].free + accountInfo[symbol].frozen)*accountInfo[symbol].last
        }
    }
    if (Date.now() - updateProfitTime > LogProfitTime*1000){
        updateAccount();
        updateProfitTime = Date.now();//Reset revenue time
        LogProfit(totalbtc);//Update revenue
    }
    updateRecords(msgTime)//Update K line
    updateTotalBTC();//Update total market value
    updateStatus(msgTime);//Update robot status
    checkTrade()//Check which orders need to be placed
    toBuy();//placing buying order
    toSell();//placing selling order
}

7.معاہدہ کا خلاصہ

function main() {
    cancellAll();
    initRecords()
    updateAccount();
    updateTotalBTC()
    Log('Total transaction digital currency:', Object.keys(accountInfo).length-1);
    updateStatus();
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
    while (true){
        var data = client.read();
        var msg = JSON.parse(data);
        updateTicker(msg);
    }
}

8.Summary

اس مضمون میں بنیادی طور پر بائننس ملٹی کرنسی ٹریڈنگ فریم ورک دکھایا گیا ہے ، جس میں بنیادی طور پر ٹریڈنگ کی معلومات کو اسٹور کرنے ، ٹکر کے مطابق K- لائن کو کس طرح ترکیب کرنے ، آرڈر دینے ، حکمت عملی کے چارٹ کو ظاہر کرنے اور ٹکر پش ایونٹس کی بنیاد پر ٹریڈنگ کو متحرک کرنے کا طریقہ شامل ہے۔ بہت ساری جگہیں ہیں جن کو تبدیل اور اپنی مرضی کے مطابق بنایا جاسکتا ہے۔ یہ سب میری ذاتی حکمت عملی سے نکالا گیا ہے۔ اس کا مطلب ایک بگ ہوسکتا ہے اور یہ صرف ان صارفین کے لئے ہے جن کے پاس ایک خاص علمی بنیاد ہے۔


مزید