using Xunit; using Trady.Analysis.Indicator; using Trady.Core; using Trady.Core.Infrastructure; using System.Diagnostics.CodeAnalysis; namespace QuanTAlib; [SuppressMessage("Security", "SCS0005:Weak random number generator.", Justification = "Acceptable for tests")] public class TradyTests { private readonly TBarSeries bars; private readonly GbmFeed feed; private readonly Random rnd; private readonly double range; private readonly int iterations; private readonly int skip; private readonly IEnumerable Candles; public TradyTests() { rnd = new((int)DateTime.Now.Ticks); feed = new(sigma: 0.5, mu: 0.0); bars = new(feed); range = 1e-9; feed.Add(10000); iterations = 3; skip = 500; Candles = bars.Select(bar => new Candle( bar.Time, (decimal)bar.Open, (decimal)bar.High, (decimal)bar.Low, (decimal)bar.Close, (decimal)bar.Volume )).ToList(); } [Fact] public void SMA() { for (int run = 0; run < iterations; run++) { int period = rnd.Next(50) + 5; Sma ma = new(period); TSeries QL = new(); foreach (TBar item in feed) { QL.Add(ma.Calc(new TValue(item.Time, item.Close))); } var Trady = new SimpleMovingAverage(Candles, period) .Compute() .Select(result => new { Date = result.DateTime, Value = result.Tick.HasValue ? (double)result.Tick.Value : double.NaN }) .ToList(); Assert.Equal(QL.Length, Trady.Count); for (int i = QL.Length - 1; i > skip; i--) { double QL_item = QL[i].Value; double Tr_item = Trady[i].Value; Assert.InRange(Tr_item - QL_item, -range, range); } } } [Fact] public void EMA() { for (int run = 0; run < iterations; run++) { int period = rnd.Next(50) + 5; Ema ma = new(period); TSeries QL = new(); foreach (TBar item in feed) { QL.Add(ma.Calc(new TValue(item.Time, item.Close))); } var Trady = new ExponentialMovingAverage(Candles, period) .Compute() .Select(result => new { Date = result.DateTime, Value = result.Tick.HasValue ? (double)result.Tick.Value : double.NaN }) .ToList(); Assert.Equal(QL.Length, Trady.Count); for (int i = QL.Length - 1; i > skip * 2; i--) { double QL_item = QL[i].Value; double Tr_item = Trady[i].Value; Assert.InRange(Tr_item - QL_item, -range, range); } } } }