mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-18 18:48:05 +00:00
normalization of methods
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 ==============
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 ==============
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 ==============
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user