mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-29 10:07:43 +00:00
b3a64f18fa
- Added Ztest class to compute the one-sample t-statistic using sample standard deviation with Bessel correction. - Implemented validation tests for Ztest to ensure accuracy against manual calculations and PineScript. - Updated documentation for Ztest, detailing its mathematical foundation, performance profile, and common pitfalls. - Adjusted NDepend badges to reflect changes in code metrics after implementation. - Updated missing indicators report to reflect the completion of statistical indicators, including ZTEST.
77 lines
2.6 KiB
C#
77 lines
2.6 KiB
C#
namespace QuanTAlib.Validation;
|
|
|
|
/// <summary>
|
|
/// Mode validation tests — self-consistency only.
|
|
/// No external library provides rolling mode calculations.
|
|
/// </summary>
|
|
public sealed class ModeValidationTests
|
|
{
|
|
[Fact]
|
|
public void Mode_SelfConsistency_KnownValues()
|
|
{
|
|
// Test with known mode values
|
|
// {1, 2, 2, 3, 3, 3, 4, 4, 4, 4} → mode = 4 (appears 4 times)
|
|
var mode = new Mode(10);
|
|
mode.Update(new TValue(DateTime.UtcNow, 1));
|
|
mode.Update(new TValue(DateTime.UtcNow, 2));
|
|
mode.Update(new TValue(DateTime.UtcNow, 2));
|
|
mode.Update(new TValue(DateTime.UtcNow, 3));
|
|
mode.Update(new TValue(DateTime.UtcNow, 3));
|
|
mode.Update(new TValue(DateTime.UtcNow, 3));
|
|
mode.Update(new TValue(DateTime.UtcNow, 4));
|
|
mode.Update(new TValue(DateTime.UtcNow, 4));
|
|
mode.Update(new TValue(DateTime.UtcNow, 4));
|
|
var result = mode.Update(new TValue(DateTime.UtcNow, 4));
|
|
|
|
Assert.Equal(4, result.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void Mode_BatchAndStreaming_Match()
|
|
{
|
|
// Use data with known repeated values
|
|
double[] data = [10, 20, 20, 30, 30, 30, 40, 20, 20, 20, 10, 10, 30, 30, 30];
|
|
int period = 5;
|
|
|
|
// Streaming
|
|
var mode = new Mode(period);
|
|
var streamingResults = new double[data.Length];
|
|
for (int i = 0; i < data.Length; i++)
|
|
{
|
|
streamingResults[i] = mode.Update(new TValue(DateTime.UtcNow, data[i])).Value;
|
|
}
|
|
|
|
// Batch via spans
|
|
var spanOutput = new double[data.Length];
|
|
Mode.Batch(data.AsSpan(), spanOutput.AsSpan(), period);
|
|
|
|
for (int i = 0; i < data.Length; i++)
|
|
{
|
|
if (double.IsNaN(streamingResults[i]))
|
|
{
|
|
Assert.True(double.IsNaN(spanOutput[i]), $"Index {i}: streaming=NaN but span={spanOutput[i]}");
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal(streamingResults[i], spanOutput[i], precision: 10);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Mode_MatchesWolframAlpha()
|
|
{
|
|
// Wolfram Alpha: mode of {1, 2, 2, 3, 3, 3, 4} = {3}
|
|
var mode = new Mode(7);
|
|
mode.Update(new TValue(DateTime.UtcNow, 1));
|
|
mode.Update(new TValue(DateTime.UtcNow, 2));
|
|
mode.Update(new TValue(DateTime.UtcNow, 2));
|
|
mode.Update(new TValue(DateTime.UtcNow, 3));
|
|
mode.Update(new TValue(DateTime.UtcNow, 3));
|
|
mode.Update(new TValue(DateTime.UtcNow, 3));
|
|
var result = mode.Update(new TValue(DateTime.UtcNow, 4));
|
|
|
|
Assert.Equal(3, result.Value);
|
|
}
|
|
}
|