Skip to content

Commit

Permalink
Updated changes (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisleekr authored Mar 8, 2021
1 parent 025be0a commit 60643b2
Show file tree
Hide file tree
Showing 20 changed files with 878 additions and 635 deletions.
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
[![CodeCov](https://codecov.io/gh/chrisleekr/binance-trading-bot/branch/master/graph/badge.svg)](https://codecov.io/gh/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)

This is a test project. I am just testing my code. **I cannot guarantee whether
you can make money or not.**
This is a test project. I am just testing my code.

## Warnings

**I cannot guarantee whether you can make money or not.**

**So use it at your own risk! I have no responsibility for any loss or hardship
incurred directly or indirectly by using this code.**
Expand All @@ -29,6 +32,9 @@ is effective than using MACD indicators.
BTCUSDT, ETHUSDT. You can add more FIAT symbols like BUSD, AUD from the
frontend. However, I didn't test in the live server. So use with your own
risk.
- Note that if the coin is worth less than $10, then the bot will remove the
last buy price because Binance does not allow to place an order of less than
$10.
- The bot is using MongoDB to provide a persistence database. However, it does
not use the latest MongoDB to support Raspberry Pi 32bit. Used MongoDB version
is 3.2.20, which is provided by
Expand Down Expand Up @@ -124,11 +130,11 @@ Or use the frontend to adjust configurations after launching the application.

| Frontend Mobile | Setting |
| -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| ![Screenshot1](https://user-images.githubusercontent.com/5715919/110196331-ea3d9d00-7e97-11eb-8517-c3eaeb0f2698.png) | ![Screenshot2](https://user-images.githubusercontent.com/5715919/110196341-f7f32280-7e97-11eb-9aea-e645f678e185.png) |
| ![Screenshot1](https://user-images.githubusercontent.com/5715919/110298077-421b0600-8048-11eb-9763-94ebc2159745.png) | ![Screenshot2](https://user-images.githubusercontent.com/5715919/110298101-4a734100-8048-11eb-8916-4d4381d3161e.png) |

| Frontend Desktop |
| ------------------------------------------------------------------------------------------------------------------- |
| ![Screenshot](https://user-images.githubusercontent.com/5715919/110196322-d2feaf80-7e97-11eb-9ee0-a71e7a5c9ed7.png) |
| ![Screenshot](https://user-images.githubusercontent.com/5715919/110298003-2b74af00-8048-11eb-81d4-52a4696b11f4.png) |

### First trade

Expand Down Expand Up @@ -166,8 +172,17 @@ Or use the frontend to adjust configurations after launching the application.
- [x] Override buy/sell configuration per symbol
- [x] Support PWA for frontend - now support "Add to Home screen"
- [x] Enable/Disable symbols trading, but continue to monitor
- [x] Add max-size for logging
- [x] Execute chaseStopLossLimitOrder on every process
- [x] Support buy trigger percentage
- [ ] Apply chase-stop-loss-limit order for buy signal as well
- [ ] Override the lowest value in the frontend
- [ ] Re-organise configuration structures
- [ ] Allow browser notification
- [ ] Secure frontend with the password

## Acknowledgments

- [@d0x2f](https://github.com/d0x2f)
- [@Maxoos](https://github.com/Maxoos)
- [@OOtta](https://github.com/OOtta)
62 changes: 57 additions & 5 deletions app/jobs/__tests__/simpleStopChaser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,18 @@ describe('simpleStopChaser', () => {
lastBuyPercentage: 1.06,
stopPercentage: 0.97,
limitPercentage: 0.96
},
buy: {
enabled: true,
triggerPercentage: 1
},
sell: {
enabled: true
}
};

cache.hset = jest.fn().mockResolvedValue(true);
cache.hdel = jest.fn().mockResolvedValue(true);
mongo.findOne = jest.fn((_logger, collection, filter) => {
if (
collection === 'simple-stop-chaser-common' &&
Expand Down Expand Up @@ -60,13 +68,31 @@ describe('simpleStopChaser', () => {
.fn()
.mockResolvedValue({ result: true });

simpleStopChaserHelper.chaseStopLossLimitOrder = jest
.fn()
.mockResolvedValue({ result: true });

await simpleStopChaserExecute(logger);
});

it('triggers getConfiguration for global configuration', () => {
expect(simpleStopChaserHelper.getConfiguration).toHaveBeenCalledWith(
logger
);
});

it('triggers getConfiguration for symbol configuration', () => {
expect(simpleStopChaserHelper.getConfiguration).toHaveBeenCalledWith(
logger,
'BTCUSDT'
);
});

it('triggers getIndicator', () => {
expect(simpleStopChaserHelper.getIndicators).toHaveBeenCalledWith(
logger,
'BTCUSDT',
logger
jobConfig
);
});

Expand All @@ -79,9 +105,17 @@ describe('simpleStopChaser', () => {
});

it('triggers placeBuyOrder', () => {
expect(simpleStopChaserHelper.placeBuyOrder).toHaveBeenCalledWith(
logger,
{ some: 'value' },
jobConfig
);
});

it('triggers chaseStopLossLimitOrder', () => {
expect(
simpleStopChaserHelper.placeBuyOrder
).toHaveBeenCalledWith(logger, { some: 'value' });
simpleStopChaserHelper.chaseStopLossLimitOrder
).toHaveBeenCalledWith(logger, { some: 'value' }, jobConfig);
});
});

Expand All @@ -101,13 +135,18 @@ describe('simpleStopChaser', () => {
.fn()
.mockResolvedValue({ result: true });

simpleStopChaserHelper.chaseStopLossLimitOrder = jest
.fn()
.mockResolvedValue({ result: true });

await simpleStopChaserExecute(logger);
});

it('triggers getIndicator', () => {
expect(simpleStopChaserHelper.getIndicators).toHaveBeenCalledWith(
logger,
'ETHUSDT',
logger
jobConfig
);
});

Expand All @@ -122,6 +161,12 @@ describe('simpleStopChaser', () => {
it('does not trigger placeBuyOrder', () => {
expect(simpleStopChaserHelper.placeBuyOrder).not.toHaveBeenCalled();
});

it('triggers chaseStopLossLimitOrder', () => {
expect(
simpleStopChaserHelper.chaseStopLossLimitOrder
).toHaveBeenCalledWith(logger, { some: 'value' }, jobConfig);
});
});

describe('when tradeaActionResult is hold and there is cached last symbol and it is last symbol at symbols', () => {
Expand Down Expand Up @@ -151,6 +196,13 @@ describe('simpleStopChaser', () => {
expect(simpleStopChaserHelper.placeBuyOrder).not.toHaveBeenCalled();
});

it('triggers hdel to place-buy-order-result', () => {
expect(cache.hdel).toHaveBeenCalledWith(
'simple-stop-chaser-symbols',
'BTCUSDT-place-buy-order-result'
);
});

it('caches last processed time and symbol', () => {
expect(cache.hset).toHaveBeenCalledWith(
'simple-stop-chaser-common',
Expand All @@ -162,7 +214,7 @@ describe('simpleStopChaser', () => {
it('triggers chaseStopLossLimitOrder', () => {
expect(
simpleStopChaserHelper.chaseStopLossLimitOrder
).toHaveBeenCalledWith(logger, { some: 'value' });
).toHaveBeenCalledWith(logger, { some: 'value' }, jobConfig);
});
});

Expand Down
67 changes: 39 additions & 28 deletions app/jobs/simpleStopChaser.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ const determineNextSymbol = async (symbols, logger) => {
};

const execute = async logger => {
logger.info('Trade: Simple Stop-Chasing');
logger.info('Trade: Start simple-stop-chaser process...');

const simpleStopChaser = await helper.getConfiguration(logger);
const globalConfiguration = await helper.getConfiguration(logger);

const { symbols } = simpleStopChaser;
const { symbols } = globalConfiguration;

logger.info({ symbols }, 'Checking symbols...');

Expand All @@ -45,52 +45,63 @@ const execute = async logger => {
);

try {
// 0. Get exchange symbols
await helper.getExchangeSymbols(symbolLogger);
// 1. Get exchange symbols
await helper.getExchangeSymbols(symbolLogger, globalConfiguration);

// 0. Get account 9info
const symbolConfiguration = await helper.getConfiguration(logger, symbol);

// 2. Get account info
const accountInfo = await helper.getAccountInfo(symbolLogger);
cache.hset(
'simple-stop-chaser-common',
`account-info`,
JSON.stringify(accountInfo)
);

// 1. Get indicators
const indicators = await helper.getIndicators(symbol, symbolLogger);
// 3. Get indicators
const indicators = await helper.getIndicators(
symbolLogger,
symbol,
symbolConfiguration
);

// 2. Determine actions
// 4. Determine actions
const tradeActionResult = await helper.determineAction(
symbolLogger,
indicators
indicators,
symbolConfiguration
);
symbolLogger.info({ tradeActionResult }, 'Determined action.');

// 3. Place order based on lowest value signal
let orderResult = {};
// 5. Place order based on lowest value signal
let buyOrderResult = {};
if (tradeActionResult.action === 'buy') {
orderResult = await helper.placeBuyOrder(symbolLogger, indicators);
} else if (tradeActionResult.action === 'sell') {
symbolLogger.warn(`Got sell signal, but do nothing. Never lose money.`);
} else {
// Delete cached buy order result
buyOrderResult = await helper.placeBuyOrder(
symbolLogger,
indicators,
symbolConfiguration
);
}

// 6. If action is wait, then clean up cache
if (tradeActionResult.action === 'wait') {
cache.hdel(
'simple-stop-chaser-symbols',
`${symbol}-place-buy-order-result`
);

// Check stop loss limit order
orderResult = await helper.chaseStopLossLimitOrder(
symbolLogger,
indicators
);
}

if (orderResult.result) {
symbolLogger.info({ orderResult }, 'Finish processing symbol...');
} else {
symbolLogger.warn({ orderResult }, 'Finish processing symbol...');
}
// 7. Check stop loss limit order
const soptLossLimitOrderResult = await helper.chaseStopLossLimitOrder(
symbolLogger,
indicators,
symbolConfiguration
);

symbolLogger.info(
{ buyOrderResult, soptLossLimitOrderResult },
'Trade: Finish simple-stop-chaser process...'
);
} catch (e) {
symbolLogger.error(e, `${symbol} Execution failed.`);
if (
Expand Down
Loading

0 comments on commit 60643b2

Please sign in to comment.