binance-exchange/node-binance-api

Internal websocket connection not answering

amelenetwork opened this issue · 8 comments

Hello there...

This issue looks like node side but Where Im doing wrong could you help me ?

because really I have no an experience about Node

What happen ?

My NodeJS stopped pump sockets and wait... around of 5 minutes then start again pump data to client . I just watch and didn't touch anything .

Then start self again...
There is CHROME logs - trying to get answer from Node socket server (Im using Socket.io )
https://snag.gy/jckmDI.jpg

Node server logs...
https://snag.gy/jBoJDL.jpg

Im getting all ....BTC coins and their resolutions ['1m', '5m', '15m', '1h', '4h', '1d'] , and their orders and trades and pumpin all always their namespaces ... I don't know Im doing true or false ...

it's worked more than 10 hours without any problem . After 10 hours work i get this ....

My node server codes I attached ....

What Im doing wrong ? Im pumping never end channels ? Looping or what Im doing wrong ? Why stacked data ?

Thank you for your support....

var app = require('express')();

var server = require('http').Server(app);
var io = require('socket.io')(server);
const axios = require('axios');
require('dotenv').load();

var variables = require('./server_modules');
var list_connection = variables.list_connection;

var resolotion = ['1m', '5m', '15m',  '1h', '4h', '1d']    
  
var connected_client = [];

var $back = []
$back['best_bid'] = 0
$back['best_ask'] = 0




 

//const binance = require('node-binance-api');
const binance = require('node-binance-api/node-binance-api.js');

binance.options({
  APIKEY: process.env.BINANCE_APIKEY,
  APISECRET: process.env.BINANCE_APISECRET,
  useServerTime: process.env.BINANCE_USESERVERTIME, // If you get timestamp errors, synchronize to server time at startup
  //test: process.env.BINANCE_TEST, // If you want to use sandbox mode where orders are simulated
  'reconnect': true
});


 
var listenPort = process.env.SOCKET_PORT || 8080;

server.listen(listenPort);

console.log('Server started....')
console.log('Waiting connectin from ' +process.env.SOCKET_ADDRESS)
console.log('Listening port: ' + listenPort)

binance.prevDay(false, (error, prevDay) => {
  let markets = [];
  for ( let obj of prevDay ) {
    let symbol = obj.symbol;
    //console.log(symbol+" volume:"+obj.volume+" change: "+obj.priceChangePercent+"%");
    //console.log(symbol);
    if(symbol.includes('BTC'))
        markets.push(symbol)
  }

  console.log('Markets are ready')

  console.log(markets)
  console.log("Size: "+markets.length)
  resolotion.forEach(function(interVal) {
    
    setTimeout(function(){ 
      binance.websockets.candlesticks(markets, interVal, (candlestickData) => {
        let { e:eventType, E:eventTime, s:symbol, k:ticks } = candlestickData;
        let { o:open, h:high, l:low, c:close, v:volume, n:trades, i:interval, t:startBar, q:quoteVolume, V:buyVolume, Q:quoteBuyVolume } = ticks;
        let answer = {
          s:'ok',
          c:[close,close],
          t:[Math.round(startBar/1000),Math.round(startBar/1000)],
          v:[volume,volume],
          h:[high, high],
          l:[low, low],
          o:[open, open]
        }

        var nsp = symbol+'_'+interVal
        //nsp.emit('kline', answer);
        //console.log('Pump...' +nsp)
        io.of('/'+nsp).emit('kline', answer)
      });
    }, 3000);      
  });


  binance.websockets.depthCache(markets, (symbol, depth) => {


                  let num_size = ( symbol == 'BTCUSDT' ||  symbol == 'BTCTRY' ||  symbol == 'TRIGBTC'  ) ? 2:6;
      
                  let max = 33; // Only show the 33 best bids / asks (optional)
                  let asks = binance.sortAsks(depth.asks, max);
                  let bids = binance.sortBids(depth.bids, max);
                  let ask_sum = binance.sum(Object.values(asks));
                  let bid_sum = binance.sum(Object.values(bids));
                  //console.log("bid sum: "+bid_sum+". ask sum: "+ask_sum);
                  let best_ask = binance.first(asks);
                  let best_bid = binance.first(bids);
                  let price;
                  //console.clear();
                  asks = binance.reverse(asks);
                  var ask_price_list = []
                  for ( price in asks ) {
                    let amount = asks[price];
                    let total = price * amount;
                    let percent = Math.round(binance.percent(amount, ask_sum));
                    ask_price_list.push({price:price, amount:amount, total:total, percent:percent, num_size:num_size})
                    //console.log(price+" "+amount+" "+total+" "+percent+"%");
                  }
                  //console.log("ask: ", best_ask);
                 // console.log("bid: ", best_bid);
                  var bid_price_list = []
                  for ( price in bids ) {
                    let amount = bids[price];
                    let total = price * amount;
                    let percent = Math.round(binance.percent(amount, bid_sum));
                    bid_price_list.push({price:price, amount:amount, total:total, percent:percent, num_size:num_size})
                    //console.log(price+" "+amount+" "+total+" "+percent+"%");
                  }

                  //console.log('Deepth pumped: ')
                  io.of('/'+symbol+'_deepth').emit('depth_list', {ask:ask_price_list, bid:bid_price_list});

                  /*
                   console.log()
                  console.log()
                   console.log()
                  console.log('Start limit 300')
                  */

                  const limit = 300;
                         bids = binance.sortBids(depth.bids, limit, 'cumulative');
                         asks = binance.sortAsks(depth.asks, limit, 'cumulative');
                        bids = binance.reverse(bids);

                        /*
                            console.log(symbol+" depth cache update");
                            console.log("Point of start: "+binance.first(bids));
                            console.log("best bid: "+binance.last(bids));
                            console.log("best ask: "+binance.first(asks));
                            */

                          if($back['best_bid'] !=  binance.first(bids) || $back['best_ask'] !=  binance.first(asks)) {
                            //let answer_deepth = {pointStart: binance.first(bids), bids: bids, asks: asks}
                            let output = {startPoint: binance.first(bids), best_bid: binance.last(bids), best_ask: binance.first(asks),  bids:binance.array(bids), asks:binance.array(asks)};
                            io.of('/'+symbol+'_deepth').emit('depth_chart', output);
                            //nspd.emit('message', coins);
                           // console.log('Updated...')
                            //console.log(output)
                          }

                        $back['best_bid'] = binance.last(bids)
                        $back['best_ask'] = binance.first(asks)
  });


  binance.websockets.trades(markets, (trades) => {
    //let {e:eventType, E:eventTime, s:symbol, p:price, q:quantity, m:maker, a:tradeId} = trades;
    //console.log('Pump trade')

    io.of('/'+trades.s+'_deepth').emit('trade_list', {s:trades.s, E: trades.E, p: trades.p, q: trades.q, m:trades.m })

    //'aggTrade'
    //console.log(symbol+" trade update. price: "+price+", quantity: "+quantity+", maker: "+maker+", event: "+eventType );
  });
  
  

  

});

