Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
bmino committed Jan 26, 2020
2 parents 615d4b0 + 4103101 commit 7b1ab04
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 30 deletions.
15 changes: 4 additions & 11 deletions package-lock.json

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

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "binance-triangle-arbitrage",
"version": "5.2.3",
"version": "5.2.4",
"repository": {
"type": "git",
"url": "https://github.com/bmino/binance-triangle-arbitrage.git"
Expand All @@ -9,8 +9,8 @@
"name": "Brandon Mino"
},
"engines": {
"node": "11.10.1",
"npm": "6.10.2"
"node": "12.14.1",
"npm": "6.13.6"
},
"scripts": {
"start": "node src/main/Main.js"
Expand Down
39 changes: 28 additions & 11 deletions src/main/ArbitrageExecution.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ const ArbitrageExecution = {
ArbitrageExecution.inProgressSymbols.add(symbol.c);

logger.execution.info(`Attempting to execute ${calculated.id} with an age of ${Math.max(age.ab, age.bc, age.ca).toFixed(0)} ms and expected profit of ${calculated.percent.toFixed(4)}%`);
logger.execution.debug(`${calculated.trade.ab.ticker} depth cache age: ${age.ab.toFixed(0)} ms`);
logger.execution.debug(`${calculated.trade.bc.ticker} depth cache age: ${age.bc.toFixed(0)} ms`);
logger.execution.debug(`${calculated.trade.ca.ticker} depth cache age: ${age.ca.toFixed(0)} ms`);

return ArbitrageExecution.execute(calculated)
.then((actual) => {
Expand All @@ -41,16 +38,32 @@ const ArbitrageExecution = {
// Results are only collected when a trade is executed
if (!CONFIG.TRADING.ENABLED) return;

const calculateVariation = (calculatedFrom, calculatedTo, actualFrom, actualTo) => {
const calculatedPrice = calculatedFrom.spent / calculatedTo.earned;
const actualPrice = actualFrom.spent / actualTo.earned;
return (actualPrice - calculatedPrice) / calculatedPrice * 100;
};

const variation = {
ab: calculateVariation(calculated.a, calculated.b, actual.a, actual.b),
bc: calculateVariation(calculated.b, calculated.c, actual.b, actual.c),
ca: calculateVariation(calculated.c, calculated.a, actual.c, actual.a)
};

logger.execution.debug(`${calculated.trade.ab.ticker} Stats:`);
logger.execution.debug(`Expected Conversion: ${calculated.a.spent.toFixed(8)} ${symbol.a} into ${calculated.b.earned.toFixed(8)} ${symbol.b}`);
logger.execution.debug(`Observed Conversion: ${actual.a.spent.toFixed(8)} ${symbol.a} into ${actual.b.earned.toFixed(8)} ${symbol.b}`);
logger.execution.debug(`Price Error: ${variation.ab.toFixed(8)}%`);
logger.execution.debug();
logger.execution.debug(`AB Expected Conversion: ${calculated.a.spent.toFixed(8)} ${symbol.a} into ${calculated.b.earned.toFixed(8)} ${symbol.b}`);
logger.execution.debug(`AB Observed Conversion: ${actual.a.spent.toFixed(8)} ${symbol.a} into ${actual.b.earned.toFixed(8)} ${symbol.b}`);
logger.execution.debug();
logger.execution.debug(`${calculated.trade.bc.ticker} Stats:`);
logger.execution.debug(`BC Expected Conversion: ${calculated.b.spent.toFixed(8)} ${symbol.b} into ${calculated.c.earned.toFixed(8)} ${symbol.c}`);
logger.execution.debug(`BC Observed Conversion: ${actual.b.spent.toFixed(8)} ${symbol.b} into ${actual.c.earned.toFixed(8)} ${symbol.c}`);
logger.execution.debug(`BC Price Error: ${variation.bc.toFixed(8)}%`);
logger.execution.debug();
logger.execution.debug(`CA Expected Conversion: ${calculated.c.spent.toFixed(8)} ${symbol.c} into ${calculated.a.earned.toFixed(8)} ${symbol.a}`);
logger.execution.debug(`CA Observed Conversion: ${actual.c.spent.toFixed(8)} ${symbol.c} into ${actual.a.earned.toFixed(8)} ${symbol.a}`);
logger.execution.debug();
logger.execution.debug(`${calculated.trade.ca.ticker} Stats:`);
logger.execution.debug(`Expected Conversion: ${calculated.c.spent.toFixed(8)} ${symbol.c} into ${calculated.a.earned.toFixed(8)} ${symbol.a}`);
logger.execution.debug(`Observed Conversion: ${actual.c.spent.toFixed(8)} ${symbol.c} into ${actual.a.earned.toFixed(8)} ${symbol.a}`);
logger.execution.debug(`Price Error: ${variation.ca.toFixed(8)}%`);

logger.execution.trace(`Depth cache used for calculation:`);
logger.execution.trace(calculated.depth);
Expand All @@ -61,10 +74,11 @@ const ArbitrageExecution = {
c: actual.c.delta / actual.c.spent * 100
};

logger.execution.info();
logger.execution.info(`${symbol.a} delta:\t ${actual.a.delta < 0 ? '' : ' '}${actual.a.delta.toFixed(8)} (${percent.a < 0 ? '' : ' '}${percent.a.toFixed(4)}%)`);
logger.execution.info(`${symbol.b} delta:\t ${actual.b.delta < 0 ? '' : ' '}${actual.b.delta.toFixed(8)} (${percent.b < 0 ? '' : ' '}${percent.b.toFixed(4)}%)`);
logger.execution.info(`${symbol.c} delta:\t ${actual.c.delta < 0 ? '' : ' '}${actual.c.delta.toFixed(8)} (${percent.c < 0 ? '' : ' '}${percent.c.toFixed(4)}%)`);
logger.execution.info(`BNB commission: ${(-1 * actual.fees).toFixed(8)}`);
logger.execution.info(`BNB commission: ${(-1 * actual.fees).toFixed(8)}`);
logger.execution.info();
})
.catch((err) => logger.execution.error(err.message))
Expand Down Expand Up @@ -246,7 +260,10 @@ const ArbitrageExecution = {
parseActualResults(method, { executedQty, cummulativeQuoteQty, fills }) {
const spent = method.toUpperCase() === 'BUY' ? parseFloat(cummulativeQuoteQty) : parseFloat(executedQty);
const earned = method.toUpperCase() === 'SELL' ? parseFloat(cummulativeQuoteQty) : parseFloat(executedQty);
const fees = fills.filter(f => f.commissionAsset === 'BNB').map(f => parseFloat(f.commission)).reduce((total, fee) => total + fee, 0);
const fees = fills
.filter(fill => fill.commissionAsset === 'BNB')
.map(fill => parseFloat(fill.commission))
.reduce((total, fee) => total + fee, 0);
return [spent, earned, fees];
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/BinanceApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ const BinanceApi = {
logger.execution.info(`Successfully bought ${response.executedQty} ${ticker} @ a quote of ${response.cummulativeQuoteQty}`);
}
return resolve(response);
})
})
});
});
},

