diff --git a/README.md b/README.md index 455b01d5..ae3dc554 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![GitHub package.json version](https://img.shields.io/github/package-json/v/chrisleekr/binance-trading-bot)](https://github.com/chrisleekr/binance-trading-bot/releases) [![Build](https://github.com/chrisleekr/binance-trading-bot/workflows/main/badge.svg)](https://github.com/chrisleekr/binance-trading-bot/actions?query=workflow%3Amain) [![CodeCov](https://codecov.io/gh/chrisleekr/binance-trading-bot/branch/master/graph/badge.svg)](https://codecov.io/gh/chrisleekr/binance-trading-bot) -[![Docker pull](https://img.shields.io/docker/pulls/chrisleekr/binance-trading-bot)](https://hub.docker.com/repository/docker/chrisleekr/binance-trading-bot) +[![Docker pull](https://img.shields.io/docker/pulls/chrisleekr/binance-trading-bot)](https://hub.docker.com/r/chrisleekr/binance-trading-bot) [![MIT License](https://img.shields.io/github/license/chrisleekr/binance-trading-bot)](https://github.com/chrisleekr/binance-trading-bot/blob/master/LICENSE) > Automated Binance trading bot with trailing buy/sell strategy @@ -306,6 +306,8 @@ Or use the frontend to adjust configurations after launching the application. - [x] Added more candle periods - 1m, 3m and 5m - [x] Allow to disable local tunnel - [x] Fix the bug with handling open orders +- [x] Fix the bug with limit step in the frontend +- [x] Updated the frontend to display buy open orders with the buy signal - [ ] Allow browser notification in the frontend - [ ] Secure frontend with the password @@ -314,3 +316,4 @@ Or use the frontend to adjust configurations after launching the application. - [@d0x2f](https://github.com/d0x2f) - [@Maxoos](https://github.com/Maxoos) - [@OOtta](https://github.com/OOtta) +- [@thamlth](https://github.com/thamlth) diff --git a/app/jobs/trailingTrade/step/__tests__/get-indicators.test.js b/app/jobs/trailingTrade/step/__tests__/get-indicators.test.js index dcf916a8..d04500b0 100644 --- a/app/jobs/trailingTrade/step/__tests__/get-indicators.test.js +++ b/app/jobs/trailingTrade/step/__tests__/get-indicators.test.js @@ -30,11 +30,11 @@ describe('get-indicators.js', () => { candles: { interval: '1h', limit: 50 }, buy: { triggerPercentage: 1.01, - limitPercentage: 1.011 + limitPercentage: 1.021 }, sell: { - triggerPercentage: 0.99, - limitPercentage: 0.98 + triggerPercentage: 1.06, + limitPercentage: 0.979 } }, baseAssetBalance: { total: 0.1 }, @@ -57,9 +57,10 @@ describe('get-indicators.js', () => { symbol: 'BTCUSDT', symbolConfiguration: { candles: { interval: '1h', limit: 50 }, - buy: { triggerPercentage: 1.01, limitPercentage: 1.011 }, - sell: { triggerPercentage: 0.99, limitPercentage: 0.98 } + buy: { triggerPercentage: 1.01, limitPercentage: 1.021 }, + sell: { triggerPercentage: 1.06, limitPercentage: 0.979 } }, + baseAssetBalance: { total: 0.1, estimatedValue: 1555.509 }, openOrders: [], indicators: { lowestPrice: 8893.03, @@ -77,13 +78,9 @@ describe('get-indicators.js', () => { quoteAssetVolume: '59899003.79417636' } }, - baseAssetBalance: { - total: 0.1, - estimatedValue: 1555.509 - }, buy: { currentPrice: 15555.09, - limitPrice: 15726.195989999998, + limitPrice: 15881.746889999999, lowestPrice: 8893.03, triggerPrice: 8981.9603, difference: 73.18146017634923, @@ -93,7 +90,7 @@ describe('get-indicators.js', () => { }, sell: { currentPrice: 15555.09, - limitPrice: 15243.9882, + limitPrice: 15228.43311, lastBuyPrice: null, triggerPrice: null, difference: null, @@ -123,11 +120,11 @@ describe('get-indicators.js', () => { candles: { interval: '1h', limit: 50 }, buy: { triggerPercentage: 1.01, - limitPercentage: 1.011 + limitPercentage: 1.021 }, sell: { - triggerPercentage: 0.99, - limitPercentage: 0.98 + triggerPercentage: 1.06, + limitPercentage: 0.979 } }, baseAssetBalance: { total: 0.1 }, @@ -180,8 +177,8 @@ describe('get-indicators.js', () => { symbol: 'BTCUSDT', symbolConfiguration: { candles: { interval: '1h', limit: 50 }, - buy: { triggerPercentage: 1.01, limitPercentage: 1.011 }, - sell: { triggerPercentage: 0.99, limitPercentage: 0.98 } + buy: { triggerPercentage: 1.01, limitPercentage: 1.021 }, + sell: { triggerPercentage: 1.06, limitPercentage: 0.979 } }, baseAssetBalance: { total: 0.1, estimatedValue: 1555.509 }, openOrders: [ @@ -206,9 +203,10 @@ describe('get-indicators.js', () => { stopPrice: '16100.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15726.195989999998, - limitPercentage: 1.011, - difference: 2.3769512362538103, + limitPrice: 15881.746889999999, + limitPercentage: 1.021, + differenceToExecute: -3.5030976998525976, + differenceToCancel: -1.37423868741684, updatedAt: expect.any(Object) }, { @@ -221,9 +219,10 @@ describe('get-indicators.js', () => { stopPrice: '15900.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15243.9882, - limitPercentage: 0.98, - difference: -4.303413197341621, + limitPrice: 15228.43311, + limitPercentage: 0.979, + differenceToExecute: -2.2173449333947826, + differenceToCancel: -4.40995396669539, minimumProfit: 35, minimumProfitPercentage: 43.75, updatedAt: expect.any(Object) @@ -247,7 +246,7 @@ describe('get-indicators.js', () => { }, buy: { currentPrice: 15555.09, - limitPrice: 15726.195989999998, + limitPrice: 15881.746889999999, lowestPrice: 8893.03, triggerPrice: 8981.9603, difference: 73.18146017634923, @@ -273,9 +272,10 @@ describe('get-indicators.js', () => { stopPrice: '16100.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15726.195989999998, - limitPercentage: 1.011, - difference: 2.3769512362538103, + limitPrice: 15881.746889999999, + limitPercentage: 1.021, + differenceToExecute: -3.5030976998525976, + differenceToCancel: -1.37423868741684, updatedAt: expect.any(Object) } ], @@ -284,10 +284,10 @@ describe('get-indicators.js', () => { }, sell: { currentPrice: 15555.09, - limitPrice: 15243.9882, + limitPrice: 15228.43311, lastBuyPrice: 9000, - triggerPrice: 8910, - difference: 42.71971425430519, + triggerPrice: 9540, + difference: 38.669593039963125, currentProfit: 655.509, currentProfitPercentage: 42.14112550939918, openOrders: [ @@ -301,9 +301,10 @@ describe('get-indicators.js', () => { stopPrice: '15900.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15243.9882, - limitPercentage: 0.98, - difference: -4.303413197341621, + limitPrice: 15228.43311, + limitPercentage: 0.979, + differenceToExecute: -2.2173449333947826, + differenceToCancel: -4.40995396669539, minimumProfit: 35, minimumProfitPercentage: 43.75, updatedAt: expect.any(Object) @@ -330,11 +331,11 @@ describe('get-indicators.js', () => { candles: { interval: '1h', limit: 50 }, buy: { triggerPercentage: 1.01, - limitPercentage: 1.011 + limitPercentage: 1.021 }, sell: { - triggerPercentage: 0.99, - limitPercentage: 0.98 + triggerPercentage: 1.06, + limitPercentage: 0.979 } }, baseAssetBalance: { @@ -381,13 +382,10 @@ describe('get-indicators.js', () => { symbol: 'BTCUSDT', symbolConfiguration: { candles: { interval: '1h', limit: 50 }, - buy: { triggerPercentage: 1.01, limitPercentage: 1.011 }, - sell: { triggerPercentage: 0.99, limitPercentage: 0.98 } - }, - baseAssetBalance: { - total: 0.1, - estimatedValue: 1555.509 + buy: { triggerPercentage: 1.01, limitPercentage: 1.021 }, + sell: { triggerPercentage: 1.06, limitPercentage: 0.979 } }, + baseAssetBalance: { total: 0.1, estimatedValue: 1555.509 }, openOrders: [ { orderId: 1, @@ -410,9 +408,10 @@ describe('get-indicators.js', () => { stopPrice: '16100.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15726.195989999998, - limitPercentage: 1.011, - difference: 2.3769512362538103, + limitPrice: 15881.746889999999, + limitPercentage: 1.021, + differenceToExecute: -3.5030976998525976, + differenceToCancel: -1.37423868741684, updatedAt: expect.any(Object) }, { @@ -425,9 +424,10 @@ describe('get-indicators.js', () => { stopPrice: '15900.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15243.9882, - limitPercentage: 0.98, - difference: -4.303413197341621, + limitPrice: 15228.43311, + limitPercentage: 0.979, + differenceToExecute: -2.2173449333947826, + differenceToCancel: -4.40995396669539, minimumProfit: null, minimumProfitPercentage: null, updatedAt: expect.any(Object) @@ -451,7 +451,7 @@ describe('get-indicators.js', () => { }, buy: { currentPrice: 15555.09, - limitPrice: 15726.195989999998, + limitPrice: 15881.746889999999, lowestPrice: 8893.03, triggerPrice: 8981.9603, difference: 73.18146017634923, @@ -477,9 +477,10 @@ describe('get-indicators.js', () => { stopPrice: '16100.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15726.195989999998, - limitPercentage: 1.011, - difference: 2.3769512362538103, + limitPrice: 15881.746889999999, + limitPercentage: 1.021, + differenceToExecute: -3.5030976998525976, + differenceToCancel: -1.37423868741684, updatedAt: expect.any(Object) } ], @@ -488,7 +489,7 @@ describe('get-indicators.js', () => { }, sell: { currentPrice: 15555.09, - limitPrice: 15243.9882, + limitPrice: 15228.43311, lastBuyPrice: null, triggerPrice: null, difference: null, @@ -505,9 +506,10 @@ describe('get-indicators.js', () => { stopPrice: '15900.000', time: 1615465601162, currentPrice: 15555.09, - limitPrice: 15243.9882, - limitPercentage: 0.98, - difference: -4.303413197341621, + limitPrice: 15228.43311, + limitPercentage: 0.979, + differenceToExecute: -2.2173449333947826, + differenceToCancel: -4.40995396669539, minimumProfit: null, minimumProfitPercentage: null, updatedAt: expect.any(Object) diff --git a/app/jobs/trailingTrade/step/get-indicators.js b/app/jobs/trailingTrade/step/get-indicators.js index 2ef44218..fe6cf87e 100644 --- a/app/jobs/trailingTrade/step/get-indicators.js +++ b/app/jobs/trailingTrade/step/get-indicators.js @@ -127,14 +127,19 @@ const execute = async (logger, rawData) => { if (order.side.toLowerCase() === 'buy') { newOrder.limitPrice = buyLimitPrice; newOrder.limitPercentage = buyLimitPercentage; - newOrder.difference = - (1 - parseFloat(order.stopPrice / buyLimitPrice)) * -100; + newOrder.differenceToExecute = + (1 - parseFloat(order.stopPrice / currentPrice)) * 100; + + newOrder.differenceToCancel = + (1 - parseFloat(order.stopPrice / buyLimitPrice)) * 100; } if (order.side.toLowerCase() === 'sell') { newOrder.limitPrice = sellLimitPrice; newOrder.limitPercentage = sellLimitPercentage; - newOrder.difference = + newOrder.differenceToExecute = + (1 - parseFloat(order.stopPrice / currentPrice)) * 100; + newOrder.differenceToCancel = (1 - parseFloat(order.stopPrice / sellLimitPrice)) * 100; newOrder.minimumProfit = null; diff --git a/public/js/CoinWrapperBuyOrders.js b/public/js/CoinWrapperBuyOrders.js index cfa27e03..8aecbc09 100644 --- a/public/js/CoinWrapperBuyOrders.js +++ b/public/js/CoinWrapperBuyOrders.js @@ -73,12 +73,7 @@ class CoinWrapperBuyOrders extends React.Component { '' )}
-
- Current price: - - {openOrder.currentPrice.toFixed(precision)} - -
+ {openOrder.limitPrice ? (
Current limit Price: @@ -89,11 +84,27 @@ class CoinWrapperBuyOrders extends React.Component { ) : ( '' )} - {openOrder.difference ? ( + {openOrder.differenceToCancel ? ( +
+ Difference to cancel: + + {openOrder.differenceToCancel.toFixed(2)}% + +
+ ) : ( + '' + )} +
+ Current price: + + {openOrder.currentPrice.toFixed(precision)} + +
+ {openOrder.differenceToExecute ? (
- Difference to buy: + Difference to execute: - {openOrder.difference.toFixed(2)}% + {openOrder.differenceToExecute.toFixed(2)}%
) : ( diff --git a/public/js/CoinWrapperBuySignal.js b/public/js/CoinWrapperBuySignal.js index 1267b7d4..a9efc979 100644 --- a/public/js/CoinWrapperBuySignal.js +++ b/public/js/CoinWrapperBuySignal.js @@ -13,10 +13,6 @@ class CoinWrapperBuySignal extends React.Component { } } = this.props; - if (buy.openOrders.length > 0) { - return ''; - } - const precision = tickSize.indexOf(1) - 1; return ( @@ -97,9 +93,8 @@ class CoinWrapperBuySignal extends React.Component { '' )} {buy.processMessage ? ( -
+
-
{buy.processMessage} diff --git a/public/js/CoinWrapperSellOrders.js b/public/js/CoinWrapperSellOrders.js index 329bf877..02e84cd6 100644 --- a/public/js/CoinWrapperSellOrders.js +++ b/public/js/CoinWrapperSellOrders.js @@ -10,7 +10,7 @@ class CoinWrapperSellOrders extends React.Component { filterPrice: { tickSize } }, symbolConfiguration, - sell: { openOrders, lastBuyPrice }, + sell: { openOrders }, quoteAssetBalance: { asset: quoteAsset } } = symbolInfo; @@ -54,22 +54,11 @@ class CoinWrapperSellOrders extends React.Component { {(+openOrder.origQty).toFixed(precision)}
-
- {lastBuyPrice > 0 ? ( -
- Last buy price: - - {(+lastBuyPrice).toFixed(precision)} - -
- ) : ( - '' - )} - {openOrder.currentPrice ? ( -
- Current price: + {openOrder.price > 0 ? ( +
+ Price: - {(+openOrder.currentPrice).toFixed(precision)} + {(+openOrder.price).toFixed(precision)}
) : ( @@ -85,11 +74,13 @@ class CoinWrapperSellOrders extends React.Component { ) : ( '' )} - {openOrder.price > 0 ? ( -
- Limit Price: +
+ + {openOrder.currentPrice ? ( +
+ Current price: - {(+openOrder.price).toFixed(precision)} + {(+openOrder.currentPrice).toFixed(precision)}
) : ( @@ -107,12 +98,6 @@ class CoinWrapperSellOrders extends React.Component { '' )}
-
- Current price: - - {openOrder.currentPrice.toFixed(precision)} - -
{openOrder.limitPrice ? (
Current limit Price: @@ -123,11 +108,27 @@ class CoinWrapperSellOrders extends React.Component { ) : ( '' )} - {openOrder.difference ? ( + {openOrder.differenceToCancel ? ( +
+ Difference to cancel: + + {openOrder.differenceToCancel.toFixed(2)}% + +
+ ) : ( + '' + )} +
+ Current price: + + {openOrder.currentPrice.toFixed(precision)} + +
+ {openOrder.differenceToExecute ? (
- Difference to sell: + Difference to execute: - {openOrder.difference.toFixed(2)}% + {openOrder.differenceToExecute.toFixed(2)}%
) : ( diff --git a/public/js/CoinWrapperSellSignal.js b/public/js/CoinWrapperSellSignal.js index bf5f4d5d..a36bdebb 100644 --- a/public/js/CoinWrapperSellSignal.js +++ b/public/js/CoinWrapperSellSignal.js @@ -20,7 +20,7 @@ class CoinWrapperSellSignal extends React.Component { const precision = tickSize.indexOf(1) - 1; - if (sell.lastBuyPrice > 0 && buy.openOrders.length === 0) { + if (sell.lastBuyPrice > 0) { return (
@@ -106,12 +106,18 @@ class CoinWrapperSellSignal extends React.Component { ) : ( '' )} -
-
- - {sell.processMessage} - -
+ {sell.processMessage ? ( +
+
+
+ + {sell.processMessage} + +
+
+ ) : ( + '' + )}
); } diff --git a/public/js/SettingIcon.js b/public/js/SettingIcon.js index 541c4a07..d14e3413 100644 --- a/public/js/SettingIcon.js +++ b/public/js/SettingIcon.js @@ -227,7 +227,7 @@ class SettingIcon extends React.Component { placeholder='Enter trigger percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='buy.triggerPercentage' value={configuration.buy.triggerPercentage} onChange={this.handleInputChange} @@ -249,7 +249,7 @@ class SettingIcon extends React.Component { placeholder='Enter stop price percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='buy.stopPercentage' value={configuration.buy.stopPercentage} onChange={this.handleInputChange} @@ -306,7 +306,7 @@ class SettingIcon extends React.Component { placeholder='Enter trigger percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='sell.triggerPercentage' value={configuration.sell.triggerPercentage} onChange={this.handleInputChange} @@ -327,7 +327,7 @@ class SettingIcon extends React.Component { placeholder='Enter stop price percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='sell.stopPercentage' value={configuration.sell.stopPercentage} onChange={this.handleInputChange} @@ -347,7 +347,7 @@ class SettingIcon extends React.Component { placeholder='Enter limit price percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='sell.limitPercentage' value={configuration.sell.limitPercentage} onChange={this.handleInputChange} diff --git a/public/js/SymbolSettingIcon.js b/public/js/SymbolSettingIcon.js index 29195b24..a126c892 100644 --- a/public/js/SymbolSettingIcon.js +++ b/public/js/SymbolSettingIcon.js @@ -208,7 +208,7 @@ class SymbolSettingIcon extends React.Component { placeholder='Enter trigger percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='buy.triggerPercentage' value={symbolConfiguration.buy.triggerPercentage} onChange={this.handleInputChange} @@ -230,7 +230,7 @@ class SymbolSettingIcon extends React.Component { placeholder='Enter stop price percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='buy.stopPercentage' value={symbolConfiguration.buy.stopPercentage} onChange={this.handleInputChange} @@ -287,7 +287,7 @@ class SymbolSettingIcon extends React.Component { placeholder='Enter trigger percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='sell.triggerPercentage' value={symbolConfiguration.sell.triggerPercentage} onChange={this.handleInputChange} @@ -308,7 +308,7 @@ class SymbolSettingIcon extends React.Component { placeholder='Enter stop price percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='sell.stopPercentage' value={symbolConfiguration.sell.stopPercentage} onChange={this.handleInputChange} @@ -328,7 +328,7 @@ class SymbolSettingIcon extends React.Component { placeholder='Enter limit price percentage' required min='0' - step='0.001' + step='0.0001' data-state-key='sell.limitPercentage' value={symbolConfiguration.sell.limitPercentage} onChange={this.handleInputChange}