mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-13 16:18:05 +00:00
This commit fixes the style issues introduced in ed45c9e according to the output
from dotnet-format.
Details: None
418 lines
18 KiB
C#
418 lines
18 KiB
C#
using Xunit;
|
|
using System;
|
|
using TALib;
|
|
using QuanTAlib;
|
|
|
|
namespace Validations;
|
|
public class Ta_Lib {
|
|
private readonly GBM_Feed bars;
|
|
private readonly Random rnd = new();
|
|
private readonly int period, digits, skip;
|
|
private readonly double[] TALIB;
|
|
private readonly double[] TALIB2;
|
|
private readonly double[] inopen;
|
|
private readonly double[] inhigh;
|
|
private readonly double[] inlow;
|
|
private readonly double[] inclose;
|
|
private readonly double[] involume;
|
|
|
|
public Ta_Lib() {
|
|
bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0, Precision: 3);
|
|
period = rnd.Next(28) + 3;
|
|
skip = period + 2;
|
|
digits = 9;
|
|
|
|
TALIB = new double[bars.Count];
|
|
TALIB2 = new double[bars.Count];
|
|
inopen = bars.Open.v.ToArray();
|
|
inhigh = bars.High.v.ToArray();
|
|
inlow = bars.Low.v.ToArray();
|
|
inclose = bars.Close.v.ToArray();
|
|
involume = bars.Volume.v.ToArray();
|
|
}
|
|
|
|
[Fact]
|
|
public void ADD() {
|
|
ADD_Series QL = new(bars.Open, bars.Close);
|
|
Core.Add(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void ADL() {
|
|
ADL_Series QL = new(bars);
|
|
Core.Ad(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > 0; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void ADOSC() {
|
|
ADOSC_Series QL = new(bars, 3, 10, false);
|
|
Core.AdOsc(inhigh, inlow, inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip * 2; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void ATR() {
|
|
ATR_Series QL = new(bars, period: period, useNaN: false);
|
|
Core.Atr(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void BBANDS() {
|
|
double[] outMiddle = new double[bars.Count];
|
|
double[] outUpper = new double[bars.Count];
|
|
double[] outLower = new double[bars.Count];
|
|
BBANDS_Series QL = new(bars.Close, period: period, multiplier: 2.0, false);
|
|
Core.Bbands(inclose, 0, bars.Count - 1, outRealUpperBand: outUpper, outRealMiddleBand: outMiddle, outRealLowerBand: outLower, out int outBegIdx, out _, optInTimePeriod: period, optInNbDevUp: 2.0, optInNbDevDn: 2.0);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL.Upper[i].v;
|
|
double TA_item = outUpper[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), high: Math.Exp(-digits));
|
|
QL_item = QL.Mid[i].v;
|
|
TA_item = outMiddle[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), high: Math.Exp(-digits));
|
|
QL_item = QL.Lower[i].v;
|
|
TA_item = outLower[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), high: Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void CCI() {
|
|
CCI_Series QL = new(bars, period, false);
|
|
Core.Cci(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
/* CMO in TA-LIB is not valid
|
|
[Fact]
|
|
public void CMO() {
|
|
CMO_Series QL = new(bars.Close, period, false);
|
|
Core.Cmo(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
*/
|
|
[Fact]
|
|
public void CORR() {
|
|
CORR_Series QL = new(bars.Open, bars.Close, period);
|
|
Core.Correl(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, optInTimePeriod: period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void DEMA() {
|
|
DEMA_Series QL = new(bars.Close, period, false, useSMA: false);
|
|
Core.Dema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > period * 10; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void DIV() {
|
|
DIV_Series QL = new(bars.Open, bars.Close);
|
|
Core.Div(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void EMA() {
|
|
EMA_Series QL = new(bars.Close, period, false);
|
|
Core.Ema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void HL2() {
|
|
TSeries QL = bars.HL2;
|
|
Core.MedPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void HLC3() {
|
|
TSeries QL = bars.HLC3;
|
|
Core.TypPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void HLCC4() {
|
|
TSeries QL = bars.HLCC4;
|
|
Core.WclPrice(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void KAMA() {
|
|
KAMA_Series QL = new(bars.Close, period, fast: 2, slow: 30);
|
|
Core.Kama(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outReal: TALIB, outBegIdx: out int outBegIdx, outNbElement: out _, optInTimePeriod: period);
|
|
for (int i = QL.Length - 1; i > skip * 15; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void MACD() {
|
|
double[] macdSignal = new double[bars.Count];
|
|
double[] macdHist = new double[bars.Count];
|
|
MACD_Series QL = new(bars.Close, slow: 26, fast: 12, signal: 9, false);
|
|
// TA-LIB runs EMA without SMA, leaving first 100 values for convergence
|
|
Core.Macd(inclose, 0, bars.Count - 1, outMacd: TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _, optInFastPeriod: 12, optInSlowPeriod: 26, optInSignalPeriod: 9);
|
|
for (int i = QL.Length - 1; i > 100; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
QL_item = QL.Signal[i].v;
|
|
TA_item = macdSignal[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
/*
|
|
[Fact]
|
|
public void MAMA()
|
|
{
|
|
MAMA_Series QL = new(bars.Close, fastlimit: 0.5, slowlimit: 0.05);
|
|
Core.Mama(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outMama: TALIB, outFama: TALIB2, outBegIdx: out int outBegIdx, outNbElement: out _, optInFastLimit: 0.5, optInSlowLimit: 0.05);
|
|
for (int i = QL.Length - 1; i > skip * 10; i--)
|
|
{
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits-1), Math.Exp(-digits-1));
|
|
}
|
|
}
|
|
*/
|
|
[Fact]
|
|
public void MAX() {
|
|
MAX_Series QL = new(bars.Close, period, false);
|
|
Core.Max(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void MIDPOINT() {
|
|
MIDPOINT_Series QL = new(bars.Close, period, false);
|
|
Core.MidPoint(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void MIDPRICE() {
|
|
MIDPRICE_Series QL = new(bars, period, false);
|
|
Core.MidPrice(inhigh, inlow, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void MIN() {
|
|
MIN_Series QL = new(bars.Close, period, false);
|
|
Core.Min(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void MUL() {
|
|
MUL_Series QL = new(bars.Open, bars.Close);
|
|
Core.Mult(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void OBV() {
|
|
OBV_Series QL = new(bars, period, false);
|
|
Core.Obv(inclose, involume, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void OHLC4() {
|
|
TSeries QL = bars.OHLC4;
|
|
Core.AvgPrice(inopen, inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void RSI() {
|
|
RSI_Series QL = new(bars.Close, period, false);
|
|
Core.Rsi(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void SDEV() {
|
|
SDEV_Series QL = new(bars.Close, period, false);
|
|
Core.StdDev(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void SMA() {
|
|
SMA_Series QL = new(bars.Close, period, false);
|
|
Core.Sma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void SUB() {
|
|
SUB_Series QL = new(bars.Open, bars.Close);
|
|
Core.Sub(inopen, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void SUM() {
|
|
CUSUM_Series QL = new(bars.Close, period, false);
|
|
Core.Sum(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void T3() {
|
|
T3_Series QL = new(source: bars.Close, period: period, vfactor: 0.7, useNaN: false);
|
|
Core.T3(inReal: inclose, startIdx: 0, endIdx: bars.Count - 1, outReal: TALIB, outBegIdx: out int outBegIdx, outNbElement: out _, optInTimePeriod: period, optInVFactor: 0.7);
|
|
for (int i = QL.Length - 1; i > period * 10; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void TEMA() {
|
|
TEMA_Series QL = new(bars.Close, period, false);
|
|
Core.Tema(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip * 15; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void TR() {
|
|
TR_Series QL = new(bars);
|
|
Core.TRange(inhigh, inlow, inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void TRIMA() {
|
|
TRIMA_Series QL = new(bars.Close, period, false);
|
|
Core.Trima(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void TRIX() {
|
|
TRIX_Series QL = new(bars.Close, period, useNaN: false, useSMA: true);
|
|
Core.Trix(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > period * 10; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void VAR() {
|
|
VAR_Series QL = new(bars.Close, period, false);
|
|
Core.Var(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip * 15; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
[Fact]
|
|
public void WMA() {
|
|
WMA_Series QL = new(bars.Close, period, false);
|
|
Core.Wma(inclose, 0, bars.Count - 1, TALIB, out int outBegIdx, out _, period);
|
|
for (int i = QL.Length - 1; i > skip; i--) {
|
|
double QL_item = QL[i].v;
|
|
double TA_item = TALIB[i - outBegIdx];
|
|
Assert.InRange(TA_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
|
|
}
|
|
}
|
|
|
|
}
|