jaggedsoft / node-binance-api

Node Binance API is an asynchronous node.js library for the Binance API designed to be easy to use.
MIT License
1.58k stars 767 forks source link

(Newcomer) Async handling problem regarding binance.depth #287

Closed Tribic closed 5 years ago

Tribic commented 6 years ago

Handling Code for working with an array of symbols Hi there, i´m pretty new to node js, but i managed to connect from windows10 to binance an get nearly exactly what i wanted to. Thanks to this great API! My Strategy is based on bids and asks, so i´m using the binance.depth function and added some calculation and concole.log code to it.

Now the problem: when i put a loop around binace.depth the results are sometimes wrong, mainly because of the wrong order.

symbol2 = ["BNBBTC","VETBTC","QTCBTC"];
    for (let value of symbol2) {
        binance.depth(value, function (error, json) {
            let max = 20; // Use 20 closest orders only
            let bids = binance.sortBids(json.bids, max);
            console.log("whatever");
            //some more code
        });
        console.log('Done');
    };

Result:

Done Done Done whatever1 whatever2 whatever3

or

Done Done Done whatever2 whatever1 whatever3

How can it be achieved, that the following loop awaits the finish of the one before? i tried async await, but it didnt work because of binance.depth function?! As i said, im pretty new to node js and async code :(

thanks in advance!

jaggedsoft commented 6 years ago

It is easier to just grab all the data at once. If you only need the best bid and ask, the bookTickers function will return the best bid/ask for every symbol. Also, you can subscribe to a WebSocket so you always have up to date data streamed to your program.

// This is a regular web request, returning bestBid, bestAsk, for all symbols
binance.bookTickers((error, ticker) => {
  console.log("bookTickers()", ticker);
  console.log("Price of BNB: ", ticker.BNBBTC);
});
View Response ```js { ETHBTC: { bid: '0.06201000', bids: '1.28200000', ask: '0.06201300', asks: '0.34200000' }, LTCBTC: { bid: '0.01042000', bids: '41.45000000', ask: '0.01048700', asks: '16.81000000' }, BNBBTC: { bid: '0.00028754', bids: '727.00000000', ask: '0.00028755', asks: '400.00000000' }, NEOBTC: { bid: '0.00601800', bids: '16.82000000', ask: '0.00603700', asks: '73.43000000' }, QTUMETH: { bid: '0.04062900', bids: '1.30000000', ask: '0.04075300', asks: '0.58000000' }, EOSETH: { bid: '0.00191400', bids: '202.53000000', ask: '0.00192500', asks: '26.08000000' }, SNTETH: { bid: '0.00007610', bids: '403.00000000', ask: '0.00007638', asks: '19850.00000000' }, BNTETH: { bid: '0.00736800', bids: '7.82000000', ask: '0.00745900', asks: '177.32000000' }, BCCBTC: { bid: '0.06862000', bids: '1.56100000', ask: '0.06893600', asks: '0.81100000' }, GASBTC: { bid: '0.00451700', bids: '44.00000000', ask: '0.00489700', asks: '44.95000000' }, BNBETH: { bid: '0.00462592', bids: '32.00000000', ask: '0.00467982', asks: '57.00000000' }, BTMETH: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, HCCBTC: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, BTCUSDT: { bid: '4786.01000000', bids: '0.58627700', ask: '4796.10000000', asks: '0.28486400' }, ETHUSDT: { bid: '297.01000000', bids: '7.17846000', ask: '297.90000000', asks: '0.30742000' }, HSRBTC: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, OAXETH: { bid: '0.00156200', bids: '96.00000000', ask: '0.00169900', asks: '552.90000000' }, DNTETH: { bid: '0.00011782', bids: '1273.00000000', ask: '0.00012045', asks: '238.00000000' }, MCOETH: { bid: '0.02651200', bids: '0.94000000', ask: '0.02681200', asks: '8.59000000' }, ICNETH: { bid: '0.00484600', bids: '448.76000000', ask: '0.00490000', asks: '0.01000000' }, ELCBTC: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, MCOBTC: { bid: '0.00164600', bids: '1.00000000', ask: '0.00164700', asks: '12.11000000' }, WTCBTC: { bid: '0.00132101', bids: '124.00000000', ask: '0.00133200', asks: '98.00000000' }, WTCETH: { bid: '0.02130000', bids: '784.35000000', ask: '0.02140800', asks: '10.70000000' }, LLTBTC: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, LRCBTC: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, LRCETH: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, QTUMBTC: { bid: '0.00252800', bids: '123.48000000', ask: '0.00253200', asks: '10.50000000' }, YOYOBTC: { bid: '0.00000000', bids: '0.00000000', ask: '0.00000000', asks: '0.00000000' }, OMGBTC: { bid: '0.00164900', bids: '25.94000000', ask: '0.00166400', asks: '0.90000000' }, OMGETH: { bid: '0.02660000', bids: '9.86000000', ask: '0.02698200', asks: '43.21000000' }, ZRXBTC: { bid: '0.00003936', bids: '117.00000000', ask: '0.00003982', asks: '8596.00000000' }, ZRXETH: { bid: '0.00062801', bids: '239.00000000', ask: '0.00063595', asks: '2446.00000000' }, STRATBTC: { bid: '0.00070600', bids: '43.43000000', ask: '0.00070900', asks: '15.00000000' }, STRATETH: { bid: '0.01092100', bids: '9.00000000', ask: '0.01162700', asks: '47.90000000' }, SNGLSBTC: { bid: '0.00003162', bids: '366.00000000', ask: '0.00003183', asks: '308.00000000' }, SNGLSETH: { bid: '0.00050064', bids: '300.00000000', ask: '0.00051543', asks: '64.00000000' }, BQXBTC: { bid: '0.00013334', bids: '13.00000000', ask: '0.00013889', asks: '1224.00000000' }, BQXETH: { bid: '0.00200740', bids: '990.00000000', ask: '0.00228890', asks: '80.00000000' }, KNCBTC: { bid: '0.00029509', bids: '300.00000000', ask: '0.00029842', asks: '4.00000000' }, KNCETH: { bid: '0.00481840', bids: '411.00000000', ask: '0.00484440', asks: '10.00000000' }, FUNBTC: { bid: '0.00000461', bids: '217.00000000', ask: '0.00000465', asks: '16668.00000000' }, FUNETH: { bid: '0.00007486', bids: '2004.00000000', ask: '0.00007617', asks: '1419.00000000' }, SNMBTC: { bid: '0.00002462', bids: '6922.00000000', ask: '0.00002495', asks: '404.00000000' }, SNMETH: { bid: '0.00040181', bids: '373.00000000', ask: '0.00043404', asks: '9281.00000000' }, NEOETH: { bid: '0.09610400', bids: '8.02000000', ask: '0.09891100', asks: '5.00000000' }, IOTABTC: { bid: '0.00009674', bids: '206.00000000', ask: '0.00009721', asks: '269.00000000' }, IOTAETH: { bid: '0.00155061', bids: '1231.00000000', ask: '0.00158100', asks: '22.00000000' }, LINKBTC: { bid: '0.00007670', bids: '2278.00000000', ask: '0.00007697', asks: '8000.00000000' }, LINKETH: { bid: '0.00123000', bids: '3492.00000000', ask: '0.00123999', asks: '4000.00000000' }, XVGBTC: { bid: '0.00000111', bids: '47758.00000000', ask: '0.00000113', asks: '215443.00000000' }, XVGETH: { bid: '0.00001801', bids: '8329.00000000', ask: '0.00001842', asks: '85146.00000000' }, CTRBTC: { bid: '0.00019801', bids: '650.00000000', ask: '0.00021103', asks: '49.00000000' }, CTRETH: { bid: '0.00320200', bids: '538.00000000', ask: '0.00351990', asks: '2081.00000000' }, SALTBTC: { bid: '0.00063900', bids: '57.13000000', ask: '0.00064000', asks: '96.48000000' }, SALTETH: { bid: '0.01030200', bids: '728.27000000', ask: '0.01038900', asks: '0.04000000' }, MDABTC: { bid: '0.00039031', bids: '282.00000000', ask: '0.00039994', asks: '540.00000000' }, MDAETH: { bid: '0.00635500', bids: '432.00000000', ask: '0.00641990', asks: '185.00000000' }, MTLBTC: { bid: '0.00145500', bids: '45.00000000', ask: '0.00145600', asks: '42.12000000' }, MTLETH: { bid: '0.02300100', bids: '96.10000000', ask: '0.02477400', asks: '131.90000000' }, SUBBTC: { bid: '0.00003250', bids: '4474.00000000', ask: '0.00003380', asks: '3878.00000000' }, SUBETH: { bid: '0.00053000', bids: '740.00000000', ask: '0.00053501', asks: '580.00000000' } } /* Price of BNB: { bid: '0.00028754', bids: '727.00000000', ask: '0.00028755', asks: '400.00000000' } */ ```
// This is a websocket, binance will send you constant updates
binance.websockets.prevDay(false, (error, response) => {
  console.log(response);
});
View Response ``` { eventType: '24hrTicker', eventTime: 1512629577435, symbol: 'BNBBTC', priceChange: '-0.00002671', percentChange: '-12.844', averagePrice: '0.00019282', prevClose: '0.00020796', close: '0.00018125', closeQty: '55.00000000', bestBid: '0.00018038', bestBidQty: '580.00000000', bestAsk: '0.00018125', bestAskQty: '144.00000000', open: '0.00020796', high: '0.00021300', low: '0.00017555', volume: '3731915.00000000', quoteVolume: '719.59011818', openTime: 1512543177433, closeTime: 1512629577433, firstTradeId: 2248079, lastTradeId: 2284725, numTrades: 36647 } ```

Having said that, I will provide a complete example of how I do it

jaggedsoft commented 6 years ago
global.bookTicker = {}; // Keep bookTicker object always updated, so you can access it anywhere in your program
binance.websockets.prevDay(false, (error, response) => {
  let symbol = response.symbol;
  global.bookTicker[symbol] = response;
  //console.log(response);
});

// this is just to show you the data we have. you can use it anywhere, for any symbol
setInterval(() => {
  // All of these variables are available: bestBid bestAsk bestBidQty bestAskQty open high low volume quoteVolume priceChange percentChange averagePrice prevClose close closeQty openTime closeTime firstTradeId lastTradeId numTrades
  console.log("BTC bid: "+global.bookTicker.BTCUSDT.bestBid+" \t best ask: "+global.bookTicker.BTCUSDT.bestAsk);
}, 3000);
Tribic commented 6 years ago

Hi, thanks for your answer :) but as i need bids and asks as arrays, it´s actually not what i thought of, but u gave me the hint of setInterval i switched my loop to setinterval - not the way it meant be by coding nodejs and your api, i think, but it works! :)

