Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
using TradingBot.Models;
|
||||
|
||||
namespace TradingBot.Services;
|
||||
|
||||
public class SimpleMovingAverageStrategy : ITradingStrategy
|
||||
{
|
||||
private readonly int _shortPeriod = 5;
|
||||
private readonly int _longPeriod = 10;
|
||||
|
||||
public string Name => "Simple Moving Average (SMA)";
|
||||
|
||||
public Task<TradingSignal> AnalyzeAsync(string symbol, List<MarketPrice> historicalPrices)
|
||||
{
|
||||
// Filtra null e valori invalidi prima di usare la lista
|
||||
if (historicalPrices == null || historicalPrices.Count < _longPeriod)
|
||||
{
|
||||
return Task.FromResult(new TradingSignal
|
||||
{
|
||||
Symbol = symbol,
|
||||
Type = SignalType.Hold,
|
||||
Price = historicalPrices?.LastOrDefault()?.Price ?? 0,
|
||||
Reason = "Dati insufficienti per l'analisi",
|
||||
Timestamp = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
|
||||
// Filtra oggetti null e ordina
|
||||
var recentPrices = historicalPrices
|
||||
.Where(p => p != null && p.Price > 0)
|
||||
.OrderByDescending(p => p.Timestamp)
|
||||
.Take(_longPeriod)
|
||||
.ToList();
|
||||
|
||||
// Verifica ancora la count dopo il filtro
|
||||
if (recentPrices.Count < _longPeriod)
|
||||
{
|
||||
return Task.FromResult(new TradingSignal
|
||||
{
|
||||
Symbol = symbol,
|
||||
Type = SignalType.Hold,
|
||||
Price = recentPrices.LastOrDefault()?.Price ?? 0,
|
||||
Reason = "Dati insufficienti per l'analisi dopo il filtro",
|
||||
Timestamp = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
|
||||
var shortSMA = recentPrices.Take(_shortPeriod).Average(p => p.Price);
|
||||
var longSMA = recentPrices.Average(p => p.Price);
|
||||
var currentPrice = recentPrices.First().Price;
|
||||
|
||||
// Strategia: Compra quando la SMA breve incrocia sopra la SMA lunga
|
||||
// Vendi quando la SMA breve incrocia sotto la SMA lunga
|
||||
if (shortSMA > longSMA * 1.02m) // 2% sopra
|
||||
{
|
||||
return Task.FromResult(new TradingSignal
|
||||
{
|
||||
Symbol = symbol,
|
||||
Type = SignalType.Buy,
|
||||
Price = currentPrice,
|
||||
Reason = $"SMA breve ({shortSMA:F2}) > SMA lunga ({longSMA:F2}) - Trend rialzista",
|
||||
Timestamp = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
else if (shortSMA < longSMA * 0.98m) // 2% sotto
|
||||
{
|
||||
return Task.FromResult(new TradingSignal
|
||||
{
|
||||
Symbol = symbol,
|
||||
Type = SignalType.Sell,
|
||||
Price = currentPrice,
|
||||
Reason = $"SMA breve ({shortSMA:F2}) < SMA lunga ({longSMA:F2}) - Trend ribassista",
|
||||
Timestamp = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return Task.FromResult(new TradingSignal
|
||||
{
|
||||
Symbol = symbol,
|
||||
Type = SignalType.Hold,
|
||||
Price = currentPrice,
|
||||
Reason = $"SMA breve ({shortSMA:F2}) ? SMA lunga ({longSMA:F2}) - Nessun segnale chiaro",
|
||||
Timestamp = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user