Nice project. Sorry I can't help you. I am unable to find your problem and can't put more time into it
Personally I would remove this part because it is more reliable to connect to everything at once

setTimeout(function(){
...
}, 3000);

Could you answer this please , I'm on right way ?

is that possible all ....BTC coins and all time frames ? It was worked around 10 hours normally then delayed to answer node websocket so muhc :(

My logic is true on this project or not ? Could you answer this ?

Thank you so much...

This is how I do it:

const binance = require('node-binance-api')
binance.prevDay(false, (error, prevDay) => {
	let intervals = ['5m', '1h'];
	let markets = [];
	for ( let obj of prevDay ) {
		let symbol = obj.symbol;
		console.log(symbol+" volume:"+obj.volume+" change: "+obj.priceChangePercent+"%");
		if ( symbol.substr(-3) !== 'BTC' ) continue;
		markets.push(symbol);
	}
	console.info("Markets: ", markets);
	for ( let interval of intervals ) {
		binance.websockets.candlesticks(markets, interval, (candlestickData) => {
			let tick = binance.last(candlestickData);
			const symbol = candlestickData.s;
			const close = candlestickData[tick].c;
			console.log(symbol+" "+interval+": "+close);
		});
	}
});

This way, they will automatically reconnect, and you will not get banned for making too many connections
You can periodically save the data to json files since you get it in real time

Really your are great person. If i will get success on this project and if i make some coins i will send you gifts .

Really you always helped me so much .

Thank you so much

Thank you for your kind words, glad to hear it. For charting there are also some built in functions that can be helpful:
ohlc, highstock, and array

this is the standard chart data as received from the websocket
image

the ohlc function allows you to get an array of open, high, low, close values, and volume too
image

the highstock function returns data in the format for highstock charts
image
and the array function will convert a list of objects to an array. examples:

const binance = require('node-binance-api')
// Get Complete Chart Data Updates via WebSocket
// Periods: 1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,1M
binance.websockets.chart("ETHBTC", "1m", function(symbol, interval, chart) {
	console.log(symbol+" "+interval+" chart update");
	// show just the last update
	let last = binance.last(chart);
	console.log(last, chart[last]);
	//console.log(chart);
	// get open, high, low, close, volume arrays for doing technical analysis
	//let highstock_data = binance.highstock(chart, true);
	//fs.writeFile("highstock/"+symbol+".json", JSON.stringify(highstock_data), function(err){});
	// Get data as OHLC
	//let ohlc = binance.ohlc(chart);
	//fs.writeFile("charts/"+symbol+".json", JSON.stringify(chart, null, 4), function(err){});
	//fs.writeFile("ohlc/"+symbol+".json", JSON.stringify(ohlc, null, 1), function(err){});
});

I also know how to interface with the kline library that binance uses https://github.com/chxj1992/kline
image

always glad to help
cheers

Another handy api endpoint I just found out about recently is the miniTicker
It streams you the last candlestick for every symbol

image

const binance = require('node-binance-api');
binance.websockets.miniTicker(markets => {
  console.log(markets);
});

Im using Trading View chart structure... I change their source codes and working now with WebSocket ...

Im getting kline chart data from URL directly for exampel BTC_USDT - 15m

https://www.binance.com/api/v1/klines?symbol=BTCUSDT&interval=15m

then Im getting last candle but Im thinking how can i organize last candle time frame if Im getting all of them last candle from mini ticker ...

really there is so much connections and their time frame , then Im pumping all of them with Socket.Io , I can't imagine how will work this system - even Im not believing it's will work normally . I don't think so :(