for dev branch

This commit is contained in:
Miha Kralj
2022-11-06 16:43:24 -08:00
parent 6465e79fc6
commit 32615af18b
14 changed files with 346 additions and 756 deletions
-52
View File
@@ -1,52 +0,0 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class JMA_chart : Indicator
{
#region Parameters
[InputParameter("Smoothing period", 0, 1, 999, 1, 1)]
private int Period = 10;
[InputParameter("Data source", 1, variants: new object[]
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
private int DataSource = 3;
#endregion Parameters
private TBars bars ;
///////
private JMA_Series indicator;
///////
public JMA_chart()
{
this.SeparateWindow = false;
this.Name = "JMA - Jurik Moving Average";
this.Description = "Jurik Moving Average description";
this.AddLineSeries("JMA", Color.RoyalBlue, 3, LineStyle.Solid);
}
protected override void OnInit()
{
this.ShortName =
"JMA (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")";
this.bars = new();
this.indicator = new(source: bars.Select(this.DataSource),
period: this.Period, useNaN: false);
}
protected override void OnUpdate(UpdateArgs args)
{
bool update = !(args.Reason == UpdateReason.NewBar ||
args.Reason == UpdateReason.HistoricalBar);
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low),
this.GetPrice(PriceType.Close),
this.GetPrice(PriceType.Volume), update);
double result = this.indicator[this.indicator.Count - 1].v;
this.SetValue(result);
}
}
-53
View File
@@ -1,53 +0,0 @@
using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class PSDEV_chart : Indicator
{
#region Parameters
[InputParameter("Smoothing period", 0, 1, 999, 1, 1)]
private int Period = 10;
[InputParameter("Data source", 1, variants: new object[]
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
private int DataSource = 8;
#endregion Parameters
private TBars bars;
///////dotnet
private PSDEV_Series indicator;
///////
public PSDEV_chart()
{
this.SeparateWindow = true;
this.Name = "PSDEV - Population Standard Deviation (Biased)";
this.Description = "PSDEV description";
this.AddLineSeries("PSDEV", Color.RoyalBlue, 3, LineStyle.Solid);
}
protected override void OnInit()
{
this.bars = new();
this.ShortName =
"PSDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")";
this.indicator = new(source: bars.Select(this.DataSource),
period: this.Period, useNaN: true);
}
protected override void OnUpdate(UpdateArgs args)
{
bool update = !(args.Reason == UpdateReason.NewBar ||
args.Reason == UpdateReason.HistoricalBar);
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low),
this.GetPrice(PriceType.Close),
this.GetPrice(PriceType.Volume), update);
double result = this.indicator[this.indicator.Count - 1].v;
this.SetValue(result, 0);
}
}
+53 -53
View File
@@ -1,53 +1,53 @@
using System.Drawing; using System.Drawing;
using TradingPlatform.BusinessLayer; using TradingPlatform.BusinessLayer;
namespace QuanTAlib; namespace QuanTAlib;
public class SDEV_chart : Indicator public class SDEV_chart : Indicator
{ {
#region Parameters #region Parameters
[InputParameter("Smoothing period", 0, 1, 999, 1, 1)] [InputParameter("Smoothing period", 0, 1, 999, 1, 1)]
private int Period = 10; private int Period = 10;
[InputParameter("Data source", 1, variants: new object[] [InputParameter("Data source", 1, variants: new object[]
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5, { "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })] "OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
private int DataSource = 8; private int DataSource = 8;
#endregion Parameters #endregion Parameters
private TBars bars; private TBars bars;
///////dotnet ///////dotnet
private SDEV_Series indicator; private SDEV_Series indicator;
/////// ///////
public SDEV_chart() public SDEV_chart()
{ {
this.SeparateWindow = true; this.SeparateWindow = true;
this.Name = "SDEV - Sample Standard Deviation (Unbiased)"; this.Name = "SDEV - Population Standard Deviation (Biased)";
this.Description = "SDEV description"; this.Description = "SDEV description";
this.AddLineSeries("SDEV", Color.RoyalBlue, 3, LineStyle.Solid); this.AddLineSeries("SDEV", Color.RoyalBlue, 3, LineStyle.Solid);
} }
protected override void OnInit() protected override void OnInit()
{ {
this.bars = new(); this.bars = new();
this.ShortName = this.ShortName =
"SDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")"; "SDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")";
this.indicator = new(source: bars.Select(this.DataSource), this.indicator = new(source: bars.Select(this.DataSource),
period: this.Period, useNaN: true); period: this.Period, useNaN: true);
} }
protected override void OnUpdate(UpdateArgs args) protected override void OnUpdate(UpdateArgs args)
{ {
bool update = !(args.Reason == UpdateReason.NewBar || bool update = !(args.Reason == UpdateReason.NewBar ||
args.Reason == UpdateReason.HistoricalBar); args.Reason == UpdateReason.HistoricalBar);
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open), this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low), this.GetPrice(PriceType.High), this.GetPrice(PriceType.Low),
this.GetPrice(PriceType.Close), this.GetPrice(PriceType.Close),
this.GetPrice(PriceType.Volume), update); this.GetPrice(PriceType.Volume), update);
double result = this.indicator[this.indicator.Count - 1].v; double result = this.indicator[this.indicator.Count - 1].v;
this.SetValue(result, 0); this.SetValue(result, 0);
} }
} }
+5 -6
View File
@@ -30,12 +30,12 @@ public class ZLMA_chart : Indicator
private readonly int matype = 2; private readonly int matype = 2;
#endregion Parameters #endregion Parameters
private TBars bars; private TBars bars;
/////// ///////
private TSeries indicator; private TSeries indicator;
/////// ///////
public ZLMA_chart() public ZLMA_chart()
{ {
this.SeparateWindow = false; this.SeparateWindow = false;
@@ -72,8 +72,7 @@ public class ZLMA_chart : Indicator
4 => new TEMA_Series(source: zerolag, period: this.Period, useNaN: false), 4 => new TEMA_Series(source: zerolag, period: this.Period, useNaN: false),
5 => new HMA_Series(source: zerolag, period: this.Period, useNaN: false), 5 => new HMA_Series(source: zerolag, period: this.Period, useNaN: false),
6 => new KAMA_Series(source: zerolag, period: this.Period, useNaN: false), 6 => new KAMA_Series(source: zerolag, period: this.Period, useNaN: false),
7 => new JMA_Series(source: zerolag, period: this.Period, useNaN: false), 7 => new SMMA_Series(source: zerolag, period: this.Period, useNaN: false),
8 => new SMMA_Series(source: zerolag, period: this.Period, useNaN: false),
_ => new EMA_Series(source: zerolag, period: this.Period, useNaN: false) _ => new EMA_Series(source: zerolag, period: this.Period, useNaN: false)
}; };
} }
+3 -1
View File
@@ -13,6 +13,8 @@ Alphavantage - Free API to collect quotes for stock, Forex and crypto. It requir
</summary> */ </summary> */
/* TODO: refactor into three feeds: FX, Crypto, Stock */
public class Alphavantage_Feed : TBars public class Alphavantage_Feed : TBars
{ {
public enum Interval { Month, Week, Day, Hour, Min30, Min15, Min5, Min1} public enum Interval { Month, Week, Day, Hour, Min30, Min15, Min5, Min1}
@@ -113,7 +115,7 @@ public class Alphavantage_Feed : TBars
{ {
Interval.Month => "_MONTHLY", Interval.Month => "_MONTHLY",
Interval.Week => "_WEEKLY", Interval.Week => "_WEEKLY",
Interval.Day => "_DAILY", Interval.Day => "_DAILY_ADJUSTED",
Interval.Hour => "_INTRADAY&interval=60min", Interval.Hour => "_INTRADAY&interval=60min",
Interval.Min30 => "_INTRADAY&interval=30min", Interval.Min30 => "_INTRADAY&interval=30min",
Interval.Min15 => "_INTRADAY&interval=15min", Interval.Min15 => "_INTRADAY&interval=15min",
+164 -159
View File
@@ -1,159 +1,164 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
/* <summary> /* <summary>
JMA: Jurik Moving Average JMA: Jurik Moving Average
Mark Jurik's Moving Average (JMA) attempts to eliminate noise to see the Mark Jurik's Moving Average (JMA) attempts to eliminate noise to see the
underlying activity. It has extremely low lag, is very smooth and is responsive underlying activity. It has extremely low lag, is very smooth and is responsive
to market gaps. to market gaps.
Sources: Sources:
https://c.mql5.com/forextsd/forum/164/jurik_1.pdf https://c.mql5.com/forextsd/forum/164/jurik_1.pdf
https://www.prorealcode.com/prorealtime-indicators/jurik-volatility-bands/ https://www.prorealcode.com/prorealtime-indicators/jurik-volatility-bands/
Issues: Issues:
Real JMA algorithm is not published and this formula is derived through Real JMA algorithm is not published and this formula is derived through
deduction and reverse analysis of JMA behavior. It is really close, but not deduction and reverse analysis of JMA behavior. It is really close, but not
exact - published JMA tests against JMA.CSV fail with small deviation. The exact - published JMA tests against JMA.CSV fail with small deviation. The
original algo is slightly different, yet this approximation is close enough. original algo is slightly different, yet this approximation is close enough.
</summary> */ </summary> */
public class JMA_Series : Single_TSeries_Indicator /* TODO: This indicator is not calculating results correctly - needs to be debugged */
{
private readonly System.Collections.Generic.List<double> vbuffer10; /*
private readonly System.Collections.Generic.List<double> vsum65; public class JMA_Series : Single_TSeries_Indicator
{
private double prev_ma1, prev_det0, prev_det1, prev_jma, bsmax, bsmin; private readonly System.Collections.Generic.List<double> vbuffer10;
private double o_prev_ma1, o_prev_det0, o_prev_det1, o_prev_jma, o_bsmax, o_bsmin; private readonly System.Collections.Generic.List<double> vsum65;
private readonly double pr, pow1, len2, beta, rvolty; private double prev_ma1, prev_det0, prev_det1, prev_jma, bsmax, bsmin;
private double o_prev_ma1, o_prev_det0, o_prev_det1, o_prev_jma, o_bsmax, o_bsmin;
public JMA_Series(TSeries source, int period, double phase = 0.0, bool useNaN = false) : base(source, period, useNaN)
{ private readonly double pr, pow1, len2, beta, rvolty;
this.vbuffer10 = new();
this.vsum65 = new(); public JMA_Series(TSeries source, int period, double phase = 0.0, bool useNaN = false) : base(source, period, useNaN)
{
// constants this.vbuffer10 = new();
this.pr = (phase < -100) ? 0.5 : (phase > 100) ? 2.5 : (phase * 0.01) + 1.5; this.vsum65 = new();
double len1 = Math.Max((Math.Log(Math.Sqrt(0.5 * (_p - 1))) / Math.Log(2.0)) + 2.0, 0);
this.pow1 = Math.Max(len1 - 2, 0.5); // constants
this.rvolty = Math.Exp((1 / this.pow1) * Math.Log(len1)); this.pr = (phase < -100) ? 0.5 : (phase > 100) ? 2.5 : (phase * 0.01) + 1.5;
this.len2 = Math.Sqrt(0.5 * (_p - 1)) * len1; double len1 = Math.Max((Math.Log(Math.Sqrt(0.5 * (_p - 1))) / Math.Log(2.0)) + 2.0, 0);
this.beta = 0.45 * (_p - 1) / (0.45 * (_p - 1) + 2); this.pow1 = Math.Max(len1 - 2, 0.5);
if (base._data.Count > 0) { base.Add(base._data); } this.rvolty = Math.Exp((1 / this.pow1) * Math.Log(len1));
} this.len2 = Math.Sqrt(0.5 * (_p - 1)) * len1;
this.beta = 0.45 * (_p - 1) / (0.45 * (_p - 1) + 2);
public override void Add((System.DateTime t, double v) TValue, bool update) if (base._data.Count > 0) { base.Add(base._data); }
{ }
if (this.Count == 0)
{ public override void Add((System.DateTime t, double v) TValue, bool update)
this.prev_ma1 = this.prev_jma = TValue.v; {
this.bsmax = this.bsmin = this.prev_det0 = this.prev_det1 = 0; if (this.Count == 0)
} {
this.prev_ma1 = this.prev_jma = TValue.v;
if (update) this.bsmax = this.bsmin = this.prev_det0 = this.prev_det1 = 0;
{ }
this.prev_jma = this.o_prev_jma;
this.prev_ma1 = this.o_prev_ma1; if (update)
this.prev_det0 = this.o_prev_det0; {
this.prev_det1 = this.o_prev_det1; this.prev_jma = this.o_prev_jma;
this.bsmax = this.o_bsmax; this.prev_ma1 = this.o_prev_ma1;
this.bsmin = this.o_bsmin; this.prev_det0 = this.o_prev_det0;
} this.prev_det1 = this.o_prev_det1;
else this.bsmax = this.o_bsmax;
{ this.bsmin = this.o_bsmin;
this.o_prev_jma = this.prev_jma; }
this.o_prev_ma1 = this.prev_ma1; else
this.o_prev_det0 = this.prev_det0; {
this.o_prev_det1 = this.prev_det1; this.o_prev_jma = this.prev_jma;
this.o_bsmax = this.bsmax; this.o_prev_ma1 = this.prev_ma1;
this.o_bsmin = this.bsmin; this.o_prev_det0 = this.prev_det0;
} this.o_prev_det1 = this.prev_det1;
this.o_bsmax = this.bsmax;
double hprice = TValue.v; this.o_bsmin = this.bsmin;
double lprice = TValue.v; }
for (int i = 0; i <= Math.Min(9, this._data.Count - 1); i++)
{ double hprice = TValue.v;
var _item = this._data[this._data.Count - 1 - i].v; double lprice = TValue.v;
hprice = (_item > hprice) ? _item : hprice; for (int i = 0; i <= Math.Min(9, this._data.Count - 1); i++)
lprice = (_item < lprice) ? _item : lprice; {
} var _item = this._data[this._data.Count - 1 - i].v;
double del1 = hprice - this.bsmax; hprice = (_item > hprice) ? _item : hprice;
double del2 = lprice - this.bsmin; lprice = (_item < lprice) ? _item : lprice;
}
double volty = (Math.Abs(del1) != Math.Abs(del2)) double del1 = hprice - this.bsmax;
? Math.Max(Math.Abs(del1), Math.Abs(del2)) double del2 = lprice - this.bsmin;
: 0;
if (update) double volty = (Math.Abs(del1) != Math.Abs(del2))
{ ? Math.Max(Math.Abs(del1), Math.Abs(del2))
this.vbuffer10[this.vbuffer10.Count - 1] = volty; : 0;
} if (update)
else {
{ this.vbuffer10[this.vbuffer10.Count - 1] = volty;
this.vbuffer10.Add(volty); }
} else
if (this.vbuffer10.Count > 10) {
{ this.vbuffer10.Add(volty);
this.vbuffer10.RemoveAt(0); }
} if (this.vbuffer10.Count > 10)
{
double prevvsum = this.vbuffer10.RemoveAt(0);
(this.vsum65.Count > 0) ? this.vsum65[this.vsum65.Count - 1] : 0; }
double vsumitem = prevvsum + 0.1 * (volty - this.vbuffer10[0]);
if (update) double prevvsum =
{ (this.vsum65.Count > 0) ? this.vsum65[this.vsum65.Count - 1] : 0;
this.vsum65[this.vsum65.Count - 1] = vsumitem; double vsumitem = prevvsum + 0.1 * (volty - this.vbuffer10[0]);
} if (update)
else {
{ this.vsum65[this.vsum65.Count - 1] = vsumitem;
this.vsum65.Add(vsumitem); }
} else
if (this.vsum65.Count > 65) {
{ this.vsum65.Add(vsumitem);
this.vsum65.RemoveAt(0); }
} if (this.vsum65.Count > 65)
{
double avolty = 0; this.vsum65.RemoveAt(0);
for (int i = 0; i < this.vsum65.Count; i++) }
{
avolty += this.vsum65[i]; double avolty = 0;
} for (int i = 0; i < this.vsum65.Count; i++)
{
avolty /= this.vsum65.Count; avolty += this.vsum65[i];
double dvolty = (avolty > 0) ? volty / avolty : 0; }
dvolty = Math.Max((dvolty > this.rvolty) ? this.rvolty : dvolty, 1.0);
avolty /= this.vsum65.Count;
double pow2 = Math.Exp(this.pow1 * Math.Log(dvolty)); double dvolty = (avolty > 0) ? volty / avolty : 0;
double kv = dvolty = Math.Max((dvolty > this.rvolty) ? this.rvolty : dvolty, 1.0);
Math.Exp(Math.Sqrt(pow2) * Math.Log(this.len2 / (this.len2 + 1)));
double pow2 = Math.Exp(this.pow1 * Math.Log(dvolty));
this.bsmax = (del1 > 0) ? hprice : hprice - (kv * del1); double kv =
this.bsmin = (del2 < 0) ? lprice : lprice - (kv * del2); Math.Exp(Math.Sqrt(pow2) * Math.Log(this.len2 / (this.len2 + 1)));
// adaptive EMA dynamic factor this.bsmax = (del1 > 0) ? hprice : hprice - (kv * del1);
double pow = Math.Pow(dvolty, this.pow1); this.bsmin = (del2 < 0) ? lprice : lprice - (kv * del2);
double alpha = Math.Pow(this.beta, pow);
// adaptive EMA dynamic factor
// 1st stage - preliminary smoothing by adaptive EMA double pow = Math.Pow(dvolty, this.pow1);
double ma1 = TValue.v * (1 - alpha) + this.prev_ma1 * alpha; double alpha = Math.Pow(this.beta, pow);
this.prev_ma1 = ma1;
// 1st stage - preliminary smoothing by adaptive EMA
// 2nd stage - one more preliminary smoothing by Kalman filter double ma1 = TValue.v * (1 - alpha) + this.prev_ma1 * alpha;
double det0 = (TValue.v - ma1) * (1 - this.beta) + this.prev_det0 * this.beta; this.prev_ma1 = ma1;
this.prev_det0 = det0;
double ma2 = ma1 + (this.pr * det0); // 2nd stage - one more preliminary smoothing by Kalman filter
double det0 = (TValue.v - ma1) * (1 - this.beta) + this.prev_det0 * this.beta;
// 3rd stage - final smoothing by Jurik adaptive filter this.prev_det0 = det0;
double det1 = ((ma2 - this.prev_jma) * (1 - alpha) * (1 - alpha)) + double ma2 = ma1 + (this.pr * det0);
(this.prev_det1 * alpha * alpha);
this.prev_det1 = det1; // 3rd stage - final smoothing by Jurik adaptive filter
var jma = this.prev_jma + det1; double det1 = ((ma2 - this.prev_jma) * (1 - alpha) * (1 - alpha)) +
this.prev_jma = jma; (this.prev_det1 * alpha * alpha);
this.prev_det1 = det1;
(System.DateTime t, double v) result = var jma = this.prev_jma + det1;
(TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : jma); this.prev_jma = jma;
base.Add(result, update);
(System.DateTime t, double v) result =
} (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : jma);
} base.Add(result, update);
}
}
*/
+2 -2
View File
@@ -13,7 +13,7 @@
<Authors>Miha Kralj</Authors> <Authors>Miha Kralj</Authors>
<Copyright>Miha Kralj</Copyright> <Copyright>Miha Kralj</Copyright>
<PackageReadmeFile>readme.md</PackageReadmeFile> <PackageReadmeFile>readme.md</PackageReadmeFile>
<TargetFrameworks>net7.0;net6.0;netstandard2.0</TargetFrameworks> <TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings> <ImplicitUsings>disable</ImplicitUsings>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<Nullable>disable</Nullable> <Nullable>disable</Nullable>
@@ -67,6 +67,6 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Text.Json" Version="7.0.0-preview.4.22229.4" /> <PackageReference Include="System.Text.Json" Version="7.0.0-rc.2.22472.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>
-44
View File
@@ -1,44 +0,0 @@
namespace QuanTAlib;
using System;
/* <summary>
PSDEV: Population Standard Deviation
Population Standard Deviation is the square root of the biased variance, also knons as
Uncorrected Sample Standard Deviation
Sources:
https://en.wikipedia.org/wiki/Standard_deviation#Uncorrected_sample_standard_deviation
Remark:
PSDEV (Population Standard Deviation) is also known as a biased/uncorrected Standard Deviation.
For unbiased version that uses Bessel's correction, use SDEV instead.
</summary> */
public class PSDEV_Series : Single_TSeries_Indicator
{
public PSDEV_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{
if (base._data.Count > 0) { base.Add(base._data); }
}
private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update)
{
if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { _buffer.Add(TValue.v); }
if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count;
double _pvar = 0;
for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_pvar /= this._buffer.Count;
double _psdev = Math.Sqrt(_pvar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _psdev);
base.Add(result, update);
}
}
+43 -43
View File
@@ -1,44 +1,44 @@
namespace QuanTAlib; namespace QuanTAlib;
using System; using System;
/* <summary> /* <summary>
SDEV: (Corrected) Sample Standard Deviation SDEV: Population Standard Deviation
Sample Standard Deviaton uses Bessel's correction to correct the bias in the variance. Population Standard Deviation is the square root of the biased variance, also known as
Uncorrected Sample Standard Deviation
Sources:
https://en.wikipedia.org/wiki/Standard_deviation#Corrected_sample_standard_deviation Sources:
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction https://en.wikipedia.org/wiki/Standard_deviation#Uncorrected_sample_standard_deviation
Remark: Remark:
SSDEV (Sample Standard Deviation) is also known as a unbiased/corrected Standard Deviation. SDEV (Population Standard Deviation) is also known as a biased/uncorrected Standard Deviation.
For a population/biased/uncorrected Standard Deviation, use PSDEV instead For unbiased version that uses Bessel's correction, use SDEV instead.
</summary> */ </summary> */
public class SDEV_Series : Single_TSeries_Indicator public class SDEV_Series : Single_TSeries_Indicator
{ {
public SDEV_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN) public SDEV_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
{ {
if (base._data.Count > 0) { base.Add(base._data); } if (base._data.Count > 0) { base.Add(base._data); }
} }
private readonly System.Collections.Generic.List<double> _buffer = new(); private readonly System.Collections.Generic.List<double> _buffer = new();
public override void Add((System.DateTime t, double v) TValue, bool update) public override void Add((System.DateTime t, double v) TValue, bool update)
{ {
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; } if (update) { _buffer[_buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); } else { _buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); } if (_buffer.Count > this._p && this._p != 0) { _buffer.RemoveAt(0); }
double _sma = 0; double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; } for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
_sma /= this._buffer.Count; _sma /= this._buffer.Count;
double _svar = 0; double _pvar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); } for (int i = 0; i < _buffer.Count; i++) { _pvar += (_buffer[i] - _sma) * (_buffer[i] - _sma); }
_svar /= (this._buffer.Count > 1) ? this._buffer.Count - 1 : 1; // Bessel's correction _pvar /= this._buffer.Count;
double _ssdev = Math.Sqrt(_svar); double _psdev = Math.Sqrt(_pvar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ssdev); var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _psdev);
base.Add(result, update); base.Add(result, update);
} }
} }
-33
View File
@@ -1,33 +0,0 @@
using Xunit;
using System;
using QuanTAlib;
namespace MovingAvg;
public class JMA_Test
{
[Fact]
public void Add_Test()
{
TSeries a = new() { 0, 1, 2, 3, 4, 5 };
JMA_Series c = new(a, 3);
Assert.Equal(6, c.Count);
a.Add(5);
Assert.Equal(a.Count, c.Count);
a.Add(0, update: true);
Assert.Equal(a.Count, c.Count);
}
[Fact]
public void Edge_Test()
{
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
JMA_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count);
a.Add(double.NaN);
Assert.Equal(a.Count, c.Count);
a.Add(double.PositiveInfinity);
Assert.Equal(a.Count, c.Count);
}
}
+33 -33
View File
@@ -1,33 +1,33 @@
using Xunit; using Xunit;
using System; using System;
using QuanTAlib; using QuanTAlib;
namespace Statistics; namespace Statistics;
public class PSDEV_Test public class PSDEV_Test
{ {
[Fact] [Fact]
public void Add_Test() public void Add_Test()
{ {
TSeries a = new() { 0, 1, 2, 3, 4, 5 }; TSeries a = new() { 0, 1, 2, 3, 4, 5 };
PSDEV_Series c = new(a, 3); SDEV_Series c = new(a, 3);
Assert.Equal(6, c.Count); Assert.Equal(6, c.Count);
a.Add(5); a.Add(5);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(0, update: true); a.Add(0, update: true);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
} }
[Fact] [Fact]
public void Edge_Test() public void Edge_Test()
{ {
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue }; TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
PSDEV_Series c = new(a, 3); SDEV_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(double.NaN); a.Add(double.NaN);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(double.PositiveInfinity); a.Add(double.PositiveInfinity);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
} }
} }
+33 -33
View File
@@ -1,33 +1,33 @@
using Xunit; using Xunit;
using System; using System;
using QuanTAlib; using QuanTAlib;
namespace Statistics; namespace Statistics;
public class SDEV_Test public class SDEV_Test
{ {
[Fact] [Fact]
public void Add_Test() public void Add_Test()
{ {
TSeries a = new() { 0, 1, 2, 3, 4, 5 }; TSeries a = new() { 0, 1, 2, 3, 4, 5 };
SDEV_Series c = new(a, 3); SSDEV_Series c = new(a, 3);
Assert.Equal(6, c.Count); Assert.Equal(6, c.Count);
a.Add(5); a.Add(5);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(0, update: true); a.Add(0, update: true);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
} }
[Fact] [Fact]
public void Edge_Test() public void Edge_Test()
{ {
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue }; TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
SDEV_Series c = new(a, 3); SSDEV_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(double.NaN); a.Add(double.NaN);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
a.Add(double.PositiveInfinity); a.Add(double.PositiveInfinity);
Assert.Equal(a.Count, c.Count); Assert.Equal(a.Count, c.Count);
} }
} }
+10
View File
@@ -129,4 +129,14 @@ MACD_Series QL = new(this.bars.Close, slow: 26, fast: 12, signal: 9, false);
Core.Macd(this.inclose, 0, this.bars.Count - 1, outMacd: this.TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _); Core.Macd(this.inclose, 0, this.bars.Count - 1, outMacd: this.TALIB, outMacdSignal: macdSignal, outMacdHist: macdHist, out int outBegIdx, out _);
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8)); Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
} }
[Fact]
public void SDEV()
{
SDEV_Series QL = new(this.bars.Close, this.period, false);
Core.StdDev(this.inclose, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
}
} }
-244
View File
@@ -1,244 +0,0 @@
#!csharp
#r "nuget: Plotly.NET, 2.0.0-preview.18 "
#r "nuget: Plotly.NET.Interactive, 2.0.0-preview.18 "
#r "nuget: QuanTAlib"
using Plotly.NET;
using Plotly.NET.LayoutObjects;
using QuanTAlib;
List<double> x = new() {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96};
List<double> Spike = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
List<double> Impulse = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
List<double> Triangle = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2};
List<double> Sawtooth = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
List<double> Sine = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.39,0.56,0.72,0.84,0.93,0.99,1,0.97,0.91,0.81,0.68,0.52,0.33,0.14,-0.06,-0.26,-0.44,-0.61,-0.76,-0.87,-0.95,-0.99,-1,-0.96,-0.88,-0.77,-0.63,-0.46,-0.28,-0.08,0.12,0.31,0.49,0.66,0.79,0.9,0.97,1,0.99,0.94,0.85,0.73,0.58,0.41,0.22,0.02,-0.17,-0.37,-0.54,-0.7,-0.83,-0.92,-0.98,-1,-0.98,-0.92,-0.82,-0.69,-0.54,-0.36,-0.17,0.03,0.23,0.42,0.59,0.74};
List<double> Chirp = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0.93,0.27,-0.59,-1,-0.71,0.05,0.75,1,0.67,0,-0.67,-0.99,-0.85,-0.34,0.31,0.81,1,0.82,0.35,-0.22,-0.71,-0.98,-0.95,-0.66,-0.2,0.31,0.72,0.96,0.98,0.78,0.43,-0.01,-0.43,-0.77,-0.96,-0.99,-0.85,-0.58,-0.23,0.16,0.51,0.79,0.95,1,0.92,0.73,0.47,0.15,-0.17,-0.47,-0.72,-0.9,-0.99,-0.99,-0.9,-0.74,-0.52,-0.26,0.01,0.28,0.53,0.73,0.88,0.97,1,0.97};
List<double> White = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0.03,-0.4,-0.47,0.19,-0.4,-0.23,0.31,0.41,0.19,0.16,-0.5,-0.31,-0.21,0.25,0.18,-0.48,-0.1,0.38,0.29,-0.38,-0.08,-0.21,0.34,0.01,-0.46,0.28,-0.48,0.11,0.02,-0.37,0.19,-0.2,0.1,0.24,0.08,-0.22,-0.12,0.15,0.36,-0.43,-0.03,-0.32,0.45,-0.5,-0.04,-0.04,-0.08,-0.18,0.13,-0.33,-0.19,0.36,-0.39,0.2,-0.31,0.28,-0.13,-0.07,-0.29,0.37,0.03,-0.25,-0.06,-0.3,-0.08,-0.09};
List<double> Gauss = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,0,0.03,0.11,-0.1,-0.43,-0.08,0.36,-0.04,-0.04,-0.21,-0.3,0.26,0.2,0.28,0.2,0.27,-0.01,-0.1,-0.23,-0.13,-0.41,-0.23,-0.07,-0.21,0.32,-0.18,-0.48,0.3,0.46,-0.2,0.52,-0.81,-0.25,-0.21,-0.12,-0.18,0.18,0.52,0.29,0.44,0.18,-1.2,0.38,0.24,0.06,0.28,0.34,0.3,-0.13,0.19,-0.5,0.59,-0.36,0.22,-0.23,0.24,0.39,0.13,-0.33,-0.57,-0.23,0.49,-0.13,0.76,0.59,0.61};
List<double> B = new() {-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0.4,-0.4,0,-0.28,0.41,-0.54,0.65,-0.75,0.84,-0.91,0.96,-0.99,1,-0.99,0.96,-0.92,0.85,-0.77,0.67,-0.56,0.44,-0.3,0.17,-0.03,-0.11,0.25,-0.39,0.51,-0.63,0.73,-0.82,0.89,-0.95,0.98,-1,0.99,-0.97,0.93,-0.86,0.78,-0.69,0.58,-0.46,0.33,-0.19,0.05,0.09,-0.23,0.36,-0.49,0.61,-0.71,0.81,-0.88,0.94,-0.98,1,-1,0.98,-0.94,0.88,-0.8,0.71,-0.6,0.48,-0.35,0.22,-0.08,-0.06};
List<double> HF = new() {-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,-0.6,0.6,0,0.14,-0.76,-0.96,-0.28,0.66,0.99,0.41,-0.54,-1,-0.54,0.42,0.99,0.65,-0.29,-0.96,-0.75,0.15,0.91,0.84,-0.01,-0.85,-0.91,-0.13,0.76,0.96,0.27,-0.66,-0.99,-0.4,0.55,1,0.53,-0.43,-0.99,-0.64,0.3,0.96,0.75,-0.16,-0.92,-0.83,0.02,0.85,0.9,0.12,-0.77,-0.95,-0.26,0.67,0.99,0.4,-0.56,-1,-0.52,0.44,0.99,0.64,-0.3,-0.97,-0.74,0.17,0.92,0.83,-0.03,-0.86};
List<double> ImpulseHF = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.05,-0.25,-0.32,-0.09,0.22,0.33,0.14,-0.18,-0.33,-0.18,0.14,0.33,0.22,-0.1,-0.32,-0.25,0.05,0.3,0.28,0,-0.28,-0.3,-0.04,0.25,0.32,0.09,-0.22,-0.33,-0.13,0.18,0.33,0.18,0.86,0.67,0.79,1.1,1.32,1.25,0.95,0.69,0.72,1.01,1.28,1.3,1.04,0.74,0.68,0.91,1.22,1.33,1.13,0.81,0.67,0.83,1.15,1.33,1.21,0.9,0.68,0.75,1.06,1.31,1.28,0.99,0.71};
List<double> SawtoothHF = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,2.7,-0.8,-0.8,3.6,9.3,11.95,10.05,6.3,5,8.3,14.1,17.95,17.25,13.55,11.2,13.25,18.75,23.55,24.2,20.95,17.75,18.45,23.35,28.8,30.8,28.35,24.7,24.05,28,33.75,37,35.65,31.85,28.05,-3.2,1.5,4.8,3.75,-0.8,-4.6,-4.15,0.1,4.25,4.5,0.6,-3.85,-4.75,-1.3,3.35,4.95,2,-2.8,-5,-2.6,2.2,4.95,3.2,-1.5,-4.85,-3.7,0.85,4.6,4.15,-0.15,-4.3};
List<double> SineG = new() {-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0.2,-0.2,0,0,0.59,0.83,0.74,0.5,0.91,1.36,0.93,0.87,0.6,0.38,0.78,0.53,0.42,0.14,0.01,-0.45,-0.71,-0.99,-1,-1.36,-1.22,-1.07,-1.17,-0.56,-0.95,-1.11,-0.16,0.18,-0.28,0.64,-0.5,0.24,0.45,0.67,0.72,1.15,1.52,1.28,1.38,1.03,-0.47,0.96,0.65,0.28,0.3,0.17,-0.07,-0.67,-0.51,-1.33,-0.33,-1.34,-0.78,-1.21,-0.68,-0.43,-0.56,-0.87,-0.93,-0.4,0.52,0.1,1.18,1.18,1.35};
List<double> ChirpG = new() {0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,0,0.01,1.3,0.3,-0.48,-1.1,-1.14,-0.03,1.11,0.96,0.63,-0.21,-0.97,-0.73,-0.65,-0.06,0.51,1.08,0.99,0.72,0.12,-0.35,-1.12,-1.21,-1.02,-0.87,0.12,0.13,0.24,1.26,1.44,0.58,0.95,-0.82,-0.68,-0.98,-1.08,-1.17,-0.67,-0.06,0.06,0.6,0.69,-0.41,1.33,1.24,0.98,1.01,0.81,0.45,-0.3,-0.28,-1.22,-0.31,-1.35,-0.77,-1.13,-0.5,-0.13,-0.13,-0.32,-0.29,0.3,1.22,0.75,1.73,1.59,1.58};
List<double> Complex = new() {175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.1,175.6,175.44,176.27,176.04,176.99,175.49,175.68,174.34,176.4,174.05,174.4,174.2,176.16,175,177.72,174.33,176.96,174.62,174.76,170.9,171.12,171.05,170.01,169.24,172.64,171.96,175.72,174.16,175.81,177.3,178.38,176.75,177.19,175.55,178.49,176.52,178.45,178.04,178.25,177.8,176.97,172.94,174.92,173.98,172.29,171.19,172.54,172.11,175.32,175.63,176.65,173.8,176.04,172.74,175.24,171.84,171.54,172.17,171.85,172.38,170.78,173.49,173.69,171.71,174.38,173.99,174.83};
List<double> Market = new() {68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,68.75,68.25,67.75,67.75,72.75,74.75,72.25,71.25,71.75,72.75,77.75,76,76,76,74.75,75.5,74.75,73.75,74,74.75,72.25,72.5,72.25,74.5,74.75,75.75,75.75,75.75,74.25,73.75,74.75,72,71.75,72.5,72.25,71,72,71.75,71.75,73.25,72.5,73.75,74,76.75,75.75,75,75.75,74.5,74.25,73.5,71.75,70.5,69,70.5,70,68.75,67.25,68.5,70.75,70,70.5,68.25,68.25,68.25,63.75,64.25};
#!csharp
TSeries data = new();
// change these two values - the period and the type of observed indicator
// currently available indicators are: DEMA_Series, EMA_Series, HEMA_Series, HMA_Series, JMA_Series, RMA_Series, SMA_Series, TEMA_Series, WMA_Series and ZLEMA_Series
int Period = 20;
HMA_Series indicator=new(source: data, period: Period);
//On charts below, blue line is the data input, the green line is a JMA reference
#!csharp
var series = Spike;
ZLEMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count-1; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Spike");
chart
#!csharp
var series = Impulse;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count-1; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Impulse");
chart
#!csharp
var series = Triangle;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x, series, false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Triangle");
chart
#!csharp
var series = Sawtooth;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Sawtooth");
chart
#!csharp
var series = Sine;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Sine");
chart
#!csharp
var series = Chirp;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Chirp");
chart
#!csharp
var series = White;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("White");
chart
#!csharp
var series = Gauss;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Gauss");
chart
#!csharp
var series = B;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("B");
chart
#!csharp
var series = HF;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("HF");
chart
#!csharp
var series = ImpulseHF;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("ImpulseHF");
chart
#!csharp
var series = SawtoothHF;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("SawtoothHF");
chart
#!csharp
var series = SineG;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("SineG");
chart
#!csharp
var series = ChirpG;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("ChirpG");
chart
#!csharp
var series = Complex;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Complex");
chart
#!csharp
var series = Market;
data = new();
indicator=new(source: data, period: Period);
JMA_Series reference = new(source: data, period: Period);
for (int i=0; i<x.Count; i++) data.Add(((DateTime.Today.AddDays(-x.Count+i)), series[i]));
GenericChart.GenericChart ch1 = Chart2D.Chart.Line<double,double,bool>(x,series,false,"data").WithLineStyle(Width: 1.0, Color: Color.fromString("blue"));
GenericChart.GenericChart ch2 = Chart2D.Chart.Line<double,double,bool>(x,indicator.v,false,"sig").WithLineStyle(Width: 2, Color: Color.fromString("red"));
GenericChart.GenericChart ch3 = Chart2D.Chart.Line<double,double,bool>(x,reference.v,false,"ref").WithLineStyle(Width: 1.5, Color: Color.fromString("green"));
var chart = Chart.Combine(new []{ch1,ch2,ch3}).WithSize(1200,400).WithMargin(Margin.init<int, int, int, int, int, bool>(1,1,60,1,1,false)).WithTitle("Maket");
chart