Refactoring TradingBotBase.cs + clean architecture (#38)

* Refactoring TradingBotBase.cs + clean architecture

* Fix basic tests

* Fix tests

* Fix workers

* Fix open positions

* Fix closing position stucking the grain

* Fix comments

* Refactor candle handling to use IReadOnlyList for chronological order preservation across various components
This commit is contained in:
Oda
2025-12-01 19:32:06 +07:00
committed by GitHub
parent ab26260f6d
commit 9d536ea49e
74 changed files with 4525 additions and 2350 deletions

View File

@@ -42,7 +42,7 @@ public class IndicatorTests
public void CalculateIndicatorsValues_WithNullScenario_ReturnsEmptyDictionary()
{
// Arrange
var candles = new HashSet<Candle> { CreateTestCandle() };
var candles = new List<Candle> { CreateTestCandle() };
// Act
var result = TradingBox.CalculateIndicatorsValues(null, candles);
@@ -56,7 +56,7 @@ public class IndicatorTests
{
// Arrange
var scenario = new Scenario(name: "TestScenario");
var candles = new HashSet<Candle> { CreateTestCandle() };
var candles = new List<Candle> { CreateTestCandle() };
// Act
var result = TradingBox.CalculateIndicatorsValues(scenario, candles);
@@ -70,7 +70,7 @@ public class IndicatorTests
{
// Arrange
var scenario = new Scenario(name: "TestScenario") { Indicators = null };
var candles = new HashSet<Candle> { CreateTestCandle() };
var candles = new List<Candle> { CreateTestCandle() };
// Act
var result = TradingBox.CalculateIndicatorsValues(scenario, candles);
@@ -83,7 +83,7 @@ public class IndicatorTests
public void CalculateIndicatorsValues_WithValidScenario_DoesNotThrow()
{
// Arrange - Create more realistic candle data
var candles = new HashSet<Candle>();
var candles = new List<Candle>();
for (int i = 0; i < 20; i++)
{
var date = TestDate.AddMinutes(i * 5);
@@ -120,7 +120,7 @@ public class IndicatorTests
public void CalculateIndicatorsValues_WithMultipleIndicators_DoesNotThrow()
{
// Arrange - Create more realistic candle data
var candles = new HashSet<Candle>();
var candles = new List<Candle>();
for (int i = 0; i < 30; i++)
{
var date = TestDate.AddMinutes(i * 5);
@@ -160,7 +160,7 @@ public class IndicatorTests
public void CalculateIndicatorsValues_WithExceptionInIndicator_CatchesAndContinues()
{
// Arrange - Create realistic candle data
var candles = new HashSet<Candle>();
var candles = new List<Candle>();
for (int i = 0; i < 25; i++)
{
candles.Add(CreateTestCandle(date: TestDate.AddMinutes(i)));
@@ -370,7 +370,7 @@ public class IndicatorTests
public void CalculateIndicatorsValues_HandlesLargeCandleSets()
{
// Arrange
var candles = new HashSet<Candle>();
var candles = new List<Candle>();
for (int i = 0; i < 100; i++)
{
var date = TestDate.AddMinutes(i * 2);
@@ -427,8 +427,8 @@ public class IndicatorTests
public void CalculateIndicatorsValues_DoesNotModifyInputCandles()
{
// Arrange
var originalCandles = new HashSet<Candle> { CreateTestCandle() };
var candlesCopy = new HashSet<Candle>(originalCandles.Select(c => new Candle
var originalCandles = new List<Candle> { CreateTestCandle() };
var candlesCopy = new List<Candle>(originalCandles.Select(c => new Candle
{
Open = c.Open,
High = c.High,

View File

@@ -22,11 +22,8 @@ public class RunIndicatorsBase
/// <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);
// Use List directly - preserves chronological order required for indicators
var signals = indicator.Run(TestCandles);
return signals ?? new List<LightSignal>();
}

View File

@@ -84,7 +84,7 @@ public class SignalProcessingTests : TradingBoxTests
public void GetSignal_WithNullScenario_ThrowsArgumentNullException()
{
// Arrange
var candles = new HashSet<Candle> { CreateTestCandle() };
var candles = new List<Candle> { CreateTestCandle() };
var signals = new Dictionary<string, LightSignal>();
// Act & Assert
@@ -98,7 +98,7 @@ public class SignalProcessingTests : TradingBoxTests
public void GetSignal_WithEmptyCandles_ReturnsNull()
{
// Arrange
var candles = new HashSet<Candle>();
var candles = new List<Candle>();
var scenario = CreateTestScenario(CreateTestIndicator());
var signals = new Dictionary<string, LightSignal>();
@@ -113,7 +113,7 @@ public class SignalProcessingTests : TradingBoxTests
public void GetSignal_WithScenarioHavingNoIndicators_ReturnsNull()
{
// Arrange
var candles = new HashSet<Candle> { CreateTestCandle() };
var candles = new List<Candle> { CreateTestCandle() };
var scenario = CreateTestScenario(); // Empty indicators
var signals = new Dictionary<string, LightSignal>();
@@ -348,8 +348,8 @@ public class SignalProcessingTests : TradingBoxTests
testCandles.Should().NotBeNull();
testCandles.Should().NotBeEmpty();
// Use last 100 candles for the test
var candles = testCandles.TakeLast(100).ToHashSet();
// Use last 100 candles for the test (preserve order)
var candles = testCandles.TakeLast(100).ToList();
var scenario = CreateTestScenario(CreateTestIndicator(IndicatorType.Stc, "StcIndicator"));
var signals = new Dictionary<string, LightSignal>();
@@ -373,8 +373,8 @@ public class SignalProcessingTests : TradingBoxTests
testCandles.Should().NotBeNull();
testCandles.Should().NotBeEmpty();
// Use last 500 candles for the test
var candles = testCandles.TakeLast(500).ToHashSet();
// Use last 500 candles for the test (preserve order)
var candles = testCandles.TakeLast(500).ToList();
var scenario = CreateTestScenario(CreateTestIndicator(IndicatorType.Stc, "StcIndicator"));
var signals = new Dictionary<string, LightSignal>();