Skip to content

Commit c07ac11

Browse files
authored
Merge pull request #15 from CAFECA-IO/feat/linear_strategy
feat: linear strategy
2 parents 5243958 + eff8c14 commit c07ac11

File tree

9 files changed

+95
-86
lines changed

9 files changed

+95
-86
lines changed

.env

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
SUGGESTION = "autoArima"
2-
TRADE_STRATEGY = "autoArima"
32
STOP_LOSS = "autoArima"
43
TAKE_PROFIT = "autoArima"
54
PRIVATE_KEY = "YOUR_PRIVATE_KEY"

src/strategies/strategies.service.spec.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,6 @@ describe('StrategiesService', () => {
6464
expect(ETHSuggestion).toBe('BUY');
6565
});
6666

67-
it('should run executeStrategy', async () => {
68-
const suggestion = 'BUY';
69-
const holdingStatus = 'BUY';
70-
const result = await strategiesService.getTradeStrategy('autoArima', {
71-
suggestion: suggestion,
72-
holdingStatus: holdingStatus,
73-
});
74-
expect(result).toBe('WAIT');
75-
});
76-
7767
it('should run takeProfit', async () => {
7868
const openPrice = 100;
7969
const currentPrice = 120;
@@ -119,13 +109,12 @@ describe('StrategiesService', () => {
119109
'autoArima',
120110
'autoArima',
121111
'autoArima',
122-
'autoArima',
123112
priceData,
124113
);
125114
// Info: (20240320 - Jacky) this is aim to sum the profit of all trades
126115
const profitArray = tradeArray.map((trade) => trade.profit);
127116
const sum = profitArray.reduce((total, profit) => total + profit, 0);
128-
expect(sum).toBe(-2093.879039695004);
117+
expect(sum).toBe(-67.06188301500049);
129118
});
130119

131120
it('should backtest use api', async () => {
@@ -172,12 +161,11 @@ describe('StrategiesService', () => {
172161
'autoArima',
173162
'autoArima',
174163
'autoArima',
175-
'autoArima',
176164
ETHPriceArray,
177165
);
178166
// Info: (20240320 - Jacky) this is aim to sum the profit of all trades
179167
const profitArray = tradeArray.map((trade) => trade.profit);
180168
const sum = profitArray.reduce((total, profit) => total + profit, 0);
181-
expect(sum).toBe(-347.9295500000012);
169+
expect(sum).toBe(-214.9824);
182170
});
183171
});

src/strategies/strategies.service.ts

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ export class StrategiesService {
88
return suggestion;
99
}
1010

