using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NT8.Core.Common.Models;
using NT8.Core.Intelligence;
using NT8.Core.Logging;
using NT8.Core.Sizing;
namespace NT8.Integration.Tests
{
///
/// Integration tests for Phase 4 intelligence flow.
///
[TestClass]
public class Phase4IntegrationTests
{
[TestMethod]
public void FullFlow_ConfluenceToGradeFilter_AllowsTradeInPCP()
{
var logger = new BasicLogger("Phase4IntegrationTests");
var scorer = new ConfluenceScorer(logger, 100);
var filter = new GradeFilter();
var modeManager = new RiskModeManager(logger);
var intent = CreateIntent(OrderSide.Buy);
var context = CreateContext();
var bar = CreateBar();
var factors = CreateStrongFactors();
var score = scorer.CalculateScore(intent, context, bar, factors);
var mode = modeManager.GetCurrentMode();
var allowed = filter.ShouldAcceptTrade(score.Grade, mode);
Assert.IsTrue(allowed);
Assert.IsTrue(score.WeightedScore >= 0.70);
}
[TestMethod]
public void FullFlow_LowConfluence_RejectedInPCP()
{
var logger = new BasicLogger("Phase4IntegrationTests");
var scorer = new ConfluenceScorer(logger, 100);
var filter = new GradeFilter();
var intent = CreateIntent(OrderSide.Buy);
var context = CreateContext();
var bar = CreateBar();
var factors = CreateWeakFactors();
var score = scorer.CalculateScore(intent, context, bar, factors);
var allowed = filter.ShouldAcceptTrade(score.Grade, RiskMode.PCP);
Assert.IsFalse(allowed);
Assert.AreEqual(TradeGrade.F, score.Grade);
}
[TestMethod]
public void FullFlow_ModeTransitionToHR_BlocksTrades()
{
var logger = new BasicLogger("Phase4IntegrationTests");
var modeManager = new RiskModeManager(logger);
var filter = new GradeFilter();
modeManager.UpdateRiskMode(-500.0, 0, 3);
var mode = modeManager.GetCurrentMode();
var allowed = filter.ShouldAcceptTrade(TradeGrade.APlus, mode);
Assert.AreEqual(RiskMode.HR, mode);
Assert.IsFalse(allowed);
}
[TestMethod]
public void FullFlow_GradeBasedSizer_AppliesGradeAndModeMultipliers()
{
var logger = new BasicLogger("Phase4IntegrationTests");
var filter = new GradeFilter();
var gradeSizer = new GradeBasedSizer(logger, filter);
var baseSizer = new StubSizer(4, 400.0);
var intent = CreateIntent(OrderSide.Buy);
var context = CreateContext();
var confluence = CreateScore(TradeGrade.A, 0.85);
var config = new SizingConfig(SizingMethod.FixedDollarRisk, 1, 20, 500.0, new Dictionary());
var modeConfig = new RiskModeConfig(RiskMode.ECP, 1.5, TradeGrade.B, 1500.0, 4, true, new Dictionary());
var result = gradeSizer.CalculateGradeBasedSize(
intent,
context,
confluence,
RiskMode.ECP,
config,
baseSizer,
modeConfig);
// 4 * 1.25 * 1.5 = 7.5 => 7
Assert.AreEqual(7, result.Contracts);
Assert.IsTrue(result.Calculations.ContainsKey("combined_multiplier"));
}
[TestMethod]
public void FullFlow_RegimeManager_ShouldAdjustForExtremeVolatility()
{
var logger = new BasicLogger("Phase4IntegrationTests");
var vol = new VolatilityRegimeDetector(logger, 20);
var trend = new TrendRegimeDetector(logger);
var regimeManager = new RegimeManager(logger, vol, trend, 50, 50);
var bars = BuildUptrendBars(6, 5000.0, 1.0);
for (var i = 0; i < bars.Count; i++)
{
regimeManager.UpdateRegime("ES", bars[i], 5000.0, 2.4, 1.0);
}
var shouldAdjust = regimeManager.ShouldAdjustStrategy("ES", CreateIntent(OrderSide.Buy));
Assert.IsTrue(shouldAdjust);
}
[TestMethod]
public void FullFlow_ConfluenceStatsAndModeState_AreAvailable()
{
var logger = new BasicLogger("Phase4IntegrationTests");
var scorer = new ConfluenceScorer(logger, 10);
var modeManager = new RiskModeManager(logger);
var score = scorer.CalculateScore(CreateIntent(OrderSide.Buy), CreateContext(), CreateBar(), CreateStrongFactors());
var stats = scorer.GetHistoricalStats();
var state = modeManager.GetState();
Assert.IsNotNull(score);
Assert.IsNotNull(stats);
Assert.IsNotNull(state);
Assert.IsTrue(stats.TotalCalculations >= 1);
}
private static StrategyIntent CreateIntent(OrderSide side)
{
return new StrategyIntent(
"ES",
side,
OrderType.Market,
null,
8,
16,
0.8,
"Phase4 integration",
new Dictionary());
}
private static StrategyContext CreateContext()
{
return new StrategyContext(
"ES",
DateTime.UtcNow,
new Position("ES", 0, 0, 0, 0, DateTime.UtcNow),
new AccountInfo(100000, 100000, 0, 0, DateTime.UtcNow),
new MarketSession(DateTime.Today.AddHours(9.5), DateTime.Today.AddHours(16), true, "RTH"),
new Dictionary());
}
private static BarData CreateBar()
{
return new BarData("ES", DateTime.UtcNow, 5000, 5004, 4998, 5003, 1200, TimeSpan.FromMinutes(1));
}
private static ConfluenceScore CreateScore(TradeGrade grade, double weighted)
{
var factors = new List();
factors.Add(new ConfluenceFactor(FactorType.Setup, "Setup", weighted, 1.0, "test", new Dictionary()));
return new ConfluenceScore(weighted, weighted, grade, factors, DateTime.UtcNow, new Dictionary());
}
private static List CreateStrongFactors()
{
var factors = new List();
factors.Add(new FixedFactor(FactorType.Setup, 0.90));
factors.Add(new FixedFactor(FactorType.Trend, 0.85));
factors.Add(new FixedFactor(FactorType.Volatility, 0.80));
return factors;
}
private static List CreateWeakFactors()
{
var factors = new List();
factors.Add(new FixedFactor(FactorType.Setup, 0.20));
factors.Add(new FixedFactor(FactorType.Trend, 0.30));
factors.Add(new FixedFactor(FactorType.Volatility, 0.25));
return factors;
}
private static List BuildUptrendBars(int count, double start, double step)
{
var list = new List();
var t = DateTime.UtcNow.AddMinutes(-count);
for (var i = 0; i < count; i++)
{
var close = start + (i * step);
list.Add(new BarData("ES", t.AddMinutes(i), close - 1.0, close + 1.0, close - 2.0, close, 1000 + i, TimeSpan.FromMinutes(1)));
}
return list;
}
private class FixedFactor : IFactorCalculator
{
private readonly FactorType _type;
private readonly double _score;
public FixedFactor(FactorType type, double score)
{
_type = type;
_score = score;
}
public FactorType Type
{
get { return _type; }
}
public ConfluenceFactor Calculate(StrategyIntent intent, StrategyContext context, BarData bar)
{
return new ConfluenceFactor(_type, "Fixed", _score, 1.0, "fixed", new Dictionary());
}
}
private class StubSizer : IPositionSizer
{
private readonly int _contracts;
private readonly double _risk;
public StubSizer(int contracts, double risk)
{
_contracts = contracts;
_risk = risk;
}
public SizingResult CalculateSize(StrategyIntent intent, StrategyContext context, SizingConfig config)
{
return new SizingResult(_contracts, _risk, SizingMethod.FixedDollarRisk, new Dictionary());
}
public SizingMetadata GetMetadata()
{
return new SizingMetadata("Stub", "Stub", new List());
}
}
}
}