namespace TradingBot.Services; public static class TechnicalAnalysis { public static decimal CalculateEMA(List prices, int period) { if (prices.Count == 0) return 0; decimal k = 2m / (period + 1); decimal ema = prices[0]; for (int i = 1; i < prices.Count; i++) { ema = prices[i] * k + ema * (1 - k); } return ema; } public static List CalculateEMAArray(List prices, int period) { if (prices.Count == 0) return new List(); decimal k = 2m / (period + 1); var emaArray = new List { prices[0] }; for (int i = 1; i < prices.Count; i++) { emaArray.Add(prices[i] * k + emaArray[i - 1] * (1 - k)); } return emaArray; } public static decimal CalculateRSI(List prices, int period = 14) { if (prices.Count < period + 1) return 50; decimal gains = 0; decimal losses = 0; for (int i = prices.Count - period; i < prices.Count; i++) { decimal diff = prices[i] - prices[i - 1]; if (diff >= 0) gains += diff; else losses -= diff; } decimal avgGain = gains / period; decimal avgLoss = losses / period; if (avgLoss == 0) return 100; decimal rs = avgGain / avgLoss; return 100 - (100 / (1 + rs)); } public static (decimal macd, decimal signal, decimal histogram) CalculateMACD(List prices) { if (prices.Count < 26) return (0, 0, 0); var ema12Array = CalculateEMAArray(prices, 12); var ema26Array = CalculateEMAArray(prices, 26); var macdLine = ema12Array[^1] - ema26Array[^1]; var signalLine = macdLine * 0.9m; // Simplified signal var histogram = macdLine - signalLine; return (macdLine, signalLine, histogram); } public static (decimal upper, decimal middle, decimal lower) CalculateBollingerBands(List prices, int period = 20, decimal standardDeviations = 2) { if (prices.Count < period) return (0, 0, 0); var recentPrices = prices.TakeLast(period).ToList(); var sma = recentPrices.Average(); // Calculate standard deviation var squaredDifferences = recentPrices.Select(p => (double)Math.Pow((double)(p - sma), 2)); var variance = squaredDifferences.Average(); var stdDev = (decimal)Math.Sqrt(variance); var upper = sma + (standardDeviations * stdDev); var lower = sma - (standardDeviations * stdDev); return (upper, sma, lower); } }