11-
async getTradeStrategy(strategyName: string, data: Record<string, any>) {
12-
const strategyModule = await import('./strategy/' + strategyName);
13-
const tradeStrategy = await strategyModule.tradeStrategy(data);
14-
return tradeStrategy;
15-
}
16-
1711
async getTakeProfit(strategyName: string, data: Record<string, any>) {
1812
const strategyModule = await import('./strategy/' + strategyName);
1913
const takeProfit = await strategyModule.takeProfit(data);
@@ -25,7 +19,7 @@ export class StrategiesService {
2519
const stopLoss = await strategyModule.stopLoss(data);
2620
return stopLoss;
2721
}
28-
async backTesting(suggestion, strategy, stopLoss, takeProfit, priceData) {
22+
async backTesting(suggestion, stopLoss, takeProfit, priceData) {
2923
let holdingStatus = 'WAIT';
3024
let openPrice;
3125
let openSpreadFee;
@@ -37,71 +31,67 @@ export class StrategiesService {
3731
let stopLossResult;
3832
let takeProfitResult;
3933
const suggestionResult = await this.getSuggestion(suggestion, {
34+
currentPrice: currentPrice,
4035
priceArray: priceArray.slice(index - 30, index),
4136
spreadFee: spreadFee,
42-
});
43-
const tradeStrategy = await this.getTradeStrategy(strategy, {
44-
suggestion: suggestionResult,
4537
holdingStatus: holdingStatus,
4638
});
4739
if (holdingStatus !== 'WAIT') {
4840
stopLossResult = await this.getStopLoss(stopLoss, {
4941
openPrice: openPrice,
50-
currentPrice: currentPrice,
42+
currentPrice: currentPrice + spreadFee,
5143
spreadFee: spreadFee,
5244
holdingStatus: holdingStatus,
5345
});
5446
takeProfitResult = await this.getTakeProfit(takeProfit, {
5547
openPrice: openPrice,
56-
currentPrice: currentPrice,
48+
currentPrice: currentPrice + spreadFee,
5749
spreadFee: spreadFee,
5850
holdingStatus: holdingStatus,
5951
});
6052
}
6153
if (
62-
tradeStrategy === 'CLOSE' ||
54+
suggestionResult === 'CLOSE' ||
6355
stopLossResult === 'CLOSE' ||
6456
takeProfitResult === 'CLOSE'
6557
) {
6658
if (holdingStatus === 'BUY') {
67-
const profit = currentPrice - openPrice;
59+
const profit = currentPrice - openPrice - openSpreadFee;
6860
tradeArray.push({
6961
openPrice: openPrice,
7062
price: currentPrice,
7163
openSpreadFee: openSpreadFee,
7264
profit: profit,
65+
holdingStatus: holdingStatus,
7366
tradeStrategy: 'CLOSE-BUY',
7467
});
7568
}
7669
if (holdingStatus === 'SELL') {
77-
const profit = openPrice - currentPrice;
70+
const profit = openPrice - currentPrice - openSpreadFee;
7871
tradeArray.push({
7972
openPrice: openPrice,
8073
price: currentPrice,
8174
profit: profit,
8275
openSpreadFee: openSpreadFee,
76+
holdingStatus: holdingStatus,
8377
tradeStrategy: 'CLOSE-SELL',
8478
});
8579
}
8680
holdingStatus = 'WAIT';
8781
openPrice = null;
8882
openSpreadFee = null;
8983
}
90-
if (tradeStrategy === 'BUY' || tradeStrategy === 'SELL') {
91-
holdingStatus = tradeStrategy;
84+
if (suggestionResult !== 'WAIT' && holdingStatus === 'WAIT') {
9285
openSpreadFee = spreadFee;
93-
if (holdingStatus === 'BUY') {
94-
openPrice = currentPrice + openSpreadFee;
95-
}
96-
if (holdingStatus === 'SELL') {
97-
openPrice = currentPrice - openSpreadFee;
98-
}
86+
holdingStatus = suggestionResult;
87+
openPrice = JSON.parse(JSON.stringify(currentPrice));
9988
tradeArray.push({
10089
openPrice: openPrice,
10190
price: currentPrice,
10291
profit: 0,
10392
openSpreadFee: openSpreadFee,
104-
tradeStrategy: tradeStrategy,
93+
holdingStatus: holdingStatus,
94+
suggestionResult: suggestionResult,
10595
});
10696
}
10797
}

src/strategies/strategy/autoArima.ts

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import * as ARIMA from 'arima';
22

3-
export function suggestion(data: { priceArray: number[]; spreadFee: number }) {
3+
export function suggestion(data: {
4+
currentPrice: number;
5+
priceArray: number[];
6+
spreadFee: number;
7+
holdingStatus: string;
8+
}) {
49
let suggestion = 'WAIT';
510
const arima = new ARIMA('auto');
611
arima.train(data.priceArray);
@@ -10,37 +15,25 @@ export function suggestion(data: { priceArray: number[]; spreadFee: number }) {
1015
const predictMax = Math.max(...predict);
1116
const predictMin = Math.min(...predict);
1217
const predictProfit = AbsspreadFee * 2.2;
13-
const currentPrice = data.priceArray[data.priceArray.length - 1];
18+
const currentPrice = data.currentPrice;
1419
if (predictMax - currentPrice > predictProfit) {
1520
suggestion = 'BUY';
16-
return suggestion;
1721
}
1822
if (currentPrice - predictMin > predictProfit) {
1923
suggestion = 'SELL';
24+
}
25+
if (suggestion === 'WAIT') {
2026
return suggestion;
2127
}
22-
return suggestion;
23-
}
24-
25-
export function tradeStrategy(data: {
26-
suggestion: string;
27-
holdingStatus: string;
28-
}) {
2928
if (data.holdingStatus === 'WAIT') {
30-
return data.suggestion;
31-
}
32-
if (data.holdingStatus === 'BUY') {
33-
if (data.suggestion === 'SELL') {
34-
return 'CLOSE';
35-
}
29+
return suggestion;
3630
}
37-
if (data.holdingStatus === 'SELL') {
38-
if (data.suggestion === 'BUY') {
39-
return 'CLOSE';
40-
}
31+
if (suggestion !== data.holdingStatus) {
32+
return 'CLOSE';
4133
}
4234
return 'WAIT';
4335
}
36+
4437
export function takeProfit(data: {
4538
openPrice: number;
4639
currentPrice: number;
@@ -50,7 +43,7 @@ export function takeProfit(data: {
5043
const AbsOpenSpreadFee = Math.abs(data.spreadFee);
5144
const openPrice = data.openPrice;
5245
const currentPrice = data.currentPrice;
53-
const takeProfit = AbsOpenSpreadFee * 2;
46+
const takeProfit = AbsOpenSpreadFee * 1.8;
5447
const holdingStatus = data.holdingStatus;
5548
if (holdingStatus === 'BUY') {
5649
if (currentPrice - openPrice > takeProfit) {
@@ -73,7 +66,7 @@ export function stopLoss(data: {
7366
const AbsOpenSpreadFee = Math.abs(data.spreadFee);
7467
const openPrice = data.openPrice;
7568
const currentPrice = data.currentPrice;
76-
const stopLoss = AbsOpenSpreadFee * 1.5;
69+
const stopLoss = AbsOpenSpreadFee * 0.6;
7770
const holdingStatus = data.holdingStatus;
7871
if (holdingStatus === 'BUY') {
7972
if (openPrice - currentPrice > stopLoss) {

src/strategies/strategy/linear.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export function suggestion(data: {
2+
currentPrice: number;
3+
priceArray: number[];
4+
spreadFee: number;
5+
holdingStatus: string;
6+
}) {
7+
let suggestion = 'WAIT';
8+
const priceArray = data.priceArray;
9+
const currentPrice = data.currentPrice;
10+
const lastHourPrice = priceArray[priceArray.length - 11];
11+
if (currentPrice > lastHourPrice) {
12+
suggestion = 'BUY';
13+
}
14+
if (currentPrice < lastHourPrice) {
15+
suggestion = 'SELL';
16+
}
17+
if (suggestion === 'WAIT') {
18+
return suggestion;
19+
}
20+
if (data.holdingStatus === 'WAIT') {
21+
return suggestion;
22+
}
23+
if (suggestion !== data.holdingStatus) {
24+
return 'CLOSE';
25+
}
26+
return 'WAIT';
27+
}

src/strategies/strategy/random.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export function suggestion(data: {
2+
currentPrice: number;
3+
priceArray: number[];
4+
spreadFee: number;
5+
holdingStatus: string;
6+
}) {
7+
let suggestion = 'WAIT';
8+
const random = Math.random();
9+
if (random > 0.9) {
10+
suggestion = 'BUY';
11+
}
12+
if (random < 0.1) {
13+
suggestion = 'SELL';
14+
}
15+
if (suggestion === 'WAIT') {
16+
return suggestion;
17+
}
18+
if (data.holdingStatus === 'WAIT') {
19+
return suggestion;
20+
}
21+
if (suggestion !== data.holdingStatus) {
22+
return 'CLOSE';
23+
}
24+
return 'WAIT';
25+
}

src/tradebot/entities/tradebot.entity.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export class Tradebot {
1010
this.created_at = new Date();
1111
this.updated_at = new Date();
1212
this.suggestion = process.env.SUGGESTION;
13-
this.tradeStrategy = process.env.TRADE_STRATEGY;
1413
this.stopLoss = process.env.STOP_LOSS;
1514
this.takeProfit = process.env.TAKE_PROFIT;
1615
this.holdingStatus = 'WAIT';
@@ -30,7 +29,6 @@ export class Tradebot {
3029
wallet: HDNodeWallet | Wallet;
3130
dewt: string;
3231
suggestion: string;
33-
tradeStrategy: string;
3432
stopLoss: string;
3533
takeProfit: string;
3634
currentAsset: myAsset;

src/tradebot/tradebot.controller.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ export class TradebotController {
5555
@Body()
5656
data: {
5757
suggestion?: string;
58-
tradeStrategy?: string;
5958
stopLoss?: string;
6059
takeProfit?: string;
6160
},
@@ -68,12 +67,7 @@ export class TradebotController {
6867
tradebot,
6968
data,
7069
);
71-
return (
72-
updatedTradebot.id +
73-
' is updated' +
74-
' and tradebot = ' +
75-
updatedTradebot.toJSON()
76-
);
70+
return tradebot.id + ' update ' + ' is ' + updatedTradebot;
7771
}
7872

7973
@Post(':tradebotId')

0 commit comments

Comments
 (0)