mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-23 04:58:08 +00:00
Refactor validation tests for various indicators to utilize shared test data structure
This commit is contained in:
@@ -1,56 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OoplesFinance.StockIndicators;
|
||||
using OoplesFinance.StockIndicators.Models;
|
||||
using Skender.Stock.Indicators;
|
||||
using Xunit;
|
||||
|
||||
namespace QuanTAlib.Tests;
|
||||
|
||||
public class RmaValidationTests
|
||||
public class RmaValidationTests : IDisposable
|
||||
{
|
||||
private readonly ValidationTestData _testData;
|
||||
private bool _disposed;
|
||||
|
||||
public RmaValidationTests()
|
||||
{
|
||||
_testData = new ValidationTestData(count: 1000, seed: 123);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_testData.Dispose();
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Rma_Matches_Skender_Smma()
|
||||
{
|
||||
// Arrange
|
||||
int period = 14;
|
||||
int length = 1000;
|
||||
var gbm = new GBM(startPrice: 100.0, mu: 0.05, sigma: 0.2, seed: 123);
|
||||
var bars = gbm.Fetch(length, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1));
|
||||
|
||||
// QuanTAlib RMA
|
||||
var rma = new Rma(period);
|
||||
var quantalibResults = new TSeries();
|
||||
foreach (var bar in bars)
|
||||
foreach (var item in _testData.Data)
|
||||
{
|
||||
quantalibResults.Add(rma.Update(new TValue(bar.Time, bar.Close)));
|
||||
quantalibResults.Add(rma.Update(item));
|
||||
}
|
||||
|
||||
// Skender SMMA
|
||||
var quotes = bars.Select(b => new Quote
|
||||
{
|
||||
Date = new DateTime(b.Time, DateTimeKind.Utc),
|
||||
Open = (decimal)b.Open,
|
||||
High = (decimal)b.High,
|
||||
Low = (decimal)b.Low,
|
||||
Close = (decimal)b.Close,
|
||||
Volume = (decimal)b.Volume
|
||||
}).ToList();
|
||||
|
||||
var skenderResults = quotes.GetSmma(period).ToList();
|
||||
var skenderResults = _testData.SkenderQuotes.GetSmma(period).ToList();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(quantalibResults.Count, skenderResults.Count);
|
||||
|
||||
// Skip warmup period for comparison
|
||||
// Skender uses SMA initialization, QuanTAlib uses zero-lag compensator
|
||||
// They should converge after some periods
|
||||
int skip = period * 20;
|
||||
int skip = period * 30;
|
||||
|
||||
for (int i = skip; i < length; i++)
|
||||
int itemsToVerify = _testData.Data.Count - skip;
|
||||
ValidationHelper.VerifyData(quantalibResults, skenderResults, (s) => s.Smma, skip: itemsToVerify, tolerance: 1e-4);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_Against_Ooples()
|
||||
{
|
||||
// Arrange
|
||||
int period = 14;
|
||||
|
||||
// QuanTAlib RMA
|
||||
var rma = new Rma(period);
|
||||
var qResult = rma.Update(_testData.Data);
|
||||
|
||||
// Ooples WWMA (Welles Wilder Moving Average)
|
||||
var ooplesData = _testData.SkenderQuotes.Select(q => new TickerData
|
||||
{
|
||||
double qValue = quantalibResults[i].Value;
|
||||
double? sValue = skenderResults[i].Smma;
|
||||
Date = q.Date,
|
||||
Close = (double)q.Close,
|
||||
High = (double)q.High,
|
||||
Low = (double)q.Low,
|
||||
Open = (double)q.Open,
|
||||
Volume = (double)q.Volume
|
||||
}).ToList();
|
||||
|
||||
if (sValue.HasValue)
|
||||
{
|
||||
Assert.Equal(sValue.Value, qValue, 1e-6);
|
||||
}
|
||||
}
|
||||
var stockData = new StockData(ooplesData);
|
||||
var oResult = stockData.CalculateWellesWilderMovingAverage(length: period);
|
||||
var oValues = oResult.OutputValues["Wwma"];
|
||||
|
||||
// Assert
|
||||
// Skip warmup period for comparison
|
||||
int skip = period * 30;
|
||||
int itemsToVerify = _testData.Data.Count - skip;
|
||||
|
||||
ValidationHelper.VerifyData(qResult, oValues, (s) => s, skip: itemsToVerify, tolerance: 5e-4);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user