Some checks failed
Build and Test / build (push) Has been cancelled
Implementation (20 files, ~4,000 lines): - Confluence Scoring System * 5-factor trade grading (A+ to F) * ORB validity, trend alignment, volatility regime * Time-in-session, execution quality factors * Weighted score aggregation * Dynamic factor weighting - Regime Detection * Volatility regime classification (Low/Normal/High/Extreme) * Trend regime detection (Strong/Weak Up/Down, Range) * Regime transition tracking * Historical regime analysis * Performance by regime - Risk Mode Framework * ECP (Elevated Confidence) - aggressive sizing * PCP (Primary Confidence) - normal operation * DCP (Diminished Confidence) - conservative * HR (High Risk) - halt trading * Automatic mode transitions based on performance * Manual override capability - Grade-Based Position Sizing * Dynamic sizing by trade quality * A+ trades: 1.5x size, A: 1.25x, B: 1.0x, C: 0.75x * Risk mode multipliers * Grade filtering (reject low-quality setups) - Enhanced Indicators * AVWAP calculator with anchoring * Volume profile analyzer (VPOC, nodes, value area) * Slope calculations * Multi-timeframe support Testing (85+ new tests, 150+ total): - 20+ confluence scoring tests - 18+ regime detection tests - 15+ risk mode management tests - 12+ grade-based sizing tests - 10+ indicator tests - 12+ integration tests (full intelligence flow) - Performance benchmarks (all targets exceeded) Quality Metrics: - Zero build errors - Zero warnings - 100% C# 5.0 compliance - Thread-safe with proper locking - Full XML documentation - No breaking changes to Phase 1-3 Performance (all targets exceeded): - Confluence scoring: <5ms ✅ - Regime detection: <3ms ✅ - Grade filtering: <1ms ✅ - Risk mode updates: <2ms ✅ - Overall flow: <15ms ✅ Integration: - Seamless integration with Phase 2-3 - Enhanced SimpleORB strategy with confluence - Grade-aware position sizing operational - Risk modes fully functional - Regime-aware trading active Phase 4 Status: ✅ COMPLETE Intelligent Trading Core: ✅ OPERATIONAL System Capability: 80% feature complete Next: Phase 5 (Analytics) or Deployment
276 lines
9.3 KiB
C#
276 lines
9.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using NT8.Core.Common.Models;
|
|
using NT8.Core.Intelligence;
|
|
using NT8.Core.Logging;
|
|
|
|
namespace NT8.Core.Tests.Intelligence
|
|
{
|
|
[TestClass]
|
|
public class RegimeDetectionTests
|
|
{
|
|
[TestMethod]
|
|
public void VolatilityDetector_ClassifiesLow()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var regime = detector.DetectRegime("ES", 0.5, 1.0);
|
|
Assert.AreEqual(VolatilityRegime.Low, regime);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_ClassifiesBelowNormal()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var regime = detector.DetectRegime("ES", 0.7, 1.0);
|
|
Assert.AreEqual(VolatilityRegime.BelowNormal, regime);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_ClassifiesNormal()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var regime = detector.DetectRegime("ES", 1.0, 1.0);
|
|
Assert.AreEqual(VolatilityRegime.Normal, regime);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_ClassifiesElevated()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var regime = detector.DetectRegime("ES", 1.3, 1.0);
|
|
Assert.AreEqual(VolatilityRegime.Elevated, regime);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_ClassifiesHigh()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var regime = detector.DetectRegime("ES", 1.7, 1.0);
|
|
Assert.AreEqual(VolatilityRegime.High, regime);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_ClassifiesExtreme()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var regime = detector.DetectRegime("ES", 2.2, 1.0);
|
|
Assert.AreEqual(VolatilityRegime.Extreme, regime);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_CalculateScore_ReturnsRatio()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var score = detector.CalculateVolatilityScore(1.5, 1.0);
|
|
Assert.AreEqual(1.5, score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_TransitionHistory_TracksChanges()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
detector.DetectRegime("NQ", 1.0, 1.0);
|
|
detector.DetectRegime("NQ", 2.3, 1.0);
|
|
|
|
var transitions = detector.GetTransitions("NQ");
|
|
Assert.IsTrue(transitions.Count >= 1);
|
|
Assert.AreEqual("NQ", transitions[0].Symbol);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void VolatilityDetector_GetCurrentRegime_Unknown_ReturnsNormal()
|
|
{
|
|
var detector = CreateVolDetector();
|
|
var regime = detector.GetCurrentRegime("GC");
|
|
Assert.AreEqual(VolatilityRegime.Normal, regime);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TrendDetector_DetectsStrongUp()
|
|
{
|
|
var detector = CreateTrendDetector();
|
|
var bars = BuildUptrendBars(12, 5000.0, 2.0);
|
|
|
|
var regime = detector.DetectTrend("ES", bars, 4995.0);
|
|
|
|
Assert.IsTrue(regime == TrendRegime.StrongUp || regime == TrendRegime.WeakUp);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TrendDetector_DetectsStrongDown()
|
|
{
|
|
var detector = CreateTrendDetector();
|
|
var bars = BuildDowntrendBars(12, 5000.0, 2.0);
|
|
|
|
var regime = detector.DetectTrend("ES", bars, 5005.0);
|
|
|
|
Assert.IsTrue(regime == TrendRegime.StrongDown || regime == TrendRegime.WeakDown);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TrendDetector_CalculateStrength_UptrendPositive()
|
|
{
|
|
var detector = CreateTrendDetector();
|
|
var bars = BuildUptrendBars(10, 100.0, 1.0);
|
|
|
|
var strength = detector.CalculateTrendStrength(bars, 95.0);
|
|
|
|
Assert.IsTrue(strength > 0.0);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TrendDetector_CalculateStrength_DowntrendNegative()
|
|
{
|
|
var detector = CreateTrendDetector();
|
|
var bars = BuildDowntrendBars(10, 100.0, 1.0);
|
|
|
|
var strength = detector.CalculateTrendStrength(bars, 105.0);
|
|
|
|
Assert.IsTrue(strength < 0.0);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TrendDetector_IsRanging_FlatBars_True()
|
|
{
|
|
var detector = CreateTrendDetector();
|
|
var bars = BuildRangeBars(10, 100.0, 0.1);
|
|
|
|
var ranging = detector.IsRanging(bars, 0.2);
|
|
|
|
Assert.IsTrue(ranging);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TrendDetector_AssessTrendQuality_GoodStructure_ReturnsNotPoor()
|
|
{
|
|
var detector = CreateTrendDetector();
|
|
var bars = BuildUptrendBars(12, 100.0, 0.8);
|
|
|
|
var quality = detector.AssessTrendQuality(bars);
|
|
|
|
Assert.IsTrue(quality == TrendQuality.Fair || quality == TrendQuality.Good || quality == TrendQuality.Excellent);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void RegimeManager_UpdateAndGetCurrentRegime_ReturnsState()
|
|
{
|
|
var manager = CreateRegimeManager();
|
|
var bar = CreateBar("ES", 5000, 5004, 4998, 5002, 1000);
|
|
|
|
manager.UpdateRegime("ES", bar, 5000.0, 1.0, 1.0);
|
|
var state = manager.GetCurrentRegime("ES");
|
|
|
|
Assert.IsNotNull(state);
|
|
Assert.AreEqual("ES", state.Symbol);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void RegimeManager_ShouldAdjustStrategy_ExtremeVolatility_True()
|
|
{
|
|
var manager = CreateRegimeManager();
|
|
var bars = BuildUptrendBars(6, 5000.0, 1.0);
|
|
|
|
for (var i = 0; i < bars.Count; i++)
|
|
{
|
|
manager.UpdateRegime("ES", bars[i], 5000.0, 2.5, 1.0);
|
|
}
|
|
|
|
var intent = CreateIntent(OrderSide.Buy);
|
|
var shouldAdjust = manager.ShouldAdjustStrategy("ES", intent);
|
|
|
|
Assert.IsTrue(shouldAdjust);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void RegimeManager_TransitionsRecorded_WhenRegimeChanges()
|
|
{
|
|
var manager = CreateRegimeManager();
|
|
var bars = BuildUptrendBars(6, 5000.0, 1.0);
|
|
|
|
for (var i = 0; i < bars.Count; i++)
|
|
{
|
|
manager.UpdateRegime("NQ", bars[i], 5000.0, 1.0, 1.0);
|
|
}
|
|
|
|
manager.UpdateRegime("NQ", CreateBar("NQ", 5000, 5001, 4990, 4991, 1500), 5000.0, 2.3, 1.0);
|
|
|
|
var transitions = manager.GetRecentTransitions("NQ", TimeSpan.FromHours(2));
|
|
Assert.IsTrue(transitions.Count >= 1);
|
|
}
|
|
|
|
private static VolatilityRegimeDetector CreateVolDetector()
|
|
{
|
|
return new VolatilityRegimeDetector(new BasicLogger("RegimeDetectionTests"), 50);
|
|
}
|
|
|
|
private static TrendRegimeDetector CreateTrendDetector()
|
|
{
|
|
return new TrendRegimeDetector(new BasicLogger("RegimeDetectionTests"));
|
|
}
|
|
|
|
private static RegimeManager CreateRegimeManager()
|
|
{
|
|
var logger = new BasicLogger("RegimeManagerTests");
|
|
var vol = new VolatilityRegimeDetector(logger, 50);
|
|
var trend = new TrendRegimeDetector(logger);
|
|
return new RegimeManager(logger, vol, trend, 200, 100);
|
|
}
|
|
|
|
private static List<BarData> BuildUptrendBars(int count, double start, double step)
|
|
{
|
|
var result = new List<BarData>();
|
|
var time = DateTime.UtcNow.AddMinutes(-count);
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var close = start + (i * step);
|
|
result.Add(new BarData("ES", time.AddMinutes(i), close - 1.0, close + 1.0, close - 2.0, close, 1000 + i, TimeSpan.FromMinutes(1)));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static List<BarData> BuildDowntrendBars(int count, double start, double step)
|
|
{
|
|
var result = new List<BarData>();
|
|
var time = DateTime.UtcNow.AddMinutes(-count);
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var close = start - (i * step);
|
|
result.Add(new BarData("ES", time.AddMinutes(i), close + 1.0, close + 2.0, close - 1.0, close, 1000 + i, TimeSpan.FromMinutes(1)));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static List<BarData> BuildRangeBars(int count, double center, double amplitude)
|
|
{
|
|
var result = new List<BarData>();
|
|
var time = DateTime.UtcNow.AddMinutes(-count);
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var close = center + ((i % 2 == 0) ? amplitude : -amplitude);
|
|
result.Add(new BarData("ES", time.AddMinutes(i), close - 0.05, close + 0.10, close - 0.10, close, 800 + i, TimeSpan.FromMinutes(1)));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static BarData CreateBar(string symbol, double open, double high, double low, double close, long volume)
|
|
{
|
|
return new BarData(symbol, DateTime.UtcNow, open, high, low, close, volume, TimeSpan.FromMinutes(1));
|
|
}
|
|
|
|
private static StrategyIntent CreateIntent(OrderSide side)
|
|
{
|
|
return new StrategyIntent(
|
|
"ES",
|
|
side,
|
|
OrderType.Market,
|
|
null,
|
|
8,
|
|
16,
|
|
0.8,
|
|
"Test",
|
|
new Dictionary<string, object>());
|
|
}
|
|
}
|
|
}
|