Skip to content

Instantly share code, notes, and snippets.

@snowkidind
Created August 7, 2020 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snowkidind/5adc755b1630e7dba4ca0cb2c7deaa53 to your computer and use it in GitHub Desktop.
Save snowkidind/5adc755b1630e7dba4ca0cb2c7deaa53 to your computer and use it in GitHub Desktop.
const chalk = require('chalk');
const player = require('play-sound')();
const eventManager = require('../operations/eventManager');
const diagnostics = require('../utilities/diagnostics.js');
const request = require('request');
let executeTrades = true;
let lastBalanceTime = 0;
let lastBalance;
let lastBalanceToken;
let lastTickerTime = 0;
let lastTicker;
let candles = {};
let markets = {};
let klineEndpoint;
let tradesEndpoint;
let userDataEndpoint;
const logAllApiCalls = false;
let apiCallsCount = 1;
const binance = require('node-binance-api')().options({
APIKEY: process.env.BINANCE_API_PUB,
APISECRET: process.env.BINANCE_API_PRIV,
useServerTime: true, // If you get timestamp errors, synchronize to server time at startup
verbose: false,
test: false // If you want to use sandbox mode where orders are simulated
});
// playground for binance api
module.exports = {
//
executePermission(set) {
executeTrades = set;
},
//
ticker: function (pair, cb) {
const time = new Date().getTime();
if (time - lastTickerTime > 2000) {
// console.log("Get Ticker" + pair);
if (logAllApiCalls) {
console.log(apiCallsCount + " binance.prices: " + pair + " - " + Date.now());
apiCallsCount += 1;
}
binance.prices(pair, (error, ticker) => {
if (error) {
console.log(pair);
console.log(chalk.red("binance.ticker error: " + error.body));
cb(false);
} else {
lastTickerTime = new Date().getTime();
lastTicker = ticker[pair];
cb(ticker[pair]);
}
});
} else {
// console.log("Using cached ticker");
cb(lastTicker);
}
},
//
allBalances: function (cb) {
binance.useServerTime(function(){
binance.balance((error, balances) => {
if (logAllApiCalls) {
console.log(apiCallsCount + " allBalances.balance: " + Date.now());
apiCallsCount += 1;
}
if (error) {
if (typeof (error.body) !== 'undefined') { // JSON Syntax error - server sent bad data
let e = JSON.parse(error.body);
switch (e.code) {
case -1021:
console.log("Binance api had some issue: " + e.msg);
console.log("Fix: System Preferences - Date and time:");
console.log("1. uncheck Set date and time automatically");
console.log("2. check Set date and time automatically");
process.exit();
break;
default:
console.log("Binance api had some issue: " + e.code + ": " + e.msg);
}
} else {
console.log("Binance api sent a syntax error.");
console.log(error);
}
cb();
} else {
cb(balances);
}
});
})
},
// When the stop is reached, a stop order becomes a market order
setStopLoss: function (pair, q, limit, stopPrice, cb) {
let qty = q.toString();
if (qty.charAt(qty.length - 1) === '.') {
qty = qty.slice(0, qty.length - 1);
}
if (logAllApiCalls) {
console.log(apiCallsCount + " setStopLoss.sell: " + pair + " - " + Date.now());
apiCallsCount += 1;
}
// console.log("Set Stop Loss: p", pair, "q", qty, "p", limit, stopPrice, " binance.js:68");
if (executeTrades) {
if (logAllApiCalls) {
console.log(apiCallsCount + " setStopLoss.binance.sell - p: ", pair, " q: ", qty, " p: ", limit + " - " + Date.now());
apiCallsCount += 1;
}
binance.sell(pair, qty, limit, {stopPrice: stopPrice, type: "STOP_LOSS_LIMIT"}, function (error, response) {
if (error) {
console.log(chalk.red("binance.setStopLoss: error: " + error.body));
cb(error, false);
} else {
cb(null, response);
}
});
} else {
console.log("Binance.js is unable to set a stop loss");
}
},
//
getAllOpenOrders: function (cb) {
if (logAllApiCalls) {
console.log(apiCallsCount + " getAllOpenOrders.openOrders - " + Date.now());
apiCallsCount += 1;
}
binance.openOrders(false, (error, openOrders, symbol) => {
cb(openOrders);
});
},
//
cancelOrder: function (pair, orderId, cb) {
if (executeTrades) {
if (logAllApiCalls) {
console.log(apiCallsCount + " cancelOrder.cancel - " + pair + " id: " + orderId + Date.now());
apiCallsCount += 1;
}
binance.cancel(pair, orderId, (error, response, symbol) => {
// console.log("Order Canceled");
cb(error, response);
});
} else {
console.log("Binance.js is unable to cancel orders");
cb("Binance.js is unable to execute trades")
}
},
marketSell: function (pair, q, callback) {
if (executeTrades) {
// rounding bug fix where decimal appears and binance doesnt like that
let qty = q.toString();
if (qty.charAt(qty.length - 1) === '.') {
qty = qty.slice(0, qty.length - 1);
}
if (logAllApiCalls) {
console.log(apiCallsCount + " marketSell.marketSell - " + pair + " q: " + qty + " " + Date.now());
apiCallsCount += 1;
}
// console.log("binance.marketSell: " + pair + " q: " + quantity + " disabled... l124")
binance.marketSell(pair, qty, function (error, response) {
const time = new Date().getTime();
const date = new Date(time);
player.play('./sounds/hurt.mp3', (err) => {
if (err) console.log('Could not play sound: ${err}');
});
callback(error, response);
});
} else {
console.log("Binance.js is unable to market sell: " + pair + " q:" + q);
// cb("Binance.js is unable to execute trades")
}
},
marketBuy: function (pair, q, callback) {
if (executeTrades) {
let qty = q.toString();
if (qty.charAt(qty.length - 1) === '.') {
qty = qty.slice(0, qty.length - 1);
}
if (logAllApiCalls) {
console.log(apiCallsCount + " marketBuy.marketBuy - " + pair + " q: " + qty + " " + Date.now());
apiCallsCount += 1;
}
binance.marketBuy(pair, qty, function (error, resp) {
if (error) {
console.log(chalk.red("Unable to place Market Buy: ", error.body.code, error.body.msg));
// console.log("BinanceMarketBuyError: " + JSON.stringify(error));
callback(error, resp);
} else {
player.play('./sounds/jump.wav', (err) => {
if (err) console.log('Could not play sound: ${err}');
});
callback(error, resp);
}
});
} else {
console.log("Binance.js is unable to market buy: " + pair + " q:" + q);
callback("Binance.js is unable to execute trades")
}
},
//
cancelAllNow: function (pair, cb) {
if (executeTrades) {
if (logAllApiCalls) {
console.log(apiCallsCount + " cancelAllNow.cancelOrders - " + pair + " " + Date.now());
apiCallsCount += 1;
}
binance.cancelOrders(pair, (error, response, symbol) => {
// console.log(chalk.green(symbol + " cancel all response:", Object.keys(response)));
// console.log(response);
cb(true);
});
} else {
console.log("Binance.js is unable to cancel orders");
cb("Binance.js is unable to execute trades");
}
},
//
getLastMinuteCandles: function (options, callback) {
options = options || {};
pair = options.pair || "BTCUSDT";
interval = options.interval || "1m";
limit = options.lastMinuteCandles || 150;
if (logAllApiCalls) {
console.log(apiCallsCount + " getLastMinuteCandeles.candlesticks: " + options.pair + " - " + Date.now());
apiCallsCount += 1;
}
binance.candlesticks(pair, interval, function (error, data) {
response = [];
for (let i = 0; i < data.length; i++) {
map = {
"time": isGoodData(data[i][0]),
"open": isGoodData(data[i][1]),
"high": isGoodData(data[i][2]),
"low": isGoodData(data[i][3]),
"close": isGoodData(data[i][4]),
"volume": isGoodData(data[i][5]),
"closeTime": isGoodData(data[i][6]),
"assetVolume": isGoodData(data[i][7]),
"trades": isGoodData(data[i][8]),
"buyBaseVolume": isGoodData(data[i][9]),
"buyAssetVolume": isGoodData(data[i][10]),
"ignored": isGoodData(data[i][11]),
"pair": pair
};
response.push(map);
}
callback(error, response);
}, {limit: limit});
},
//
getLastCandlesInterval: function (options, callback) {
options = options || {};
pair = options.pair || "BTCUSDT";
interval = options.interval || "5m";
if (logAllApiCalls) {
console.log(apiCallsCount + " getLastCandlesInterval.candlesticks: " + options.pair + " - " + Date.now());
apiCallsCount += 1;
}
binance.candlesticks(pair, interval, function (error, data) {
// console.log(data)
response = [];
for (let i = 0; i < data.length; i++) {
map = {
"time": isGoodData(data[i][0]),
"open": isGoodData(data[i][1]),
"high": isGoodData(data[i][2]),
"low": isGoodData(data[i][3]),
"close": isGoodData(data[i][4]),
"volume": isGoodData(data[i][5]),
"closeTime": isGoodData(data[i][6]),
"assetVolume": isGoodData(data[i][7]),
"trades": isGoodData(data[i][8]),
"buyBaseVolume": isGoodData(data[i][9]),
"buyAssetVolume": isGoodData(data[i][10]),
"ignored": isGoodData(data[i][11]),
"pair": pair
};
response.push(map);
}
callback(error, response);
}, {limit: 150});
},
//
latestPrice: function (pair, cb) {
if (logAllApiCalls) {
console.log(apiCallsCount + " latestPrice.prices: " + pair + " - " + Date.now());
apiCallsCount += 1;
}
binance.prices(pair, (error, ticker) => {
if (error){
console.log("An error occured getting latest price: " + error);
diagnostics.connectivity(function(alive){
if (!alive){
console.log("A connectivity issue was discovered.");
// fallback on some other api that deals in tether...
}
});
cb(error, null)
} else {
cb(null, ticker[pair]);
}
});
},
//
startTradeUpdates: function (pair) {
if (logAllApiCalls) {
console.log(apiCallsCount + " startTradeUpdates.websockets.trades: " + pair + " - " + Date.now());
apiCallsCount += 1;
}
if (typeof(tradesEndpoint) === 'undefined') {
tradesEndpoint = binance.websockets.trades([pair], (tradesData) => {
eventManager.emitMessage('ticker', tradesData.p);
});
}
},
//
terminate: function () {
if (logAllApiCalls) {
console.log(apiCallsCount + " terminates.websockets.terminate: " + Date.now());
apiCallsCount += 3;
}
if (typeof(klineEndpoint) !== 'undefined') binance.websockets.terminate(klineEndpoint);
if (typeof(tradesEndpoint) !== 'undefined') binance.websockets.terminate(tradesEndpoint);
if (typeof(userDataEndpoint) !== 'undefined') binance.websockets.terminate(userDataEndpoint);
},
//
// only fires when an action is taken
userData: function (cb) {
if (logAllApiCalls) {
console.log(apiCallsCount + " userData.websockets.userData: " + Date.now());
apiCallsCount += 1;
}
userDataEndpoint = binance.websockets.userData(function (pkg) {
cb(pkg);
})
},
//
allOrders: function(pair, cb){
binance.allOrders(pair, function(error, data){
if (error){
console.log("Error " + error);
} else {
data = data.reverse(); // newest orders at zero index
cb(error, data);
}
}, {limit: 15});
},
//
allOrdersNoLimit: function (pair, cb) {
binance.allOrders(pair, function (error, data) {
if (error) {
console.log("Error " + error);
} else {
data = data.reverse(); // newest orders at zero index
cb(error, data);
}
});
},
//
exchangeinfo: function (cb) {
if (logAllApiCalls) {
console.log(apiCallsCount + " exchangeInfo.exchangeInfo: " + Date.now());
apiCallsCount += 1;
}
let url = 'https://api.binance.com/api/v1/exchangeInfo';
request(url, function (error, response) {
cb(error, JSON.parse(response.body))
});
},
//
// subscriptions: function (cb) {
// console.log("Calling for subs");
// if (logAllApiCalls) {
// console.log(apiCallsCount + " subscriptions.websockets.subscriptions: " + Date.now());
// apiCallsCount += 1;
// }
// binance.websockets.subscriptions(function (subs) {
// console.log("returning subs", subs);
// cb(subs);
// });
// }
};
function isGoodData(d) {
if (typeof (d) !== 'undefined') {
return d;
} else {
console.log("dataGlitch: " + d);
return 0.0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment