Migliora robustezza Dockerfile e controlli TradingBotService
- Installa wget e aggiorna healthcheck in Dockerfile (usa wget invece di curl, UID 1001 per utente non-root) - Aggiunti controlli di nullità e validità su simboli, prezzi e segnali in TradingBotService - Migliorata gestione delle eccezioni con stampa dello stack trace - Filtrati dati non validi prima del calcolo degli indicatori - Aumentata la sicurezza e la resilienza contro dati corrotti o incompleti
This commit is contained in:
@@ -21,8 +21,13 @@ RUN dotnet publish "TradingBot.csproj" -c Release -o /app/publish /p:UseAppHost=
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
|
||||
WORKDIR /app
|
||||
|
||||
# Installa wget per health check (curl non disponibile nell'immagine base)
|
||||
RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Crea utente non-root per sicurezza
|
||||
RUN useradd -m -u 1000 tradingbot && \
|
||||
# Usa UID 1001 invece di 1000 (1000 spesso già in uso nell'immagine base)
|
||||
RUN groupadd -r -g 1001 tradingbot && \
|
||||
useradd -r -u 1001 -g tradingbot -m -s /bin/bash tradingbot && \
|
||||
chown -R tradingbot:tradingbot /app
|
||||
|
||||
# Esponi porta
|
||||
@@ -46,9 +51,9 @@ ENV ASPNETCORE_URLS=http://+:8080
|
||||
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||
ENV DOTNET_RUNNING_IN_CONTAINER=true
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost:8080/health || exit 1
|
||||
# Health check con wget invece di curl
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
|
||||
|
||||
# Entry point
|
||||
ENTRYPOINT ["dotnet", "TradingBot.dll"]
|
||||
|
||||
@@ -162,17 +162,23 @@ public class TradingBotService
|
||||
try
|
||||
{
|
||||
var enabledSymbols = _assetConfigs.Values
|
||||
.Where(c => c.IsEnabled)
|
||||
.Where(c => c != null && c.IsEnabled)
|
||||
.Select(c => c.Symbol)
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||
.ToList();
|
||||
|
||||
if (enabledSymbols.Count == 0) return;
|
||||
|
||||
var prices = await _marketDataService.GetMarketPricesAsync(enabledSymbols);
|
||||
|
||||
if (prices == null) return;
|
||||
|
||||
foreach (var price in prices)
|
||||
{
|
||||
await ProcessAssetUpdate(price);
|
||||
if (price != null)
|
||||
{
|
||||
await ProcessAssetUpdate(price);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateGlobalStatistics();
|
||||
@@ -180,11 +186,16 @@ public class TradingBotService
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error in UpdateAsync: {ex.Message}");
|
||||
Console.WriteLine($"Stack trace: {ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessAssetUpdate(MarketPrice price)
|
||||
{
|
||||
// Add null check for price
|
||||
if (price == null || price.Price <= 0)
|
||||
return;
|
||||
|
||||
if (!_assetConfigs.TryGetValue(price.Symbol, out var config) || !config.IsEnabled)
|
||||
return;
|
||||
|
||||
@@ -216,10 +227,15 @@ public class TradingBotService
|
||||
|
||||
// Generate trading signal
|
||||
var signal = await _strategy.AnalyzeAsync(price.Symbol, _priceHistory[price.Symbol]);
|
||||
OnSignalGenerated?.Invoke(signal);
|
||||
|
||||
// Add null check for signal
|
||||
if (signal != null)
|
||||
{
|
||||
OnSignalGenerated?.Invoke(signal);
|
||||
|
||||
// Execute trades based on strategy and configuration
|
||||
await EvaluateAndExecuteTrade(price.Symbol, signal, price, config);
|
||||
// Execute trades based on strategy and configuration
|
||||
await EvaluateAndExecuteTrade(price.Symbol, signal, price, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,10 +355,18 @@ public class TradingBotService
|
||||
|
||||
private void UpdateIndicators(string symbol)
|
||||
{
|
||||
var history = _priceHistory[symbol];
|
||||
if (history.Count < 26) return;
|
||||
if (!_priceHistory.TryGetValue(symbol, out var history) || history == null || history.Count < 26)
|
||||
return;
|
||||
|
||||
var prices = history.Select(p => p.Price).ToList();
|
||||
// Filter out null prices and extract valid price values
|
||||
var prices = history
|
||||
.Where(p => p != null && p.Price > 0)
|
||||
.Select(p => p.Price)
|
||||
.ToList();
|
||||
|
||||
// Ensure we still have enough data after filtering
|
||||
if (prices.Count < 26)
|
||||
return;
|
||||
|
||||
var rsi = TechnicalAnalysis.CalculateRSI(prices);
|
||||
var (macd, signal, histogram) = TechnicalAnalysis.CalculateMACD(prices);
|
||||
@@ -482,6 +506,9 @@ public class TradingBotService
|
||||
|
||||
public MarketPrice? GetLatestPrice(string symbol)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(symbol))
|
||||
return null;
|
||||
|
||||
var history = GetPriceHistory(symbol);
|
||||
return history?.LastOrDefault();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user