Skip to content

Commit 115b5d3

Browse files
committed
refactoring to use controller files
1 parent 2ffb6f2 commit 115b5d3

18 files changed

+713
-1299
lines changed

src/command/backfill.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ export class BackfillCommand {
44
constructor() {}
55

66
async execute(exchangeName: string, symbol: string, period: string, date: string): Promise<void> {
7-
await services.getBackfill().backfill(exchangeName, symbol, period, date);
7+
await services.getBackfill().backfill(exchangeName, symbol, period, parseInt(date, 10));
88
}
99
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { BaseController, TemplateHelpers } from './base_controller';
2+
import { Backtest } from '../modules/backtest';
3+
import express from 'express';
4+
5+
export class BacktestController extends BaseController {
6+
private backtest: Backtest;
7+
8+
constructor(templateHelpers: TemplateHelpers, backtest: Backtest) {
9+
super(templateHelpers);
10+
this.backtest = backtest;
11+
}
12+
13+
registerRoutes(router: express.Router): void {
14+
// Backtest form page
15+
router.get('/backtest', async (req: any, res: any) => {
16+
res.render('backtest', {
17+
activePage: 'backtest',
18+
title: 'Backtesting | Crypto Bot',
19+
stylesheet:
20+
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.min.css" integrity="sha512-yVvxUQV0QESBt1SyZbNJMAwyKvFTLMyXSyBHDO4BG5t7k/Lw34tyqlSDlKIrIENIzCl+RVUNjmCPG+V/GMesRw==" crossorigin="anonymous" />',
21+
strategies: this.backtest.getBacktestStrategies(),
22+
pairs: await this.backtest.getBacktestPairs()
23+
});
24+
});
25+
26+
// Backtest submit
27+
router.post('/backtest/submit', async (req: any, res: any) => {
28+
let pairs = req.body.pair;
29+
30+
if (typeof pairs === 'string') {
31+
pairs = [pairs];
32+
}
33+
34+
const asyncs = pairs.map((pair: string) => async () => {
35+
const p = pair.split('.');
36+
37+
return {
38+
pair: pair,
39+
result: await this.backtest.getBacktestResult(
40+
parseInt(req.body.ticker_interval, 10),
41+
req.body.hours,
42+
req.body.strategy,
43+
req.body.candle_period,
44+
p[0],
45+
p[1],
46+
req.body.options ? JSON.parse(req.body.options) : {},
47+
req.body.initial_capital
48+
)
49+
};
50+
});
51+
52+
const backtests = await Promise.all(asyncs.map((fn: any) => fn()));
53+
54+
// single details view
55+
if (backtests.length === 1) {
56+
res.render('backtest_submit', {
57+
activePage: 'backtest',
58+
title: 'Backtesting Results | Crypto Bot',
59+
stylesheet: '<link rel="stylesheet" href="/css/backtest.css?v=' + this.templateHelpers.assetVersion() + '">',
60+
...backtests[0].result
61+
});
62+
return;
63+
}
64+
65+
// multiple view
66+
res.render('backtest_submit_multiple', {
67+
activePage: 'backtest',
68+
title: 'Backtesting Results | Crypto Bot',
69+
stylesheet: '<link rel="stylesheet" href="/css/backtest.css?v=' + this.templateHelpers.assetVersion() + '">',
70+
backtests: backtests
71+
});
72+
});
73+
}
74+
}

src/controller/base_controller.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import express from 'express';
2+
3+
export interface Controller {
4+
registerRoutes(router: express.Router): void;
5+
}
6+
7+
export interface TemplateHelpers {
8+
priceFormat(value: any): string;
9+
formatDate(date: any, format: string): string;
10+
escapeHtml(text: any): string;
11+
decodeHtml(text: any): string;
12+
assetVersion(): string;
13+
nodeVersion(): string;
14+
memoryUsage(): number;
15+
}
16+
17+
export abstract class BaseController implements Controller {
18+
protected templateHelpers: TemplateHelpers;
19+
20+
constructor(templateHelpers: TemplateHelpers) {
21+
this.templateHelpers = templateHelpers;
22+
}
23+
24+
abstract registerRoutes(router: express.Router): void;
25+
26+
protected render(res: express.Response, view: string, options: Record<string, any> = {}): void {
27+
res.render(view, {
28+
...options,
29+
assetVersion: this.templateHelpers.assetVersion,
30+
nodeVersion: this.templateHelpers.nodeVersion,
31+
memoryUsage: this.templateHelpers.memoryUsage
32+
});
33+
}
34+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import moment from 'moment';
2+
import { BaseController, TemplateHelpers } from './base_controller';
3+
import { CandleExportHttp } from '../modules/system/candle_export_http';
4+
import { CandleImporter } from '../modules/system/candle_importer';
5+
import express from 'express';
6+
7+
export class CandlesController extends BaseController {
8+
private candleExportHttp: CandleExportHttp;
9+
private candleImporter: CandleImporter;
10+
11+
constructor(templateHelpers: TemplateHelpers, candleExportHttp: CandleExportHttp, candleImporter: CandleImporter) {
12+
super(templateHelpers);
13+
this.candleExportHttp = candleExportHttp;
14+
this.candleImporter = candleImporter;
15+
}
16+
17+
registerRoutes(router: express.Router): void {
18+
// GET - Display candle form and data
19+
router.get('/tools/candles', async (req: any, res: any) => {
20+
const options: any = {
21+
pairs: await this.candleExportHttp.getPairs(),
22+
start: moment().subtract(7, 'days').toDate(),
23+
end: new Date()
24+
};
25+
26+
if (req.query.pair && req.query.period && req.query.start && req.query.end) {
27+
const [exchange, symbol] = req.query.pair.split('.');
28+
const candles = await this.candleExportHttp.getCandles(exchange, symbol, req.query.period, new Date(req.query.start), new Date(req.query.end));
29+
30+
if (req.query.metadata) {
31+
candles.map((c: any) => {
32+
c.exchange = exchange;
33+
c.symbol = symbol;
34+
c.period = req.query.period;
35+
return c;
36+
});
37+
}
38+
39+
options.start = new Date(req.query.start);
40+
options.end = new Date(req.query.end);
41+
options.exchange = exchange;
42+
options.symbol = symbol;
43+
options.period = req.query.period;
44+
options.candles = candles;
45+
options.candles_json = JSON.stringify(candles, null, 2);
46+
}
47+
48+
res.render('candles', {
49+
activePage: 'candles',
50+
title: 'Candles | Crypto Bot',
51+
stylesheet:
52+
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.min.css" integrity="sha512-yVvxUQV0QESBt1SyZbNJMAwyKvFTLMyXSyBHDO4BG5t7k/Lw34tyqlSDlKIrIENIzCl+RVUNjmCPG+V/GMesRw==" crossorigin="anonymous" />',
53+
...options
54+
});
55+
});
56+
57+
// POST - Import candles
58+
router.post('/tools/candles', async (req: any, res: any) => {
59+
const exchangeCandlesticks = JSON.parse(req.body.json);
60+
await this.candleImporter.insertCandles(exchangeCandlesticks);
61+
62+
console.log(`Imported: ${exchangeCandlesticks.length} items`);
63+
64+
res.redirect('/tools/candles');
65+
});
66+
}
67+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { BaseController, TemplateHelpers } from './base_controller';
2+
import { Ta } from '../modules/ta';
3+
import { SystemUtil } from '../modules/system/system_util';
4+
import express from 'express';
5+
6+
export class DashboardController extends BaseController {
7+
private ta: Ta;
8+
private systemUtil: SystemUtil;
9+
10+
constructor(templateHelpers: TemplateHelpers, ta: Ta, systemUtil: SystemUtil) {
11+
super(templateHelpers);
12+
this.ta = ta;
13+
this.systemUtil = systemUtil;
14+
}
15+
16+
registerRoutes(router: express.Router): void {
17+
router.get('/', async (req: any, res: any) => {
18+
const data = await this.ta.getTaForPeriods(this.systemUtil.getConfig('dashboard.periods', ['15m', '1h']));
19+
res.render('dashboard', {
20+
activePage: 'dashboard',
21+
title: 'Dashboard | Crypto Bot',
22+
periods: data.periods,
23+
rows: Object.values(data.rows)
24+
});
25+
});
26+
}
27+
}

src/controller/desks_controller.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { BaseController, TemplateHelpers } from './base_controller';
2+
import { SystemUtil } from '../modules/system/system_util';
3+
import express from 'express';
4+
5+
export class DesksController extends BaseController {
6+
private systemUtil: SystemUtil;
7+
8+
constructor(templateHelpers: TemplateHelpers, systemUtil: SystemUtil) {
9+
super(templateHelpers);
10+
this.systemUtil = systemUtil;
11+
}
12+
13+
registerRoutes(router: express.Router): void {
14+
// Desk view
15+
router.get('/desks/:desk', async (req: any, res: any) => {
16+
res.render('desks', {
17+
activePage: 'desks',
18+
title: `Desk: ${this.systemUtil.getConfig('desks')[req.params.desk].name} | Crypto Bot`,
19+
desk: this.systemUtil.getConfig('desks')[req.params.desk],
20+
interval: req.query.interval || undefined,
21+
id: req.params.desk
22+
});
23+
});
24+
25+
// Desk fullscreen view
26+
router.get('/desks/:desk/fullscreen', (req: any, res: any) => {
27+
const configElement = this.systemUtil.getConfig('desks')[req.params.desk];
28+
res.render('tradingview_desk', {
29+
layout: false,
30+
desk: configElement,
31+
interval: req.query.interval || undefined,
32+
id: req.params.desk,
33+
watchlist: configElement.pairs.map((i: any) => i.symbol),
34+
desks: this.systemUtil.getConfig('desks', []).map((d: any) => d.name)
35+
});
36+
});
37+
}
38+
}

src/controller/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Controller exports
2+
export { Controller, BaseController, TemplateHelpers } from './base_controller';
3+
export { DashboardController } from './dashboard_controller';
4+
export { TradesController } from './trades_controller';
5+
export { PairsController } from './pairs_controller';
6+
export { OrdersController } from './orders_controller';
7+
export { SignalsController } from './signals_controller';
8+
export { CandlesController } from './candles_controller';
9+
export { BacktestController } from './backtest_controller';
10+
export { LogsController } from './logs_controller';
11+
export { DesksController } from './desks_controller';
12+
export { TradingViewController } from './tradingview_controller';

src/controller/logs_controller.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { BaseController, TemplateHelpers } from './base_controller';
2+
import { LogsHttp } from '../modules/system/logs_http';
3+
import express from 'express';
4+
5+
export class LogsController extends BaseController {
6+
private logsHttp: LogsHttp;
7+
8+
constructor(templateHelpers: TemplateHelpers, logsHttp: LogsHttp) {
9+
super(templateHelpers);
10+
this.logsHttp = logsHttp;
11+
}
12+
13+
registerRoutes(router: express.Router): void {
14+
router.get('/logs', async (req: any, res: any) => {
15+
const logData = await this.logsHttp.getLogsPageVariables(req, res);
16+
res.render('logs', {
17+
activePage: 'logs',
18+
title: 'Logs | Crypto Bot',
19+
...logData
20+
});
21+
});
22+
}
23+
}

0 commit comments

Comments
 (0)