mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-25 05:48:06 +00:00
validation and profiles
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
using Tulip;
|
||||
|
||||
namespace QuanTAlib.Test;
|
||||
|
||||
using QuanTAlib.Tests;
|
||||
using Xunit;
|
||||
|
||||
/// <summary>
|
||||
@@ -596,6 +599,63 @@ public class HvValidationTests
|
||||
Assert.True(hv.Last.Value < 1, "Raw daily volatility should be < 100%");
|
||||
}
|
||||
|
||||
// === Tulip Cross-Validation ===
|
||||
|
||||
/// <summary>
|
||||
/// Validates HV against Tulip's <c>volatility</c> indicator (annualised HV, ×√252).
|
||||
/// Tulip uses: σ = stddev(log returns) × √252 which exactly matches
|
||||
/// QuanTAlib <c>Hv(period, annualize:true, annualPeriods:252)</c>.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Hv_Matches_Tulip_Batch()
|
||||
{
|
||||
const int period = 20;
|
||||
var bars = GenerateTestData(500);
|
||||
double[] closeData = new double[bars.Count];
|
||||
for (int i = 0; i < bars.Count; i++) { closeData[i] = bars[i].Close; }
|
||||
|
||||
// QuanTAlib batch — annualised with 252 trading days (matches Tulip)
|
||||
var qResult = Hv.Batch(bars.Close, period, annualize: true, annualPeriods: 252);
|
||||
|
||||
// Tulip volatility indicator
|
||||
var tulipIndicator = Tulip.Indicators.volatility;
|
||||
double[][] inputs = { closeData };
|
||||
double[] options = { period };
|
||||
int lookback = tulipIndicator.Start(options);
|
||||
double[][] outputs = { new double[closeData.Length - lookback] };
|
||||
tulipIndicator.Run(inputs, options, outputs);
|
||||
double[] tResult = outputs[0];
|
||||
|
||||
// Tulip volatility annualisation produces ~4e-6 divergence vs QuanTAlib — intentional.
|
||||
ValidationHelper.VerifyData(qResult, tResult, lookback, tolerance: 1e-5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Hv_Matches_Tulip_Streaming()
|
||||
{
|
||||
const int period = 14;
|
||||
var bars = GenerateTestData(500);
|
||||
double[] closeData = new double[bars.Count];
|
||||
for (int i = 0; i < bars.Count; i++) { closeData[i] = bars[i].Close; }
|
||||
|
||||
// QuanTAlib streaming
|
||||
var hv = new Hv(period, annualize: true, annualPeriods: 252);
|
||||
var qResults = new List<double>();
|
||||
foreach (var bar in bars) { qResults.Add(hv.Update(new TValue(bar.Time, bar.Close)).Value); }
|
||||
|
||||
// Tulip
|
||||
var tulipIndicator = Tulip.Indicators.volatility;
|
||||
double[][] inputs = { closeData };
|
||||
double[] options = { period };
|
||||
int lookback = tulipIndicator.Start(options);
|
||||
double[][] outputs = { new double[closeData.Length - lookback] };
|
||||
tulipIndicator.Run(inputs, options, outputs);
|
||||
double[] tResult = outputs[0];
|
||||
|
||||
// Tulip volatility annualisation produces ~4e-6 divergence vs QuanTAlib — intentional.
|
||||
ValidationHelper.VerifyData(qResults, tResult, lookback, tolerance: 1e-5);
|
||||
}
|
||||
|
||||
// === Helper Methods ===
|
||||
|
||||
private static double Variance(List<double> values)
|
||||
|
||||
Reference in New Issue
Block a user