marketSell(ticker, quantity) {
Expand Down
11 changes: 8 additions & 3 deletions src/main/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ ArbitrageExecution.refreshBalances()
function calculateArbitrage() {
if (CONFIG.DEPTH.PRUNE) MarketCache.pruneDepthsAboveThreshold(CONFIG.DEPTH.SIZE);

const { calculationTime, successCount, errorCount, results } = CalculationNode.cycle(MarketCache.relationships, BinanceApi.cloneDepths(MarketCache.getTickerArray(), CONFIG.DEPTH.SIZE), (e) => logger.performance.warn(e), ArbitrageExecution.executeCalculatedPosition);
const { calculationTime, successCount, errorCount, results } = CalculationNode.cycle(
MarketCache.relationships,
BinanceApi.cloneDepths(MarketCache.getTickerArray(), CONFIG.DEPTH.SIZE),
(e) => logger.performance.warn(e),
ArbitrageExecution.executeCalculatedPosition
);

if (CONFIG.HUD.ENABLED) refreshHUD(results);
displayCalculationResults(successCount, errorCount, calculationTime);
Expand Down Expand Up @@ -168,12 +173,12 @@ function checkBalances() {
console.log(`Checking balances ...`);

if (ArbitrageExecution.balances[CONFIG.INVESTMENT.BASE].available < CONFIG.INVESTMENT.MIN) {
const msg = `An available balance of ${CONFIG.INVESTMENT.MIN} ${CONFIG.INVESTMENT.BASE} is required to satisfy your INVESTMENT.MIN configuration`;
const msg = `Only detected ${ArbitrageExecution.balances[CONFIG.INVESTMENT.BASE].available} ${CONFIG.INVESTMENT.BASE}, but ${CONFIG.INVESTMENT.MIN} ${CONFIG.INVESTMENT.BASE} is required to satisfy your INVESTMENT.MIN configuration`;
logger.execution.error(msg);
throw new Error(msg);
}
if (ArbitrageExecution.balances[CONFIG.INVESTMENT.BASE].available < CONFIG.INVESTMENT.MAX) {
const msg = `An available balance of ${CONFIG.INVESTMENT.MAX} ${CONFIG.INVESTMENT.BASE} is required to satisfy your INVESTMENT.MAX configuration`;
const msg = `Only detected ${ArbitrageExecution.balances[CONFIG.INVESTMENT.BASE].available} ${CONFIG.INVESTMENT.BASE}, but ${CONFIG.INVESTMENT.MAX} ${CONFIG.INVESTMENT.BASE} is required to satisfy your INVESTMENT.MAX configuration`;
logger.execution.error(msg);
throw new Error(msg);
}
Expand Down
Binary file removed src/resources/favicon.png
Binary file not shown.

0 comments on commit 7b1ab04

Please sign in to comment.