Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added multiple tradingview indicators #539

Merged
merged 48 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a8555ac
feat: added multiple tradingview indicators
chrisleekr Nov 18, 2022
7592694
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Nov 20, 2022
753301d
chore: updated UI
chrisleekr Nov 20, 2022
355861d
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Nov 24, 2022
6f83abe
chore: remove unnecessary log
chrisleekr Nov 24, 2022
a398096
chore: change logger.info to logger.debug for mongo helper
chrisleekr Nov 24, 2022
2b44911
fix: logger to have debug stub
chrisleekr Nov 24, 2022
7dc2180
chore: updated docker-compose for BINANCE_LOG_LEVEL
chrisleekr Nov 24, 2022
55ebadc
fix: use hgetWithoutLock to reduce redlock error
chrisleekr Nov 24, 2022
5e825b1
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Nov 30, 2022
4717239
refactor: move queue to helpers
chrisleekr Nov 30, 2022
a3d3715
Revert "refactor: move queue to helpers"
chrisleekr Nov 30, 2022
915cc58
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Dec 5, 2022
1e413cf
fix: optimised tradingview waitress default variables
chrisleekr Dec 5, 2022
6cd31ec
fix: migration deleting cache
chrisleekr Dec 10, 2022
8932438
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Dec 10, 2022
8190502
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Dec 19, 2022
5adcc5b
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Dec 20, 2022
5937cfa
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Dec 22, 2022
f7c73f6
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Jan 7, 2023
a05011c
feat: (wip) updating trading view
chrisleekr Jan 9, 2023
05830b5
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Jan 11, 2023
f5fcda8
feat: updated trading view with cronjob
chrisleekr Jan 11, 2023
6609c58
chore: removed unnecessary comment
chrisleekr Jan 11, 2023
c690b60
chore: removed unnecessary commit
chrisleekr Jan 11, 2023
a4d0fee
test: added tests
chrisleekr Jan 11, 2023
0546d74
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Jan 14, 2023
e55dce7
chore: fixed UI error
chrisleekr Jan 14, 2023
da47339
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Jan 16, 2023
925a77b
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Feb 8, 2023
82c3233
build: added docker-compose.arm64.yml
chrisleekr Feb 8, 2023
ca7f27c
test: fixed tests
chrisleekr Feb 8, 2023
6bfe74f
build: updated docker-compose.arm64.yml
chrisleekr Feb 10, 2023
c71887e
chore: updated settings.json
chrisleekr Feb 10, 2023
d174302
fix: handle undefined in tradingview
chrisleekr Feb 10, 2023
e18adcc
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Mar 20, 2023
eb12db8
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Mar 26, 2023
01d7373
chore: ignore redlock error
chrisleekr Mar 26, 2023
a3c6507
chore: added tradingview test
chrisleekr Mar 26, 2023
4ae205c
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Mar 28, 2023
3af0be7
build: added buildx
chrisleekr Apr 4, 2023
e706106
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Apr 4, 2023
9c8d9fc
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr May 3, 2023
4210c42
fix: fixed coinwrapper setting
chrisleekr May 4, 2023
e05a653
Merge branch 'master' into feat/multiple-tradingview-indicators
chrisleekr Apr 14, 2024
eae49d5
docs: updated CHANGELOG.md
chrisleekr May 4, 2024
5636144
revert: updated CHANGELOG.md
chrisleekr May 4, 2024
5c99cad
docs: updated CHANGELOG.md
chrisleekr May 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.tabSize": 2,
"eslint.alwaysShowStatus": true,
"files.trimTrailingWhitespace": true,
"files.exclude": {},
"files.insertFinalNewline": true,
Expand All @@ -18,10 +17,13 @@
"cSpell.words": [
"bbands",
"Bollinger",
"buildx",
"chrisleekr",
"cummulative",
"hgetall",
"MACD",
"mrkdwn",
"redlock",
"tradingview",
"tulind",
"uuidv"
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to this project will be documented in this file.

## Unreleased

- Added multiple TradingView indicators - [#539](https://github.com/chrisleekr/binance-trading-bot/pull/539)

## [0.0.98] - 2023-04-13

- Added the prefix to environment parameter for `TRADINGVIEW` related - [#616](https://github.com/chrisleekr/binance-trading-bot/pull/616)
Expand Down
12 changes: 12 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,18 @@ module.exports = grunt => {
'./public/dist/js/SymbolEditLastBuyPriceIcon.min.js',
'./public/dist/js/SymbolTriggerSellIcon.min.js',
'./public/dist/js/SymbolTriggerBuyIcon.min.js',
'./public/dist/js/SymbolSettingActionResetGridTrade.min.js',
'./public/dist/js/SymbolSettingActionResetToGlobalSetting.min.js',
'./public/dist/js/SymbolSettingActions.min.js',
'./public/dist/js/SymbolSettingIconBotOptionsAutoTriggerBuy.min.js',
'./public/dist/js/SymbolSettingIconBotOptions.min.js',
'./public/dist/js/SymbolSettingIconTradingView.min.js',
'./public/dist/js/SymbolSettingIconGridBuy.min.js',
'./public/dist/js/SymbolSettingIconGridSell.min.js',
'./public/dist/js/SymbolSettingIcon.min.js',
'./public/dist/js/SymbolLogsIcon.min.js',
'./public/dist/js/CoinWrapperSymbol.min.js',
'./public/dist/js/CoinWrapperTradingViews.min.js',
'./public/dist/js/CoinWrapperTradingView.min.js',
'./public/dist/js/CoinWrapper.min.js',
'./public/dist/js/DustTransferIcon.min.js',
Expand All @@ -68,6 +74,12 @@ module.exports = grunt => {
'./public/dist/js/SettingIconActions.min.js',
'./public/dist/js/SettingIconGridSell.min.js',
'./public/dist/js/SettingIconGridBuy.min.js',
'./public/dist/js/SettingIconTradingView.min.js',
'./public/dist/js/SettingIconBotOptionsLogs.min.js',
'./public/dist/js/SettingIconBotOptionsOrderLimit.min.js',
'./public/dist/js/SettingIconBotOptionsAutoTriggerBuy.min.js',
'./public/dist/js/SettingIconBotOptionsAuthentication.min.js',
'./public/dist/js/SettingIconBotOptionsTradingView.min.js',
'./public/dist/js/SettingIconBotOptions.min.js',
'./public/dist/js/SettingIconLastBuyPriceRemoveThreshold.min.js',
'./public/dist/js/SettingIcon.min.js',
Expand Down
18 changes: 18 additions & 0 deletions app/__tests__/error-handler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,5 +217,23 @@ describe('error-handler', () => {
}).toThrow(`something-unhandled`);
});
});

describe(`redlock error`, () => {
it('does not throws an error', async () => {
expect(() => {
process.on = jest.fn().mockImplementation((event, error) => {
if (event === 'uncaughtException') {
error({
message: `redlock:lock-XRPBUSD`,
code: 500
});
}
});

const { runErrorHandler } = require('../error-handler');
runErrorHandler(mockLogger);
}).not.toThrow();
});
});
});
});
9 changes: 7 additions & 2 deletions app/__tests__/server-cronjob.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe('server-cronjob', () => {

let mockExecuteAlive;
let mockExecuteTrailingTradeIndicator;
let mockExecuteTradingView;

describe('cronjob running fine', () => {
beforeEach(async () => {
Expand All @@ -19,10 +20,12 @@ describe('server-cronjob', () => {

mockExecuteAlive = jest.fn().mockResolvedValue(true);
mockExecuteTrailingTradeIndicator = jest.fn().mockResolvedValue(true);
mockExecuteTradingView = jest.fn().mockResolvedValue(true);

jest.mock('../cronjob', () => ({
executeAlive: mockExecuteAlive,
executeTrailingTradeIndicator: mockExecuteTrailingTradeIndicator
executeTrailingTradeIndicator: mockExecuteTrailingTradeIndicator,
executeTradingView: mockExecuteTradingView
}));

mockCronJob = jest
Expand Down Expand Up @@ -201,10 +204,12 @@ describe('server-cronjob', () => {
mockExecuteTrailingTradeIndicator = jest.fn().mockImplementation(() => {
setTimeout(() => Promise.resolve(true), 30000);
});
mockExecuteTradingView = jest.fn().mockResolvedValue(true);

jest.mock('../cronjob', () => ({
executeAlive: mockExecuteAlive,
executeTrailingTradeIndicator: mockExecuteTrailingTradeIndicator
executeTrailingTradeIndicator: mockExecuteTrailingTradeIndicator,
executeTradingView: mockExecuteTradingView
}));

mockCronJob = jest
Expand Down
50 changes: 50 additions & 0 deletions app/binance/__tests__/orders.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ describe('orders.js', () => {
let spyOnClearInterval;

let mockUpdateGridTradeLastOrder;
let mockDeleteGridTradeOrder;
let mockGetOpenOrdersFromAPI;
let mockErrorHandlerWrapper;

Expand Down Expand Up @@ -216,6 +217,7 @@ describe('orders.js', () => {
);
});
});

describe('when database orders not found', () => {
beforeEach(async () => {
mongoMock.findAll = jest.fn().mockResolvedValue([]);
Expand Down Expand Up @@ -245,5 +247,53 @@ describe('orders.js', () => {
expect(mockUpdateGridTradeLastOrder).not.toHaveBeenCalled();
});
});

describe('when an error is occurred', () => {
beforeEach(async () => {
mongoMock.findAll = jest.fn().mockResolvedValue([
{
key: 'BTCUSDT',
order: {
symbol: 'BTCUSDT',
cummulativeQuoteQty: '0.00000000',
executedQty: '0.00000000',
isWorking: false,
orderId: 7479643460,
origQty: '0.00920000',
price: '3248.37000000',
side: 'BUY',
status: 'NEW',
stopPrice: '3245.19000000',
type: 'STOP_LOSS_LIMIT',
updateTime: 1642713283562
}
}
]);

binanceMock.client.getOrder = jest
.fn()
.mockRejectedValue(new Error('something happened'));

mockUpdateGridTradeLastOrder = jest.fn();

mockDeleteGridTradeOrder = jest.fn().mockResolvedValue(true);

jest.mock('../../cronjob/trailingTradeHelper/order', () => ({
updateGridTradeLastOrder: mockUpdateGridTradeLastOrder,
deleteGridTradeOrder: mockDeleteGridTradeOrder
}));

const { syncDatabaseOrders } = require('../orders');

await syncDatabaseOrders(loggerMock);
});

it('triggers deleteGridTradeOrder', () => {
expect(mockDeleteGridTradeOrder).toHaveBeenCalledWith(
loggerMock,
'BTCUSDT'
);
});
});
});
});
35 changes: 23 additions & 12 deletions app/binance/orders.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const {
getOpenOrdersFromAPI
} = require('../cronjob/trailingTradeHelper/common');
const {
updateGridTradeLastOrder
updateGridTradeLastOrder,
deleteGridTradeOrder
} = require('../cronjob/trailingTradeHelper/order');
const { errorHandlerWrapper } = require('../error-handler');

Expand Down Expand Up @@ -70,22 +71,32 @@ const syncDatabaseOrders = async logger => {
{}
);

await Promise.all(
return Promise.all(
databaseOrders.map(async databaseOrder => {
const { order } = databaseOrder;
const { key, order } = databaseOrder;
const { symbol, orderId } = order;

const orderResult = await binance.client.getOrder({
symbol,
orderId
});
try {
const orderResult = await binance.client.getOrder({
symbol,
orderId
});

const { side } = orderResult;
const { side } = orderResult;

return updateGridTradeLastOrder(logger, symbol, side.toLowerCase(), {
...order,
...orderResult
});
return updateGridTradeLastOrder(logger, symbol, side.toLowerCase(), {
...order,
...orderResult
});
} catch (e) {
logger.info(
{ databaseOrder, saveLog: true, e },
`There was an error that occurred while retrieving the last grid order. ` +
`Delete the order - ${symbol} - ${orderId}`
);

return deleteGridTradeOrder(logger, key);
}
})
);
};
Expand Down
3 changes: 2 additions & 1 deletion app/cronjob/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ describe('index', () => {
expect(index).toStrictEqual({
executeAlive: expect.any(Function),
executeTrailingTrade: expect.any(Function),
executeTrailingTradeIndicator: expect.any(Function)
executeTrailingTradeIndicator: expect.any(Function),
executeTradingView: expect.any(Function)
});
});
});
86 changes: 86 additions & 0 deletions app/cronjob/__tests__/tradingView.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* eslint-disable max-classes-per-file */
/* eslint-disable global-require */
const { logger } = require('../../helpers');

describe('tradingView', () => {
let mockLoggerInfo;

let mockGetGlobalConfiguration;
let mockGetTradingView;

let mockErrorHandlerWrapper;

beforeEach(() => {
jest.clearAllMocks().resetModules();

mockLoggerInfo = jest.fn();

logger.info = mockLoggerInfo;
jest.mock('../../helpers', () => ({
logger: {
info: mockLoggerInfo,
error: jest.fn(),
warn: jest.fn(),
debug: jest.fn(),
child: jest.fn()
}
}));

mockErrorHandlerWrapper = jest
.fn()
.mockImplementation((_logger, _job, callback) =>
Promise.resolve(callback())
);

jest.mock('../../error-handler', () => ({
errorHandlerWrapper: mockErrorHandlerWrapper
}));
});

const mockSteps = () => {
mockGetGlobalConfiguration = jest
.fn()
.mockImplementation((_logger, rawData) => ({
...rawData,
...{
globalConfiguration: {
global: 'configuration data'
}
}
}));

mockGetTradingView = jest.fn().mockImplementation((_logger, rawData) => ({
...rawData,
...{
tradingView: { tradingview: 'data' }
}
}));

jest.mock('../trailingTradeIndicator/steps', () => ({
getGlobalConfiguration: mockGetGlobalConfiguration,
getTradingView: mockGetTradingView
}));
};

describe('without any error', () => {
beforeEach(async () => {
mockSteps();

const { execute: tradingViewExecute } = require('../tradingView');

await tradingViewExecute(logger);
});

it('returns expected result', () => {
expect(mockLoggerInfo).toHaveBeenCalledWith(
{
data: {
globalConfiguration: { global: 'configuration data' },
tradingView: { tradingview: 'data' }
}
},
'TradingView: Finish process...'
);
});
});
});
10 changes: 0 additions & 10 deletions app/cronjob/__tests__/trailingTradeIndicator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ describe('trailingTradeIndicator', () => {
let mockExecuteDustTransfer;
let mockGetClosedTrades;
let mockGetOrderStats;
let mockGetTradingView;
let mockSaveDataToCache;

let mockExecute;
Expand Down Expand Up @@ -132,13 +131,6 @@ describe('trailingTradeIndicator', () => {
}
}));

mockGetTradingView = jest.fn().mockImplementation((_logger, rawData) => ({
...rawData,
...{
tradingView: 'retrieved'
}
}));

mockSaveDataToCache = jest.fn().mockImplementation((_logger, rawData) => ({
...rawData,
...{
Expand All @@ -155,7 +147,6 @@ describe('trailingTradeIndicator', () => {
executeDustTransfer: mockExecuteDustTransfer,
getClosedTrades: mockGetClosedTrades,
getOrderStats: mockGetOrderStats,
getTradingView: mockGetTradingView,
saveDataToCache: mockSaveDataToCache
}));
};
Expand Down Expand Up @@ -207,7 +198,6 @@ describe('trailingTradeIndicator', () => {
dustTransfer: 'dust-transfer',
getClosedTrades: 'executed',
getOrderStats: 'retrieved',
tradingView: 'retrieved',
saved: 'data-to-cache'
}
},
Expand Down
4 changes: 3 additions & 1 deletion app/cronjob/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ const { execute: executeTrailingTrade } = require('./trailingTrade');
const {
execute: executeTrailingTradeIndicator
} = require('./trailingTradeIndicator');
const { execute: executeTradingView } = require('./tradingView');

module.exports = {
executeAlive,
executeTrailingTrade,
executeTrailingTradeIndicator
executeTrailingTradeIndicator,
executeTradingView
};
Loading
Loading