learning_ai_invt_trdg/backend/src/utils/indicators.ts

63 lines
2.0 KiB
TypeScript

export class Indicators {
static calculateEMA(data: number[], period: number): number {
if (data.length === 0) return 0;
const k = 2 / (period + 1);
let ema = data[0] || 0;
for (let i = 1; i < data.length; i++) {
const current = data[i] || 0;
ema = current * k + ema * (1 - k);
}
return ema;
}
static calculateRSI(data: number[], period: number): number {
if (data.length <= period) return 50; // Default if not enough data
let gains = 0;
let losses = 0;
// First average
for (let i = 1; i <= period; i++) {
const diff = data[i] - data[i - 1];
if (diff >= 0) gains += diff;
else losses -= diff;
}
let avgGain = gains / period;
let avgLoss = losses / period;
// Smoothing
for (let i = period + 1; i < data.length; i++) {
const diff = data[i] - data[i - 1];
if (diff >= 0) {
avgGain = (avgGain * (period - 1) + diff) / period;
avgLoss = (avgLoss * (period - 1)) / period;
} else {
avgGain = (avgGain * (period - 1)) / period;
avgLoss = (avgLoss * (period - 1) - diff) / period;
}
}
if (avgLoss === 0) return 100;
const rs = avgGain / avgLoss;
return 100 - (100 / (1 + rs));
}
static calculateATR(candles: any[], period: number): number {
if (candles.length <= period) return 0;
let trs: number[] = [];
for (let i = 1; i < candles.length; i++) {
const h = candles[i].high;
const l = candles[i].low;
const pc = candles[i - 1].close;
const tr = Math.max(h - l, Math.abs(h - pc), Math.abs(l - pc));
trs.push(tr);
}
// Return SMA of TR
const recentTrs = trs.slice(-period);
return recentTrs.reduce((a, b) => a + b, 0) / period;
}
}