From 1a276488fb54c3bd63b30d0f67455c453fba5527 Mon Sep 17 00:00:00 2001 From: Brandon Mino Date: Sat, 27 Apr 2019 18:29:24 -0400 Subject: [PATCH 1/5] Remove Reference Renaming --- src/main/BinanceApi.js | 1 - src/main/CalculationNode.js | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/BinanceApi.js b/src/main/BinanceApi.js index 42e2f68..946d2e9 100644 --- a/src/main/BinanceApi.js +++ b/src/main/BinanceApi.js @@ -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; } }; diff --git a/src/main/CalculationNode.js b/src/main/CalculationNode.js index a7719e8..f3ce40b 100644 --- a/src/main/CalculationNode.js +++ b/src/main/CalculationNode.js @@ -27,15 +27,15 @@ 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); @@ -43,7 +43,7 @@ const CalculationNode = { 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); @@ -51,7 +51,7 @@ const CalculationNode = { 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); @@ -59,10 +59,10 @@ const CalculationNode = { 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; }, @@ -74,14 +74,14 @@ const CalculationNode = { return CalculationNode.calculateDustless(ticker, quantityEarned); } }, - + orderBookConversion(amountFrom, symbolFrom, symbolTo, ticker) { let i, j, rates, rate, quantity, exchangeableAmount; let orderBook = binance.depthCache(ticker) || {}; let amountTo = 0; - + if (amountFrom === 0) return 0; - + if (ticker === symbolFrom + symbolTo) { rates = Object.keys(orderBook.bids || {}); for (i=0; i Date: Sat, 27 Apr 2019 20:55:13 -0400 Subject: [PATCH 2/5] WiP: Check Order Book Spread --- src/main/CalculationNode.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/CalculationNode.js b/src/main/CalculationNode.js index f3ce40b..1b20d3d 100644 --- a/src/main/CalculationNode.js +++ b/src/main/CalculationNode.js @@ -76,17 +76,19 @@ const CalculationNode = { }, 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 Date: Thu, 2 May 2019 22:37:24 -0400 Subject: [PATCH 3/5] Ensure All Trading Symbols are Recognized --- src/main/MarketCache.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/MarketCache.js b/src/main/MarketCache.js index f029e69..0a0ae6f 100644 --- a/src/main/MarketCache.js +++ b/src/main/MarketCache.js @@ -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; }); From ae18afb746643ed7d3649788560b3459adff46c0 Mon Sep 17 00:00:00 2001 From: Brandon Mino Date: Thu, 2 May 2019 23:21:42 -0400 Subject: [PATCH 4/5] Insight into Depth Cache Events Tickers with low volume might not emit a depth cache update during long periods of time --- src/main/Main.js | 3 +++ src/main/MarketCache.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/main/Main.js b/src/main/Main.js index ded08a5..119a943 100644 --- a/src/main/Main.js +++ b/src/main/Main.js @@ -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); diff --git a/src/main/MarketCache.js b/src/main/MarketCache.js index 0a0ae6f..48b8c45 100644 --- a/src/main/MarketCache.js +++ b/src/main/MarketCache.js @@ -61,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; From 6d0522eb879a3df99d4fbd31ca39a72598dc9405 Mon Sep 17 00:00:00 2001 From: Brandon Mino Date: Thu, 2 May 2019 23:23:37 -0400 Subject: [PATCH 5/5] Update Version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e5eca3..cb32bac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "binance-triangle-arbitrage", - "version": "5.1.0", + "version": "5.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a236e94..8eb8afd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "binance-triangle-arbitrage", - "version": "5.1.0", + "version": "5.1.1", "private": true, "engines": { "node": "11.10.1",