A much more elegant way? Is there a way to call the binance.depth function from outside, giving it the symbol and getting back an object, lets say myObj, so that i can work with it?

Like:

z=0;
max=20;
MySymbolArray= ["VETBTC", "BNBBTC", "XVGBTC"];

Do {

myObj = binance.depth(MySymbolArray[z]);    //  <------------------
let bids = binance.sortBids(myObj.bids, max);
let asks = binance.sortAsks(myObj.asks, max);

//make sure it´s done till here before going on somehow!!!  // <------------------

//Converting into Arrays
askQuantity = myObj.values(asks);
askPrice = myObj.keys(asks);
bidQuantity = myObj.values(bids);
bidPrice = myObj.keys(bids);
//Calculating and Output
//...
z++;
} //forever
jaggedsoft commented 6 years ago

The best way to do this is to subscribe with websockets depthCache. Then you will always have an up to date order book. You will get a notification every time there is an update.

Example:

const Binance = require('node-binance-api');
const binance = new Binance();
binance.websockets.depthCache(["BTCUSDT"], function(symbol, depth) {
    let max = 9; // Only show the 9 best bids / asks (optional)
    let baseVolume = true; // Show results in BTC/ETH/USDT value (optional)
    let bids = binance.sortBids(depth.bids, max, baseVolume);
    let asks = binance.sortAsks(depth.asks, max, baseVolume);
    console.log("asks", binance.reverse(asks));
    console.log("bids", bids);
    let askvol = binance.sum(Object.values(asks));
    let bidvol = binance.sum(Object.values(bids));
    let ratio = binance.percent(bidvol, bidvol + askvol);
    console.log("ask: " + binance.first(asks)+"\tvolume: "+askvol.toFixed(3));
    console.log("bid: " + binance.first(bids)+"\tvolume: "+bidvol.toFixed(3));
    console.log("buy ratio: " + ratio.toFixed(2) + "%");
});