Update genetics
This commit is contained in:
@@ -319,7 +319,12 @@ public class GeneticService : IGeneticService
|
|||||||
{
|
{
|
||||||
Termination = new GenerationNumberTermination(request.Generations),
|
Termination = new GenerationNumberTermination(request.Generations),
|
||||||
MutationProbability = (float)request.MutationRate,
|
MutationProbability = (float)request.MutationRate,
|
||||||
CrossoverProbability = 0.7f // Fixed crossover rate as in frontend
|
CrossoverProbability = 0.7f, // Fixed crossover rate as in frontend
|
||||||
|
TaskExecutor = new ParallelTaskExecutor
|
||||||
|
{
|
||||||
|
MinThreads = 4,
|
||||||
|
MaxThreads = Environment.ProcessorCount
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set the genetic algorithm reference in the fitness function
|
// Set the genetic algorithm reference in the fitness function
|
||||||
@@ -511,11 +516,8 @@ public class TradingBotChromosome : ChromosomeBase
|
|||||||
_eligibleIndicators = eligibleIndicators;
|
_eligibleIndicators = eligibleIndicators;
|
||||||
_maxTakeProfit = maxTakeProfit;
|
_maxTakeProfit = maxTakeProfit;
|
||||||
|
|
||||||
// Initialize all genes
|
// Initialize genes with proper constraint handling
|
||||||
for (int i = 0; i < Length; i++)
|
InitializeGenesWithConstraints();
|
||||||
{
|
|
||||||
ReplaceGene(i, GenerateGene(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Gene GenerateGene(int geneIndex)
|
public override Gene GenerateGene(int geneIndex)
|
||||||
@@ -526,7 +528,7 @@ public class TradingBotChromosome : ChromosomeBase
|
|||||||
return geneIndex switch
|
return geneIndex switch
|
||||||
{
|
{
|
||||||
0 => new Gene(GetRandomInRange((0.9, _maxTakeProfit))), // Take profit (0.9% to max TP)
|
0 => new Gene(GetRandomInRange((0.9, _maxTakeProfit))), // Take profit (0.9% to max TP)
|
||||||
1 => new Gene(GetRandomInRange(GeneticService.ParameterRanges["stopLoss"])), // Stop loss
|
1 => new Gene(GetRandomInRange(GeneticService.ParameterRanges["stopLoss"])), // Stop loss (will be constrained during initialization)
|
||||||
2 => new Gene(GetRandomIntInRange(GeneticService.ParameterRanges["cooldownPeriod"])), // Cooldown period
|
2 => new Gene(GetRandomIntInRange(GeneticService.ParameterRanges["cooldownPeriod"])), // Cooldown period
|
||||||
3 => new Gene(GetRandomIntInRange(GeneticService.ParameterRanges["maxLossStreak"])), // Max loss streak
|
3 => new Gene(GetRandomIntInRange(GeneticService.ParameterRanges["maxLossStreak"])), // Max loss streak
|
||||||
_ => new Gene(0)
|
_ => new Gene(0)
|
||||||
@@ -695,20 +697,15 @@ public class TradingBotChromosome : ChromosomeBase
|
|||||||
// Get take profit from chromosome (gene 0)
|
// Get take profit from chromosome (gene 0)
|
||||||
var takeProfit = Convert.ToDouble(genes[0].Value);
|
var takeProfit = Convert.ToDouble(genes[0].Value);
|
||||||
|
|
||||||
// Calculate stop loss based on 1.1:1 risk-reward ratio (gene 1)
|
// Get stop loss from chromosome (gene 1) and enforce constraints at phenotype level
|
||||||
var stopLoss = Convert.ToDouble(genes[1].Value);
|
var stopLoss = Convert.ToDouble(genes[1].Value);
|
||||||
|
|
||||||
// Ensure minimum 1.1:1 risk-reward ratio and minimum 0.2% to cover fees
|
// Enforce 1.1:1 risk-reward ratio constraint at phenotype level
|
||||||
var minStopLossForRR = takeProfit / 1.1;
|
var minStopLoss = Math.Max(0.2, takeProfit / 1.1); // Minimum 0.2% to cover fees
|
||||||
var minStopLossForFees = 0.2; // Minimum 0.2% to cover trading fees
|
|
||||||
var minStopLoss = Math.Max(minStopLossForRR, minStopLossForFees);
|
|
||||||
var maxStopLoss = takeProfit - 0.1; // Ensure SL is less than TP with some buffer
|
var maxStopLoss = takeProfit - 0.1; // Ensure SL is less than TP with some buffer
|
||||||
|
|
||||||
// Adjust stop loss if it doesn't meet the constraints
|
// Clamp stop loss to valid range (this maintains genotype-phenotype mapping)
|
||||||
if (stopLoss > maxStopLoss || stopLoss < minStopLoss)
|
stopLoss = Math.Max(minStopLoss, Math.Min(maxStopLoss, stopLoss));
|
||||||
{
|
|
||||||
stopLoss = GetRandomInRange((minStopLoss, maxStopLoss));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get loopback period from gene 4
|
// Get loopback period from gene 4
|
||||||
var loopbackPeriod = Convert.ToInt32(genes[4].Value);
|
var loopbackPeriod = Convert.ToInt32(genes[4].Value);
|
||||||
@@ -823,6 +820,30 @@ public class TradingBotChromosome : ChromosomeBase
|
|||||||
_indicatorSelectionPattern[i] = selectedIndices.Contains(i) ? 1 : 0;
|
_indicatorSelectionPattern[i] = selectedIndices.Contains(i) ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes genes with proper constraint handling for take profit and stop loss
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeGenesWithConstraints()
|
||||||
|
{
|
||||||
|
// 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));
|
||||||
|
ReplaceGene(1, new Gene(stopLoss));
|
||||||
|
|
||||||
|
// Initialize remaining genes normally
|
||||||
|
for (int i = 2; i < Length; i++)
|
||||||
|
{
|
||||||
|
ReplaceGene(i, GenerateGene(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -917,8 +938,48 @@ public class TradingBotFitness : IFitness
|
|||||||
if (backtest == null || backtest.Statistics == null)
|
if (backtest == null || backtest.Statistics == null)
|
||||||
return 0.1;
|
return 0.1;
|
||||||
|
|
||||||
// Use the comprehensive backtest score directly as fitness
|
// Calculate base fitness from backtest score
|
||||||
// The BacktestScorer already includes all important metrics with proper weighting
|
var baseFitness = backtest.Score;
|
||||||
return backtest.Score;
|
|
||||||
|
// Apply constraint penalty if needed (this will guide the GA toward valid solutions)
|
||||||
|
var constraintPenalty = CalculateConstraintPenalty(config);
|
||||||
|
|
||||||
|
// Return penalized fitness (constraint violations reduce fitness)
|
||||||
|
return baseFitness * constraintPenalty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates a penalty factor for constraint violations (1.0 = no penalty, < 1.0 = penalty)
|
||||||
|
/// </summary>
|
||||||
|
private double CalculateConstraintPenalty(TradingBotConfig config)
|
||||||
|
{
|
||||||
|
var takeProfit = Convert.ToDouble(config.MoneyManagement.TakeProfit);
|
||||||
|
var stopLoss = Convert.ToDouble(config.MoneyManagement.StopLoss);
|
||||||
|
|
||||||
|
// Check 1.1:1 risk-reward ratio constraint
|
||||||
|
var minStopLoss = Math.Max(0.2, takeProfit / 1.1);
|
||||||
|
var maxStopLoss = takeProfit - 0.1;
|
||||||
|
|
||||||
|
// If stop loss is within valid range, no penalty
|
||||||
|
if (stopLoss >= minStopLoss && stopLoss <= maxStopLoss)
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate penalty based on how far outside the valid range the stop loss is
|
||||||
|
var violation = 0.0;
|
||||||
|
if (stopLoss < minStopLoss)
|
||||||
|
{
|
||||||
|
violation = (minStopLoss - stopLoss) / minStopLoss;
|
||||||
|
}
|
||||||
|
else if (stopLoss > maxStopLoss)
|
||||||
|
{
|
||||||
|
violation = (stopLoss - maxStopLoss) / maxStopLoss;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply penalty: 0.5 for severe violations, 0.8 for minor violations
|
||||||
|
var penalty = Math.Max(0.5, 1.0 - (violation * 0.5));
|
||||||
|
|
||||||
|
return penalty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user