Add test for RSI Divergence
This commit is contained in:
58
src/Managing.Domain.Tests/Indicators/RsiDivergenceTests.cs
Normal file
58
src/Managing.Domain.Tests/Indicators/RsiDivergenceTests.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using FluentAssertions;
|
||||||
|
using Managing.Domain.Strategies.Signals;
|
||||||
|
using Xunit;
|
||||||
|
using static Managing.Common.Enums;
|
||||||
|
|
||||||
|
namespace Managing.Domain.Tests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests for RSI Divergence indicator signal generation.
|
||||||
|
/// Tests verify that the indicator produces a consistent number of signals
|
||||||
|
/// when run on the same historical data.
|
||||||
|
/// </summary>
|
||||||
|
public class RsiDivergenceTests : RunIndicatorsBase
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void RsiDivergenceIndicator_Should_Generate_Consistent_Signal_Count()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var rsiIndicator = new RsiDivergenceIndicatorBase("RSI_Divergence_Test", 14);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var signals = RunIndicatorAndGetSignals(rsiIndicator);
|
||||||
|
var signalCount = signals.Count;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// The RSI divergence indicator should generate a consistent number of signals
|
||||||
|
// when run on the same historical ETH data.
|
||||||
|
// This test ensures that any changes to the indicator logic don't accidentally
|
||||||
|
// change the signal generation behavior.
|
||||||
|
signalCount.Should().BeGreaterThan(0, "RSI divergence indicator should generate signals from historical data");
|
||||||
|
signalCount.Should().Be(11, "RSI divergence indicator should generate exactly 11 signals with the current ETH dataset");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void RsiDivergenceIndicator_Should_Generate_Valid_Signals()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var rsiIndicator = new RsiDivergenceIndicatorBase("RSI_Divergence_Test", 14);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var signals = RunIndicatorAndGetSignals(rsiIndicator);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
signals.Should().NotBeNull();
|
||||||
|
signals.Should().NotBeEmpty();
|
||||||
|
|
||||||
|
// Verify each signal has required properties
|
||||||
|
foreach (var signal in signals)
|
||||||
|
{
|
||||||
|
signal.Should().NotBeNull();
|
||||||
|
signal.Date.Should().NotBe(default(DateTime));
|
||||||
|
// Enums cannot be null by definition, so we just verify they have valid values
|
||||||
|
signal.Direction.Should().BeOneOf(TradeDirection.Long, TradeDirection.Short);
|
||||||
|
signal.Ticker.Should().NotBe(Ticker.Unknown);
|
||||||
|
signal.Confidence.Should().BeOneOf(Confidence.Low, Confidence.Medium, Confidence.High);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/Managing.Domain.Tests/Indicators/RunIndicatorsBase.cs
Normal file
33
src/Managing.Domain.Tests/Indicators/RunIndicatorsBase.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using Managing.Core;
|
||||||
|
using Managing.Domain.Candles;
|
||||||
|
using Managing.Domain.Indicators;
|
||||||
|
using Managing.Domain.Strategies;
|
||||||
|
|
||||||
|
namespace Managing.Domain.Tests;
|
||||||
|
|
||||||
|
public class RunIndicatorsBase
|
||||||
|
{
|
||||||
|
protected readonly List<Candle> TestCandles;
|
||||||
|
|
||||||
|
public RunIndicatorsBase()
|
||||||
|
{
|
||||||
|
// Load the ETH Fifteen Minutes candles data for indicator testing
|
||||||
|
TestCandles = FileHelpers.ReadJson<List<Candle>>("Data/ETH-FifteenMinutes-candles-20:44:15 +00:00-.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs an indicator on the test candles and returns the signals generated
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="indicator">The indicator to run</param>
|
||||||
|
/// <returns>List of signals generated by the indicator</returns>
|
||||||
|
protected List<LightSignal> RunIndicatorAndGetSignals(IndicatorBase indicator)
|
||||||
|
{
|
||||||
|
// Convert list to HashSet as expected by the Run method
|
||||||
|
var candleSet = TestCandles.ToHashSet();
|
||||||
|
|
||||||
|
// Run the indicator
|
||||||
|
var signals = indicator.Run(candleSet);
|
||||||
|
|
||||||
|
return signals ?? new List<LightSignal>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,9 @@
|
|||||||
<None Update="Data\ETH-FifteenMinutes-candles-large.json">
|
<None Update="Data\ETH-FifteenMinutes-candles-large.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Data\ETH-FifteenMinutes-candles-20:44:15 +00:00-.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -15,3 +15,6 @@ DateTime,TestName,CandlesCount,ExecutionTimeSeconds,ProcessingRateCandlesPerSec,
|
|||||||
2025-11-12T14:04:57Z,Telemetry_ETH_RSI_EMACROSS,5760,6.45,893.2,15.27,16.06,23.13,0.0,0,0.0,0.0,0.0,0.0,-53491.95,20,-53.49,0.00,d9489691,dev,development
|
2025-11-12T14:04:57Z,Telemetry_ETH_RSI_EMACROSS,5760,6.45,893.2,15.27,16.06,23.13,0.0,0,0.0,0.0,0.0,0.0,-53491.95,20,-53.49,0.00,d9489691,dev,development
|
||||||
2025-11-12T17:31:53Z,Telemetry_ETH_RSI_EMACROSS,5760,5.10,1128.5,15.26,15.61,23.10,0.0,0,0.0,0.0,0.0,0.0,-34137.42,20,-34.14,0.00,6d6f70ae,dev,development
|
2025-11-12T17:31:53Z,Telemetry_ETH_RSI_EMACROSS,5760,5.10,1128.5,15.26,15.61,23.10,0.0,0,0.0,0.0,0.0,0.0,-34137.42,20,-34.14,0.00,6d6f70ae,dev,development
|
||||||
2025-11-13T19:34:27Z,Telemetry_ETH_RSI_EMACROSS,5760,3.68,1566.4,15.26,15.45,23.08,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,1f7d9146,dev,development
|
2025-11-13T19:34:27Z,Telemetry_ETH_RSI_EMACROSS,5760,3.68,1566.4,15.26,15.45,23.08,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,1f7d9146,dev,development
|
||||||
|
2025-11-14T12:43:33Z,Telemetry_ETH_RSI_EMACROSS,5760,6.43,896.2,29.02,22.13,36.21,0.0,0,0.0,0.0,0.0,0.0,-35450.45,20,-49.76,0.00,b60295fc,dev,development
|
||||||
|
2025-11-14T12:45:51Z,Telemetry_ETH_RSI_EMACROSS,5760,4.12,1398.2,29.05,21.88,36.24,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
|
||||||
|
|||||||
|
@@ -60,3 +60,6 @@ DateTime,TestName,CandlesCount,ExecutionTimeSeconds,ProcessingRateCandlesPerSec,
|
|||||||
2025-11-12T17:31:53Z,Telemetry_ETH_RSI,5760,3.145,1826.0,15.26,16.99,24.08,0.00,0,0.0,2982.49,0.00,0.52,-29063.40,24,-29.06,0.00,6d6f70ae,dev,development
|
2025-11-12T17:31:53Z,Telemetry_ETH_RSI,5760,3.145,1826.0,15.26,16.99,24.08,0.00,0,0.0,2982.49,0.00,0.52,-29063.40,24,-29.06,0.00,6d6f70ae,dev,development
|
||||||
2025-11-13T19:31:55Z,Telemetry_ETH_RSI,5760,3.27,1755.7,15.26,17.03,24.09,0.00,0,0.0,3141.00,0.00,0.55,-30689.97,24,-51.70,0.00,1f7d9146,dev,development
|
2025-11-13T19:31:55Z,Telemetry_ETH_RSI,5760,3.27,1755.7,15.26,17.03,24.09,0.00,0,0.0,3141.00,0.00,0.55,-30689.97,24,-51.70,0.00,1f7d9146,dev,development
|
||||||
2025-11-13T19:34:27Z,Telemetry_ETH_RSI,5760,1.655,3461.5,15.26,17.10,23.48,0.00,0,0.0,1595.88,0.00,0.28,-30689.97,24,-51.70,0.00,1f7d9146,dev,development
|
2025-11-13T19:34:27Z,Telemetry_ETH_RSI,5760,1.655,3461.5,15.26,17.10,23.48,0.00,0,0.0,1595.88,0.00,0.28,-30689.97,24,-51.70,0.00,1f7d9146,dev,development
|
||||||
|
2025-11-14T12:43:33Z,Telemetry_ETH_RSI,5760,4.345,1324.3,21.03,20.35,28.95,0.00,0,0.0,4210.13,0.00,0.73,-30689.97,24,-51.70,0.00,b60295fc,dev,development
|
||||||
|
2025-11-14T12:45:51Z,Telemetry_ETH_RSI,5760,2.235,2576.6,29.03,20.37,36.11,0.00,0,0.0,2103.00,0.00,0.37,-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
|
||||||
|
|||||||
|
Reference in New Issue
Block a user