using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; using NT8.Core.Common.Models; using NT8.Core.Indicators; namespace NT8.Core.Tests.Indicators { [TestClass] public class AVWAPCalculatorTests { [TestMethod] public void Constructor_InitializesWithAnchorMode() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); Assert.AreEqual(AVWAPAnchorMode.Day, calc.GetAnchorMode()); } [TestMethod] public void Calculate_NullBars_ThrowsArgumentNullException() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); Assert.ThrowsException(delegate { calc.Calculate(null, DateTime.UtcNow); }); } [TestMethod] public void Calculate_NoEligibleBars_ReturnsZero() { var anchor = DateTime.UtcNow; var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, anchor); var bars = new List(); bars.Add(new BarData("ES", anchor.AddMinutes(-2), 100, 101, 99, 100, 1000, TimeSpan.FromMinutes(1))); var value = calc.Calculate(bars, anchor); Assert.AreEqual(0.0, value, 0.000001); } [TestMethod] public void Calculate_SingleBar_ReturnsTypicalPrice() { var anchor = DateTime.UtcNow; var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, anchor); var bars = new List(); bars.Add(new BarData("ES", anchor, 100, 103, 97, 101, 10, TimeSpan.FromMinutes(1))); var value = calc.Calculate(bars, anchor); var expected = (103.0 + 97.0 + 101.0) / 3.0; Assert.AreEqual(expected, value, 0.000001); } [TestMethod] public void Calculate_MultipleBars_ReturnsVolumeWeightedValue() { var anchor = DateTime.UtcNow; var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, anchor); var bars = new List(); bars.Add(new BarData("ES", anchor, 100, 102, 98, 101, 10, TimeSpan.FromMinutes(1))); // typical 100.3333 bars.Add(new BarData("ES", anchor.AddMinutes(1), 101, 103, 99, 102, 30, TimeSpan.FromMinutes(1))); // typical 101.3333 var value = calc.Calculate(bars, anchor); var p1 = (102.0 + 98.0 + 101.0) / 3.0; var p2 = (103.0 + 99.0 + 102.0) / 3.0; var expected = ((p1 * 10.0) + (p2 * 30.0)) / 40.0; Assert.AreEqual(expected, value, 0.000001); } [TestMethod] public void Update_NegativeVolume_ThrowsArgumentException() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); Assert.ThrowsException(delegate { calc.Update(100.0, -1); }); } [TestMethod] public void Update_ThenGetCurrentValue_ReturnsWeightedAverage() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); calc.Update(100.0, 10); calc.Update(110.0, 30); var value = calc.GetCurrentValue(); var expected = ((100.0 * 10.0) + (110.0 * 30.0)) / 40.0; Assert.AreEqual(expected, value, 0.000001); } [TestMethod] public void GetSlope_InsufficientHistory_ReturnsZero() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); calc.Update(100.0, 10); var slope = calc.GetSlope(5); Assert.AreEqual(0.0, slope, 0.000001); } [TestMethod] public void GetSlope_WithHistory_ReturnsPositiveForRisingSeries() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); calc.Update(100.0, 10); calc.Update(101.0, 10); calc.Update(102.0, 10); calc.Update(103.0, 10); calc.Update(104.0, 10); calc.Update(105.0, 10); var slope = calc.GetSlope(3); Assert.IsTrue(slope > 0.0); } [TestMethod] public void ResetAnchor_ClearsAccumulation() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); calc.Update(100.0, 10); Assert.IsTrue(calc.GetCurrentValue() > 0.0); calc.ResetAnchor(DateTime.UtcNow.AddHours(1)); Assert.AreEqual(0.0, calc.GetCurrentValue(), 0.000001); } [TestMethod] public void SetAnchorMode_ChangesMode() { var calc = new AVWAPCalculator(AVWAPAnchorMode.Day, DateTime.UtcNow); calc.SetAnchorMode(AVWAPAnchorMode.Week); Assert.AreEqual(AVWAPAnchorMode.Week, calc.GetAnchorMode()); } } }