- Sidebar portfolio con metriche dettagliate (Totale, Investito, Disponibile, P&L, ROI) e aggiornamento real-time - Sistema multi-strategia: 8 strategie assegnabili per asset, voting decisionale, pagina Trading Control - Nuova pagina Posizioni: gestione, chiusura manuale, P&L non realizzato, notifiche - Sistema indicatori tecnici: 7+ indicatori configurabili, segnali real-time, raccomandazioni, storico segnali - Refactoring TradingBotService per capitale, P&L, ROI, eventi - Nuovi modelli e servizi per strategie/indicatori, persistenza configurazioni - UI/UX: navigazione aggiornata, widget, modali, responsive - Aggiornamento README e CHANGELOG con tutte le novità
92 lines
2.8 KiB
C#
92 lines
2.8 KiB
C#
namespace TradingBot.Services;
|
|
|
|
public static class TechnicalAnalysis
|
|
{
|
|
public static decimal CalculateEMA(List<decimal> 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<decimal> CalculateEMAArray(List<decimal> prices, int period)
|
|
{
|
|
if (prices.Count == 0) return new List<decimal>();
|
|
|
|
decimal k = 2m / (period + 1);
|
|
var emaArray = new List<decimal> { 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<decimal> 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<decimal> 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<decimal> 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);
|
|
}
|
|
}
|