300 lines
11 KiB
C#
300 lines
11 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 OrbConfluenceFactorTests
|
|
{
|
|
[TestMethod]
|
|
public void NarrowRange_NR7_ScoresOne()
|
|
{
|
|
var calc = new NarrowRangeFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
intent.Metadata["daily_bars"] = CreateDailyContext(new double[] { 10, 10, 10, 10, 10, 10, 5 });
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(1.0, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void NarrowRange_NR4_Scores075()
|
|
{
|
|
var calc = new NarrowRangeFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
intent.Metadata["daily_bars"] = CreateDailyContext(new double[] { 5, 5, 5, 10, 9, 8, 7 });
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(0.75, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void NarrowRange_WideRange_ScoresLow()
|
|
{
|
|
var calc = new NarrowRangeFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
intent.Metadata["daily_bars"] = CreateDailyContext(new double[] { 5, 5, 5, 5, 5, 5, 12 });
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.IsTrue(result.Score <= 0.3);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void NarrowRange_MissingContext_DefaultsTo03()
|
|
{
|
|
var calc = new NarrowRangeFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(0.3, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void NarrowRange_InsufficientBars_DefaultsTo03()
|
|
{
|
|
var calc = new NarrowRangeFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
intent.Metadata["daily_bars"] = CreateDailyContext(new double[] { 8, 7, 6, 5 });
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(0.3, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void OrbRangeVsAtr_SmallRange_ScoresOne()
|
|
{
|
|
var calc = new OrbRangeVsAtrFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 10, 10, 10, 10, 10, 10, 10 });
|
|
intent.Metadata["daily_bars"] = daily;
|
|
intent.Metadata["orb_range_ticks"] = 8.0;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(1.0, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void OrbRangeVsAtr_LargeRange_ScoresVeryLow()
|
|
{
|
|
var calc = new OrbRangeVsAtrFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 10, 10, 10, 10, 10, 10, 10 });
|
|
intent.Metadata["daily_bars"] = daily;
|
|
intent.Metadata["orb_range_ticks"] = 40.0;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.IsTrue(result.Score <= 0.15);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void OrbRangeVsAtr_MissingContext_DefaultsTo05()
|
|
{
|
|
var calc = new OrbRangeVsAtrFactorCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(0.5, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void GapDirection_LargeAlignedGap_ScoresOne()
|
|
{
|
|
var calc = new GapDirectionAlignmentCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
daily.Closes[daily.Count - 2] = 100.0;
|
|
daily.TodayOpen = 106.0;
|
|
daily.TradeDirection = 1;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(1.0, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void GapDirection_LargeOpposingGap_ScoresVeryLow()
|
|
{
|
|
var calc = new GapDirectionAlignmentCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
daily.Closes[daily.Count - 2] = 100.0;
|
|
daily.TodayOpen = 106.0;
|
|
daily.TradeDirection = -1;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.IsTrue(result.Score <= 0.15);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void GapDirection_FlatOpen_ScoresNeutral()
|
|
{
|
|
var calc = new GapDirectionAlignmentCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
daily.Closes[daily.Count - 2] = 100.0;
|
|
daily.TodayOpen = 100.1;
|
|
daily.TradeDirection = 1;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(0.55, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void BreakoutVolume_ThreeX_ScoresOne()
|
|
{
|
|
var calc = new BreakoutVolumeStrengthCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
daily.BreakoutBarVolume = 3000.0;
|
|
daily.AvgIntradayBarVolume = 1000.0;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(1.0, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void BreakoutVolume_BelowAverage_ScoresLow()
|
|
{
|
|
var calc = new BreakoutVolumeStrengthCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
daily.BreakoutBarVolume = 800.0;
|
|
daily.AvgIntradayBarVolume = 1200.0;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.IsTrue(result.Score <= 0.25);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void PriorCloseStrength_LongTopQuartile_ScoresOne()
|
|
{
|
|
var calc = new PriorDayCloseStrengthCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
int prev = daily.Count - 2;
|
|
daily.Lows[prev] = 100.0;
|
|
daily.Highs[prev] = 120.0;
|
|
daily.Closes[prev] = 118.0;
|
|
daily.TradeDirection = 1;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(1.0, result.Score, 0.000001);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void PriorCloseStrength_LongBottomQuartile_ScoresLow()
|
|
{
|
|
var calc = new PriorDayCloseStrengthCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
int prev = daily.Count - 2;
|
|
daily.Lows[prev] = 100.0;
|
|
daily.Highs[prev] = 120.0;
|
|
daily.Closes[prev] = 101.0;
|
|
daily.TradeDirection = 1;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.IsTrue(result.Score <= 0.20);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void PriorCloseStrength_ShortBottomQuartile_ScoresOne()
|
|
{
|
|
var calc = new PriorDayCloseStrengthCalculator(new BasicLogger("test"));
|
|
var intent = CreateIntent();
|
|
var daily = CreateDailyContext(new double[] { 8, 8, 8, 8, 8, 8, 8 });
|
|
int prev = daily.Count - 2;
|
|
daily.Lows[prev] = 100.0;
|
|
daily.Highs[prev] = 120.0;
|
|
daily.Closes[prev] = 101.0;
|
|
daily.TradeDirection = -1;
|
|
intent.Metadata["daily_bars"] = daily;
|
|
|
|
var result = calc.Calculate(intent, CreateContext(), CreateBar());
|
|
|
|
Assert.AreEqual(1.0, result.Score, 0.000001);
|
|
}
|
|
|
|
private static StrategyIntent CreateIntent()
|
|
{
|
|
return new StrategyIntent(
|
|
"ES",
|
|
OrderSide.Buy,
|
|
OrderType.Market,
|
|
null,
|
|
8,
|
|
16,
|
|
0.8,
|
|
"test",
|
|
new Dictionary<string, object>());
|
|
}
|
|
|
|
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<string, object>());
|
|
}
|
|
|
|
private static BarData CreateBar()
|
|
{
|
|
return new BarData("ES", DateTime.UtcNow, 5000, 5005, 4998, 5002, 1000, TimeSpan.FromMinutes(5));
|
|
}
|
|
|
|
private static DailyBarContext CreateDailyContext(double[] ranges)
|
|
{
|
|
DailyBarContext context = new DailyBarContext();
|
|
context.Count = ranges.Length;
|
|
context.Highs = new double[ranges.Length];
|
|
context.Lows = new double[ranges.Length];
|
|
context.Closes = new double[ranges.Length];
|
|
context.Opens = new double[ranges.Length];
|
|
context.Volumes = new long[ranges.Length];
|
|
|
|
for (int i = 0; i < ranges.Length; i++)
|
|
{
|
|
context.Lows[i] = 100.0;
|
|
context.Highs[i] = 100.0 + ranges[i];
|
|
context.Opens[i] = 100.0 + (ranges[i] * 0.25);
|
|
context.Closes[i] = 100.0 + (ranges[i] * 0.75);
|
|
context.Volumes[i] = 100000;
|
|
}
|
|
|
|
context.TodayOpen = context.Closes[Math.Max(0, context.Count - 2)] + 1.0;
|
|
context.BreakoutBarVolume = 1000.0;
|
|
context.AvgIntradayBarVolume = 1000.0;
|
|
context.TradeDirection = 1;
|
|
return context;
|
|
}
|
|
}
|
|
}
|