Dpo chart + refactored tests

This commit is contained in:
Miha Kralj
2024-11-07 09:55:19 -08:00
parent a0ffd952af
commit 69aef2b127
8 changed files with 416 additions and 864 deletions
+4
View File
@@ -46,6 +46,10 @@
<ProjectReference Include="..\quantower\Volatility\_Volatility.csproj" Aliases="volatility" /> <ProjectReference Include="..\quantower\Volatility\_Volatility.csproj" Aliases="volatility" />
<ProjectReference Include="..\quantower\Averages\_Averages.csproj" Aliases="averages" /> <ProjectReference Include="..\quantower\Averages\_Averages.csproj" Aliases="averages" />
<ProjectReference Include="..\quantower\Statistics\_Statistics.csproj" Aliases="statistics" /> <ProjectReference Include="..\quantower\Statistics\_Statistics.csproj" Aliases="statistics" />
<ProjectReference Include="..\quantower\Momentum\_Momentum.csproj" Aliases="momentum" />
<ProjectReference Include="..\quantower\Oscillators\_Oscillators.csproj" Aliases="oscillators" />
<ProjectReference Include="..\quantower\Volume\_Volume.csproj" Aliases="volume" />
<ProjectReference Include="..\quantower\Experiments\_Experiments.csproj" Aliases="experiments" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+91
View File
@@ -0,0 +1,91 @@
using Xunit;
using System.Security.Cryptography;
namespace QuanTAlib.Tests;
public abstract class UpdateTestBase
{
protected readonly RandomNumberGenerator rng = RandomNumberGenerator.Create();
protected const int RandomUpdates = 100;
protected const double ReferenceValue = 100.0;
protected const int precision = 8;
protected double GetRandomDouble()
{
byte[] bytes = new byte[8];
rng.GetBytes(bytes);
return ((double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue * 200) - 100; // Range: -100 to 100
}
protected TBar GetRandomBar(bool IsNew)
{
double open = GetRandomDouble();
double high = open + Math.Abs(GetRandomDouble());
double low = open - Math.Abs(GetRandomDouble());
double close = low + ((high - low) * GetRandomDouble());
return new TBar(DateTime.Now, open, high, low, close, 1000, IsNew);
}
protected void TestTValueUpdate<T>(T indicator, Func<TValue, TValue> calc) where T : class
{
var initialValue = calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true));
for (int i = 0; i < RandomUpdates; i++)
{
calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
var finalValue = calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue.Value, finalValue.Value, precision);
}
protected void TestTBarUpdate<T>(T indicator, Func<TBar, TValue> calc) where T : class
{
TBar r = GetRandomBar(true);
var initialValue = calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
calc(GetRandomBar(IsNew: false));
}
var finalValue = calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue.Value, finalValue.Value, precision);
}
protected void TestDualTValueUpdate<T>(T indicator, Func<TValue, TValue, TValue> calc) where T : class
{
var initialValue = calc(
new TValue(DateTime.Now, ReferenceValue, IsNew: true),
new TValue(DateTime.Now, ReferenceValue, IsNew: true));
for (int i = 0; i < RandomUpdates; i++)
{
calc(
new TValue(DateTime.Now, GetRandomDouble(), IsNew: false),
new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
var finalValue = calc(
new TValue(DateTime.Now, ReferenceValue, IsNew: false),
new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue.Value, finalValue.Value, precision);
}
protected void TestDualTBarUpdate<T>(T indicator, Func<TBar, TBar, TValue> calc) where T : class
{
TBar bar1 = GetRandomBar(true);
TBar bar2 = GetRandomBar(true);
var initialValue = calc(bar1, bar2);
for (int i = 0; i < RandomUpdates; i++)
{
calc(GetRandomBar(false), GetRandomBar(false));
}
var finalValue = calc(
new TBar(bar1.Time, bar1.Open, bar1.High, bar1.Low, bar1.Close, bar1.Volume, false),
new TBar(bar2.Time, bar2.Open, bar2.High, bar2.Low, bar2.Close, bar2.Volume, false));
Assert.Equal(initialValue.Value, finalValue.Value, precision);
}
}
+164 -159
View File
@@ -1,172 +1,112 @@
using Xunit; using Xunit;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Reflection;
#pragma warning disable S1944, S2053, S2222, S2259, S2583, S2589, S3329, S3655, S3900, S3949, S3966, S4158, S4347, S5773, S6781 namespace QuanTAlib.Tests;
namespace QuanTAlib;
public class EventingTests public class EventingTests
{ {
[Fact] private const int TestDataPoints = 200;
public void EventBasedCalculations() private const int DefaultPeriod = 10;
private const double Tolerance = 1e-9;
private static readonly (string Name, object[] DirectParams, object[] EventParams)[] ValueIndicators = new[]
{ {
// Create a cryptographically secure random number generator ("Afirma", new object[] { DefaultPeriod, DefaultPeriod, Afirma.WindowType.BlackmanHarris }, new object[] { new TSeries(), DefaultPeriod, DefaultPeriod, Afirma.WindowType.BlackmanHarris }),
using var rng = RandomNumberGenerator.Create(); ("Alma", new object[] { DefaultPeriod, 0.85, 6.0 }, new object[] { new TSeries(), DefaultPeriod, 0.85, 6.0 }),
("Convolution", new object[] { new double[] {1,2,3,2,1} }, new object[] { new TSeries(), new double[] {1,2,3,2,1} }),
("Dema", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Dsma", new object[] { DefaultPeriod, 0.9 }, new object[] { new TSeries(), DefaultPeriod, 0.9 }),
("Dwma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Ema", new object[] { DefaultPeriod, true }, new object[] { new TSeries(), DefaultPeriod, true }),
("Epma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Pwma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Frama", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Fwma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Gma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Hma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Htit", new object[] { }, new object[] { new TSeries() }),
("Hwma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Jma", new object[] { DefaultPeriod, 0, 0.45, 10 }, new object[] { new TSeries(), DefaultPeriod, 0, 0.45, 10 }),
("Kama", new object[] { DefaultPeriod, 2, 30 }, new object[] { new TSeries(), DefaultPeriod, 2, 30 }),
("Ltma", new object[] { 0.2 }, new object[] { new TSeries(), 0.2 }),
("Maaf", new object[] { 39, 0.002 }, new object[] { new TSeries(), 39, 0.002 }),
("Mama", new object[] { 0.5, 0.05 }, new object[] { new TSeries(), 0.5, 0.05 }),
("Mgdi", new object[] { DefaultPeriod, 0.6 }, new object[] { new TSeries(), DefaultPeriod, 0.6 }),
("Mma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Qema", new object[] { 0.2, 0.2, 0.2, 0.2 }, new object[] { new TSeries(), 0.2, 0.2, 0.2, 0.2 }),
("Rema", new object[] { DefaultPeriod, 0.5 }, new object[] { new TSeries(), DefaultPeriod, 0.5 }),
("Rma", new object[] { DefaultPeriod, true }, new object[] { new TSeries(), DefaultPeriod, true }),
("Sma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Wma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Tema", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Zlema", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Sinema", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Smma", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("T3", new object[] { DefaultPeriod, 0.7, true }, new object[] { new TSeries(), DefaultPeriod, 0.7, true }),
("Trima", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Vidya", new object[] { DefaultPeriod, 0, 0.2 }, new object[] { new TSeries(), DefaultPeriod, 0, 0.2 }),
("Apo", new object[] { 12, 26 }, new object[] { new TSeries(), 12, 26 }),
("Macd", new object[] { 12, 26, 9 }, new object[] { new TSeries(), 12, 26, 9 }),
("Rsi", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Rsx", new object[] { DefaultPeriod, 0, 0.55 }, new object[] { new TSeries(), DefaultPeriod, 0, 0.55 }),
("Cmo", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Cog", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Curvature", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Entropy", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Kurtosis", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Max", new object[] { DefaultPeriod, 0.0 }, new object[] { new TSeries(), DefaultPeriod, 0.0 }),
("Median", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Min", new object[] { DefaultPeriod, 0.0 }, new object[] { new TSeries(), DefaultPeriod, 0.0 }),
("Mode", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Percentile", new object[] { DefaultPeriod, 0.5 }, new object[] { new TSeries(), DefaultPeriod, 0.5 }),
("Skew", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Slope", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Stddev", new object[] { DefaultPeriod, false }, new object[] { new TSeries(), DefaultPeriod, false }),
("Variance", new object[] { DefaultPeriod, false }, new object[] { new TSeries(), DefaultPeriod, false }),
("Zscore", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Beta", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Corr", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Hv", new object[] { DefaultPeriod, false }, new object[] { new TSeries(), DefaultPeriod, false }),
("Jvolty", new object[] { DefaultPeriod, 0 }, new object[] { new TSeries(), DefaultPeriod, 0 }),
("Rv", new object[] { DefaultPeriod, false }, new object[] { new TSeries(), DefaultPeriod, false }),
("Rvi", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Mae", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Mapd", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Mape", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Mase", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Mda", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Me", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Mpe", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Mse", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Msle", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Rae", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Rmse", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Rmsle", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Rse", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Smape", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Rsquared", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }),
("Huber", new object[] { DefaultPeriod, 1.0 }, new object[] { new TSeries(), DefaultPeriod, 1.0 })
};
// Create input series to hold our random values private static readonly (string Name, object[] DirectParams, object[] EventParams)[] BarIndicators = new[]
var input = new TSeries(); {
var barInput = new TBarSeries(); ("Adl", new object[] { }, new object[] { new TBarSeries() }),
int p = 10; ("Adosc", new object[] { 3, 10 }, new object[] { new TBarSeries(), 3, 10 }),
("Aobv", new object[] { }, new object[] { new TBarSeries() }),
("Cmf", new object[] { 20 }, new object[] { new TBarSeries(), 20 }),
("Eom", new object[] { 14 }, new object[] { new TBarSeries(), 14 }),
("Kvo", new object[] { 34, 55 }, new object[] { new TBarSeries(), 34, 55 }),
("Atr", new object[] { 14 }, new object[] { new TBarSeries(), 14 }),
("Chop", new object[] { 14 }, new object[] { new TBarSeries(), 14 }),
("Dosc", new object[] { }, new object[] { new TBarSeries() })
};
// Create a list of value-based indicator pairs public static IEnumerable<object[]> GetValueIndicatorData()
var valueIndicators = new List<(string Name, AbstractBase Direct, AbstractBase EventBased)> => ValueIndicators.Select(x => new object[] { x.Name, x.DirectParams, x.EventParams });
{
("Afirma", new Afirma(p,p,Afirma.WindowType.BlackmanHarris), new Afirma(input, p,p,Afirma.WindowType.BlackmanHarris)),
("Alma", new Alma(p), new Alma(input, p)),
("Convolution", new Convolution(new double[] {1,2,3,2,1}), new Convolution(input, new double[] {1,2,3,2,1})),
("Dema", new Dema(p), new Dema(input, p)),
("Dsma", new Dsma(p), new Dsma(input, p)),
("Dwma", new Dwma(p), new Dwma(input, p)),
("Ema", new Ema(p), new Ema(input, p)),
("Epma", new Epma(p), new Epma(input, p)),
("Pwma", new Pwma(p), new Pwma(input, p)),
("Frama", new Frama(p), new Frama(input, p)),
("Fwma", new Fwma(p), new Fwma(input, p)),
("Gma", new Gma(p), new Gma(input, p)),
("Hma", new Hma(p), new Hma(input, p)),
("Htit", new Htit(), new Htit(input)),
("Hwma", new Hwma(p), new Hwma(input, p)),
("Jma", new Jma(p), new Jma(input, p)),
("Kama", new Kama(p), new Kama(input, p)),
("Ltma", new Ltma(gamma: 0.2), new Ltma(input, gamma: 0.2)),
("Maaf", new Maaf(p), new Maaf(input, p)),
("Mama", new Mama(p), new Mama(input, p)),
("Mgdi", new Mgdi(p, kFactor: 0.6), new Mgdi(input, p, kFactor: 0.6)),
("Mma", new Mma(p), new Mma(input, p)),
("Qema", new Qema(k1: 0.2, k2: 0.2, k3: 0.2, k4: 0.2), new Qema(input, k1: 0.2, k2: 0.2, k3: 0.2, k4: 0.2)),
("Rema", new Rema(p), new Rema(input, p)),
("Rma", new Rma(p), new Rma(input, p)),
("Sma", new Sma(p), new Sma(input, p)),
("Wma", new Wma(p), new Wma(input, p)),
("Rma", new Rma(p), new Rma(input, p)),
("Tema", new Tema(p), new Tema(input, p)),
("Kama", new Kama(2, 30, 6), new Kama(input, 2, 30, 6)),
("Zlema", new Zlema(p), new Zlema(input, p)),
("Sinema", new Sinema(p), new Sinema(input, p)),
("Smma", new Smma(p), new Smma(input, p)),
("T3", new T3(p), new T3(input, p)),
("Trima", new Trima(p), new Trima(input, p)),
("Vidya", new Vidya(p), new Vidya(input, p)),
("Apo", new Apo(12, 26), new Apo(input, 12, 26)),
("Macd", new Macd(12, 26, 9), new Macd(input, 12, 26, 9)),
("Rsi", new Rsi(p), new Rsi(input, p)),
("Rsx", new Rsx(p), new Rsx(input, p)),
("Cmo", new Cmo(p), new Cmo(input, p)),
("Cog", new Cog(p), new Cog(input, p)),
("Curvature", new Curvature(p), new Curvature(input, p)),
("Entropy", new Entropy(p), new Entropy(input, p)),
("Kurtosis", new Kurtosis(p), new Kurtosis(input, p)),
("Max", new Max(p), new Max(input, p)),
("Median", new Median(p), new Median(input, p)),
("Min", new Min(p), new Min(input, p)),
("Mode", new Mode(p), new Mode(input, p)),
("Percentile", new Percentile(p, 0.5), new Percentile(input, p, 0.5)),
("Skew", new Skew(p), new Skew(input, p)),
("Slope", new Slope(p), new Slope(input, p)),
("Stddev", new Stddev(p), new Stddev(input, p)),
("Variance", new Variance(p), new Variance(input, p)),
("Zscore", new Zscore(p), new Zscore(input, p)),
("Beta", new Beta(p), new Beta(input, p)),
("Corr", new Corr(p), new Corr(input, p)),
// Volatility indicators (value-based)
("Hv", new Hv(p), new Hv(input, p)),
("Jvolty", new Jvolty(p), new Jvolty(input, p)),
("Rv", new Rv(p), new Rv(input, p)),
("Rvi", new Rvi(p), new Rvi(input, p)),
// Error classes
("Mae", new Mae(p), new Mae(input, p)),
("Mapd", new Mapd(p), new Mapd(input, p)),
("Mape", new Mape(p), new Mape(input, p)),
("Mase", new Mase(p), new Mase(input, p)),
("Mda", new Mda(p), new Mda(input, p)),
("Me", new Me(p), new Me(input, p)),
("Mpe", new Mpe(p), new Mpe(input, p)),
("Mse", new Mse(p), new Mse(input, p)),
("Msle", new Msle(p), new Msle(input, p)),
("Rae", new Rae(p), new Rae(input, p)),
("Rmse", new Rmse(p), new Rmse(input, p)),
("Rmsle", new Rmsle(p), new Rmsle(input, p)),
("Rse", new Rse(p), new Rse(input, p)),
("Smape", new Smape(p), new Smape(input, p)),
("Rsquared", new Rsquared(p), new Rsquared(input, p)),
("Huber", new Huber(p), new Huber(input, p))
};
// Create a list of bar-based indicator pairs public static IEnumerable<object[]> GetBarIndicatorData()
var barIndicators = new List<(string Name, AbstractBase Direct, AbstractBase EventBased)> => BarIndicators.Select(x => new object[] { x.Name, x.DirectParams, x.EventParams });
{
// Volume indicators
("Adl", new Adl(), new Adl(barInput)),
("Adosc", new Adosc(3, 10), new Adosc(barInput, 3, 10)),
("Aobv", new Aobv(), new Aobv(barInput)),
("Cmf", new Cmf(20), new Cmf(barInput, 20)),
("Eom", new Eom(14), new Eom(barInput, 14)),
("Kvo", new Kvo(34, 55), new Kvo(barInput, 34, 55)),
// Volatility indicators (bar-based)
("Atr", new Atr(14), new Atr(barInput, 14)),
// Oscillators (bar-based)
("Chop", new Chop(14), new Chop(barInput, 14)),
("Dosc", new Dosc(), new Dosc(barInput))
};
// Generate 200 random values and feed them to indicators
for (int i = 0; i < 200; i++)
{
// Generate random value for value-based indicators
double randomValue = GetRandomDouble(rng) * 100;
input.Add(randomValue);
// Calculate value-based indicators
foreach (var (_, direct, _) in valueIndicators)
{
direct.Calc(randomValue);
}
// Generate random bar for bar-based indicators
var bar = new TBar(
DateTime.Now,
randomValue,
randomValue + Math.Abs(GetRandomDouble(rng) * 10),
randomValue - Math.Abs(GetRandomDouble(rng) * 10),
randomValue + (GetRandomDouble(rng) * 5),
Math.Abs(GetRandomDouble(rng) * 1000),
true
);
barInput.Add(bar);
// Calculate bar-based indicators
foreach (var (_, direct, _) in barIndicators)
{
direct.Calc(bar);
}
}
// Compare the results for value-based indicators
foreach (var (name, direct, eventBased) in valueIndicators)
{
bool areEqual = (double.IsNaN(direct.Value) && double.IsNaN(eventBased.Value)) ||
Math.Abs(direct.Value - eventBased.Value) < 1e-9;
Assert.True(areEqual, $"Value indicator {name} failed: Expected {direct.Value}, Actual {eventBased.Value}");
}
// Compare the results for bar-based indicators
foreach (var (name, direct, eventBased) in barIndicators)
{
bool areEqual = (double.IsNaN(direct.Value) && double.IsNaN(eventBased.Value)) ||
Math.Abs(direct.Value - eventBased.Value) < 1e-9;
Assert.True(areEqual, $"Bar indicator {name} failed: Expected {direct.Value}, Actual {eventBased.Value}");
}
}
private static double GetRandomDouble(RandomNumberGenerator rng) private static double GetRandomDouble(RandomNumberGenerator rng)
{ {
@@ -174,4 +114,69 @@ public class EventingTests
rng.GetBytes(bytes); rng.GetBytes(bytes);
return (double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue; return (double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue;
} }
private static TBar GenerateRandomBar(RandomNumberGenerator rng, double baseValue)
{
return new TBar(
DateTime.Now,
baseValue,
baseValue + Math.Abs(GetRandomDouble(rng) * 10),
baseValue - Math.Abs(GetRandomDouble(rng) * 10),
baseValue + (GetRandomDouble(rng) * 5),
Math.Abs(GetRandomDouble(rng) * 1000),
true
);
}
[Theory]
[MemberData(nameof(GetValueIndicatorData))]
public void ValueIndicatorEventTest(string indicatorName, object[] directParams, object[] eventParams)
{
using var rng = RandomNumberGenerator.Create();
var input = (TSeries)eventParams[0];
// Create indicator instances using reflection
var indicatorType = Type.GetType($"QuanTAlib.{indicatorName}, QuanTAlib")!;
var directIndicator = (AbstractBase)Activator.CreateInstance(indicatorType, directParams)!;
var eventIndicator = (AbstractBase)Activator.CreateInstance(indicatorType, eventParams)!;
// Generate test data and calculate
for (int i = 0; i < TestDataPoints; i++)
{
double randomValue = GetRandomDouble(rng) * 100;
input.Add(randomValue);
directIndicator.Calc(randomValue);
}
bool areEqual = (double.IsNaN(directIndicator.Value) && double.IsNaN(eventIndicator.Value)) ||
Math.Abs(directIndicator.Value - eventIndicator.Value) < Tolerance;
Assert.True(areEqual, $"Value indicator {indicatorName} failed: Expected {directIndicator.Value}, Actual {eventIndicator.Value}");
}
[Theory]
[MemberData(nameof(GetBarIndicatorData))]
public void BarIndicatorEventTest(string indicatorName, object[] directParams, object[] eventParams)
{
using var rng = RandomNumberGenerator.Create();
var barInput = (TBarSeries)eventParams[0];
// Create indicator instances using reflection
var indicatorType = Type.GetType($"QuanTAlib.{indicatorName}, QuanTAlib")!;
var directIndicator = (AbstractBase)Activator.CreateInstance(indicatorType, directParams)!;
var eventIndicator = (AbstractBase)Activator.CreateInstance(indicatorType, eventParams)!;
// Generate test data and calculate
for (int i = 0; i < TestDataPoints; i++)
{
var bar = GenerateRandomBar(rng, GetRandomDouble(rng) * 100);
barInput.Add(bar);
directIndicator.Calc(bar);
}
bool areEqual = (double.IsNaN(directIndicator.Value) && double.IsNaN(eventIndicator.Value)) ||
Math.Abs(directIndicator.Value - eventIndicator.Value) < Tolerance;
Assert.True(areEqual, $"Bar indicator {indicatorName} failed: Expected {directIndicator.Value}, Actual {eventIndicator.Value}");
}
} }
+54 -1
View File
@@ -1,6 +1,10 @@
extern alias volatility; extern alias volatility;
extern alias averages; extern alias averages;
extern alias statistics; extern alias statistics;
extern alias momentum;
extern alias oscillators;
extern alias volume;
extern alias experiments;
using Xunit; using Xunit;
using System.Reflection; using System.Reflection;
@@ -8,6 +12,10 @@ using TradingPlatform.BusinessLayer;
using statistics::QuanTAlib; using statistics::QuanTAlib;
using averages::QuanTAlib; using averages::QuanTAlib;
using volatility::QuanTAlib; using volatility::QuanTAlib;
using momentum::QuanTAlib;
using oscillators::QuanTAlib;
using volume::QuanTAlib;
using experiments::QuanTAlib;
namespace QuanTAlib namespace QuanTAlib
{ {
@@ -43,6 +51,39 @@ namespace QuanTAlib
} }
} }
private static void TestIndicatorMultipleFields<T>(string[] fieldNames) where T : Indicator, new()
{
var indicator = new T();
try
{
var onInitMethod = typeof(T).GetMethod("OnInit", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(onInitMethod);
onInitMethod.Invoke(indicator, null);
var onUpdateMethod = typeof(T).GetMethod("OnUpdate", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(onUpdateMethod);
foreach (var fieldName in fieldNames)
{
var field = typeof(T).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(field);
var fieldValue = field.GetValue(indicator);
Assert.NotNull(fieldValue);
}
Assert.NotNull(indicator.ShortName);
Assert.NotEmpty(indicator.ShortName);
Assert.NotNull(indicator.Name);
Assert.NotEmpty(indicator.Name);
Assert.NotNull(indicator.Description);
Assert.NotEmpty(indicator.Description);
Assert.IsAssignableFrom<Indicator>(indicator);
}
catch (Exception ex)
{
throw new Xunit.Sdk.XunitException($"Test failed for {typeof(T).Name}: {ex.Message}");
}
}
// Averages Indicators // Averages Indicators
[Fact] public void Afirma() => TestIndicator<AfirmaIndicator>(); [Fact] public void Afirma() => TestIndicator<AfirmaIndicator>();
[Fact] public void Alma() => TestIndicator<AlmaIndicator>(); [Fact] public void Alma() => TestIndicator<AlmaIndicator>();
@@ -95,9 +136,21 @@ namespace QuanTAlib
// Volatility Indicators // Volatility Indicators
[Fact] public void Atr() => TestIndicator<AtrIndicator>("atr"); [Fact] public void Atr() => TestIndicator<AtrIndicator>("atr");
[Fact] public void Cmo() => TestIndicator<CmoIndicator>("cmo");
[Fact] public void Cvi() => TestIndicator<CviIndicator>("cvi");
[Fact] public void Historical() => TestIndicator<HistoricalIndicator>("historical"); [Fact] public void Historical() => TestIndicator<HistoricalIndicator>("historical");
[Fact] public void Jbands() => TestIndicatorMultipleFields<JbandsIndicator>(new[] { "jmaUp", "jmaLo" });
[Fact] public void Jvolty() => TestIndicator<JvoltyIndicator>("jma");
[Fact] public void Realized() => TestIndicator<RealizedIndicator>("realized"); [Fact] public void Realized() => TestIndicator<RealizedIndicator>("realized");
[Fact] public void Rvi() => TestIndicator<RviIndicator>("rvi"); [Fact] public void Rvi() => TestIndicator<RviIndicator>("rvi");
// Momentum Indicators
[Fact] public void Adx() => TestIndicator<momentum::QuanTAlib.AdxIndicator>("adx");
[Fact] public void Adxr() => TestIndicator<momentum::QuanTAlib.AdxrIndicator>("adxr");
[Fact] public void Apo() => TestIndicator<momentum::QuanTAlib.ApoIndicator>("apo");
[Fact] public void Dmi() => TestIndicator<momentum::QuanTAlib.DmiIndicator>("dmi");
[Fact] public void Dmx() => TestIndicator<momentum::QuanTAlib.DmxIndicator>("dmx");
[Fact] public void Dpo() => TestIndicator<momentum::QuanTAlib.DpoIndicator>("dpo");
[Fact] public void Macd() => TestIndicator<momentum::QuanTAlib.MacdIndicator>("macd");
} }
} }
+33 -213
View File
@@ -1,340 +1,160 @@
using Xunit; using Xunit;
using System.Security.Cryptography;
namespace QuanTAlib.Tests; namespace QuanTAlib.Tests;
public class OscillatorsUpdateTests public class OscillatorsUpdateTests : UpdateTestBase
{ {
private readonly RandomNumberGenerator rng = RandomNumberGenerator.Create();
private const int RandomUpdates = 100;
private const double ReferenceValue = 100.0;
private const int precision = 8;
private double GetRandomDouble()
{
byte[] bytes = new byte[8];
rng.GetBytes(bytes);
return ((double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue * 200) - 100; // Range: -100 to 100
}
private TBar GetRandomBar(bool IsNew)
{
double open = GetRandomDouble();
double high = open + Math.Abs(GetRandomDouble());
double low = open - Math.Abs(GetRandomDouble());
double close = low + ((high - low) * GetRandomDouble());
return new TBar(DateTime.Now, open, high, low, close, 1000, IsNew);
}
[Fact] [Fact]
public void Rsi_Update() public void Rsi_Update()
{ {
var indicator = new Rsi(period: 14); var indicator = new Rsi(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Rsx_Update() public void Rsx_Update()
{ {
var indicator = new Rsx(period: 14); var indicator = new Rsx(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Cmo_Update() public void Cmo_Update()
{ {
var indicator = new Cmo(period: 14); var indicator = new Cmo(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Ao_Update() public void Ao_Update()
{ {
var indicator = new Ao(); var indicator = new Ao();
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Ac_Update() public void Ac_Update()
{ {
var indicator = new Ac(); var indicator = new Ac();
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Aroon_Update() public void Aroon_Update()
{ {
var indicator = new Aroon(period: 25); var indicator = new Aroon(period: 25);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Bop_Update() public void Bop_Update()
{ {
var indicator = new Bop(); var indicator = new Bop();
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Cci_Update() public void Cci_Update()
{ {
var indicator = new Cci(period: 20); var indicator = new Cci(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Cfo_Update() public void Cfo_Update()
{ {
var indicator = new Cfo(period: 14); var indicator = new Cfo(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Chop_Update() public void Chop_Update()
{ {
var indicator = new Chop(period: 14); var indicator = new Chop(period: 14);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Cog_Update() public void Cog_Update()
{ {
var indicator = new Cog(period: 10); var indicator = new Cog(period: 10);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
}
for (int i = 0; i < RandomUpdates; i++) [Fact]
{ public void Coppock_Update()
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false)); {
} var indicator = new Coppock(roc1Period: 14, roc2Period: 11, wmaPeriod: 10);
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false)); TestTValueUpdate(indicator, indicator.Calc);
}
Assert.Equal(initialValue, finalValue, precision); [Fact]
public void Crsi_Update()
{
var indicator = new Crsi(period1: 10, period2: 14, period3: 30);
TestTValueUpdate(indicator, indicator.Calc);
} }
[Fact] [Fact]
public void Smi_Update() public void Smi_Update()
{ {
var indicator = new Smi(period: 10, smooth1: 3, smooth2: 3); var indicator = new Smi(period: 10, smooth1: 3, smooth2: 3);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Srsi_Update() public void Srsi_Update()
{ {
var indicator = new Srsi(rsiPeriod: 14, stochPeriod: 14, smoothK: 3, smoothD: 3); var indicator = new Srsi(rsiPeriod: 14, stochPeriod: 14, smoothK: 3, smoothD: 3);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Stc_Update() public void Stc_Update()
{ {
var indicator = new Stc(cyclePeriod: 10, fastPeriod: 23, slowPeriod: 50); var indicator = new Stc(cyclePeriod: 10, fastPeriod: 23, slowPeriod: 50);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Stoch_Update() public void Stoch_Update()
{ {
var indicator = new Stoch(period: 14, smoothK: 3, smoothD: 3); var indicator = new Stoch(period: 14, smoothK: 3, smoothD: 3);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Tsi_Update() public void Tsi_Update()
{ {
var indicator = new Tsi(firstPeriod: 25, secondPeriod: 13); var indicator = new Tsi(firstPeriod: 25, secondPeriod: 13);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Uo_Update() public void Uo_Update()
{ {
var indicator = new Uo(period1: 7, period2: 14, period3: 28); var indicator = new Uo(period1: 7, period2: 14, period3: 28);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Willr_Update() public void Willr_Update()
{ {
var indicator = new Willr(period: 14); var indicator = new Willr(period: 14);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Dosc_Update() public void Dosc_Update()
{ {
var indicator = new Dosc(); var indicator = new Dosc();
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Efi_Update() public void Efi_Update()
{ {
var indicator = new Efi(period: 13); var indicator = new Efi(period: 13);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
} }
+29 -169
View File
@@ -1,272 +1,132 @@
using Xunit; using Xunit;
using System.Security.Cryptography;
namespace QuanTAlib.Tests; namespace QuanTAlib.Tests;
public class StatisticsUpdateTests public class StatisticsUpdateTests : UpdateTestBase
{ {
private readonly RandomNumberGenerator rng = RandomNumberGenerator.Create();
private const int RandomUpdates = 100;
private const double ReferenceValue = 100.0;
private const int precision = 8;
private double GetRandomDouble()
{
byte[] bytes = new byte[8];
rng.GetBytes(bytes);
return ((double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue * 200) - 100; // Range: -100 to 100
}
private TBar GetRandomBar(bool IsNew)
{
double open = GetRandomDouble();
double high = open + Math.Abs(GetRandomDouble());
double low = open - Math.Abs(GetRandomDouble());
double close = low + ((high - low) * GetRandomDouble());
return new TBar(DateTime.Now, open, high, low, close, 1000, IsNew);
}
[Fact] [Fact]
public void Beta_Update() public void Beta_Update()
{ {
var indicator = new Beta(period: 14); var indicator = new Beta(period: 14);
TBar marketBar = GetRandomBar(true); TestDualTBarUpdate(indicator, indicator.Calc);
TBar assetBar = GetRandomBar(true);
double initialValue = indicator.Calc(marketBar, assetBar);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(false), GetRandomBar(false));
}
double finalValue = indicator.Calc(new TBar(marketBar.Time, marketBar.Open, marketBar.High, marketBar.Low, marketBar.Close, marketBar.Volume, false),
new TBar(assetBar.Time, assetBar.Open, assetBar.High, assetBar.Low, assetBar.Close, assetBar.Volume, false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Corr_Update() public void Corr_Update()
{ {
var indicator = new Corr(period: 14); var indicator = new Corr(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true), new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestDualTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false), new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false), new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Curvature_Update() public void Curvature_Update()
{ {
var indicator = new Curvature(period: 14); var indicator = new Curvature(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Entropy_Update() public void Entropy_Update()
{ {
var indicator = new Entropy(period: 14); var indicator = new Entropy(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Hurst_Update() public void Hurst_Update()
{ {
var indicator = new Hurst(period: 100, minLength: 10); var indicator = new Hurst(period: 100, minLength: 10);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Kurtosis_Update() public void Kurtosis_Update()
{ {
var indicator = new Kurtosis(period: 14); var indicator = new Kurtosis(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Max_Update() public void Max_Update()
{ {
var indicator = new Max(period: 14); var indicator = new Max(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Median_Update() public void Median_Update()
{ {
var indicator = new Median(period: 14); var indicator = new Median(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Min_Update() public void Min_Update()
{ {
var indicator = new Min(period: 14); var indicator = new Min(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Mode_Update() public void Mode_Update()
{ {
var indicator = new Mode(period: 14); var indicator = new Mode(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Percentile_Update() public void Percentile_Update()
{ {
var indicator = new Percentile(period: 14, percent: 50); var indicator = new Percentile(period: 14, percent: 50);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Skew_Update() public void Skew_Update()
{ {
var indicator = new Skew(period: 14); var indicator = new Skew(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Slope_Update() public void Slope_Update()
{ {
var indicator = new Slope(period: 14); var indicator = new Slope(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Stddev_Update() public void Stddev_Update()
{ {
var indicator = new Stddev(period: 14); var indicator = new Stddev(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
}
for (int i = 0; i < RandomUpdates; i++) [Fact]
{ public void Theil_Update()
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false)); {
} var indicator = new Theil(period: 14);
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false)); TestTValueUpdate(indicator, indicator.Calc);
}
Assert.Equal(initialValue, finalValue, precision); [Fact]
public void Tsf_Update()
{
var indicator = new Tsf(period: 14);
TestTValueUpdate(indicator, indicator.Calc);
} }
[Fact] [Fact]
public void Variance_Update() public void Variance_Update()
{ {
var indicator = new Variance(period: 14); var indicator = new Variance(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Zscore_Update() public void Zscore_Update()
{ {
var indicator = new Zscore(period: 14); var indicator = new Zscore(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
} }
+37 -318
View File
@@ -1,504 +1,223 @@
using Xunit; using Xunit;
using System.Security.Cryptography;
namespace QuanTAlib.Tests; namespace QuanTAlib.Tests;
public class VolatilityUpdateTests public class VolatilityUpdateTests : UpdateTestBase
{ {
private readonly RandomNumberGenerator rng = RandomNumberGenerator.Create();
private const int RandomUpdates = 100;
private const double ReferenceValue = 100.0;
private const int precision = 8;
private double GetRandomDouble()
{
byte[] bytes = new byte[8];
rng.GetBytes(bytes);
return ((double)BitConverter.ToUInt64(bytes, 0) / ulong.MaxValue * 200) - 100; // Range: -100 to 100
}
private TBar GetRandomBar(bool IsNew)
{
double open = GetRandomDouble();
double high = open + Math.Abs(GetRandomDouble());
double low = open - Math.Abs(GetRandomDouble());
double close = low + ((high - low) * GetRandomDouble());
return new TBar(DateTime.Now, open, high, low, close, 1000, IsNew);
}
[Fact] [Fact]
public void Adr_Update() public void Adr_Update()
{ {
var indicator = new Adr(period: 14); var indicator = new Adr(period: 14);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Atr_Update() public void Atr_Update()
{ {
var indicator = new Atr(period: 14); var indicator = new Atr(period: 14);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r); }
for (int i = 0; i < RandomUpdates; i++) [Fact]
{ public void Atrs_Update()
indicator.Calc(GetRandomBar(IsNew: false)); {
} var indicator = new Atrs(period: 14, factor: 2.0);
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false)); TestTBarUpdate(indicator, indicator.Calc);
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Ap_Update() public void Ap_Update()
{ {
var indicator = new Ap(period: 20); var indicator = new Ap(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Atrp_Update() public void Atrp_Update()
{ {
var indicator = new Atrp(period: 14); var indicator = new Atrp(period: 14);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Bband_Update() public void Bband_Update()
{ {
var indicator = new Bband(period: 20, multiplier: 2.0); var indicator = new Bband(period: 20, multiplier: 2.0);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Ccv_Update() public void Ccv_Update()
{ {
var indicator = new Ccv(period: 20); var indicator = new Ccv(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Ce_Update() public void Ce_Update()
{ {
var indicator = new Ce(period: 22, multiplier: 3.0); var indicator = new Ce(period: 22, multiplier: 3.0);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Cv_Update() public void Cv_Update()
{ {
var indicator = new Cv(period: 20); var indicator = new Cv(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Cvi_Update() public void Cvi_Update()
{ {
var indicator = new Cvi(period: 10, smoothPeriod: 10); var indicator = new Cvi(period: 10, smoothPeriod: 10);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Dchn_Update() public void Dchn_Update()
{ {
var indicator = new Dchn(period: 20); var indicator = new Dchn(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Ewma_Update() public void Ewma_Update()
{ {
var indicator = new Ewma(period: 20, lambda: 0.94); var indicator = new Ewma(period: 20, lambda: 0.94);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Fcb_Update() public void Fcb_Update()
{ {
var indicator = new Fcb(period: 20, smoothing: 0.5); var indicator = new Fcb(period: 20, smoothing: 0.5);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Gkv_Update() public void Gkv_Update()
{ {
var indicator = new Gkv(period: 20); var indicator = new Gkv(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Historical_Update() public void Historical_Update()
{ {
var indicator = new Hv(period: 14); var indicator = new Hv(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Hlv_Update() public void Hlv_Update()
{ {
var indicator = new Hlv(period: 20); var indicator = new Hlv(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Jvolty_Update() public void Jvolty_Update()
{ {
var indicator = new Jvolty(period: 14); var indicator = new Jvolty(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Natr_Update() public void Natr_Update()
{ {
var indicator = new Natr(period: 14); var indicator = new Natr(period: 14);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Pch_Update() public void Pch_Update()
{ {
var indicator = new Pch(period: 20); var indicator = new Pch(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Pv_Update() public void Pv_Update()
{ {
var indicator = new Pv(period: 10); var indicator = new Pv(period: 10);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Realized_Update() public void Realized_Update()
{ {
var indicator = new Rv(period: 14); var indicator = new Rv(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Rsv_Update() public void Rsv_Update()
{ {
var indicator = new Rsv(period: 10); var indicator = new Rsv(period: 10);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Rvi_Update() public void Rvi_Update()
{ {
var indicator = new Rvi(period: 14); var indicator = new Rvi(period: 14);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true)); TestTValueUpdate(indicator, indicator.Calc);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble(), IsNew: false));
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Sv_Update() public void Sv_Update()
{ {
var indicator = new Sv(period: 20, lambda: 0.94); var indicator = new Sv(period: 20, lambda: 0.94);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Tr_Update() public void Tr_Update()
{ {
var indicator = new Tr(); var indicator = new Tr();
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Ui_Update() public void Ui_Update()
{ {
var indicator = new Ui(period: 14); var indicator = new Ui(period: 14);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Vc_Update() public void Vc_Update()
{ {
var indicator = new Vc(period: 20, deviations: 2.0); var indicator = new Vc(period: 20, deviations: 2.0);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Vov_Update() public void Vov_Update()
{ {
var indicator = new Vov(period: 20); var indicator = new Vov(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Vr_Update() public void Vr_Update()
{ {
var indicator = new Vr(shortPeriod: 10, longPeriod: 20); var indicator = new Vr(shortPeriod: 10, longPeriod: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Vs_Update() public void Vs_Update()
{ {
var indicator = new Vs(period: 14, multiplier: 2.0); var indicator = new Vs(period: 14, multiplier: 2.0);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
[Fact] [Fact]
public void Yzv_Update() public void Yzv_Update()
{ {
var indicator = new Yzv(period: 20); var indicator = new Yzv(period: 20);
TBar r = GetRandomBar(true); TestTBarUpdate(indicator, indicator.Calc);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(GetRandomBar(IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
} }
} }
+4 -4
View File
@@ -25,7 +25,7 @@ public class DpoIndicator : Indicator, IWatchlistIndicator
[InputParameter("Show cold values", sortIndex: 3)] [InputParameter("Show cold values", sortIndex: 3)]
public bool ShowColdValues { get; set; } = true; public bool ShowColdValues { get; set; } = true;
private Dpo? Dpo; private Dpo? dpo;
protected LineSeries? DpoSeries; protected LineSeries? DpoSeries;
public int MinHistoryDepths => Period * 2; public int MinHistoryDepths => Period * 2;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths; int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
@@ -42,14 +42,14 @@ public class DpoIndicator : Indicator, IWatchlistIndicator
protected override void OnInit() protected override void OnInit()
{ {
Dpo = new Dpo(Period); dpo = new Dpo(Period);
base.OnInit(); base.OnInit();
} }
protected override void OnUpdate(UpdateArgs args) protected override void OnUpdate(UpdateArgs args)
{ {
TBar input = this.GetInputBar(args); TBar input = this.GetInputBar(args);
TValue result = Dpo!.Calc(input); TValue result = dpo!.Calc(input);
DpoSeries!.SetValue(result.Value); DpoSeries!.SetValue(result.Value);
DpoSeries!.SetMarker(0, Color.Transparent); DpoSeries!.SetMarker(0, Color.Transparent);
@@ -62,6 +62,6 @@ public class DpoIndicator : Indicator, IWatchlistIndicator
public override void OnPaintChart(PaintChartEventArgs args) public override void OnPaintChart(PaintChartEventArgs args)
{ {
base.OnPaintChart(args); base.OnPaintChart(args);
this.PaintSmoothCurve(args, DpoSeries!, Dpo!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2); this.PaintSmoothCurve(args, DpoSeries!, dpo!.WarmupPeriod, showColdValues: ShowColdValues, tension: 0.2);
} }
} }