mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-26 06:18:05 +00:00
docs: remove C# Implementation Considerations sections, clean up temp scripts, reorganize test files
- Remove 'C# Implementation Considerations' sections from 34 indicator .md files - Delete 29 temp PowerShell scripts (_fix_mojibake.ps1, _hex_scan.ps1, etc.) - Move test files into tests/ subdirectories for consistent project structure - Add trader-focused bullet points to indicator documentation
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace QuanTAlib;
|
||||
|
||||
public class StcTests
|
||||
{
|
||||
private const int CycleLength = 12;
|
||||
private const int FastLength = 26;
|
||||
private const int SlowLength = 50;
|
||||
|
||||
private static Stc CreateDefaultStc() => new(kPeriod: CycleLength, dPeriod: CycleLength, fastLength: FastLength, slowLength: SlowLength, smoothing: StcSmoothing.Sigmoid);
|
||||
|
||||
[Fact]
|
||||
public void Constructor_ValidatesInput()
|
||||
{
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => new Stc(kPeriod: 1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => new Stc(dPeriod: 0));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => new Stc(fastLength: 1));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => new Stc(slowLength: 1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Calc_ReturnsValue()
|
||||
{
|
||||
var stc = CreateDefaultStc();
|
||||
var result = stc.Update(new TValue(DateTime.UtcNow, 100));
|
||||
// Expect NaN during warmup
|
||||
Assert.True(double.IsNaN(result.Value) || double.IsFinite(result.Value));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Properties_Accessible()
|
||||
{
|
||||
var stc = CreateDefaultStc();
|
||||
Assert.Equal(0, stc.Last.Value); // Initial value before updates
|
||||
Assert.False(stc.IsHot);
|
||||
Assert.Contains("Stc", stc.Name, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsHot_BecomesTrueWhenBufferFull()
|
||||
{
|
||||
var stc = CreateDefaultStc();
|
||||
int warmup = stc.WarmupPeriod;
|
||||
|
||||
for (int i = 0; i < warmup - 1; i++)
|
||||
{
|
||||
stc.Update(new TValue(DateTime.UtcNow, 100));
|
||||
Assert.False(stc.IsHot);
|
||||
}
|
||||
|
||||
stc.Update(new TValue(DateTime.UtcNow, 100));
|
||||
Assert.True(stc.IsHot);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BatchCalc_MatchesIterativeCalc()
|
||||
{
|
||||
var iterativeStc = CreateDefaultStc();
|
||||
var batchStc = CreateDefaultStc();
|
||||
var series = new TSeries();
|
||||
var gbm = new GBM(startPrice: 100, mu: 0.05, sigma: 0.2, seed: 123);
|
||||
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
var bar = gbm.Next();
|
||||
series.Add(bar.Time, bar.Close);
|
||||
iterativeStc.Update(new TValue(bar.Time, bar.Close));
|
||||
}
|
||||
|
||||
var batchResult = batchStc.Update(series);
|
||||
|
||||
Assert.Equal(iterativeStc.Last.Value, batchResult.Last.Value, 1e-9);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SpanBatch_MatchesTSeriesBatch()
|
||||
{
|
||||
// Use default parameters for static calculation
|
||||
var series = new TSeries();
|
||||
var gbm = new GBM(startPrice: 100, mu: 0.05, sigma: 0.2, seed: 123);
|
||||
double[] input = new double[200];
|
||||
double[] output = new double[200];
|
||||
|
||||
for (int i = 0; i < 200; i++)
|
||||
{
|
||||
var bar = gbm.Next();
|
||||
series.Add(bar.Time, bar.Close);
|
||||
input[i] = bar.Close;
|
||||
}
|
||||
|
||||
var batchStc = CreateDefaultStc();
|
||||
var tseriesResult = batchStc.Update(series);
|
||||
|
||||
Stc.Batch(input.AsSpan(), output.AsSpan(), kPeriod: CycleLength, dPeriod: CycleLength, fastLength: FastLength, slowLength: SlowLength, smoothing: StcSmoothing.Sigmoid);
|
||||
|
||||
// Compare last value
|
||||
Assert.Equal(tseriesResult.Last.Value, output[^1], 1e-9);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NaN_Input_HandledSafely()
|
||||
{
|
||||
var stc = CreateDefaultStc();
|
||||
stc.Update(new TValue(DateTime.UtcNow, 100));
|
||||
var result = stc.Update(new TValue(DateTime.UtcNow, double.NaN));
|
||||
// Should be NaN during warmup
|
||||
Assert.True(double.IsNaN(result.Value) || double.IsFinite(result.Value));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SmoothingOptions_ProduceDifferentResults()
|
||||
{
|
||||
var stcSigmoid = new Stc(kPeriod: 10, dPeriod: 10, fastLength: 20, slowLength: 40, smoothing: StcSmoothing.Sigmoid);
|
||||
var stcEma = new Stc(kPeriod: 10, dPeriod: 10, fastLength: 20, slowLength: 40, smoothing: StcSmoothing.Ema);
|
||||
var stcDigital = new Stc(kPeriod: 10, dPeriod: 10, fastLength: 20, slowLength: 40, smoothing: StcSmoothing.Digital);
|
||||
|
||||
var gbm = new GBM(startPrice: 100, mu: 0.05, sigma: 0.2, seed: 123);
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
double val = gbm.Next().Close;
|
||||
stcSigmoid.Update(new TValue(DateTime.UtcNow, val));
|
||||
stcEma.Update(new TValue(DateTime.UtcNow, val));
|
||||
stcDigital.Update(new TValue(DateTime.UtcNow, val));
|
||||
}
|
||||
|
||||
Assert.NotEqual(stcSigmoid.Last.Value, stcEma.Last.Value);
|
||||
Assert.NotEqual(stcSigmoid.Last.Value, stcDigital.Last.Value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user