Files
Miha Kralj 060649192f 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
2026-03-12 12:34:16 -07:00

133 lines
4.4 KiB
C#

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);
}
}