Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
bmino committed May 3, 2019
2 parents f934908 + 6d0522e commit 1a99e5e
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 26 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "binance-triangle-arbitrage",
"version": "5.1.0",
"version": "5.1.1",
"private": true,
"engines": {
"node": "11.10.1",
Expand Down
1 change: 0 additions & 1 deletion src/main/BinanceApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ const BinanceApi = {
processDepth(ticker, depth) {
depth.bids = binance.sortBids(depth.bids);
depth.asks = binance.sortAsks(depth.asks);
depth.time = depth.eventTime;
}

};
Expand Down
47 changes: 24 additions & 23 deletions src/main/CalculationNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,42 @@ const CalculationNode = {
bc: 0,
ca: 0,
times: {
ab: binance.depthCache(trade.ab.ticker).time,
bc: binance.depthCache(trade.bc.ticker).time,
ca: binance.depthCache(trade.ca.ticker).time
ab: binance.depthCache(trade.ab.ticker).eventTime,
bc: binance.depthCache(trade.bc.ticker).eventTime,
ca: binance.depthCache(trade.ca.ticker).eventTime
},
a: 0,
b: 0,
c: 0
};

if (trade.ab.method === 'Buy') {
const dustedAB = CalculationNode.orderBookConversion(investmentA, trade.symbol.a, trade.symbol.b, trade.ab.ticker);
calculated.b = calculated.ab = CalculationNode.calculateDustless(trade.ab.ticker, dustedAB);
} else {
calculated.start = calculated.ab = CalculationNode.calculateDustless(trade.ab.ticker, investmentA);
calculated.b = CalculationNode.orderBookConversion(calculated.ab, trade.symbol.a, trade.symbol.b, trade.ab.ticker);
}

if (trade.bc.method === 'Buy') {
const dustedBC = CalculationNode.orderBookConversion(calculated.b, trade.symbol.b, trade.symbol.c, trade.bc.ticker);
calculated.c = calculated.bc = CalculationNode.calculateDustless(trade.bc.ticker, dustedBC);
} else {
calculated.bc = CalculationNode.calculateDustless(trade.bc.ticker, calculated.b);
calculated.c = CalculationNode.orderBookConversion(calculated.bc, trade.symbol.b, trade.symbol.c, trade.bc.ticker);
}

if (trade.ca.method === 'Buy') {
const dustedCA = CalculationNode.orderBookConversion(calculated.c, trade.symbol.c, trade.symbol.a, trade.ca.ticker);
calculated.a = calculated.ca = CalculationNode.calculateDustless(trade.ca.ticker, dustedCA);
} else {
calculated.ca = CalculationNode.calculateDustless(trade.ca.ticker, calculated.c);
calculated.a = CalculationNode.orderBookConversion(calculated.ca, trade.symbol.c, trade.symbol.a, trade.ca.ticker);
}

calculated.percent = (calculated.a - calculated.start) / calculated.start * 100 - (CONFIG.TRADING.TAKER_FEE * 3);
if (!calculated.percent) calculated.percent = 0;

return calculated;
},

Expand All @@ -74,19 +74,21 @@ const CalculationNode = {
return CalculationNode.calculateDustless(ticker, quantityEarned);
}
},

orderBookConversion(amountFrom, symbolFrom, symbolTo, ticker) {
let i, j, rates, rate, quantity, exchangeableAmount;
let i, j, rate, quantity, exchangeableAmount;
let orderBook = binance.depthCache(ticker) || {};
const bidRates = Object.keys(orderBook.bids || {});
const askRates = Object.keys(orderBook.asks || {});
let amountTo = 0;

if (amountFrom === 0) return 0;

if (parseFloat(bidRates[0]) > parseFloat(askRates[0])) throw new Error(`Spread does not exist for ${ticker}`);

if (ticker === symbolFrom + symbolTo) {
rates = Object.keys(orderBook.bids || {});
for (i=0; i<rates.length; i++) {
rate = parseFloat(rates[i]);
quantity = orderBook.bids[rates[i]];
for (i=0; i<bidRates.length; i++) {
rate = parseFloat(bidRates[i]);
quantity = orderBook.bids[bidRates[i]];
if (quantity < amountFrom) {
amountFrom -= quantity;
amountTo += quantity * rate;
Expand All @@ -96,10 +98,9 @@ const CalculationNode = {
}
}
} else {
rates = Object.keys(orderBook.asks || {});
for (j=0; j<rates.length; j++) {
rate = parseFloat(rates[j]);
quantity = orderBook.asks[rates[j]];
for (j=0; j<askRates.length; j++) {
rate = parseFloat(askRates[j]);
quantity = orderBook.asks[askRates[j]];
exchangeableAmount = quantity * rate;
if (exchangeableAmount < amountFrom) {
amountFrom -= quantity * rate;
Expand All @@ -110,10 +111,10 @@ const CalculationNode = {
}
}
}
throw new Error(`Depth (${rates.length}) too shallow to convert ${amountFrom} ${symbolFrom} to ${symbolTo} using ${ticker}`);

throw new Error(`Bid depth (${bidRates.length}) or ask depth (${askRates.length}) too shallow to convert ${amountFrom} ${symbolFrom} to ${symbolTo} using ${ticker}`);
},

calculateDustless(ticker, amount) {
if (Number.isInteger(amount)) return amount;
const amountString = amount.toFixed(12);
Expand Down
3 changes: 3 additions & 0 deletions src/main/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ function calculateArbitrage() {
const msg = `Completed ${completedCalculations}/${totalCalculations} (${((completedCalculations/totalCalculations)*100).toFixed(1)}%) calculations in ${calculationTime} ms`;
(errorCount > 0) ? logger.performance.info(msg) : logger.performance.trace(msg);

const tickersWithoutDepthUpdate = MarketCache.getTickersWithoutDepthCacheUpdate();
(tickersWithoutDepthUpdate.length > 0) && logger.execution.trace(`Found ${tickersWithoutDepthUpdate.length} tickers without a depth cache update: [${tickersWithoutDepthUpdate}]`);

if (CONFIG.HUD.ENABLED) refreshHUD(results);

setTimeout(calculateArbitrage, CONFIG.CALCULATION_COOLDOWN);
Expand Down
5 changes: 5 additions & 0 deletions src/main/MarketCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const MarketCache = {
if (!whitelistSymbols.includes(symbolObj.quoteAsset)) return;
}
symbols.add(symbolObj.baseAsset);
symbols.add(symbolObj.quoteAsset);
symbolObj.dustDecimals = Math.max(symbolObj.filters.filter(f => f.filterType === 'LOT_SIZE')[0].minQty.indexOf('1') - 1, 0);
tickers[symbolObj.symbol] = symbolObj;
});
Expand Down Expand Up @@ -60,6 +61,10 @@ const MarketCache = {
return trades;
},

getTickersWithoutDepthCacheUpdate() {
return MarketCache.getTickerArray().filter(ticker => !binance.depthCache(ticker).eventTime);
},

createTrade(a, b, c) {
const ab = MarketCache.getRelationship(a, b);
if (!ab) return;
Expand Down

0 comments on commit 1a99e5e

Please sign in to comment.