normalization of methods

This commit is contained in:
Miha Kralj
2026-02-10 21:33:16 -08:00
parent 915d7a007b
commit 6d6259a47d
527 changed files with 10525 additions and 2123 deletions
+7
View File
@@ -209,6 +209,13 @@ public sealed class Adr : AbstractBase
var adr = new Adr(period, method);
return adr.Update(source);
}
public static (TSeries Results, Adr Indicator) Calculate(TBarSeries source, int period, AdrMethod method = AdrMethod.Sma)
{
var indicator = new Adr(period, method);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
/// <summary>
+7
View File
@@ -240,4 +240,11 @@ public sealed class Atr : AbstractBase
var atr = new Atr(period);
return atr.Update(source);
}
public static (TSeries Results, Atr Indicator) Calculate(TBarSeries source, int period)
{
var indicator = new Atr(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+7
View File
@@ -289,6 +289,13 @@ public sealed class Atrn : AbstractBase
return atrn.Update(source);
}
public static (TSeries Results, Atrn Indicator) Calculate(TBarSeries source, int period)
{
var indicator = new Atrn(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private double GetMax()
{
+7
View File
@@ -270,4 +270,11 @@ public sealed class Atrp : AbstractBase
var atrp = new Atrp(period);
return atrp.Update(source);
}
public static (TSeries Results, Atrp Indicator) Calculate(TBarSeries source, int period)
{
var indicator = new Atrp(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+7 -7
View File
@@ -276,7 +276,7 @@ public class BbwTests
{
ts.Add(new TValue(times[i], close[i]));
}
var batchResult = Bbw.Calculate(ts, 20);
var batchResult = Bbw.Batch(ts, 20);
Assert.Equal(iterativeResult, batchResult[batchResult.Count - 1].Value, 1e-8);
}
@@ -302,7 +302,7 @@ public class BbwTests
{
ts.Add(new TValue(times[i], close[i]));
}
var bbwBatch = Bbw.Calculate(ts, 20);
var bbwBatch = Bbw.Batch(ts, 20);
var smaResult = smaBatch.Update(bbwBatch);
Assert.Equal(sma.Last.Value, smaResult[smaResult.Count - 1].Value, 1e-8);
@@ -321,7 +321,7 @@ public class BbwTests
ts.Add(new TValue(times[i], close[i]));
}
var result = Bbw.Calculate(ts, 20, 2.0);
var result = Bbw.Batch(ts, 20, 2.0);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -336,10 +336,10 @@ public class BbwTests
ts.Add(new TValue(DateTime.UtcNow.AddMinutes(i), 100 + i));
}
Assert.Throws<ArgumentException>(() => Bbw.Calculate(ts, 0));
Assert.Throws<ArgumentException>(() => Bbw.Calculate(ts, -1));
Assert.Throws<ArgumentException>(() => Bbw.Calculate(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Bbw.Calculate(ts, 5, -1));
Assert.Throws<ArgumentException>(() => Bbw.Batch(ts, 0));
Assert.Throws<ArgumentException>(() => Bbw.Batch(ts, -1));
Assert.Throws<ArgumentException>(() => Bbw.Batch(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Bbw.Batch(ts, 5, -1));
}
[Fact]
+8 -1
View File
@@ -219,7 +219,7 @@ public sealed class Bbw : AbstractBase
/// <summary>
/// Calculates BBW for entire series.
/// </summary>
public static TSeries Calculate(TSeries source, int period, double multiplier = 2.0)
public static TSeries Batch(TSeries source, int period, double multiplier = 2.0)
{
int len = source.Count;
var t = new List<long>(len);
@@ -308,4 +308,11 @@ public sealed class Bbw : AbstractBase
output[i] = mean > 0 ? (mult2 * stddev) / mean : 0.0;
}
}
public static (TSeries Results, Bbw Indicator) Calculate(TSeries source, int period, double multiplier = 2.0)
{
var indicator = new Bbw(period, multiplier);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+9 -9
View File
@@ -212,7 +212,7 @@ public class BbwnTests
ts.Add(new TValue(bars.Times[i], bars.CloseValues[i]));
}
var result = Bbwn.Calculate(ts, 10, 2.0, 50);
var result = Bbwn.Batch(ts, 10, 2.0, 50);
Assert.Equal(ts.Count, result.Count);
@@ -332,7 +332,7 @@ public class BbwnTests
{
ts.Add(new TValue(times[i], close[i]));
}
var batchResult = Bbwn.Calculate(ts, 10, 2.0, 30);
var batchResult = Bbwn.Batch(ts, 10, 2.0, 30);
Assert.Equal(iterativeResult, batchResult[batchResult.Count - 1].Value, 1e-8);
}
@@ -350,7 +350,7 @@ public class BbwnTests
ts.Add(new TValue(times[i], close[i]));
}
var result = Bbwn.Calculate(ts, 20, 2.0, 50);
var result = Bbwn.Batch(ts, 20, 2.0, 50);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -367,12 +367,12 @@ public class BbwnTests
ts.Add(new TValue(DateTime.UtcNow.AddMinutes(i), 100 + i));
}
Assert.Throws<ArgumentException>(() => Bbwn.Calculate(ts, 0));
Assert.Throws<ArgumentException>(() => Bbwn.Calculate(ts, -1));
Assert.Throws<ArgumentException>(() => Bbwn.Calculate(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Bbwn.Calculate(ts, 5, -1));
Assert.Throws<ArgumentException>(() => Bbwn.Calculate(ts, 5, 2.0, 0));
Assert.Throws<ArgumentException>(() => Bbwn.Calculate(ts, 5, 2.0, -1));
Assert.Throws<ArgumentException>(() => Bbwn.Batch(ts, 0));
Assert.Throws<ArgumentException>(() => Bbwn.Batch(ts, -1));
Assert.Throws<ArgumentException>(() => Bbwn.Batch(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Bbwn.Batch(ts, 5, -1));
Assert.Throws<ArgumentException>(() => Bbwn.Batch(ts, 5, 2.0, 0));
Assert.Throws<ArgumentException>(() => Bbwn.Batch(ts, 5, 2.0, -1));
}
[Fact]
+1 -1
View File
@@ -141,7 +141,7 @@ public class BbwnValidationTests
{
source.Add(new TValue(bars.Times[i], bars.CloseValues[i]));
}
var result = Bbwn.Calculate(source, period: 10, multiplier: 2.0, lookback: 20);
var result = Bbwn.Batch(source, period: 10, multiplier: 2.0, lookback: 20);
Assert.Equal(source.Count, result.Count);
+8 -1
View File
@@ -273,7 +273,7 @@ public sealed class Bbwn : AbstractBase
/// <summary>
/// Calculates BBWN for entire series.
/// </summary>
public static TSeries Calculate(TSeries source, int period, double multiplier = 2.0, int lookback = 252)
public static TSeries Batch(TSeries source, int period, double multiplier = 2.0, int lookback = 252)
{
int len = source.Count;
var t = new List<long>(len);
@@ -382,4 +382,11 @@ public sealed class Bbwn : AbstractBase
output[i] = Math.Max(0.0, Math.Min(1.0, bbwn));
}
}
public static (TSeries Results, Bbwn Indicator) Calculate(TSeries source, int period, double multiplier = 2.0, int lookback = 252)
{
var indicator = new Bbwn(period, multiplier, lookback);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+9 -9
View File
@@ -211,7 +211,7 @@ public class BbwpTests
ts.Add(new TValue(bars.Times[i], bars.CloseValues[i]));
}
var result = Bbwp.Calculate(ts, 10, 2.0, 50);
var result = Bbwp.Batch(ts, 10, 2.0, 50);
Assert.Equal(ts.Count, result.Count);
@@ -331,7 +331,7 @@ public class BbwpTests
{
ts.Add(new TValue(times[i], close[i]));
}
var batchResult = Bbwp.Calculate(ts, 10, 2.0, 30);
var batchResult = Bbwp.Batch(ts, 10, 2.0, 30);
Assert.Equal(iterativeResult, batchResult[batchResult.Count - 1].Value, 1e-8);
}
@@ -349,7 +349,7 @@ public class BbwpTests
ts.Add(new TValue(times[i], close[i]));
}
var result = Bbwp.Calculate(ts, 20, 2.0, 50);
var result = Bbwp.Batch(ts, 20, 2.0, 50);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -366,12 +366,12 @@ public class BbwpTests
ts.Add(new TValue(DateTime.UtcNow.AddMinutes(i), 100 + i));
}
Assert.Throws<ArgumentException>(() => Bbwp.Calculate(ts, 0));
Assert.Throws<ArgumentException>(() => Bbwp.Calculate(ts, -1));
Assert.Throws<ArgumentException>(() => Bbwp.Calculate(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Bbwp.Calculate(ts, 5, -1));
Assert.Throws<ArgumentException>(() => Bbwp.Calculate(ts, 5, 2.0, 0));
Assert.Throws<ArgumentException>(() => Bbwp.Calculate(ts, 5, 2.0, -1));
Assert.Throws<ArgumentException>(() => Bbwp.Batch(ts, 0));
Assert.Throws<ArgumentException>(() => Bbwp.Batch(ts, -1));
Assert.Throws<ArgumentException>(() => Bbwp.Batch(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Bbwp.Batch(ts, 5, -1));
Assert.Throws<ArgumentException>(() => Bbwp.Batch(ts, 5, 2.0, 0));
Assert.Throws<ArgumentException>(() => Bbwp.Batch(ts, 5, 2.0, -1));
}
[Fact]
+1 -1
View File
@@ -50,7 +50,7 @@ public class BbwpValidationTests
{
ts.Add(new TValue(times[i], close[i]));
}
var batchResults = Bbwp.Calculate(ts, 10, 2.0, 50);
var batchResults = Bbwp.Batch(ts, 10, 2.0, 50);
// Compare results (should be identical)
for (int i = 0; i < bars.Count; i++)
+8 -1
View File
@@ -266,7 +266,7 @@ public sealed class Bbwp : AbstractBase
/// <summary>
/// Calculates BBWP for entire series.
/// </summary>
public static TSeries Calculate(TSeries source, int period, double multiplier = 2.0, int lookback = 252)
public static TSeries Batch(TSeries source, int period, double multiplier = 2.0, int lookback = 252)
{
if (period <= 0)
{
@@ -396,4 +396,11 @@ public sealed class Bbwp : AbstractBase
output[i] = Math.Max(0.0, Math.Min(1.0, bbwp));
}
}
public static (TSeries Results, Bbwp Indicator) Calculate(TSeries source, int period, double multiplier = 2.0, int lookback = 252)
{
var indicator = new Bbwp(period, multiplier, lookback);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+6 -6
View File
@@ -268,7 +268,7 @@ public class CcvTests
{
ts.Add(new TValue(times[i], close[i]));
}
var batchResult = Ccv.Calculate(ts, 20);
var batchResult = Ccv.Batch(ts, 20);
Assert.Equal(iterativeResult, batchResult[batchResult.Count - 1].Value, 1e-8);
}
@@ -286,7 +286,7 @@ public class CcvTests
ts.Add(new TValue(times[i], close[i]));
}
var result = Ccv.Calculate(ts, 20);
var result = Ccv.Batch(ts, 20);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -301,10 +301,10 @@ public class CcvTests
ts.Add(new TValue(DateTime.UtcNow.AddMinutes(i), 100 + i));
}
Assert.Throws<ArgumentException>(() => Ccv.Calculate(ts, 0));
Assert.Throws<ArgumentException>(() => Ccv.Calculate(ts, -1));
Assert.Throws<ArgumentException>(() => Ccv.Calculate(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Ccv.Calculate(ts, 5, 4));
Assert.Throws<ArgumentException>(() => Ccv.Batch(ts, 0));
Assert.Throws<ArgumentException>(() => Ccv.Batch(ts, -1));
Assert.Throws<ArgumentException>(() => Ccv.Batch(ts, 5, 0));
Assert.Throws<ArgumentException>(() => Ccv.Batch(ts, 5, 4));
}
[Fact]
+8 -1
View File
@@ -299,7 +299,7 @@ public sealed class Ccv : AbstractBase
/// <summary>
/// Calculates CCV for entire series.
/// </summary>
public static TSeries Calculate(TSeries source, int period, int method = 1)
public static TSeries Batch(TSeries source, int period, int method = 1)
{
if (period <= 0)
{
@@ -448,4 +448,11 @@ public sealed class Ccv : AbstractBase
output[i] = double.IsFinite(result) ? result : 0.0;
}
}
public static (TSeries Results, Ccv Indicator) Calculate(TSeries source, int period, int method = 1)
{
var indicator = new Ccv(period, method);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+6 -6
View File
@@ -277,7 +277,7 @@ public class CvTests
{
ts.Add(new TValue(times[i], close[i]));
}
var batchResult = Cv.Calculate(ts, 20);
var batchResult = Cv.Batch(ts, 20);
Assert.Equal(iterativeResult, batchResult[batchResult.Count - 1].Value, 1e-8);
}
@@ -295,7 +295,7 @@ public class CvTests
ts.Add(new TValue(times[i], close[i]));
}
var result = Cv.Calculate(ts, 20);
var result = Cv.Batch(ts, 20);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -310,10 +310,10 @@ public class CvTests
ts.Add(new TValue(DateTime.UtcNow.AddMinutes(i), 100 + i));
}
Assert.Throws<ArgumentException>(() => Cv.Calculate(ts, 0));
Assert.Throws<ArgumentException>(() => Cv.Calculate(ts, -1));
Assert.Throws<ArgumentException>(() => Cv.Calculate(ts, 5, 0.0)); // alpha = 0
Assert.Throws<ArgumentException>(() => Cv.Calculate(ts, 5, 0.5, 0.6)); // alpha + beta >= 1
Assert.Throws<ArgumentException>(() => Cv.Batch(ts, 0));
Assert.Throws<ArgumentException>(() => Cv.Batch(ts, -1));
Assert.Throws<ArgumentException>(() => Cv.Batch(ts, 5, 0.0)); // alpha = 0
Assert.Throws<ArgumentException>(() => Cv.Batch(ts, 5, 0.5, 0.6)); // alpha + beta >= 1
}
[Fact]
+3 -3
View File
@@ -229,13 +229,13 @@ public class CvValidationTests
streamingCv.Update(new TValue(times[i], close[i]));
}
// Batch calculation using Calculate (TSeries -> TSeries)
// Batch calculation using Batch(TSeries -> TSeries)
var source = new TSeries();
for (int i = 0; i < bars.Count; i++)
{
source.Add(times[i], close[i]);
}
var batchResult = Cv.Calculate(source, 20, 0.2, 0.7);
var batchResult = Cv.Batch(source, 20, 0.2, 0.7);
// Compare last values
Assert.Equal(batchResult.Last.Value, streamingCv.Last.Value, 8);
@@ -266,7 +266,7 @@ public class CvValidationTests
}
// TSeries batch using Calculate
var batch = Cv.Calculate(source, 20, 0.2, 0.7);
var batch = Cv.Batch(source, 20, 0.2, 0.7);
// Compare
Assert.Equal(batch.Last.Value, streaming.Last.Value, 10);
+8 -1
View File
@@ -286,7 +286,7 @@ public sealed class Cv : AbstractBase
/// <summary>
/// Calculates CV for entire series.
/// </summary>
public static TSeries Calculate(TSeries source, int period = 20, double alpha = 0.2, double beta = 0.7)
public static TSeries Batch(TSeries source, int period = 20, double alpha = 0.2, double beta = 0.7)
{
if (period <= 0)
{
@@ -430,4 +430,11 @@ public sealed class Cv : AbstractBase
output[i] = double.IsFinite(result) ? result : 0.0;
}
}
public static (TSeries Results, Cv Indicator) Calculate(TSeries source, int period = 20, double alpha = 0.2, double beta = 0.7)
{
var indicator = new Cv(period, alpha, beta);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+6 -6
View File
@@ -311,7 +311,7 @@ public class CviTests
var iterativeResult = cvi.Last.Value;
// Batch via static method
var batchResult = Cvi.Calculate(bars, 10, 10);
var batchResult = Cvi.Batch(bars, 10, 10);
Assert.Equal(iterativeResult, batchResult[batchResult.Count - 1].Value, 1e-8);
}
@@ -321,7 +321,7 @@ public class CviTests
{
var bars = GenerateTestData(100);
var result = Cvi.Calculate(bars, 14, 10);
var result = Cvi.Batch(bars, 14, 10);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -336,10 +336,10 @@ public class CviTests
ts.Add(new TValue(DateTime.UtcNow.AddMinutes(i), 100 + i));
}
Assert.Throws<ArgumentException>(() => Cvi.Calculate(ts, 0, 10));
Assert.Throws<ArgumentException>(() => Cvi.Calculate(ts, -1, 10));
Assert.Throws<ArgumentException>(() => Cvi.Calculate(ts, 10, 0));
Assert.Throws<ArgumentException>(() => Cvi.Calculate(ts, 10, -1));
Assert.Throws<ArgumentException>(() => Cvi.Batch(ts, 0, 10));
Assert.Throws<ArgumentException>(() => Cvi.Batch(ts, -1, 10));
Assert.Throws<ArgumentException>(() => Cvi.Batch(ts, 10, 0));
Assert.Throws<ArgumentException>(() => Cvi.Batch(ts, 10, -1));
}
[Fact]
+1 -1
View File
@@ -196,7 +196,7 @@ public class CviValidationTests
}
// Batch calculation
var batchResult = Cvi.Calculate(bars, 10, 10);
var batchResult = Cvi.Batch(bars, 10, 10);
// Compare last values
Assert.Equal(batchResult.Last.Value, streamingCvi.Last.Value, 8);
+9 -2
View File
@@ -276,7 +276,7 @@ public sealed class Cvi : AbstractBase
/// <summary>
/// Calculates CVI for entire TBarSeries.
/// </summary>
public static TSeries Calculate(TBarSeries source, int rocLength = 10, int smoothLength = 10)
public static TSeries Batch(TBarSeries source, int rocLength = 10, int smoothLength = 10)
{
var cvi = new Cvi(rocLength, smoothLength);
return cvi.Update(source);
@@ -285,7 +285,7 @@ public sealed class Cvi : AbstractBase
/// <summary>
/// Calculates CVI for entire series (assumes values are pre-calculated ranges).
/// </summary>
public static TSeries Calculate(TSeries source, int rocLength = 10, int smoothLength = 10)
public static TSeries Batch(TSeries source, int rocLength = 10, int smoothLength = 10)
{
if (rocLength <= 0)
{
@@ -381,4 +381,11 @@ public sealed class Cvi : AbstractBase
output[i] = double.IsFinite(result) ? result : 0.0;
}
}
public static (TSeries Results, Cvi Indicator) Calculate(TBarSeries source, int rocLength = 10, int smoothLength = 10)
{
var indicator = new Cvi(rocLength, smoothLength);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+6 -6
View File
@@ -274,7 +274,7 @@ public class EwmaTests
{
ts.Add(new TValue(times[i], close[i]));
}
var batchResult = Ewma.Calculate(ts, 20);
var batchResult = Ewma.Batch(ts, 20);
Assert.Equal(iterativeResult, batchResult[batchResult.Count - 1].Value, 1e-8);
}
@@ -292,7 +292,7 @@ public class EwmaTests
ts.Add(new TValue(times[i], close[i]));
}
var result = Ewma.Calculate(ts, 20);
var result = Ewma.Batch(ts, 20);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -307,10 +307,10 @@ public class EwmaTests
ts.Add(new TValue(DateTime.UtcNow.AddMinutes(i), 100 + i));
}
Assert.Throws<ArgumentException>(() => Ewma.Calculate(ts, 0));
Assert.Throws<ArgumentException>(() => Ewma.Calculate(ts, -1));
Assert.Throws<ArgumentException>(() => Ewma.Calculate(ts, 5, true, 0));
Assert.Throws<ArgumentException>(() => Ewma.Calculate(ts, 5, true, -1));
Assert.Throws<ArgumentException>(() => Ewma.Batch(ts, 0));
Assert.Throws<ArgumentException>(() => Ewma.Batch(ts, -1));
Assert.Throws<ArgumentException>(() => Ewma.Batch(ts, 5, true, 0));
Assert.Throws<ArgumentException>(() => Ewma.Batch(ts, 5, true, -1));
}
[Fact]
+2 -2
View File
@@ -160,7 +160,7 @@ public class EwmaValidationTests
}
// Batch
var batchResult = Ewma.Calculate(ts, DefaultPeriod, DefaultAnnualize, DefaultAnnualPeriods);
var batchResult = Ewma.Batch(ts, DefaultPeriod, DefaultAnnualize, DefaultAnnualPeriods);
Assert.Equal(ewmaStream.Last.Value, batchResult[batchResult.Count - 1].Value, StreamingTolerance);
}
@@ -226,7 +226,7 @@ public class EwmaValidationTests
double tseriesValue = tseriesResult[tseriesResult.Count - 1].Value;
// Mode 3: Static Calculate
var batchResult = Ewma.Calculate(ts, DefaultPeriod, DefaultAnnualize, DefaultAnnualPeriods);
var batchResult = Ewma.Batch(ts, DefaultPeriod, DefaultAnnualize, DefaultAnnualPeriods);
double batchValue = batchResult[batchResult.Count - 1].Value;
// Mode 4: Span Batch
+8 -1
View File
@@ -238,7 +238,7 @@ public sealed class Ewma : AbstractBase
/// <summary>
/// Calculates EWMA Volatility for entire series.
/// </summary>
public static TSeries Calculate(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
if (period <= 0)
{
@@ -350,4 +350,11 @@ public sealed class Ewma : AbstractBase
output[i] = double.IsFinite(result) ? result : 0.0;
}
}
public static (TSeries Results, Ewma Indicator) Calculate(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var indicator = new Ewma(period, annualize, annualPeriods);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+5 -5
View File
@@ -420,7 +420,7 @@ public class GkvTests
const int dataCount = 50;
var barSeries = GenerateTestData(dataCount);
var result = Gkv.Calculate(barSeries, period: 10);
var result = Gkv.Batch(barSeries, period: 10);
Assert.Equal(dataCount, result.Count);
}
@@ -614,7 +614,7 @@ public class GkvTests
{
var bars = GenerateTestData(100);
var result = Gkv.Calculate(bars, period: 14);
var result = Gkv.Batch(bars, period: 14);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -625,9 +625,9 @@ public class GkvTests
{
var bars = GenerateTestData(10);
Assert.Throws<ArgumentException>(() => Gkv.Calculate(bars, period: 0));
Assert.Throws<ArgumentException>(() => Gkv.Calculate(bars, period: -1));
Assert.Throws<ArgumentException>(() => Gkv.Calculate(bars, period: 10, annualize: true, annualPeriods: 0));
Assert.Throws<ArgumentException>(() => Gkv.Batch(bars, period: 0));
Assert.Throws<ArgumentException>(() => Gkv.Batch(bars, period: -1));
Assert.Throws<ArgumentException>(() => Gkv.Batch(bars, period: 10, annualize: true, annualPeriods: 0));
}
[Fact]
+1 -1
View File
@@ -191,7 +191,7 @@ public class GkvValidationTests
}
// Batch calculation
var batchResult = Gkv.Calculate(bars, 14);
var batchResult = Gkv.Batch(bars, 14);
// Compare last values
Assert.Equal(batchResult.Last.Value, streamingGkv.Last.Value, 8);
+11 -3
View File
@@ -350,7 +350,7 @@ public sealed class Gkv : AbstractBase
/// <param name="annualize">Whether to annualize.</param>
/// <param name="annualPeriods">Periods per year.</param>
/// <returns>A TSeries containing the volatility values.</returns>
public static TSeries Calculate(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var gkv = new Gkv(period, annualize, annualPeriods);
return gkv.Update(source);
@@ -359,7 +359,7 @@ public sealed class Gkv : AbstractBase
/// <summary>
/// Calculates GKV for a TSeries (treats values as pre-computed GK estimators).
/// </summary>
public static TSeries Calculate(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
if (period <= 0)
{
@@ -496,6 +496,14 @@ public sealed class Gkv : AbstractBase
}
}
public static (TSeries Results, Gkv Indicator) Calculate(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var indicator = new Gkv(period, annualize, annualPeriods);
TSeries results = indicator.Update(source);
return (results, indicator);
}
/// <summary>
/// Batch calculation from pre-computed GK estimators.
/// </summary>
@@ -570,4 +578,4 @@ public sealed class Gkv : AbstractBase
output[i] = volatility;
}
}
}
}
+5 -5
View File
@@ -415,7 +415,7 @@ public class HlvTests
const int dataCount = 50;
var barSeries = GenerateTestData(dataCount);
var result = Hlv.Calculate(barSeries, period: 10);
var result = Hlv.Batch(barSeries, period: 10);
Assert.Equal(dataCount, result.Count);
}
@@ -599,7 +599,7 @@ public class HlvTests
{
var bars = GenerateTestData(100);
var result = Hlv.Calculate(bars, period: 14);
var result = Hlv.Batch(bars, period: 14);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -610,9 +610,9 @@ public class HlvTests
{
var bars = GenerateTestData(10);
Assert.Throws<ArgumentException>(() => Hlv.Calculate(bars, period: 0));
Assert.Throws<ArgumentException>(() => Hlv.Calculate(bars, period: -1));
Assert.Throws<ArgumentException>(() => Hlv.Calculate(bars, period: 10, annualize: true, annualPeriods: 0));
Assert.Throws<ArgumentException>(() => Hlv.Batch(bars, period: 0));
Assert.Throws<ArgumentException>(() => Hlv.Batch(bars, period: -1));
Assert.Throws<ArgumentException>(() => Hlv.Batch(bars, period: 10, annualize: true, annualPeriods: 0));
}
[Fact]
+1 -1
View File
@@ -192,7 +192,7 @@ public class HlvValidationTests
}
// Batch calculation
var batchResult = Hlv.Calculate(bars, 14);
var batchResult = Hlv.Batch(bars, 14);
// Compare last values
Assert.Equal(batchResult.Last.Value, streamingHlv.Last.Value, 8);
+11 -3
View File
@@ -335,7 +335,7 @@ public sealed class Hlv : AbstractBase
/// <param name="annualize">Whether to annualize.</param>
/// <param name="annualPeriods">Periods per year.</param>
/// <returns>A TSeries containing the volatility values.</returns>
public static TSeries Calculate(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var hlv = new Hlv(period, annualize, annualPeriods);
return hlv.Update(source);
@@ -344,7 +344,7 @@ public sealed class Hlv : AbstractBase
/// <summary>
/// Calculates HLV for a TSeries (treats values as pre-computed Parkinson estimators).
/// </summary>
public static TSeries Calculate(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
if (period <= 0)
{
@@ -474,6 +474,14 @@ public sealed class Hlv : AbstractBase
}
}
public static (TSeries Results, Hlv Indicator) Calculate(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var indicator = new Hlv(period, annualize, annualPeriods);
TSeries results = indicator.Update(source);
return (results, indicator);
}
/// <summary>
/// Batch calculation from pre-computed Parkinson estimators.
/// </summary>
@@ -548,4 +556,4 @@ public sealed class Hlv : AbstractBase
output[i] = volatility;
}
}
}
}
+7 -7
View File
@@ -465,7 +465,7 @@ public class HvTests
const int dataCount = 50;
var priceSeries = GeneratePriceSeries(dataCount);
var result = Hv.Calculate(priceSeries, period: 10);
var result = Hv.Batch(priceSeries, period: 10);
Assert.Equal(dataCount, result.Count);
}
@@ -657,7 +657,7 @@ public class HvTests
{
var prices = GeneratePriceSeries(100);
var result = Hv.Calculate(prices, period: 14);
var result = Hv.Batch(prices, period: 14);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -668,7 +668,7 @@ public class HvTests
{
var bars = GenerateTestData(100);
var result = Hv.Calculate(bars, period: 14);
var result = Hv.Batch(bars, period: 14);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -679,10 +679,10 @@ public class HvTests
{
var prices = GeneratePriceSeries(10);
Assert.Throws<ArgumentException>(() => Hv.Calculate(prices, period: 1));
Assert.Throws<ArgumentException>(() => Hv.Calculate(prices, period: 0));
Assert.Throws<ArgumentException>(() => Hv.Calculate(prices, period: -1));
Assert.Throws<ArgumentException>(() => Hv.Calculate(prices, period: 10, annualize: true, annualPeriods: 0));
Assert.Throws<ArgumentException>(() => Hv.Batch(prices, period: 1));
Assert.Throws<ArgumentException>(() => Hv.Batch(prices, period: 0));
Assert.Throws<ArgumentException>(() => Hv.Batch(prices, period: -1));
Assert.Throws<ArgumentException>(() => Hv.Batch(prices, period: 10, annualize: true, annualPeriods: 0));
}
[Fact]
+1 -1
View File
@@ -192,7 +192,7 @@ public class HvValidationTests
}
// Batch calculation
var batchResult = Hv.Calculate(prices, 14);
var batchResult = Hv.Batch(prices, 14);
// Compare last values
Assert.Equal(batchResult.Last.Value, streamingHv.Last.Value, 8);
+11 -3
View File
@@ -335,7 +335,7 @@ public sealed class Hv : AbstractBase
/// <param name="annualize">Whether to annualize.</param>
/// <param name="annualPeriods">Periods per year.</param>
/// <returns>A TSeries containing the volatility values.</returns>
public static TSeries Calculate(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
if (period < 2)
{
@@ -364,7 +364,7 @@ public sealed class Hv : AbstractBase
/// <summary>
/// Calculates HV for a bar series (static).
/// </summary>
public static TSeries Calculate(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var hv = new Hv(period, annualize, annualPeriods);
return hv.Update(source);
@@ -492,4 +492,12 @@ public sealed class Hv : AbstractBase
output[i] = volatility;
}
}
}
public static (TSeries Results, Hv Indicator) Calculate(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var indicator = new Hv(period, annualize, annualPeriods);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+4 -4
View File
@@ -397,7 +397,7 @@ public class JvoltyTests
// Span calculation
var output = new double[series.Count];
Jvolty.Calculate(series.Values, output, 10);
Jvolty.Batch(series.Values, output, 10);
// Compare last value (after warmup)
Assert.Equal(streamingLast, output[series.Count - 1], 1e-6);
@@ -435,7 +435,7 @@ public class JvoltyTests
var source = new double[10];
var output = new double[5]; // Wrong size
var ex = Assert.Throws<ArgumentException>(() => Jvolty.Calculate(source, output, 10));
var ex = Assert.Throws<ArgumentException>(() => Jvolty.Batch(source, output, 10));
Assert.Equal("output", ex.ParamName);
}
@@ -445,7 +445,7 @@ public class JvoltyTests
var source = Array.Empty<double>();
var output = Array.Empty<double>();
var exception = Record.Exception(() => Jvolty.Calculate(source, output, 10));
var exception = Record.Exception(() => Jvolty.Batch(source, output, 10));
Assert.Null(exception);
}
@@ -455,7 +455,7 @@ public class JvoltyTests
var source = new double[10];
var output = new double[10];
Assert.Throws<ArgumentOutOfRangeException>(() => Jvolty.Calculate(source, output, 0));
Assert.Throws<ArgumentOutOfRangeException>(() => Jvolty.Batch(source, output, 0));
}
// ============== Edge Cases ==============
+15 -3
View File
@@ -37,6 +37,7 @@ public sealed class Jvolty : AbstractBase
private readonly RingBuffer _volBuffer;
private readonly TValuePublishedHandler _handler;
private readonly ITValuePublisher? _source;
private bool _disposed;
// Streaming state (current + previous snapshot for isNew=false)
private State _s;
@@ -293,9 +294,13 @@ public sealed class Jvolty : AbstractBase
protected override void Dispose(bool disposing)
{
if (disposing && _source != null)
if (!_disposed)
{
_source.Pub -= _handler;
if (disposing && _source != null)
{
_source.Pub -= _handler;
}
_disposed = true;
}
base.Dispose(disposing);
}
@@ -320,7 +325,7 @@ public sealed class Jvolty : AbstractBase
/// <summary>
/// Static helper for span-based calculation.
/// </summary>
public static void Calculate(ReadOnlySpan<double> source,
public static void Batch(ReadOnlySpan<double> source,
Span<double> output,
int period)
{
@@ -341,6 +346,13 @@ public sealed class Jvolty : AbstractBase
}
}
public static (TSeries Results, Jvolty Indicator) Calculate(TSeries source, int period)
{
var indicator = new Jvolty(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private double CalculateTrimmedMean(double fallback)
{
+4 -4
View File
@@ -424,7 +424,7 @@ public class JvoltynTests
// Span calculation
var output = new double[series.Count];
Jvoltyn.Calculate(series.Values, output, 10);
Jvoltyn.Batch(series.Values, output, 10);
// Compare last value (after warmup)
Assert.Equal(streamingLast, output[series.Count - 1], 1e-6);
@@ -503,7 +503,7 @@ public class JvoltynTests
var source = new double[10];
var output = new double[5]; // Wrong size
var ex = Assert.Throws<ArgumentException>(() => Jvoltyn.Calculate(source, output, 10));
var ex = Assert.Throws<ArgumentException>(() => Jvoltyn.Batch(source, output, 10));
Assert.Equal("output", ex.ParamName);
}
@@ -513,7 +513,7 @@ public class JvoltynTests
var source = Array.Empty<double>();
var output = Array.Empty<double>();
var exception = Record.Exception(() => Jvoltyn.Calculate(source, output, 10));
var exception = Record.Exception(() => Jvoltyn.Batch(source, output, 10));
Assert.Null(exception);
}
@@ -523,7 +523,7 @@ public class JvoltynTests
var source = new double[10];
var output = new double[10];
Assert.Throws<ArgumentOutOfRangeException>(() => Jvoltyn.Calculate(source, output, 0));
Assert.Throws<ArgumentOutOfRangeException>(() => Jvoltyn.Batch(source, output, 0));
}
// ============== Edge Cases ==============
+15 -3
View File
@@ -38,6 +38,7 @@ public sealed class Jvoltyn : AbstractBase
private readonly RingBuffer _volBuffer;
private readonly TValuePublishedHandler _handler;
private readonly ITValuePublisher? _source;
private bool _disposed;
// Streaming state (current + previous snapshot for isNew=false)
private State _s;
@@ -305,9 +306,13 @@ public sealed class Jvoltyn : AbstractBase
protected override void Dispose(bool disposing)
{
if (disposing && _source != null)
if (!_disposed)
{
_source.Pub -= _handler;
if (disposing && _source != null)
{
_source.Pub -= _handler;
}
_disposed = true;
}
base.Dispose(disposing);
}
@@ -332,7 +337,7 @@ public sealed class Jvoltyn : AbstractBase
/// <summary>
/// Static helper for span-based calculation.
/// </summary>
public static void Calculate(ReadOnlySpan<double> source,
public static void Batch(ReadOnlySpan<double> source,
Span<double> output,
int period)
{
@@ -353,6 +358,13 @@ public sealed class Jvoltyn : AbstractBase
}
}
public static (TSeries Results, Jvoltyn Indicator) Calculate(TSeries source, int period)
{
var indicator = new Jvoltyn(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private double CalculateTrimmedMean(double fallback)
{
+5 -5
View File
@@ -439,7 +439,7 @@ public class MassiTests
// Span calculation
var output = new double[series.Count];
Massi.Calculate(series.Values, output, 9, 25);
Massi.Batch(series.Values, output, 9, 25);
// Compare last value
Assert.Equal(streamingLast, output[series.Count - 1], 1e-6);
@@ -530,7 +530,7 @@ public class MassiTests
var source = new double[10];
var output = new double[5]; // Wrong size
var ex = Assert.Throws<ArgumentException>(() => Massi.Calculate(source, output, 9, 25));
var ex = Assert.Throws<ArgumentException>(() => Massi.Batch(source, output, 9, 25));
Assert.Equal("output", ex.ParamName);
}
@@ -540,7 +540,7 @@ public class MassiTests
var source = Array.Empty<double>();
var output = Array.Empty<double>();
var exception = Record.Exception(() => Massi.Calculate(source, output, 9, 25));
var exception = Record.Exception(() => Massi.Batch(source, output, 9, 25));
Assert.Null(exception);
}
@@ -550,8 +550,8 @@ public class MassiTests
var source = new double[10];
var output = new double[10];
Assert.Throws<ArgumentOutOfRangeException>(() => Massi.Calculate(source, output, 0, 25));
Assert.Throws<ArgumentOutOfRangeException>(() => Massi.Calculate(source, output, 9, 0));
Assert.Throws<ArgumentOutOfRangeException>(() => Massi.Batch(source, output, 0, 25));
Assert.Throws<ArgumentOutOfRangeException>(() => Massi.Batch(source, output, 9, 0));
}
// ============== Edge Cases ==============
+15 -3
View File
@@ -30,6 +30,7 @@ public sealed class Massi : AbstractBase
private readonly RingBuffer _sumBuffer;
private readonly TValuePublishedHandler _handler;
private readonly ITValuePublisher? _source;
private bool _disposed;
private State _s;
private State _ps;
@@ -324,9 +325,13 @@ public sealed class Massi : AbstractBase
protected override void Dispose(bool disposing)
{
if (disposing && _source != null)
if (!_disposed)
{
_source.Pub -= _handler;
if (disposing && _source != null)
{
_source.Pub -= _handler;
}
_disposed = true;
}
base.Dispose(disposing);
}
@@ -363,7 +368,7 @@ public sealed class Massi : AbstractBase
/// <summary>
/// Static helper for span-based calculation (assumes input is H-L range).
/// </summary>
public static void Calculate(ReadOnlySpan<double> source, Span<double> output,
public static void Batch(ReadOnlySpan<double> source, Span<double> output,
int emaLength = 9, int sumLength = 25)
{
if (output.Length != source.Length)
@@ -382,4 +387,11 @@ public sealed class Massi : AbstractBase
output[i] = massi.CalculateMassiStep(source[i]);
}
}
public static (TSeries Results, Massi Indicator) Calculate(TBarSeries source, int emaLength = 9, int sumLength = 25)
{
var indicator = new Massi(emaLength, sumLength);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+8 -1
View File
@@ -275,4 +275,11 @@ public sealed class Natr : AbstractBase
var natr = new Natr(period);
return natr.Update(source);
}
}
public static (TSeries Results, Natr Indicator) Calculate(TBarSeries source, int period = 14)
{
var indicator = new Natr(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+5 -5
View File
@@ -419,7 +419,7 @@ public class RsvTests
const int dataCount = 50;
var barSeries = GenerateTestData(dataCount);
var result = Rsv.Calculate(barSeries, period: 10);
var result = Rsv.Batch(barSeries, period: 10);
Assert.Equal(dataCount, result.Count);
}
@@ -685,7 +685,7 @@ public class RsvTests
{
var bars = GenerateTestData(100);
var result = Rsv.Calculate(bars, period: 14);
var result = Rsv.Batch(bars, period: 14);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -696,9 +696,9 @@ public class RsvTests
{
var bars = GenerateTestData(10);
Assert.Throws<ArgumentException>(() => Rsv.Calculate(bars, period: 0));
Assert.Throws<ArgumentException>(() => Rsv.Calculate(bars, period: -1));
Assert.Throws<ArgumentException>(() => Rsv.Calculate(bars, period: 10, annualize: true, annualPeriods: 0));
Assert.Throws<ArgumentException>(() => Rsv.Batch(bars, period: 0));
Assert.Throws<ArgumentException>(() => Rsv.Batch(bars, period: -1));
Assert.Throws<ArgumentException>(() => Rsv.Batch(bars, period: 10, annualize: true, annualPeriods: 0));
}
[Fact]
+1 -1
View File
@@ -184,7 +184,7 @@ public class RsvValidationTests
}
// Batch calculation
var batchResult = Rsv.Calculate(bars, 14);
var batchResult = Rsv.Batch(bars, 14);
// Compare last values
Assert.Equal(batchResult.Last.Value, streamingRsv.Last.Value, 8);
+18 -5
View File
@@ -49,6 +49,7 @@ public sealed class Rsv : AbstractBase
// Event source for disposal
private readonly ITValuePublisher? _source;
private bool _disposed;
[StructLayout(LayoutKind.Auto)]
private record struct State(
@@ -363,9 +364,13 @@ public sealed class Rsv : AbstractBase
/// <param name="disposing">True if disposing managed resources.</param>
protected override void Dispose(bool disposing)
{
if (disposing && _source is not null)
if (!_disposed)
{
_source.Pub -= Handle;
if (disposing && _source is not null)
{
_source.Pub -= Handle;
}
_disposed = true;
}
base.Dispose(disposing);
}
@@ -378,7 +383,7 @@ public sealed class Rsv : AbstractBase
/// <param name="annualize">Whether to annualize.</param>
/// <param name="annualPeriods">Periods per year.</param>
/// <returns>A TSeries containing the volatility values.</returns>
public static TSeries Calculate(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var rsv = new Rsv(period, annualize, annualPeriods);
return rsv.Update(source);
@@ -387,7 +392,7 @@ public sealed class Rsv : AbstractBase
/// <summary>
/// Calculates RSV for a TSeries (treats values as pre-computed RS variances).
/// </summary>
public static TSeries Calculate(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
if (period <= 0)
{
@@ -523,6 +528,14 @@ public sealed class Rsv : AbstractBase
}
}
public static (TSeries Results, Rsv Indicator) Calculate(TBarSeries source, int period = 20, bool annualize = true, int annualPeriods = 252)
{
var indicator = new Rsv(period, annualize, annualPeriods);
TSeries results = indicator.Update(source);
return (results, indicator);
}
/// <summary>
/// Batch calculation from pre-computed RS variances.
/// </summary>
@@ -596,4 +609,4 @@ public sealed class Rsv : AbstractBase
output[i] = volatility;
}
}
}
}
+7 -7
View File
@@ -439,7 +439,7 @@ public class RvTests
const int dataCount = 50;
var priceSeries = GeneratePriceSeries(dataCount);
var result = Rv.Calculate(priceSeries, period: 5, smoothingPeriod: 10);
var result = Rv.Batch(priceSeries, period: 5, smoothingPeriod: 10);
Assert.Equal(dataCount, result.Count);
}
@@ -617,7 +617,7 @@ public class RvTests
{
var prices = GeneratePriceSeries(100);
var result = Rv.Calculate(prices, period: 5, smoothingPeriod: 14);
var result = Rv.Batch(prices, period: 5, smoothingPeriod: 14);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -628,7 +628,7 @@ public class RvTests
{
var bars = GenerateTestData(100);
var result = Rv.Calculate(bars, period: 5, smoothingPeriod: 14);
var result = Rv.Batch(bars, period: 5, smoothingPeriod: 14);
Assert.Equal(100, result.Count);
Assert.True(double.IsFinite(result[result.Count - 1].Value));
@@ -639,10 +639,10 @@ public class RvTests
{
var prices = GeneratePriceSeries(10);
Assert.Throws<ArgumentException>(() => Rv.Calculate(prices, period: 0));
Assert.Throws<ArgumentException>(() => Rv.Calculate(prices, period: -1));
Assert.Throws<ArgumentException>(() => Rv.Calculate(prices, period: 5, smoothingPeriod: 0));
Assert.Throws<ArgumentException>(() => Rv.Calculate(prices, period: 5, smoothingPeriod: 10, annualize: true, annualPeriods: 0));
Assert.Throws<ArgumentException>(() => Rv.Batch(prices, period: 0));
Assert.Throws<ArgumentException>(() => Rv.Batch(prices, period: -1));
Assert.Throws<ArgumentException>(() => Rv.Batch(prices, period: 5, smoothingPeriod: 0));
Assert.Throws<ArgumentException>(() => Rv.Batch(prices, period: 5, smoothingPeriod: 10, annualize: true, annualPeriods: 0));
}
[Fact]
+1 -1
View File
@@ -178,7 +178,7 @@ public class RvValidationTests
}
// Batch calculation
var batchResult = Rv.Calculate(prices, 5, 10);
var batchResult = Rv.Batch(prices, 5, 10);
Assert.Equal(batchResult.Last.Value, streamingRv.Last.Value, 8);
}
+11 -3
View File
@@ -349,7 +349,7 @@ public sealed class Rv : AbstractBase
/// <param name="annualize">Whether to annualize.</param>
/// <param name="annualPeriods">Periods per year.</param>
/// <returns>A TSeries containing the volatility values.</returns>
public static TSeries Calculate(TSeries source, int period = 5, int smoothingPeriod = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TSeries source, int period = 5, int smoothingPeriod = 20, bool annualize = true, int annualPeriods = 252)
{
if (period < 1)
{
@@ -382,7 +382,7 @@ public sealed class Rv : AbstractBase
/// <summary>
/// Calculates RV for a bar series (static).
/// </summary>
public static TSeries Calculate(TBarSeries source, int period = 5, int smoothingPeriod = 20, bool annualize = true, int annualPeriods = 252)
public static TSeries Batch(TBarSeries source, int period = 5, int smoothingPeriod = 20, bool annualize = true, int annualPeriods = 252)
{
var rv = new Rv(period, smoothingPeriod, annualize, annualPeriods);
return rv.Update(source);
@@ -524,4 +524,12 @@ public sealed class Rv : AbstractBase
output[i] = result;
}
}
}
public static (TSeries Results, Rv Indicator) Calculate(TSeries source, int period = 5, int smoothingPeriod = 20, bool annualize = true, int annualPeriods = 252)
{
var indicator = new Rv(period, smoothingPeriod, annualize, annualPeriods);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+3 -3
View File
@@ -423,7 +423,7 @@ public class RviTests
// Mode 2: Batch via TSeries
var tSeries = new TSeries(new List<long>(times), new List<double>(prices));
var batchResult = Rvi.Calculate(tSeries, stdevLength: 10, rmaLength: 14);
var batchResult = Rvi.Batch(tSeries, stdevLength: 10, rmaLength: 14);
// Mode 3: Span-based
double[] spanOutput = new double[dataLen];
@@ -636,7 +636,7 @@ public class RviTests
source.Add(new TValue(DateTime.UtcNow.AddSeconds(i), 100.0 + i * 0.5));
}
var result = Rvi.Calculate(source, stdevLength: 10, rmaLength: 14);
var result = Rvi.Batch(source, stdevLength: 10, rmaLength: 14);
Assert.Equal(50, result.Count);
// Allow small floating-point tolerance beyond [0,100]
@@ -654,7 +654,7 @@ public class RviTests
source.Add(new TBar(time, price - 1, price + 1, price - 2, price, 1000));
}
var result = Rvi.Calculate(source, stdevLength: 10, rmaLength: 14);
var result = Rvi.Batch(source, stdevLength: 10, rmaLength: 14);
Assert.Equal(50, result.Count);
}
+1 -1
View File
@@ -204,7 +204,7 @@ public class RviValidationTests
}
// Batch calculation
var batchResult = Rvi.Calculate(prices, 10, 14);
var batchResult = Rvi.Batch(prices, 10, 14);
// Compare last values
Assert.Equal(batchResult.Last.Value, streamingRvi.Last.Value, 8);
+11 -3
View File
@@ -370,7 +370,7 @@ public sealed class Rvi : AbstractBase
/// <param name="stdevLength">The lookback period for standard deviation.</param>
/// <param name="rmaLength">The lookback period for RMA smoothing.</param>
/// <returns>A TSeries containing the RVI values.</returns>
public static TSeries Calculate(TSeries source, int stdevLength = 10, int rmaLength = 14)
public static TSeries Batch(TSeries source, int stdevLength = 10, int rmaLength = 14)
{
if (stdevLength < 2)
{
@@ -399,7 +399,7 @@ public sealed class Rvi : AbstractBase
/// <summary>
/// Calculates RVI for a bar series (static).
/// </summary>
public static TSeries Calculate(TBarSeries source, int stdevLength = 10, int rmaLength = 14)
public static TSeries Batch(TBarSeries source, int stdevLength = 10, int rmaLength = 14)
{
var rvi = new Rvi(stdevLength, rmaLength);
return rvi.Update(source);
@@ -563,4 +563,12 @@ public sealed class Rvi : AbstractBase
output[i] = rviValue;
}
}
}
public static (TSeries Results, Rvi Indicator) Calculate(TSeries source, int stdevLength = 10, int rmaLength = 14)
{
var indicator = new Rvi(stdevLength, rmaLength);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+2 -2
View File
@@ -343,7 +343,7 @@ public class TrTests
}
// Mode 2: Batch via TBarSeries
var batchResult = Tr.Calculate(bars);
var batchResult = Tr.Batch(bars);
// Mode 3: Span-based
double[] highs = new double[dataLen];
@@ -523,7 +523,7 @@ public class TrTests
{
var bars = GenerateBars(50);
var result = Tr.Calculate(bars);
var result = Tr.Batch(bars);
Assert.Equal(50, result.Count);
Assert.All(result.Values.ToArray(), v => Assert.True(v >= 0));
+1 -1
View File
@@ -210,7 +210,7 @@ public class TrValidationTests
}
// Batch via TBarSeries
var batchResult = Tr.Calculate(bars);
var batchResult = Tr.Batch(bars);
Assert.Equal(streamingTr.Last.Value, batchResult.Last.Value, 10);
}
+10 -2
View File
@@ -281,7 +281,7 @@ public sealed class Tr : AbstractBase
/// </summary>
/// <param name="source">The source bar series.</param>
/// <returns>A TSeries containing the True Range values.</returns>
public static TSeries Calculate(TBarSeries source)
public static TSeries Batch(TBarSeries source)
{
var tr = new Tr();
return tr.Update(source);
@@ -412,4 +412,12 @@ public sealed class Tr : AbstractBase
Batch(highs, lows, closes, output);
}
}
public static (TSeries Results, Tr Indicator) Calculate(TBarSeries source)
{
var indicator = new Tr();
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+2 -2
View File
@@ -405,7 +405,7 @@ public class UiTests
}
// Mode 2: Batch via TSeries
var batchResult = Ui.Calculate(data, DefaultPeriod);
var batchResult = Ui.Batch(data, DefaultPeriod);
// Mode 3: Span-based
double[] spanOutput = new double[dataLen];
@@ -575,7 +575,7 @@ public class UiTests
{
var data = GenerateData(50);
var result = Ui.Calculate(data, DefaultPeriod);
var result = Ui.Batch(data, DefaultPeriod);
Assert.Equal(50, result.Count);
Assert.All(result.Values.ToArray(), v => Assert.True(v >= 0));
+1 -1
View File
@@ -220,7 +220,7 @@ public class UiValidationTests
}
// Batch via TSeries
var batchResult = Ui.Calculate(data, DefaultPeriod);
var batchResult = Ui.Batch(data, DefaultPeriod);
Assert.Equal(streamingUi.Last.Value, batchResult.Last.Value, 10);
}
+10 -2
View File
@@ -263,7 +263,7 @@ public sealed class Ui : AbstractBase
/// <param name="source">The source series.</param>
/// <param name="period">The lookback period.</param>
/// <returns>A TSeries containing the Ulcer Index values.</returns>
public static TSeries Calculate(TSeries source, int period = 14)
public static TSeries Batch(TSeries source, int period = 14)
{
var ui = new Ui(period);
return ui.Update(source);
@@ -398,4 +398,12 @@ public sealed class Ui : AbstractBase
}
}
}
}
public static (TSeries Results, Ui Indicator) Calculate(TSeries source, int period = 14)
{
var indicator = new Ui(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+2 -2
View File
@@ -399,7 +399,7 @@ public class VovTests
{
var data = GenerateData(100);
var result = Vov.Calculate(data, volatilityPeriod: 10, vovPeriod: 5);
var result = Vov.Batch(data, volatilityPeriod: 10, vovPeriod: 5);
Assert.Equal(data.Count, result.Count);
for (int i = 0; i < result.Count; i++)
@@ -482,7 +482,7 @@ public class VovTests
}
// Mode 2: TSeries batch
var batchResult = Vov.Calculate(data, volPeriod, vovPeriod);
var batchResult = Vov.Batch(data, volPeriod, vovPeriod);
// Mode 3: Span batch
double[] spanOutput = new double[dataLen];
+1 -1
View File
@@ -187,7 +187,7 @@ public class VovValidationTests
}
// Batch via TSeries
var batchResult = Vov.Calculate(data, DefaultVolatilityPeriod, DefaultVovPeriod);
var batchResult = Vov.Batch(data, DefaultVolatilityPeriod, DefaultVovPeriod);
Assert.Equal(streamingVov.Last.Value, batchResult.Last.Value, 10);
}
+10 -2
View File
@@ -308,7 +308,7 @@ public sealed class Vov : AbstractBase
/// <param name="volatilityPeriod">The volatility period.</param>
/// <param name="vovPeriod">The VOV period.</param>
/// <returns>A TSeries containing the VOV values.</returns>
public static TSeries Calculate(TSeries source, int volatilityPeriod = 20, int vovPeriod = 10)
public static TSeries Batch(TSeries source, int volatilityPeriod = 20, int vovPeriod = 10)
{
var vov = new Vov(volatilityPeriod, vovPeriod);
return vov.Update(source);
@@ -462,4 +462,12 @@ public sealed class Vov : AbstractBase
}
}
}
}
public static (TSeries Results, Vov Indicator) Calculate(TSeries source, int volatilityPeriod = 20, int vovPeriod = 10)
{
var indicator = new Vov(volatilityPeriod, vovPeriod);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+2 -2
View File
@@ -377,7 +377,7 @@ public class VrTests
{
var bars = GenerateBarData(100);
var result = Vr.Calculate(bars, period: 10);
var result = Vr.Batch(bars, period: 10);
Assert.Equal(bars.Count, result.Count);
for (int i = 0; i < result.Count; i++)
@@ -472,7 +472,7 @@ public class VrTests
}
// Mode 2: TBarSeries batch
var batchResult = Vr.Calculate(bars, period);
var batchResult = Vr.Batch(bars, period);
// Mode 3: Span batch
double[] spanOutput = new double[bars.Count];
+1 -1
View File
@@ -167,7 +167,7 @@ public class VrValidationTests
int period = 14;
// Using static Calculate
var calculateResult = Vr.Calculate(bars, period);
var calculateResult = Vr.Batch(bars, period);
// Using Batch
double[] batchOutput = new double[bars.Count];
+10 -2
View File
@@ -269,7 +269,7 @@ public sealed class Vr : AbstractBase
/// <summary>
/// Calculates VR for a TBarSeries (static).
/// </summary>
public static TSeries Calculate(TBarSeries source, int period = 14)
public static TSeries Batch(TBarSeries source, int period = 14)
{
var vr = new Vr(period);
return vr.Update(source);
@@ -411,4 +411,12 @@ public sealed class Vr : AbstractBase
output[i] = vr;
}
}
}
public static (TSeries Results, Vr Indicator) Calculate(TBarSeries source, int period = 14)
{
var indicator = new Vr(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}
+2 -2
View File
@@ -374,7 +374,7 @@ public class YzvTests
{
var bars = GenerateBarData(100);
var result = Yzv.Calculate(bars, period: 10);
var result = Yzv.Batch(bars, period: 10);
Assert.Equal(bars.Count, result.Count);
for (int i = 0; i < result.Count; i++)
@@ -471,7 +471,7 @@ public class YzvTests
}
// Mode 2: TBarSeries batch
var batchResult = Yzv.Calculate(bars, period);
var batchResult = Yzv.Batch(bars, period);
// Mode 3: Span batch
double[] spanOutput = new double[bars.Count];
+1 -1
View File
@@ -167,7 +167,7 @@ public class YzvValidationTests
int period = 14;
// Using static Calculate
var calculateResult = Yzv.Calculate(bars, period);
var calculateResult = Yzv.Batch(bars, period);
// Using Batch
double[] batchOutput = new double[bars.Count];
+10 -2
View File
@@ -280,7 +280,7 @@ public sealed class Yzv : AbstractBase
/// <summary>
/// Calculates YZV for a TBarSeries (static).
/// </summary>
public static TSeries Calculate(TBarSeries source, int period = 20)
public static TSeries Batch(TBarSeries source, int period = 20)
{
var yzv = new Yzv(period);
return yzv.Update(source);
@@ -441,4 +441,12 @@ public sealed class Yzv : AbstractBase
output[i] = yzv;
}
}
}
public static (TSeries Results, Yzv Indicator) Calculate(TBarSeries source, int period = 20)
{
var indicator = new Yzv(period);
TSeries results = indicator.Update(source);
return (results, indicator);
}
}