Remove orderBy to improve perfs
This commit is contained in:
@@ -33,7 +33,7 @@ public class StDevContext : IndicatorBase
|
|||||||
|
|
||||||
ProcessStDevSignals(stDev, candles);
|
ProcessStDevSignals(stDev, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,6 @@ public class StDevContext : IndicatorBase
|
|||||||
// Filter pre-calculated StdDev values to match the candles we're processing
|
// Filter pre-calculated StdDev values to match the candles we're processing
|
||||||
stDev = preCalculatedValues.StdDev
|
stDev = preCalculatedValues.StdDev
|
||||||
.Where(s => candles.Any(c => c.Date == s.Date))
|
.Where(s => candles.Any(c => c.Date == s.Date))
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ public class StDevContext : IndicatorBase
|
|||||||
|
|
||||||
ProcessStDevSignals(stDev, candles);
|
ProcessStDevSignals(stDev, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class ChandelierExitIndicatorBase : IndicatorBase
|
|||||||
{
|
{
|
||||||
ProcessChandelierSignals(candles);
|
ProcessChandelierSignals(candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -61,11 +61,9 @@ public class ChandelierExitIndicatorBase : IndicatorBase
|
|||||||
// Filter pre-calculated Chandelier values to match the candles we're processing
|
// Filter pre-calculated Chandelier values to match the candles we're processing
|
||||||
chandelierLong = preCalculatedValues.ChandelierLong
|
chandelierLong = preCalculatedValues.ChandelierLong
|
||||||
.Where(c => c.ChandelierExit.HasValue && candles.Any(candle => candle.Date == c.Date))
|
.Where(c => c.ChandelierExit.HasValue && candles.Any(candle => candle.Date == c.Date))
|
||||||
.OrderBy(c => c.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
chandelierShort = preCalculatedValues.ChandelierShort
|
chandelierShort = preCalculatedValues.ChandelierShort
|
||||||
.Where(c => c.ChandelierExit.HasValue && candles.Any(candle => candle.Date == c.Date))
|
.Where(c => c.ChandelierExit.HasValue && candles.Any(candle => candle.Date == c.Date))
|
||||||
.OrderBy(c => c.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ public class ChandelierExitIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessChandelierSignalsWithPreCalculated(chandelierLong, chandelierShort, candles);
|
ProcessChandelierSignalsWithPreCalculated(chandelierLong, chandelierShort, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -127,7 +125,8 @@ public class ChandelierExitIndicatorBase : IndicatorBase
|
|||||||
ProcessChandelierSignalsForType(chandelier, chandelierType, candles);
|
ProcessChandelierSignalsForType(chandelier, chandelierType, candles);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetSignalsWithPreCalculated(ChandelierType chandelierType, List<ChandelierResult> chandelier, HashSet<Candle> candles)
|
private void GetSignalsWithPreCalculated(ChandelierType chandelierType, List<ChandelierResult> chandelier,
|
||||||
|
HashSet<Candle> candles)
|
||||||
{
|
{
|
||||||
ProcessChandelierSignalsForType(chandelier, chandelierType, candles);
|
ProcessChandelierSignalsForType(chandelier, chandelierType, candles);
|
||||||
}
|
}
|
||||||
@@ -139,7 +138,8 @@ public class ChandelierExitIndicatorBase : IndicatorBase
|
|||||||
/// <param name="chandelier">Chandelier calculation results</param>
|
/// <param name="chandelier">Chandelier calculation results</param>
|
||||||
/// <param name="chandelierType">Type of Chandelier (Long or Short)</param>
|
/// <param name="chandelierType">Type of Chandelier (Long or Short)</param>
|
||||||
/// <param name="candles">Candles to process</param>
|
/// <param name="candles">Candles to process</param>
|
||||||
private void ProcessChandelierSignalsForType(List<ChandelierResult> chandelier, ChandelierType chandelierType, HashSet<Candle> candles)
|
private void ProcessChandelierSignalsForType(List<ChandelierResult> chandelier, ChandelierType chandelierType,
|
||||||
|
HashSet<Candle> candles)
|
||||||
{
|
{
|
||||||
var chandelierCandle = MapChandelierToCandle(chandelier, candles.TakeLast(MinimumHistory));
|
var chandelierCandle = MapChandelierToCandle(chandelier, candles.TakeLast(MinimumHistory));
|
||||||
if (chandelierCandle.Count == 0)
|
if (chandelierCandle.Count == 0)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class DualEmaCrossIndicatorBase : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessDualEmaCrossSignals(fastEma, slowEma, candles);
|
ProcessDualEmaCrossSignals(fastEma, slowEma, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -76,11 +76,9 @@ public class DualEmaCrossIndicatorBase : EmaBaseIndicatorBase
|
|||||||
// Filter pre-calculated EMA values to match the candles we're processing
|
// Filter pre-calculated EMA values to match the candles we're processing
|
||||||
fastEma = preCalculatedValues.FastEma
|
fastEma = preCalculatedValues.FastEma
|
||||||
.Where(e => candles.Any(c => c.Date == e.Date))
|
.Where(e => candles.Any(c => c.Date == e.Date))
|
||||||
.OrderBy(e => e.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
slowEma = preCalculatedValues.SlowEma
|
slowEma = preCalculatedValues.SlowEma
|
||||||
.Where(e => candles.Any(c => c.Date == e.Date))
|
.Where(e => candles.Any(c => c.Date == e.Date))
|
||||||
.OrderBy(e => e.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +90,7 @@ public class DualEmaCrossIndicatorBase : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessDualEmaCrossSignals(fastEma, slowEma, candles);
|
ProcessDualEmaCrossSignals(fastEma, slowEma, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class EmaCrossIndicator : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessEmaCrossSignals(ema, candles);
|
ProcessEmaCrossSignals(ema, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -79,7 +79,7 @@ public class EmaCrossIndicator : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessEmaCrossSignals(ema, candles);
|
ProcessEmaCrossSignals(ema, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class EmaCrossIndicatorBase : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessEmaCrossSignals(ema, candles);
|
ProcessEmaCrossSignals(ema, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -68,7 +68,6 @@ public class EmaCrossIndicatorBase : EmaBaseIndicatorBase
|
|||||||
// Filter pre-calculated EMA values to match the candles we're processing
|
// Filter pre-calculated EMA values to match the candles we're processing
|
||||||
ema = preCalculatedValues.Ema
|
ema = preCalculatedValues.Ema
|
||||||
.Where(e => candles.Any(c => c.Date == e.Date))
|
.Where(e => candles.Any(c => c.Date == e.Date))
|
||||||
.OrderBy(e => e.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +79,7 @@ public class EmaCrossIndicatorBase : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessEmaCrossSignals(ema, candles);
|
ProcessEmaCrossSignals(ema, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class LaggingSTC : IndicatorBase
|
|||||||
|
|
||||||
ProcessLaggingStcSignals(stc, candles);
|
ProcessLaggingStcSignals(stc, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -70,7 +70,6 @@ public class LaggingSTC : IndicatorBase
|
|||||||
// Filter pre-calculated STC values to match the candles we're processing
|
// Filter pre-calculated STC values to match the candles we're processing
|
||||||
stc = preCalculatedValues.Stc
|
stc = preCalculatedValues.Stc
|
||||||
.Where(s => candles.Any(c => c.Date == s.Date))
|
.Where(s => candles.Any(c => c.Date == s.Date))
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ public class LaggingSTC : IndicatorBase
|
|||||||
|
|
||||||
ProcessLaggingStcSignals(stc, candles);
|
ProcessLaggingStcSignals(stc, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class MacdCrossIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessMacdSignals(macd, candles);
|
ProcessMacdSignals(macd, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -63,7 +63,6 @@ public class MacdCrossIndicatorBase : IndicatorBase
|
|||||||
// Filter pre-calculated MACD values to match the candles we're processing
|
// Filter pre-calculated MACD values to match the candles we're processing
|
||||||
macd = preCalculatedValues.Macd
|
macd = preCalculatedValues.Macd
|
||||||
.Where(m => candles.Any(c => c.Date == m.Date))
|
.Where(m => candles.Any(c => c.Date == m.Date))
|
||||||
.OrderBy(m => m.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +74,7 @@ public class MacdCrossIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessMacdSignals(macd, candles);
|
ProcessMacdSignals(macd, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class RsiDivergenceConfirmIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessRsiDivergenceConfirmSignals(rsiResult, candles);
|
ProcessRsiDivergenceConfirmSignals(rsiResult, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -65,7 +65,6 @@ public class RsiDivergenceConfirmIndicatorBase : IndicatorBase
|
|||||||
var relevantCandles = candles.TakeLast(10 * Period.Value);
|
var relevantCandles = candles.TakeLast(10 * Period.Value);
|
||||||
rsiResult = preCalculatedValues.Rsi
|
rsiResult = preCalculatedValues.Rsi
|
||||||
.Where(r => relevantCandles.Any(c => c.Date == r.Date))
|
.Where(r => relevantCandles.Any(c => c.Date == r.Date))
|
||||||
.OrderBy(r => r.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ public class RsiDivergenceConfirmIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessRsiDivergenceConfirmSignals(rsiResult, candles);
|
ProcessRsiDivergenceConfirmSignals(rsiResult, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class StcIndicatorBase : IndicatorBase
|
|||||||
ProcessStcSignals(stc, candles);
|
ProcessStcSignals(stc, candles);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -66,7 +66,6 @@ public class StcIndicatorBase : IndicatorBase
|
|||||||
// Filter pre-calculated STC values to match the candles we're processing
|
// Filter pre-calculated STC values to match the candles we're processing
|
||||||
stc = preCalculatedValues.Stc
|
stc = preCalculatedValues.Stc
|
||||||
.Where(s => candles.Any(c => c.Date == s.Date))
|
.Where(s => candles.Any(c => c.Date == s.Date))
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +77,7 @@ public class StcIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessStcSignals(stc, candles);
|
ProcessStcSignals(stc, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ public class SuperTrendCrossEma : IndicatorBase
|
|||||||
.Where(a => a.Adx.HasValue && a.Pdi.HasValue && a.Mdi.HasValue) // Ensure all values exist
|
.Where(a => a.Adx.HasValue && a.Pdi.HasValue && a.Mdi.HasValue) // Ensure all values exist
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
ProcessSuperTrendCrossEmaSignals(superTrend, ema50, adxResults, candles, minimumRequiredHistory, adxThreshold);
|
ProcessSuperTrendCrossEmaSignals(superTrend, ema50, adxResults, candles, minimumRequiredHistory,
|
||||||
|
adxThreshold);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None)
|
return Signals.Where(s => s.Confidence != Confidence.None)
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
@@ -111,7 +111,6 @@ public class SuperTrendCrossEma : IndicatorBase
|
|||||||
// Filter pre-calculated SuperTrend values to match the candles we're processing
|
// Filter pre-calculated SuperTrend values to match the candles we're processing
|
||||||
superTrend = preCalculatedValues.SuperTrend
|
superTrend = preCalculatedValues.SuperTrend
|
||||||
.Where(s => s.SuperTrend.HasValue && candles.Any(c => c.Date == s.Date))
|
.Where(s => s.SuperTrend.HasValue && candles.Any(c => c.Date == s.Date))
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,10 +131,10 @@ public class SuperTrendCrossEma : IndicatorBase
|
|||||||
.Where(a => a.Adx.HasValue && a.Pdi.HasValue && a.Mdi.HasValue)
|
.Where(a => a.Adx.HasValue && a.Pdi.HasValue && a.Mdi.HasValue)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
ProcessSuperTrendCrossEmaSignals(superTrend, ema50, adxResults, candles, minimumRequiredHistory, adxThreshold);
|
ProcessSuperTrendCrossEmaSignals(superTrend, ema50, adxResults, candles, minimumRequiredHistory,
|
||||||
|
adxThreshold);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None)
|
return Signals.Where(s => s.Confidence != Confidence.None)
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class SuperTrendIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessSuperTrendSignals(superTrend, candles);
|
ProcessSuperTrendSignals(superTrend, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -64,7 +64,6 @@ public class SuperTrendIndicatorBase : IndicatorBase
|
|||||||
// Filter pre-calculated SuperTrend values to match the candles we're processing
|
// Filter pre-calculated SuperTrend values to match the candles we're processing
|
||||||
superTrend = preCalculatedValues.SuperTrend
|
superTrend = preCalculatedValues.SuperTrend
|
||||||
.Where(s => s.SuperTrend.HasValue && candles.Any(c => c.Date == s.Date))
|
.Where(s => s.SuperTrend.HasValue && candles.Any(c => c.Date == s.Date))
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +75,7 @@ public class SuperTrendIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessSuperTrendSignals(superTrend, candles);
|
ProcessSuperTrendSignals(superTrend, candles);
|
||||||
|
|
||||||
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
return Signals.Where(s => s.Confidence != Confidence.None).ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class EmaTrendIndicatorBase : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessEmaTrendSignals(ema, candles);
|
ProcessEmaTrendSignals(ema, candles);
|
||||||
|
|
||||||
return Signals.OrderBy(s => s.Date).ToList();
|
return Signals.ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,6 @@ public class EmaTrendIndicatorBase : EmaBaseIndicatorBase
|
|||||||
// Filter pre-calculated EMA values to match the candles we're processing
|
// Filter pre-calculated EMA values to match the candles we're processing
|
||||||
ema = preCalculatedValues.Ema
|
ema = preCalculatedValues.Ema
|
||||||
.Where(e => candles.Any(c => c.Date == e.Date))
|
.Where(e => candles.Any(c => c.Date == e.Date))
|
||||||
.OrderBy(e => e.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ public class EmaTrendIndicatorBase : EmaBaseIndicatorBase
|
|||||||
|
|
||||||
ProcessEmaTrendSignals(ema, candles);
|
ProcessEmaTrendSignals(ema, candles);
|
||||||
|
|
||||||
return Signals.OrderBy(s => s.Date).ToList();
|
return Signals.ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class StochRsiTrendIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessStochRsiTrendSignals(stochRsi, candles);
|
ProcessStochRsiTrendSignals(stochRsi, candles);
|
||||||
|
|
||||||
return Signals.OrderBy(s => s.Date).ToList();
|
return Signals.ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
@@ -71,7 +71,6 @@ public class StochRsiTrendIndicatorBase : IndicatorBase
|
|||||||
// Filter pre-calculated StochRsi values to match the candles we're processing
|
// Filter pre-calculated StochRsi values to match the candles we're processing
|
||||||
stochRsi = preCalculatedValues.StochRsi
|
stochRsi = preCalculatedValues.StochRsi
|
||||||
.Where(s => s.Signal.HasValue && candles.Any(c => c.Date == s.Date))
|
.Where(s => s.Signal.HasValue && candles.Any(c => c.Date == s.Date))
|
||||||
.OrderBy(s => s.Date)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +82,7 @@ public class StochRsiTrendIndicatorBase : IndicatorBase
|
|||||||
|
|
||||||
ProcessStochRsiTrendSignals(stochRsi, candles);
|
ProcessStochRsiTrendSignals(stochRsi, candles);
|
||||||
|
|
||||||
return Signals.OrderBy(s => s.Date).ToList();
|
return Signals.ToList();
|
||||||
}
|
}
|
||||||
catch (RuleException)
|
catch (RuleException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ public static class TradingBox
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Optimized: Sort only if needed, then convert to HashSet
|
// Optimized: Sort only if needed, then convert to HashSet
|
||||||
var orderedSignals = signalOnCandles.OrderBy(s => s.Date).ToList();
|
var orderedSignals = signalOnCandles.ToList();
|
||||||
signalOnCandles = new HashSet<LightSignal>(orderedSignals);
|
signalOnCandles = new HashSet<LightSignal>(orderedSignals);
|
||||||
|
|
||||||
// Check if all strategies produced signals - this is required for composite signals
|
// Check if all strategies produced signals - this is required for composite signals
|
||||||
@@ -246,7 +246,8 @@ public static class TradingBox
|
|||||||
// Calculate confidence based on the average confidence of all signals
|
// Calculate confidence based on the average confidence of all signals
|
||||||
var averageConfidence = CalculateAverageConfidence(allDirectionalSignals);
|
var averageConfidence = CalculateAverageConfidence(allDirectionalSignals);
|
||||||
|
|
||||||
if (finalDirection == TradeDirection.None || averageConfidence == Confidence.None || averageConfidence < config.MinimumConfidence)
|
if (finalDirection == TradeDirection.None || averageConfidence == Confidence.None ||
|
||||||
|
averageConfidence < config.MinimumConfidence)
|
||||||
{
|
{
|
||||||
return null; // No valid signal, None confidence, or below minimum confidence
|
return null; // No valid signal, None confidence, or below minimum confidence
|
||||||
}
|
}
|
||||||
@@ -468,7 +469,8 @@ public static class TradingBox
|
|||||||
|
|
||||||
// Filter candles after the position's opening trade was filled, up to the next position
|
// Filter candles after the position's opening trade was filled, up to the next position
|
||||||
var candlesBeforeNextPosition = candles.Where(c =>
|
var candlesBeforeNextPosition = candles.Where(c =>
|
||||||
c.Date >= position.Open.Date && c.Date <= (nextPosition == null ? candles.Last().Date : nextPosition.Open.Date))
|
c.Date >= position.Open.Date &&
|
||||||
|
c.Date <= (nextPosition == null ? candles.Last().Date : nextPosition.Open.Date))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// If no candles after position opened, return zeros
|
// If no candles after position opened, return zeros
|
||||||
@@ -585,8 +587,8 @@ public static class TradingBox
|
|||||||
public static AgentSummaryMetrics CalculateAgentSummaryMetrics(List<Position> positions)
|
public static AgentSummaryMetrics CalculateAgentSummaryMetrics(List<Position> positions)
|
||||||
{
|
{
|
||||||
var validPositions = positions?
|
var validPositions = positions?
|
||||||
.Where(p => p.IsValidForMetrics())
|
.Where(p => p.IsValidForMetrics())
|
||||||
.ToList() ?? new List<Position>();
|
.ToList() ?? new List<Position>();
|
||||||
|
|
||||||
if (!validPositions.Any())
|
if (!validPositions.Any())
|
||||||
{
|
{
|
||||||
@@ -613,7 +615,8 @@ public static class TradingBox
|
|||||||
/// <param name="positions">List of all positions to analyze</param>
|
/// <param name="positions">List of all positions to analyze</param>
|
||||||
/// <param name="previousTotalVolume">Previous total volume to ensure cumulative volume never decreases</param>
|
/// <param name="previousTotalVolume">Previous total volume to ensure cumulative volume never decreases</param>
|
||||||
/// <returns>PlatformSummaryMetrics with all calculated values</returns>
|
/// <returns>PlatformSummaryMetrics with all calculated values</returns>
|
||||||
public static PlatformSummaryMetrics CalculatePlatformSummaryMetrics(List<Position> positions, decimal previousTotalVolume = 0m)
|
public static PlatformSummaryMetrics CalculatePlatformSummaryMetrics(List<Position> positions,
|
||||||
|
decimal previousTotalVolume = 0m)
|
||||||
{
|
{
|
||||||
if (positions == null || !positions.Any())
|
if (positions == null || !positions.Any())
|
||||||
{
|
{
|
||||||
@@ -660,12 +663,14 @@ public static class TradingBox
|
|||||||
|
|
||||||
if (position.TakeProfit1?.Status == TradeStatus.Filled)
|
if (position.TakeProfit1?.Status == TradeStatus.Filled)
|
||||||
{
|
{
|
||||||
closingVolume += position.TakeProfit1.Price * position.TakeProfit1.Quantity * position.TakeProfit1.Leverage;
|
closingVolume += position.TakeProfit1.Price * position.TakeProfit1.Quantity *
|
||||||
|
position.TakeProfit1.Leverage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position.TakeProfit2?.Status == TradeStatus.Filled)
|
if (position.TakeProfit2?.Status == TradeStatus.Filled)
|
||||||
{
|
{
|
||||||
closingVolume += position.TakeProfit2.Price * position.TakeProfit2.Quantity * position.TakeProfit2.Leverage;
|
closingVolume += position.TakeProfit2.Price * position.TakeProfit2.Quantity *
|
||||||
|
position.TakeProfit2.Leverage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,6 +688,7 @@ public static class TradingBox
|
|||||||
{
|
{
|
||||||
volumeByAsset[ticker] = 0;
|
volumeByAsset[ticker] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeByAsset[ticker] += positionVolume;
|
volumeByAsset[ticker] += positionVolume;
|
||||||
|
|
||||||
// Position count breakdown by asset - update state directly
|
// Position count breakdown by asset - update state directly
|
||||||
@@ -690,6 +696,7 @@ public static class TradingBox
|
|||||||
{
|
{
|
||||||
positionCountByAsset[ticker] = 0;
|
positionCountByAsset[ticker] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
positionCountByAsset[ticker]++;
|
positionCountByAsset[ticker]++;
|
||||||
|
|
||||||
// Calculate fees and PnL for all positions
|
// Calculate fees and PnL for all positions
|
||||||
@@ -709,6 +716,7 @@ public static class TradingBox
|
|||||||
{
|
{
|
||||||
positionCountByDirection[direction] = 0;
|
positionCountByDirection[direction] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
positionCountByDirection[direction]++;
|
positionCountByDirection[direction]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1183,7 +1191,8 @@ public static class TradingBox
|
|||||||
/// <param name="leverage">The leverage multiplier</param>
|
/// <param name="leverage">The leverage multiplier</param>
|
||||||
/// <param name="direction">The trade direction (Long or Short)</param>
|
/// <param name="direction">The trade direction (Long or Short)</param>
|
||||||
/// <returns>The calculated PnL</returns>
|
/// <returns>The calculated PnL</returns>
|
||||||
public static decimal CalculatePnL(decimal entryPrice, decimal exitPrice, decimal quantity, decimal leverage, TradeDirection direction)
|
public static decimal CalculatePnL(decimal entryPrice, decimal exitPrice, decimal quantity, decimal leverage,
|
||||||
|
TradeDirection direction)
|
||||||
{
|
{
|
||||||
var positionSize = CalculatePositionSize(quantity, leverage);
|
var positionSize = CalculatePositionSize(quantity, leverage);
|
||||||
|
|
||||||
@@ -1301,7 +1310,8 @@ public static class TradingBox
|
|||||||
/// <param name="maxLossStreak">Maximum allowed loss streak (0 or negative means no limit)</param>
|
/// <param name="maxLossStreak">Maximum allowed loss streak (0 or negative means no limit)</param>
|
||||||
/// <param name="signalDirection">The direction of the signal for the new position</param>
|
/// <param name="signalDirection">The direction of the signal for the new position</param>
|
||||||
/// <returns>True if position can be opened, false if blocked by loss streak</returns>
|
/// <returns>True if position can be opened, false if blocked by loss streak</returns>
|
||||||
public static bool CheckLossStreak(List<Position> recentPositions, int maxLossStreak, TradeDirection signalDirection)
|
public static bool CheckLossStreak(List<Position> recentPositions, int maxLossStreak,
|
||||||
|
TradeDirection signalDirection)
|
||||||
{
|
{
|
||||||
// If MaxLossStreak is 0, there's no limit
|
// If MaxLossStreak is 0, there's no limit
|
||||||
if (maxLossStreak <= 0)
|
if (maxLossStreak <= 0)
|
||||||
|
|||||||
@@ -20,3 +20,4 @@ DateTime,TestName,CandlesCount,ExecutionTimeSeconds,ProcessingRateCandlesPerSec,
|
|||||||
2025-11-14T12:46:43Z,Telemetry_ETH_RSI_EMACROSS,5760,3.86,1491.9,29.05,20.88,36.27,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,b60295fc,dev,development
|
2025-11-14T12:46:43Z,Telemetry_ETH_RSI_EMACROSS,5760,3.86,1491.9,29.05,20.88,36.27,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,b60295fc,dev,development
|
||||||
2025-11-15T06:46:21Z,Telemetry_ETH_RSI_EMACROSS,5760,12.58,457.8,28.82,21.79,35.28,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,e814eb74,dev,development
|
2025-11-15T06:46:21Z,Telemetry_ETH_RSI_EMACROSS,5760,12.58,457.8,28.82,21.79,35.28,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,e814eb74,dev,development
|
||||||
2025-11-15T06:50:04Z,Telemetry_ETH_RSI_EMACROSS,5760,4.84,1190.4,29.01,19.10,35.17,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,e814eb74,dev,development
|
2025-11-15T06:50:04Z,Telemetry_ETH_RSI_EMACROSS,5760,4.84,1190.4,29.01,19.10,35.17,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,e814eb74,dev,development
|
||||||
|
2025-11-15T07:11:55Z,Telemetry_ETH_RSI_EMACROSS,5760,5.44,1059.4,28.81,18.07,33.80,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,bed25e72,dev,development
|
||||||
|
|||||||
|
@@ -65,3 +65,4 @@ DateTime,TestName,CandlesCount,ExecutionTimeSeconds,ProcessingRateCandlesPerSec,
|
|||||||
2025-11-14T12:46:43Z,Telemetry_ETH_RSI,5760,3.44,1669.8,28.85,20.34,35.90,0.00,0,0.0,3304.34,0.00,0.57,-30689.97,24,-51.70,0.00,b60295fc,dev,development
|
2025-11-14T12:46:43Z,Telemetry_ETH_RSI,5760,3.44,1669.8,28.85,20.34,35.90,0.00,0,0.0,3304.34,0.00,0.57,-30689.97,24,-51.70,0.00,b60295fc,dev,development
|
||||||
2025-11-15T06:46:21Z,Telemetry_ETH_RSI,5760,4.83,1191.0,29.02,20.22,37.20,4105.51,0,0.0,499.39,0.00,0.09,-30689.97,24,-51.70,0.00,e814eb74,dev,development
|
2025-11-15T06:46:21Z,Telemetry_ETH_RSI,5760,4.83,1191.0,29.02,20.22,37.20,4105.51,0,0.0,499.39,0.00,0.09,-30689.97,24,-51.70,0.00,e814eb74,dev,development
|
||||||
2025-11-15T06:50:04Z,Telemetry_ETH_RSI,5760,4.47,1286.2,28.81,20.58,34.89,3324.75,0,0.0,965.71,0.00,0.17,-30689.97,24,-51.70,0.00,e814eb74,dev,development
|
2025-11-15T06:50:04Z,Telemetry_ETH_RSI,5760,4.47,1286.2,28.81,20.58,34.89,3324.75,0,0.0,965.71,0.00,0.17,-30689.97,24,-51.70,0.00,e814eb74,dev,development
|
||||||
|
2025-11-15T07:11:55Z,Telemetry_ETH_RSI,5760,3.365,1707.1,29.06,20.43,36.29,2872.29,0,0.0,371.33,0.00,0.06,-30689.97,24,-51.70,0.00,bed25e72,dev,development
|
||||||
|
|||||||
|
Reference in New Issue
Block a user