Skip to content

Commit be6e8c9

Browse files
committed
Merge branch 'develop'
2 parents e3ccd48 + bcfb5e3 commit be6e8c9

File tree

9 files changed

+81
-96
lines changed

9 files changed

+81
-96
lines changed

package-lock.json

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "binance-triangle-arbitrage",
3-
"version": "5.5.0",
3+
"version": "5.5.1",
44
"repository": {
55
"type": "git",
66
"url": "https://github.com/bmino/binance-triangle-arbitrage.git"

src/main/ArbitrageExecution.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const ArbitrageExecution = {
1010
attemptedPositions: {},
1111

1212
executeCalculatedPosition(calculated) {
13-
const startTime = new Date().getTime();
13+
const startTime = Date.now();
1414

1515
if (!ArbitrageExecution.isSafeToExecute(calculated)) return false;
1616

@@ -32,7 +32,7 @@ const ArbitrageExecution = {
3232

3333
return ArbitrageExecution.getExecutionStrategy()(calculated)
3434
.then((actual) => {
35-
logger.execution.info(`${CONFIG.TRADING.ENABLED ? 'Executed' : 'Test: Executed'} ${calculated.id} position in ${new Date().getTime() - startTime} ms`);
35+
logger.execution.info(`${CONFIG.TRADING.ENABLED ? 'Executed' : 'Test: Executed'} ${calculated.id} position in ${Date.now() - startTime} ms`);
3636

3737
// Results are only collected when a trade is executed
3838
if (!CONFIG.TRADING.ENABLED) return;
@@ -95,7 +95,7 @@ const ArbitrageExecution = {
9595
},
9696

9797
isSafeToExecute(calculated) {
98-
const now = new Date().getTime();
98+
const now = Date.now();
9999
const { symbol } = calculated.trade;
100100

101101
// Profit Threshold is Not Satisfied
@@ -138,7 +138,7 @@ const ArbitrageExecution = {
138138
},
139139

140140
getAttemptedPositionsCountInLastSecond() {
141-
const timeFloor = new Date().getTime() - 1000;
141+
const timeFloor = Date.now() - 1000;
142142
return Object.keys(ArbitrageExecution.attemptedPositions).filter(time => time > timeFloor).length;
143143
},
144144

@@ -219,15 +219,15 @@ const ArbitrageExecution = {
219219
if (results.orderId) {
220220
[actual.a.spent, actual.b.earned, fees] = ArbitrageExecution.parseActualResults(calculated.trade.ab.method, results);
221221
actual.fees += fees;
222-
recalculated.bc = CalculationNode.recalculateTradeLeg(calculated.trade.bc, actual.b.earned, BinanceApi.getDepthSnapshots(calculated.trade.bc.ticker));
222+
recalculated.bc = CalculationNode.recalculateTradeLeg(calculated.trade.bc, actual.b.earned, BinanceApi.depthCache(calculated.trade.bc.ticker));
223223
}
224224
return BinanceApi.marketBuyOrSell(calculated.trade.bc.method)(calculated.trade.bc.ticker, recalculated.bc);
225225
})
226226
.then((results) => {
227227
if (results.orderId) {
228228
[actual.b.spent, actual.c.earned, fees] = ArbitrageExecution.parseActualResults(calculated.trade.bc.method, results);
229229
actual.fees += fees;
230-
recalculated.ca = CalculationNode.recalculateTradeLeg(calculated.trade.ca, actual.c.earned, BinanceApi.getDepthSnapshots(calculated.trade.ca.ticker));
230+
recalculated.ca = CalculationNode.recalculateTradeLeg(calculated.trade.ca, actual.c.earned, BinanceApi.depthCache(calculated.trade.ca.ticker));
231231
}
232232
return BinanceApi.marketBuyOrSell(calculated.trade.ca.method)(calculated.trade.ca.ticker, recalculated.ca);
233233
})

src/main/BinanceApi.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ const BinanceApi = {
3737

3838
getDepthSnapshots(tickers) {
3939
const depthSnapshot = {};
40-
if (!Array.isArray(tickers)) tickers = [tickers];
4140
tickers.forEach((ticker) => {
4241
depthSnapshot[ticker] = binance.depthCache(ticker);
4342
});
@@ -46,14 +45,14 @@ const BinanceApi = {
4645

4746
marketBuy(ticker, quantity) {
4847
logger.execution.info(`${binance.getOption('test') ? 'Test: Buying' : 'Buying'} ${quantity} ${ticker} @ market price`);
49-
const before = new Date().getTime();
48+
const before = Date.now();
5049
return new Promise((resolve, reject) => {
5150
binance.marketBuy(ticker, quantity, (error, response) => {
5251
if (error) return BinanceApi.handleBuyOrSellError(error, reject);
5352
if (binance.getOption('test')) {
5453
logger.execution.info(`Test: Successfully bought ${ticker} @ market price`);
5554
} else {
56-
logger.execution.info(`Successfully bought ${response.executedQty} ${ticker} @ a quote of ${response.cummulativeQuoteQty} in ${new Date().getTime() - before} ms`);
55+
logger.execution.info(`Successfully bought ${response.executedQty} ${ticker} @ a quote of ${response.cummulativeQuoteQty} in ${Date.now() - before} ms`);
5756
}
5857
return resolve(response);
5958
});
@@ -62,14 +61,14 @@ const BinanceApi = {
6261

6362
marketSell(ticker, quantity) {
6463
logger.execution.info(`${binance.getOption('test') ? 'Test: Selling' : 'Selling'} ${quantity} ${ticker} @ market price`);
65-
const before = new Date().getTime();
64+
const before = Date.now();
6665
return new Promise((resolve, reject) => {
6766
binance.marketSell(ticker, quantity, (error, response) => {
6867
if (error) return BinanceApi.handleBuyOrSellError(error, reject);
6968
if (binance.getOption('test')) {
7069
logger.execution.info(`Test: Successfully sold ${ticker} @ market price`);
7170
} else {
72-
logger.execution.info(`Successfully sold ${response.executedQty} ${ticker} @ a quote of ${response.cummulativeQuoteQty} in ${new Date().getTime() - before} ms`);
71+
logger.execution.info(`Successfully sold ${response.executedQty} ${ticker} @ a quote of ${response.cummulativeQuoteQty} in ${Date.now() - before} ms`);
7372
}
7473
return resolve(response);
7574
});

src/main/CalculationNode.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const CalculationNode = {
55
cycleCount: 0,
66

77
cycle(relationships, depthCacheClone, errorCallback, executionCallback) {
8-
const startTime = new Date().getTime();
8+
const startTime = Date.now();
99

1010
let successCount = 0;
1111
let errorCount = 0;
@@ -30,7 +30,7 @@ const CalculationNode = {
3030
}
3131
});
3232

33-
const calculationTime = new Date().getTime() - startTime;
33+
const calculationTime = Date.now() - startTime;
3434

3535
CalculationNode.cycleCount++;
3636

@@ -41,7 +41,7 @@ const CalculationNode = {
4141
let quantity, calculation;
4242
let bestCalculation = null;
4343

44-
for (quantity = CONFIG.INVESTMENT.MIN || CONFIG.INVESTMENT.STEP; quantity <= CONFIG.INVESTMENT.MAX; quantity += CONFIG.INVESTMENT.STEP) {
44+
for (quantity = CONFIG.INVESTMENT.MIN; quantity <= CONFIG.INVESTMENT.MAX; quantity += CONFIG.INVESTMENT.STEP) {
4545
calculation = CalculationNode.calculate(quantity, trade, depthSnapshot);
4646
if (!bestCalculation || calculation.percent > bestCalculation.percent) {
4747
bestCalculation = calculation;
@@ -115,7 +115,7 @@ const CalculationNode = {
115115
calculated.c.delta = calculated.c.earned - calculated.c.spent;
116116

117117
calculated.percent = (calculated.a.delta / calculated.a.spent * 100) - (CONFIG.TRADING.TAKER_FEE * 3);
118-
if (!calculated.percent) calculated.percent = 0;
118+
if (!calculated.percent) calculated.percent = -100;
119119

120120
return calculated;
121121
},

src/main/HUD.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const HUD = {
3939
HUD.screen.append(HUD.objects.arbTable);
4040
}
4141

42-
const now = new Date().getTime();
42+
const now = Date.now();
4343

4444
let tableData = [HUD.headers.arb];
4545
arbs.forEach(arb => {

src/main/Main.js

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ logger.performance.info(logger.LINE);
1414

1515
if (CONFIG.TRADING.ENABLED) console.log(`WARNING! Order execution is enabled!\n`);
1616

17-
SpeedTest.multiPing()
17+
checkConfig()
18+
.then(SpeedTest.multiPing)
1819
.then((pings) => {
1920
const msg = `Successfully pinged Binance in ${(pings.reduce((a,b) => a+b, 0) / pings.length).toFixed(0)} ms`;
2021
console.log(msg);
2122
logger.performance.info(msg);
2223
})
2324
.then(BinanceApi.exchangeInfo)
2425
.then(exchangeInfo => MarketCache.initialize(exchangeInfo, CONFIG.TRADING.WHITELIST, CONFIG.INVESTMENT.BASE))
25-
.then(checkConfig)
2626
.then(checkBalances)
2727
.then(() => {
2828
// Listen for depth updates
29-
const tickers = MarketCache.getTickerArray();
29+
const tickers = MarketCache.tickers.watching;
3030
console.log(`Opening ${tickers.length} depth websockets ...`);
3131
return BinanceApi.depthCacheStaggered(tickers, CONFIG.DEPTH.SIZE, CONFIG.DEPTH.INITIALIZATION_INTERVAL);
3232
})
@@ -52,7 +52,7 @@ function calculateArbitrage() {
5252

5353
const { calculationTime, successCount, errorCount, results } = CalculationNode.cycle(
5454
MarketCache.relationships,
55-
BinanceApi.getDepthSnapshots(MarketCache.getTickerArray()),
55+
BinanceApi.getDepthSnapshots(MarketCache.tickers.watching),
5656
(e) => logger.performance.warn(e),
5757
ArbitrageExecution.executeCalculatedPosition
5858
);
@@ -70,7 +70,7 @@ function displayCalculationResults(successCount, errorCount, calculationTime) {
7070
}
7171

7272
if (CalculationNode.cycleCount % 500 === 0) {
73-
const tickersWithoutDepthUpdate = MarketCache.getTickersWithoutDepthCacheUpdate();
73+
const tickersWithoutDepthUpdate = MarketCache.getWatchedTickersWithoutDepthCacheUpdate();
7474
if (tickersWithoutDepthUpdate.length > 0) {
7575
logger.performance.debug(`Tickers without a depth cache update: [${tickersWithoutDepthUpdate}]`);
7676
}
@@ -90,20 +90,8 @@ function checkConfig() {
9090
}
9191
};
9292

93-
if (MarketCache.getTickerArray().length < 3) {
94-
const msg = `Watching ${MarketCache.getTickerArray().length} ticker(s) is not sufficient to engage in triangle arbitrage`;
95-
logger.execution.debug(`Watched Tickers: [${MarketCache.getTickerArray()}]`);
96-
logger.execution.error(msg);
97-
throw new Error(msg);
98-
}
99-
if (MarketCache.symbols.size < 3) {
100-
const msg = `Watching ${MarketCache.symbols.size} symbol(s) is not sufficient to engage in triangle arbitrage`;
101-
logger.execution.debug(`Watched Symbols: [${Array.from(MarketCache.symbols)}]`);
102-
logger.execution.error(msg);
103-
throw new Error(msg);
104-
}
105-
if (MarketCache.relationships.length === 0) {
106-
const msg = `Watching ${MarketCache.relationships.length} triangular relationships is not sufficient to engage in triangle arbitrage`;
93+
if (CONFIG.INVESTMENT.MIN <= 0) {
94+
const msg = `INVESTMENT.MIN must be a positive value`;
10795
logger.execution.error(msg);
10896
throw new Error(msg);
10997
}
@@ -122,6 +110,11 @@ function checkConfig() {
122110
logger.execution.error(msg);
123111
throw new Error(msg);
124112
}
113+
if (CONFIG.TRADING.WHITELIST.some(sym => sym !== sym.toUpperCase())) {
114+
const msg = `Whitelist symbols must all be uppercase`;
115+
logger.execution.error(msg);
116+
throw new Error(msg);
117+
}
125118
if (CONFIG.TRADING.WHITELIST.length > 0 && !CONFIG.TRADING.WHITELIST.includes(CONFIG.INVESTMENT.BASE)) {
126119
const msg = `Whitelist must include the base symbol of ${CONFIG.INVESTMENT.BASE}`;
127120
logger.execution.debug(`Whitelist: [${CONFIG.TRADING.WHITELIST}]`);
@@ -168,6 +161,8 @@ function checkConfig() {
168161
logger.execution.error(msg);
169162
throw new Error(msg);
170163
}
164+
165+
return Promise.resolve();
171166
}
172167

173168
function checkBalances() {

0 commit comments

Comments
 (0)