Update score

This commit is contained in:
2025-07-15 10:08:00 +07:00
parent fbc858980a
commit f1c7259bc6

View File

@@ -8,8 +8,8 @@ public class BacktestScorer
{ {
{ "GrowthPercentage", 0.20 }, { "GrowthPercentage", 0.20 },
{ "SharpeRatio", 0.15 }, { "SharpeRatio", 0.15 },
{ "MaxDrawdownUsd", 0.10 }, { "MaxDrawdownUsd", 0.15 },
{ "HodlComparison", 0.15 }, // Increased from 0.05 to 0.15 { "HodlComparison", 0.10 }, // Increased from 0.05 to 0.15
{ "WinRate", 0.12 }, { "WinRate", 0.12 },
{ "ProfitabilityBonus", 0.08 }, { "ProfitabilityBonus", 0.08 },
{ "TradeCount", 0.05 }, { "TradeCount", 0.05 },
@@ -29,6 +29,18 @@ public class BacktestScorer
return 0; return 0;
} }
// Early exit for negative PnL - should be 0 score
if (p.TotalPnL <= 0)
{
return 0;
}
// Early exit if strategy significantly underperforms HODL (more than 2% worse)
if (p.GrowthPercentage < p.HodlPercentage - 2)
{
return 0;
}
var baseScore = CalculateBaseScore(p); var baseScore = CalculateBaseScore(p);
var finalScore = ApplyProfitabilityRules(baseScore, p); var finalScore = ApplyProfitabilityRules(baseScore, p);
@@ -64,18 +76,14 @@ public class BacktestScorer
{ {
var penaltyMultiplier = 1.0; var penaltyMultiplier = 1.0;
// 1. Negative PnL Penalty (Dynamic) // 1. Negative Growth Penalty (Dynamic) - only for positive PnL but negative growth
if (p.GrowthPercentage < 0) if (p.GrowthPercentage < 0)
{ {
var negativePenalty = Math.Abs(p.GrowthPercentage) * 0.1; // 10% penalty per 1% loss var negativePenalty = Math.Abs(p.GrowthPercentage) * 0.1; // 10% penalty per 1% loss
penaltyMultiplier *= Math.Max(0.1, 1 - negativePenalty); penaltyMultiplier *= Math.Max(0.1, 1 - negativePenalty);
} }
// 2. Absolute PnL Validation (Dynamic) // Note: Negative PnL is now handled by early exit in CalculateTotalScore
if (p.TotalPnL <= 0)
{
penaltyMultiplier *= 0.3; // 70% penalty for negative absolute PnL
}
// 3. Win Rate Validation (Dynamic) // 3. Win Rate Validation (Dynamic)
if (p.WinRate < 0.3 && p.TradeCount > 10) if (p.WinRate < 0.3 && p.TradeCount > 10)
@@ -117,6 +125,14 @@ public class BacktestScorer
penaltyMultiplier *= Math.Max(0.5, 1 - durationPenalty); penaltyMultiplier *= Math.Max(0.5, 1 - durationPenalty);
} }
// 8. HODL Underperformance Penalty (Dynamic)
if (p.GrowthPercentage < p.HodlPercentage)
{
var hodlUnderperformance = p.HodlPercentage - p.GrowthPercentage;
var hodlPenalty = hodlUnderperformance * 0.3; // 30% penalty per 1% underperformance
penaltyMultiplier *= Math.Max(0.1, 1 - hodlPenalty);
}
return baseScore * penaltyMultiplier; return baseScore * penaltyMultiplier;
} }
@@ -206,9 +222,9 @@ public class BacktestScorer
> 5 => 100, // Significantly outperform HODL (>5% better) > 5 => 100, // Significantly outperform HODL (>5% better)
> 2 => 80 + (difference - 2) * 6.67, // 2-5% better: 80-100 points > 2 => 80 + (difference - 2) * 6.67, // 2-5% better: 80-100 points
> 0 => 40 + difference * 20, // 0-2% better: 40-80 points > 0 => 40 + difference * 20, // 0-2% better: 40-80 points
> -2 => 20 + (difference + 2) * 10, // -2-0%: 20-40 points > -1 => 20 + (difference + 1) * 20, // -1-0%: 20-40 points
> -5 => Math.Max(0, 10 + (difference + 5) * 3.33), // -5 to -2%: 0-20 points > -2 => Math.Max(0, 10 + (difference + 2) * 10), // -2 to -1%: 0-20 points
_ => 0 // More than 5% worse than HODL = 0 points _ => 0 // More than 2% worse than HODL = 0 points (handled by early exit)
}; };
} }