-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
130 lines (119 loc) · 3.24 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import fetch from 'node-fetch';
import { babyrageOk } from './babyrageOk';
import stocks from './stocklist/sv.json';
async function sleep(ms: number) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
async function requestStock(orderbookId: number) {
const body = {
orderbookId,
chartType: 'AREA',
widthOfPlotContainer: 558,
chartResolution: 'DAY',
navigator: false,
percentage: false,
volume: false,
owners: false,
timePeriod: 'year',
ta: [
{
type: 'ema',
timeFrame: 21
},
{
type: 'sma',
timeFrame: 50
},
{
type: 'sma',
timeFrame: 200
}
],
compareIds: []
};
return fetch(
'https://www.avanza.se/ab/component/highstockchart/getchart/orderbook',
{
method: 'POST',
headers: [
['Content-Type', 'application/json'],
['Cache-Control', 'no-cache']
],
body: JSON.stringify(body)
}
)
.then((response: any) => {
if (response.status === 500) return; // If stock gives no match, eg Kappahl
return response.json();
})
.then((result: unknown) => result)
.catch(async (error: Error) => {
// Retry same stock if timeout
if (error.name === 'FetchError') {
await sleep(500);
await requestStock(orderbookId);
return;
}
console.log(error);
});
}
async function parseResponse(response: {
dataPoints?: (number | null)[][];
trendSeries?: number[][];
allowedResolutions?: string[];
defaultResolution?: string;
technicalAnalysis: any;
ownersPoints?: never[];
changePercent?: number;
high: number;
lastPrice: number;
low: number;
}) {
const { technicalAnalysis, lastPrice, high } = response;
const ema21TA = technicalAnalysis.filter(
(x: { type: string; timeFrame: number }) =>
x.type === 'ema' && x.timeFrame === 21
);
const sma50TA = technicalAnalysis.filter(
(x: { type: string; timeFrame: number }) =>
x.type === 'sma' && x.timeFrame === 50
);
const sma200TA = technicalAnalysis.filter(
(x: { type: string; timeFrame: number }) =>
x.type === 'sma' && x.timeFrame === 200
);
const ema21: number =
ema21TA[0].dataPoints[ema21TA[0].dataPoints.length - 1][1];
const sma50: number =
sma50TA[0].dataPoints[sma50TA[0].dataPoints.length - 1][1];
const sma200: number =
sma200TA[0].dataPoints[sma200TA[0].dataPoints.length - 1][1];
return { ema21, sma50, sma200, lastPrice, high };
}
/**
* Fetch, parse and calculate if stock meets requirments
* @param stock
* @returns true if valid and Error if not
*/
async function calculate(stock: { api_id: string; name: string }) {
const response = await requestStock(Number.parseInt(stock.api_id));
const { ema21, sma50, sma200, lastPrice, high } = await parseResponse(
response as any
);
return await babyrageOk(ema21, sma50, sma200, lastPrice, high);
}
async function main() {
stocks.forEach(async stock => {
try {
await calculate(stock);
console.log(
`Buy: ${stock.name} https://www.avanza.se/aktier/om-aktien.html/${stock.api_id}`
);
} catch (error) {
// console.error(error); // Enable to see stocks that not meet requirments.
}
});
}
main();