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;
    }
}
