Add new strat DualEmaCross
This commit is contained in:
@@ -60,13 +60,13 @@ public static class TradingBox
|
||||
{
|
||||
var signalOnCandles = new HashSet<Signal>();
|
||||
var limitedCandles = newCandles.ToList().TakeLast(600).ToList();
|
||||
|
||||
|
||||
foreach (var strategy in strategies)
|
||||
{
|
||||
strategy.UpdateCandles(limitedCandles.ToHashSet());
|
||||
var signals = strategy.Run();
|
||||
|
||||
if (signals == null || signals.Count == 0)
|
||||
if (signals == null || signals.Count == 0)
|
||||
{
|
||||
// For trend and context strategies, lack of signal might be meaningful
|
||||
// Signal strategies are expected to be sparse, so we continue
|
||||
@@ -74,7 +74,7 @@ public static class TradingBox
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// For trend strategies, no signal might mean neutral trend
|
||||
// For context strategies, no signal might mean no restrictions
|
||||
// We'll let the ComputeSignals method handle these cases
|
||||
@@ -82,6 +82,7 @@ public static class TradingBox
|
||||
}
|
||||
|
||||
// Ensure limitedCandles is ordered chronologically
|
||||
loopbackPeriod = 20;
|
||||
var orderedCandles = limitedCandles.OrderBy(c => c.Date).ToList();
|
||||
var loopback = loopbackPeriod.HasValue && loopbackPeriod > 1 ? loopbackPeriod.Value : 1;
|
||||
var candleLoopback = orderedCandles.TakeLast(loopback).ToList();
|
||||
@@ -135,6 +136,13 @@ public static class TradingBox
|
||||
return signalOnCandles.Single();
|
||||
}
|
||||
|
||||
// Check if all strategies produced signals - this is required for composite signals
|
||||
if (signalOnCandles.Count != strategies.Count)
|
||||
{
|
||||
// Not all strategies produced signals - composite signal requires all strategies to contribute
|
||||
return null;
|
||||
}
|
||||
|
||||
// Group signals by type for analysis
|
||||
var signalStrategies = signalOnCandles.Where(s => s.SignalType == SignalType.Signal).ToList();
|
||||
var trendStrategies = signalOnCandles.Where(s => s.SignalType == SignalType.Trend).ToList();
|
||||
@@ -153,7 +161,8 @@ public static class TradingBox
|
||||
var signalDirection = EvaluateSignalDirection(signalStrategies, config);
|
||||
|
||||
// Determine final direction and confidence
|
||||
var (finalDirection, confidence) = DetermineFinalSignal(signalDirection, trendDirection, signalStrategies, trendStrategies, config);
|
||||
var (finalDirection, confidence) =
|
||||
DetermineFinalSignal(signalDirection, trendDirection, signalStrategies, trendStrategies, config);
|
||||
|
||||
if (finalDirection == TradeDirection.None || confidence < config.MinimumConfidence)
|
||||
{
|
||||
@@ -161,8 +170,9 @@ public static class TradingBox
|
||||
}
|
||||
|
||||
// Create composite signal
|
||||
var lastSignal = signalStrategies.LastOrDefault() ?? trendStrategies.LastOrDefault() ?? contextStrategies.LastOrDefault();
|
||||
|
||||
var lastSignal = signalStrategies.LastOrDefault() ??
|
||||
trendStrategies.LastOrDefault() ?? contextStrategies.LastOrDefault();
|
||||
|
||||
return new Signal(
|
||||
ticker,
|
||||
finalDirection,
|
||||
@@ -170,17 +180,18 @@ public static class TradingBox
|
||||
lastSignal?.Candle,
|
||||
lastSignal?.Date ?? DateTime.UtcNow,
|
||||
lastSignal?.Exchange ?? config.DefaultExchange,
|
||||
StrategyType.Composite,
|
||||
StrategyType.Composite,
|
||||
SignalType.Signal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates context strategies based on confidence levels indicating market condition quality
|
||||
/// </summary>
|
||||
private static bool ValidateContextStrategies(HashSet<IStrategy> allStrategies, List<Signal> contextSignals, StrategyComboConfig config)
|
||||
private static bool ValidateContextStrategies(HashSet<IStrategy> allStrategies, List<Signal> contextSignals,
|
||||
StrategyComboConfig config)
|
||||
{
|
||||
var contextStrategiesCount = allStrategies.Count(s => s.SignalType == SignalType.Context);
|
||||
|
||||
|
||||
if (contextStrategiesCount == 0)
|
||||
{
|
||||
return true; // No context strategies, no restrictions
|
||||
@@ -256,9 +267,9 @@ public static class TradingBox
|
||||
/// Determines final signal direction and confidence based on signal and trend analysis
|
||||
/// </summary>
|
||||
private static (TradeDirection Direction, Confidence Confidence) DetermineFinalSignal(
|
||||
TradeDirection signalDirection,
|
||||
TradeDirection trendDirection,
|
||||
List<Signal> signalStrategies,
|
||||
TradeDirection signalDirection,
|
||||
TradeDirection trendDirection,
|
||||
List<Signal> signalStrategies,
|
||||
List<Signal> trendStrategies,
|
||||
StrategyComboConfig config)
|
||||
{
|
||||
@@ -294,12 +305,12 @@ public static class TradingBox
|
||||
{
|
||||
// Calculate confidence based on trend strength
|
||||
var totalTrend = trendStrategies.Count;
|
||||
var majorityDirection = trendDirection == TradeDirection.Long
|
||||
var majorityDirection = trendDirection == TradeDirection.Long
|
||||
? trendStrategies.Count(s => s.Direction == TradeDirection.Long)
|
||||
: trendStrategies.Count(s => s.Direction == TradeDirection.Short);
|
||||
|
||||
var agreementPercentage = (decimal)majorityDirection / totalTrend;
|
||||
|
||||
|
||||
if (agreementPercentage >= 0.8m)
|
||||
return (trendDirection, Confidence.High);
|
||||
else if (agreementPercentage >= config.TrendStrongAgreementThreshold)
|
||||
|
||||
Reference in New Issue
Block a user