Quantower adaptation

This commit is contained in:
Miha Kralj
2022-12-21 16:39:34 -08:00
parent 3c3caaf700
commit 798d9b424d
3 changed files with 253 additions and 252 deletions
+57 -57
View File
@@ -1,57 +1,57 @@
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using TradingPlatform.BusinessLayer; using TradingPlatform.BusinessLayer;
namespace QuanTAlib; namespace QuanTAlib;
public class AAA_chart : Indicator { public class AAA_chart : Indicator {
#region Parameters #region Parameters
[InputParameter("Smoothing period", 0, 1, 999, 1, 1)] [InputParameter("Smoothing period", 0, 1, 999, 1, 1)]
private readonly int Period = 10; private readonly int Period = 10;
#endregion Parameters #endregion Parameters
private TBars bars; private TBars bars;
private JMA_Series ind_a; private JMA_Series ind_a;
private DWMA_Series ind_b; private DWMA_Series ind_b;
public override string ShortName => $"AAA ({this.Period})"; public override string ShortName => $"AAA ({this.Period})";
public AAA_chart() : base() public AAA_chart() : base()
{ {
this.SeparateWindow = false; this.SeparateWindow = false;
this.Name = "AAA - Test indicator"; this.Name = "AAA - Test indicator";
this.Description = "Test indicator"; this.Description = "Test indicator";
this.AddLineSeries("JMA", Color.RoyalBlue, 3, LineStyle.Solid); this.AddLineSeries("JMA", Color.RoyalBlue, 3, LineStyle.Solid);
this.AddLineSeries("DWMA", Color.OrangeRed, 3, LineStyle.Solid); this.AddLineSeries("DWMA", Color.OrangeRed, 3, LineStyle.Solid);
this.SeparateWindow = false; this.SeparateWindow = false;
} }
protected override void OnInit() protected override void OnInit()
{ {
this.bars = new(); this.bars = new();
this.ind_a = new(source: bars.Close, period: this.Period, useNaN: false); this.ind_a = new(source: bars.Close, period: this.Period, useNaN: false);
this.ind_b = new(source: bars.OHLC4, period: this.Period, useNaN: false); this.ind_b = new(source: bars.OHLC4, period: this.Period, useNaN: false);
} }
protected override void OnUpdate(UpdateArgs args) protected override void OnUpdate(UpdateArgs args)
{ {
bool update = !(args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar); bool update = !(args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar);
this.bars.Add(this.Time(), this.bars.Add(this.Time(),
this.GetPrice(PriceType.Open), this.GetPrice(PriceType.Open),
this.GetPrice(PriceType.High), this.GetPrice(PriceType.High),
this.GetPrice(PriceType.Low), this.GetPrice(PriceType.Low),
this.GetPrice(PriceType.Close), this.GetPrice(PriceType.Close),
this.GetPrice(PriceType.Volume), this.GetPrice(PriceType.Volume),
update); update);
this.SetValue(this.ind_a.v.Last(), 0); this.SetValue(this.ind_a.v.Last(), 0);
this.SetValue(this.ind_b.v.Last(), 1); this.SetValue(this.ind_b.v.Last(), 1);
} }
} }
+1
View File
@@ -33,6 +33,7 @@ public class Skender
[Fact] [Fact]
public void ADL() public void ADL()
{ {
// TODO: check precision of ADL()
ADL_Series QL = new(bars, false); ADL_Series QL = new(bars, false);
var SK = quotes.GetAdl().Select(i => i.Adl); var SK = quotes.GetAdl().Select(i => i.Adl);
for (int i = QL.Length; i > skip; i--) for (int i = QL.Length; i > skip; i--)
+195 -195
View File
@@ -1,195 +1,195 @@
using Xunit; using Xunit;
using System; using System;
using Tulip; using Tulip;
using QuanTAlib; using QuanTAlib;
namespace Validations; namespace Validations;
public class Tulip_Test public class Tulip_Test
{ {
private readonly GBM_Feed bars; private readonly GBM_Feed bars;
private readonly Random rnd = new(); private readonly Random rnd = new();
private readonly int period, digits, skip; private readonly int period, digits, skip;
private readonly double[] outdata; private readonly double[] outdata;
private readonly double[] inopen; private readonly double[] inopen;
private readonly double[] inhigh; private readonly double[] inhigh;
private readonly double[] inlow; private readonly double[] inlow;
private readonly double[] inclose; private readonly double[] inclose;
private readonly double[] involume; private readonly double[] involume;
public Tulip_Test() public Tulip_Test()
{ {
bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0, Precision: 3); bars = new(Bars: 5000, Volatility: 0.8, Drift: 0.0, Precision: 3);
period = rnd.Next(28) + 3; period = rnd.Next(28) + 3;
skip = 200; skip = 200;
digits = 10; digits = 10;
outdata = new double[bars.Count]; outdata = new double[bars.Count];
inopen = bars.Open.v.ToArray(); inopen = bars.Open.v.ToArray();
inhigh = bars.High.v.ToArray(); inhigh = bars.High.v.ToArray();
inlow = bars.Low.v.ToArray(); inlow = bars.Low.v.ToArray();
inclose = bars.Close.v.ToArray()!; inclose = bars.Close.v.ToArray()!;
involume = bars.Volume.v.ToArray()!; involume = bars.Volume.v.ToArray()!;
} }
[Fact] [Fact]
public void ADL() public void ADL()
{ {
double[][] arrin = {inhigh, inlow, inclose, involume }; double[][] arrin = {inhigh, inlow, inclose, involume };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
ADL_Series QL = new(bars, false); ADL_Series QL = new(bars, false);
Tulip.Indicators.ad.Run(inputs: arrin, options: new double[] { }, outputs: arrout); Tulip.Indicators.ad.Run(inputs: arrin, options: new double[] { }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i], digits); double TU_item = Math.Round(arrout[0][i], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void ADD() public void ADD()
{ {
double[][] arrin = { inhigh, inlow }; double[][] arrin = { inhigh, inlow };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
ADD_Series QL = new(bars.High, bars.Low); ADD_Series QL = new(bars.High, bars.Low);
Tulip.Indicators.add.Run(inputs: arrin, options: new double[] { period }, outputs: arrout); Tulip.Indicators.add.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i], digits); double TU_item = Math.Round(arrout[0][i], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void ADOSC() public void ADOSC()
{ {
double[][] arrin = { inhigh, inlow, inclose, involume }; double[][] arrin = { inhigh, inlow, inclose, involume };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
int s = 3; int s = 3;
ADOSC_Series QL = new(bars, s, period, false); ADOSC_Series QL = new(bars, s, period, false);
Tulip.Indicators.adosc.Run(inputs: arrin, options: new double[] { s, period }, outputs: arrout); Tulip.Indicators.adosc.Run(inputs: arrin, options: new double[] { s, period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i-period+1], digits); double TU_item = Math.Round(arrout[0][i-period+1], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void ATR() public void ATR()
{ {
double[][] arrin = { inhigh, inlow, inclose }; double[][] arrin = { inhigh, inlow, inclose };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
ATR_Series QL = new(bars, period, false); ATR_Series QL = new(bars, period, false);
Tulip.Indicators.atr.Run(inputs: arrin, options: new double[] { period }, outputs: arrout); Tulip.Indicators.atr.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i - period + 1], digits); double TU_item = Math.Round(arrout[0][i - period + 1], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void BBANDS() public void BBANDS()
{ {
double[][] arrin = { inclose }; double[][] arrin = { inclose };
double[] outmid = new double[bars.Count]; double[] outmid = new double[bars.Count];
double[] outlower = new double[bars.Count]; double[] outlower = new double[bars.Count];
double[] outupper = new double[bars.Count]; double[] outupper = new double[bars.Count];
double[][] arrout = { outlower, outmid, outupper}; double[][] arrout = { outlower, outmid, outupper};
BBANDS_Series QL = new(bars.Close, period, 2, false); BBANDS_Series QL = new(bars.Close, period, 2, false);
Tulip.Indicators.bbands.Run(inputs: arrin, options: new double[] { period, 2 }, outputs: arrout); Tulip.Indicators.bbands.Run(inputs: arrin, options: new double[] { period, 2 }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL.Lower[i].v, digits: digits); double QL_item = Math.Round(QL.Lower[i].v, digits: digits);
double TU_item = Math.Round(outlower[i - period + 1], digits); double TU_item = Math.Round(outlower[i - period + 1], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
QL_item = Math.Round(QL.Mid[i].v, digits: digits); QL_item = Math.Round(QL.Mid[i].v, digits: digits);
TU_item = Math.Round(outmid[i - period + 1], digits); TU_item = Math.Round(outmid[i - period + 1], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
QL_item = Math.Round(QL.Upper[i].v, digits: digits); QL_item = Math.Round(QL.Upper[i].v, digits: digits);
TU_item = Math.Round(outupper[i - period + 1], digits); TU_item = Math.Round(outupper[i - period + 1], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void DEMA() { public void DEMA() {
double[][] arrin = { inclose }; double[][] arrin = { inclose };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
DEMA_Series QL = new(bars.Close, period, useNaN: false, useSMA: false); DEMA_Series QL = new(bars.Close, period, useNaN: false, useSMA: false);
Tulip.Indicators.dema.Run(inputs: arrin, options: new double[] { period }, outputs: arrout); Tulip.Indicators.dema.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) { for (int i = QL.Length - 1; i > skip; i--) {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i-(period+period-2)], digits); double TU_item = Math.Round(arrout[0][i-(period+period-2)], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void EMA() public void EMA()
{ {
double[][] arrin = { inclose }; double[][] arrin = { inclose };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
EMA_Series QL = new(bars.Close, period, false); EMA_Series QL = new(bars.Close, period, false);
Tulip.Indicators.ema.Run(inputs: arrin, options: new double[] { period }, outputs: arrout); Tulip.Indicators.ema.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i], digits); double TU_item = Math.Round(arrout[0][i], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void AVGPRICE() public void AVGPRICE()
{ {
double[][] arrin = { inopen, inhigh, inlow, inclose }; double[][] arrin = { inopen, inhigh, inlow, inclose };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
TSeries QL = bars.OHLC4; TSeries QL = bars.OHLC4;
Tulip.Indicators.avgprice.Run(inputs: arrin, options: new double[] { }, outputs: arrout); Tulip.Indicators.avgprice.Run(inputs: arrin, options: new double[] { }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i], digits); double TU_item = Math.Round(arrout[0][i], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
[Fact] [Fact]
public void SMA() public void SMA()
{ {
double[][] arrin = { inclose }; double[][] arrin = { inclose };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
SMA_Series QL = new(bars.Close, period, false); SMA_Series QL = new(bars.Close, period, false);
Tulip.Indicators.sma.Run(inputs: arrin, options: new double[] { period }, outputs: arrout); Tulip.Indicators.sma.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) for (int i = QL.Length - 1; i > skip; i--)
{ {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i-period+1], digits); double TU_item = Math.Round(arrout[0][i-period+1], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
/* /*
[Fact] [Fact]
public void HMA() { public void HMA() {
double[][] arrin = { inclose }; double[][] arrin = { inclose };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
HMA_Series QL = new(bars.Close, period, false); HMA_Series QL = new(bars.Close, period, false);
Tulip.Indicators.hma.Run(inputs: arrin, options: new double[] { period }, outputs: arrout); Tulip.Indicators.hma.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) { for (int i = QL.Length - 1; i > skip; i--) {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i-period-1], digits); double TU_item = Math.Round(arrout[0][i-period-1], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
}*/ }*/
[Fact] [Fact]
public void CMO() { public void CMO() {
double[][] arrin = { inclose }; double[][] arrin = { inclose };
double[][] arrout = { outdata }; double[][] arrout = { outdata };
CMO_Series QL = new(bars.Close, period, useNaN: false); CMO_Series QL = new(bars.Close, period, useNaN: false);
Tulip.Indicators.cmo.Run(inputs: arrin, options: new double[] { period }, outputs: arrout); Tulip.Indicators.cmo.Run(inputs: arrin, options: new double[] { period }, outputs: arrout);
for (int i = QL.Length - 1; i > skip; i--) { for (int i = QL.Length - 1; i > skip; i--) {
double QL_item = Math.Round(QL[i].v, digits: digits); double QL_item = Math.Round(QL[i].v, digits: digits);
double TU_item = Math.Round(arrout[0][i-period], digits); double TU_item = Math.Round(arrout[0][i-period], digits);
Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits)); Assert.InRange(TU_item! - QL_item, -Math.Exp(-digits), Math.Exp(-digits));
} }
} }
} }