diff --git a/src/Managing.Application/Backtesting/Backtester.cs b/src/Managing.Application/Backtesting/Backtester.cs index 1e53551..a97a594 100644 --- a/src/Managing.Application/Backtesting/Backtester.cs +++ b/src/Managing.Application/Backtesting/Backtester.cs @@ -364,7 +364,7 @@ namespace Managing.Application.Backtesting { try { - if (backtest.Score > 50) + if (backtest.Score > 60) { await _messengerService.SendBacktestNotification(backtest); } diff --git a/src/Managing.Application/GeneticService.cs b/src/Managing.Application/GeneticService.cs index f124b6b..c3ce964 100644 --- a/src/Managing.Application/GeneticService.cs +++ b/src/Managing.Application/GeneticService.cs @@ -422,7 +422,8 @@ public class GeneticService : IGeneticService } catch (Exception notificationEx) { - _logger.LogWarning(notificationEx, "Failed to send genetic algorithm notification for request {RequestId}", request.RequestId); + _logger.LogWarning(notificationEx, + "Failed to send genetic algorithm notification for request {RequestId}", request.RequestId); } return new GeneticAlgorithmResult @@ -531,7 +532,10 @@ public class TradingBotChromosome : ChromosomeBase return geneIndex switch { 0 => new Gene(GetRandomInRange((0.9, _maxTakeProfit))), // Take profit (0.9% to max TP) - 1 => new Gene(GetRandomInRange(GeneticService.ParameterRanges["stopLoss"])), // Stop loss (will be constrained during initialization) + 1 => new Gene( + GetRandomInRange( + GeneticService.ParameterRanges + ["stopLoss"])), // Stop loss (will be constrained during initialization) 2 => new Gene(GetRandomIntInRange(GeneticService.ParameterRanges["cooldownPeriod"])), // Cooldown period 3 => new Gene(GetRandomIntInRange(GeneticService.ParameterRanges["maxLossStreak"])), // Max loss streak _ => new Gene(0) @@ -550,7 +554,7 @@ public class TradingBotChromosome : ChromosomeBase { GenerateIndicatorSelectionPattern(); } - + return new Gene(_indicatorSelectionPattern![geneIndex - 5]); } else @@ -614,6 +618,7 @@ public class TradingBotChromosome : ChromosomeBase { clone._indicatorSelectionPattern = (int[])_indicatorSelectionPattern.Clone(); } + return clone; } @@ -700,15 +705,12 @@ public class TradingBotChromosome : ChromosomeBase // Get take profit from chromosome (gene 0) var takeProfit = Convert.ToDouble(genes[0].Value); - // Get stop loss from chromosome (gene 1) and enforce constraints at phenotype level + // Get stop loss from chromosome (gene 1) var stopLoss = Convert.ToDouble(genes[1].Value); - - // Enforce 1.1:1 risk-reward ratio constraint at phenotype level - var minStopLoss = Math.Max(0.2, takeProfit / 1.1); // Minimum 0.2% to cover fees - var maxStopLoss = takeProfit - 0.1; // Ensure SL is less than TP with some buffer - - // Clamp stop loss to valid range (this maintains genotype-phenotype mapping) - stopLoss = Math.Max(minStopLoss, Math.Min(maxStopLoss, stopLoss)); + + // Only enforce minimum stop loss to cover fees, allow any risk-reward ratio above that + var minStopLoss = 0.2; // Minimum 0.2% to cover fees + stopLoss = Math.Max(minStopLoss, stopLoss); // Get loopback period from gene 4 var loopbackPeriod = Convert.ToInt32(genes[4].Value); @@ -809,13 +811,13 @@ public class TradingBotChromosome : ChromosomeBase // Generate a random combination of up to 4 indicators var selectedCount = _random.Next(1, Math.Min(5, _eligibleIndicators.Count + 1)); // 1 to 4 indicators var selectedIndices = new HashSet(); - + // Randomly select indices while (selectedIndices.Count < selectedCount) { selectedIndices.Add(_random.Next(_eligibleIndicators.Count)); } - + // Create the selection pattern _indicatorSelectionPattern = new int[_eligibleIndicators.Count]; for (int i = 0; i < _eligibleIndicators.Count; i++) @@ -832,21 +834,17 @@ public class TradingBotChromosome : ChromosomeBase // Generate take profit first (gene 0) var takeProfit = GetRandomInRange((0.9, _maxTakeProfit)); ReplaceGene(0, new Gene(takeProfit)); - - // Generate stop loss with constraints based on take profit (gene 1) - var minStopLoss = Math.Max(0.2, takeProfit / 1.1); // Minimum 0.2% to cover fees - var maxStopLoss = takeProfit - 0.1; // Ensure SL is less than TP with some buffer - var stopLoss = GetRandomInRange((minStopLoss, maxStopLoss)); + + // Generate stop loss independently (gene 1) - only enforce minimum to cover fees + var stopLoss = GetRandomInRange(GeneticService.ParameterRanges["stopLoss"]); ReplaceGene(1, new Gene(stopLoss)); - + // Initialize remaining genes normally for (int i = 2; i < Length; i++) { ReplaceGene(i, GenerateGene(i)); } } - - } /// @@ -934,7 +932,7 @@ public class TradingBotFitness : IFitness // Calculate base fitness from backtest score var baseFitness = backtest.Score; - + // Return base fitness (no penalty for now) return baseFitness; }