sdev, psdev, alphavantage

This commit is contained in:
Miha Kralj
2022-11-06 17:20:57 -08:00
parent 32615af18b
commit 28025fbdd3
28 changed files with 1860 additions and 2545 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+52
View File
@@ -0,0 +1,52 @@
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);
}
}
@@ -2,7 +2,7 @@ using System.Drawing;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
public class SSDEV_chart : Indicator
public class PSDEV_chart : Indicator
{
#region Parameters
@@ -19,22 +19,22 @@ public class SSDEV_chart : Indicator
private TBars bars;
///////dotnet
private SSDEV_Series indicator;
private PSDEV_Series indicator;
///////
public SSDEV_chart()
public PSDEV_chart()
{
this.SeparateWindow = true;
this.Name = "SSDEV - Sample Standard Deviation (Unbiased)";
this.Description = "SSDEV description";
this.AddLineSeries("SSDEV", Color.RoyalBlue, 3, LineStyle.Solid);
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.bars = new();
this.ShortName =
"SSDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")";
"PSDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")";
this.indicator = new(source: bars.Select(this.DataSource),
period: this.Period, useNaN: true);
}
+53
View File
@@ -0,0 +1,53 @@
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);
}
}
@@ -0,0 +1,53 @@
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);
}
}
+2 -2
View File
@@ -25,14 +25,14 @@ public class SDEV_chart : Indicator
public SDEV_chart()
{
this.SeparateWindow = true;
this.Name = "SDEV - Population Standard Deviation (Biased)";
this.Name = "SDEV - Sample Standard Deviation (Unbiased)";
this.Description = "SDEV description";
this.AddLineSeries("SDEV", Color.RoyalBlue, 3, LineStyle.Solid);
}
protected override void OnInit()
{
this.bars = new();
this.bars = new();
this.ShortName =
"SDEV (" + TBars.SelectStr(this.DataSource) + ", " + this.Period + ")";
this.indicator = new(source: bars.Select(this.DataSource),
+6 -5
View File
@@ -30,12 +30,12 @@ public class ZLMA_chart : Indicator
private readonly int matype = 2;
#endregion Parameters
private TBars bars;
///////
///////
private TSeries indicator;
///////
///////
public ZLMA_chart()
{
this.SeparateWindow = false;
@@ -72,7 +72,8 @@ public class ZLMA_chart : Indicator
4 => new TEMA_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),
7 => new SMMA_Series(source: zerolag, period: this.Period, useNaN: false),
7 => new JMA_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)
};
}
+1 -3
View File
@@ -13,8 +13,6 @@ Alphavantage - Free API to collect quotes for stock, Forex and crypto. It requir
</summary> */
/* TODO: refactor into three feeds: FX, Crypto, Stock */
public class Alphavantage_Feed : TBars
{
public enum Interval { Month, Week, Day, Hour, Min30, Min15, Min5, Min1}
@@ -115,7 +113,7 @@ public class Alphavantage_Feed : TBars
{
Interval.Month => "_MONTHLY",
Interval.Week => "_WEEKLY",
Interval.Day => "_DAILY_ADJUSTED",
Interval.Day => "_DAILY",
Interval.Hour => "_INTRADAY&interval=60min",
Interval.Min30 => "_INTRADAY&interval=30min",
Interval.Min15 => "_INTRADAY&interval=15min",
+27 -27
View File
@@ -1,28 +1,28 @@
namespace QuanTAlib;
using System;
/* <summary>
Random Bars generator - used for testing, validation and fun
Returns 'bars' number of candles that follow common market movement.
volatility defines how 'jumpy' is the series of
startvalue defines beginning closing price that then guides the rest of series
</summary> */
public class RND_Feed : TBars
{
public RND_Feed(int bars, double volatility = 0.05, double startvalue = 100.0)
{
Random rnd = new();
double c = startvalue;
for (int i = 0; i < bars; i++)
{
double o = Math.Round(c + c * (volatility * 0.1 * rnd.NextDouble() - 0.005), 2);
double h = Math.Round(o + c * volatility * rnd.NextDouble(), 2);
double l = Math.Round(o - c * volatility * rnd.NextDouble(), 2);
c = Math.Round(l + (h - l) * rnd.NextDouble(), 2);
double v = Math.Round(1000 * rnd.NextDouble(), 2);
this.Add(DateTime.Today.AddDays(i - bars), o, h, l, c, v);
}
}
namespace QuanTAlib;
using System;
/* <summary>
Random Bars generator - used for testing, validation and fun
Returns 'bars' number of candles that follow common market movement.
volatility defines how 'jumpy' is the series of
startvalue defines beginning closing price that then guides the rest of series
</summary> */
public class RND_Feed : TBars
{
public RND_Feed(int bars, double volatility = 0.05, double startvalue = 100.0)
{
Random rnd = new();
double c = startvalue;
for (int i = 0; i < bars; i++)
{
double o = Math.Round(c + c * (volatility * 0.1 * rnd.NextDouble() - 0.005), 2);
double h = Math.Round(o + c * volatility * rnd.NextDouble(), 2);
double l = Math.Round(o - c * volatility * rnd.NextDouble(), 2);
c = Math.Round(l + (h - l) * rnd.NextDouble(), 2);
double v = Math.Round(1000 * rnd.NextDouble(), 2);
this.Add(DateTime.Today.AddDays(i - bars), o, h, l, c, v);
}
}
}
+1 -6
View File
@@ -19,9 +19,6 @@ Issues:
</summary> */
/* TODO: This indicator is not calculating results correctly - needs to be debugged */
/*
public class JMA_Series : Single_TSeries_Indicator
{
private readonly System.Collections.Generic.List<double> vbuffer10;
@@ -159,6 +156,4 @@ public class JMA_Series : Single_TSeries_Indicator
base.Add(result, update);
}
}
*/
}
+2 -2
View File
@@ -13,7 +13,7 @@
<Authors>Miha Kralj</Authors>
<Copyright>Miha Kralj</Copyright>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net7.0;net6.0;netstandard2.0</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings>
<LangVersion>preview</LangVersion>
<Nullable>disable</Nullable>
@@ -67,6 +67,6 @@
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Text.Json" Version="7.0.0-rc.2.22472.3" />
<PackageReference Include="System.Text.Json" Version="7.0.0-preview.4.22229.4" />
</ItemGroup>
</Project>
+44
View File
@@ -0,0 +1,44 @@
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);
}
}
+16 -16
View File
@@ -2,17 +2,17 @@
using System;
/* <summary>
SDEV: Population Standard Deviation
Population Standard Deviation is the square root of the biased variance, also known as
Uncorrected Sample Standard Deviation
SDEV: (Corrected) Sample Standard Deviation
Sample Standard Deviaton uses Bessel's correction to correct the bias in the variance.
Sources:
https://en.wikipedia.org/wiki/Standard_deviation#Uncorrected_sample_standard_deviation
https://en.wikipedia.org/wiki/Standard_deviation#Corrected_sample_standard_deviation
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction
Remark:
SDEV (Population Standard Deviation) is also known as a biased/uncorrected Standard Deviation.
For unbiased version that uses Bessel's correction, use SDEV instead.
SSDEV (Sample Standard Deviation) is also known as a unbiased/corrected Standard Deviation.
For a population/biased/uncorrected Standard Deviation, use PSDEV instead
</summary> */
public class SDEV_Series : Single_TSeries_Indicator
@@ -25,20 +25,20 @@ public class SDEV_Series : Single_TSeries_Indicator
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); }
if (update) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < _buffer.Count; i++) { _sma += _buffer[i]; }
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._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);
double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); }
_svar /= (this._buffer.Count > 1) ? this._buffer.Count - 1 : 1; // Bessel's correction
double _ssdev = Math.Sqrt(_svar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _psdev);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ssdev);
base.Add(result, update);
}
}
-44
View File
@@ -1,44 +0,0 @@
namespace QuanTAlib;
using System;
/* <summary>
SSDEV: (Corrected) Sample Standard Deviation
Sample Standard Deviaton uses Bessel's correction to correct the bias in the variance.
Sources:
https://en.wikipedia.org/wiki/Standard_deviation#Corrected_sample_standard_deviation
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction
Remark:
SSDEV (Sample Standard Deviation) is also known as a unbiased/corrected Standard Deviation.
For a population/biased/uncorrected Standard Deviation, use SDEV instead
</summary> */
public class SSDEV_Series : Single_TSeries_Indicator
{
public SSDEV_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) { this._buffer[this._buffer.Count - 1] = TValue.v; }
else { this._buffer.Add(TValue.v); }
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
double _sma = 0;
for (int i = 0; i < this._buffer.Count; i++) { _sma += this._buffer[i]; }
_sma /= this._buffer.Count;
double _svar = 0;
for (int i = 0; i < this._buffer.Count; i++) { _svar += (this._buffer[i] - _sma) * (this._buffer[i] - _sma); }
_svar /= (this._buffer.Count > 1) ? this._buffer.Count - 1 : 1; // Bessel's correction
double _ssdev = Math.Sqrt(_svar);
var result = (TValue.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _ssdev);
base.Add(result, update);
}
}
+33
View File
@@ -0,0 +1,33 @@
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);
}
}
+2 -2
View File
@@ -9,7 +9,7 @@ public class PSDEV_Test
public void Add_Test()
{
TSeries a = new() { 0, 1, 2, 3, 4, 5 };
SDEV_Series c = new(a, 3);
PSDEV_Series c = new(a, 3);
Assert.Equal(6, c.Count);
a.Add(5);
Assert.Equal(a.Count, c.Count);
@@ -21,7 +21,7 @@ public class PSDEV_Test
public void Edge_Test()
{
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
SDEV_Series c = new(a, 3);
PSDEV_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count);
a.Add(double.NaN);
Assert.Equal(a.Count, c.Count);
+2 -2
View File
@@ -9,7 +9,7 @@ public class SDEV_Test
public void Add_Test()
{
TSeries a = new() { 0, 1, 2, 3, 4, 5 };
SSDEV_Series c = new(a, 3);
SDEV_Series c = new(a, 3);
Assert.Equal(6, c.Count);
a.Add(5);
Assert.Equal(a.Count, c.Count);
@@ -21,7 +21,7 @@ public class SDEV_Test
public void Edge_Test()
{
TSeries a = new() { double.NaN, double.Epsilon, double.PositiveInfinity, double.MaxValue };
SSDEV_Series c = new(a, 3);
SDEV_Series c = new(a, 3);
Assert.Equal(a.Count, c.Count);
a.Add(double.NaN);
Assert.Equal(a.Count, c.Count);
-10
View File
@@ -129,14 +129,4 @@ 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 _);
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));
}
}
View File
+148 -148
View File
@@ -1,148 +1,148 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>QuanTAlib, 0.1.10-beta</span></li><li><span>TALib.NETCore, 0.4.4</span></li></ul></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#r \"nuget: TALib.NETCore, 0.4.4\" \n",
"#r \"nuget: QuanTAlib, 0.1.10-beta\" \n",
"\n",
"using QuanTAlib;\n",
"using TALib;\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"ename": "Error",
"evalue": "(1,1): error CS0246: The type or namespace name 'YAHOO_Feed' could not be found (are you missing a using directive or an assembly reference?)",
"output_type": "error",
"traceback": [
"(1,1): error CS0246: The type or namespace name 'YAHOO_Feed' could not be found (are you missing a using directive or an assembly reference?)"
]
}
],
"source": [
"YAHOO_Feed aapl = new(2020,\"AAPL\");\n",
"TSeries data = aapl.Close;\n",
"\n",
"data.Count()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [],
"source": [
"int period = 10;\n",
"\n",
"//QuanTAlib SMA algorithm\n",
"SMA_Series e = new(data, period, false); \n",
"\n",
"// direct call to SMA from TA-LIB - with stitching NaNs in front\n",
"int outBegIdx, outNbElement;\n",
"double[] output = new double[data.Count];\n",
"double[] nans = new double[period];\n",
"double[] ta_temp = new double[data.Count-period+1];\n",
"Array.Fill(nans, double.NaN);\n",
"Core.Sma(data.v.ToArray(), 0, data.Count-1, ta_temp, out outBegIdx, out outNbElement, period); //TA-LIB SMA method\n",
"nans.CopyTo(output,0);\n",
"ta_temp.CopyTo(output,period-1);\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"QuantLib\t TA-LIB\n",
"164.31\t\t 164.31\n",
"166.81\t\t 166.81\n",
"169.20\t\t 169.20\n",
"171.01\t\t 171.01\n",
"172.41\t\t 172.41\n",
"173.45\t\t 173.45\n",
"174.75\t\t 174.75\n",
"175.38\t\t 175.38\n",
"175.54\t\t 175.54\n",
"\n",
"1394\t\t 1394\n"
]
}
],
"source": [
"// comparing the tail of QuanTAlib and TA-LIB\n",
"Console.Write($\"QuanTAlib\\t TA-LIB\\n\");\n",
"for (int i=data.Count-10; i<data.Count-1; i++) \n",
" Console.Write($\"{e[i].v:f2}\\t\\t {output[i]:f2}\\n\");\n",
"\n",
"Console.Write($\"\\n{e.Count()}\\t\\t {output.Length}\\n\");\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "9.0"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>QuanTAlib, 0.1.10-beta</span></li><li><span>TALib.NETCore, 0.4.4</span></li></ul></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#r \"nuget: TALib.NETCore, 0.4.4\" \n",
"#r \"nuget: QuanTAlib, 0.1.10-beta\" \n",
"\n",
"using QuanTAlib;\n",
"using TALib;\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"ename": "Error",
"evalue": "(1,1): error CS0246: The type or namespace name 'YAHOO_Feed' could not be found (are you missing a using directive or an assembly reference?)",
"output_type": "error",
"traceback": [
"(1,1): error CS0246: The type or namespace name 'YAHOO_Feed' could not be found (are you missing a using directive or an assembly reference?)"
]
}
],
"source": [
"YAHOO_Feed aapl = new(2020,\"AAPL\");\n",
"TSeries data = aapl.Close;\n",
"\n",
"data.Count()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [],
"source": [
"int period = 10;\n",
"\n",
"//QuanTAlib SMA algorithm\n",
"SMA_Series e = new(data, period, false); \n",
"\n",
"// direct call to SMA from TA-LIB - with stitching NaNs in front\n",
"int outBegIdx, outNbElement;\n",
"double[] output = new double[data.Count];\n",
"double[] nans = new double[period];\n",
"double[] ta_temp = new double[data.Count-period+1];\n",
"Array.Fill(nans, double.NaN);\n",
"Core.Sma(data.v.ToArray(), 0, data.Count-1, ta_temp, out outBegIdx, out outNbElement, period); //TA-LIB SMA method\n",
"nans.CopyTo(output,0);\n",
"ta_temp.CopyTo(output,period-1);\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"QuantLib\t TA-LIB\n",
"164.31\t\t 164.31\n",
"166.81\t\t 166.81\n",
"169.20\t\t 169.20\n",
"171.01\t\t 171.01\n",
"172.41\t\t 172.41\n",
"173.45\t\t 173.45\n",
"174.75\t\t 174.75\n",
"175.38\t\t 175.38\n",
"175.54\t\t 175.54\n",
"\n",
"1394\t\t 1394\n"
]
}
],
"source": [
"// comparing the tail of QuanTAlib and TA-LIB\n",
"Console.Write($\"QuanTAlib\\t TA-LIB\\n\");\n",
"for (int i=data.Count-10; i<data.Count-1; i++) \n",
" Console.Write($\"{e[i].v:f2}\\t\\t {output[i]:f2}\\n\");\n",
"\n",
"Console.Write($\"\\n{e.Count()}\\t\\t {output.Length}\\n\");\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "9.0"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
+201 -201
View File
@@ -1,201 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+305 -305
View File
@@ -1,305 +1,305 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#r \"nuget:YahooFinanceApi;\" \n",
"#r \"nuget:QuanTAlib;\" \n",
"using YahooFinanceApi;\n",
"using QuanTAlib;\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Date\t\t Value\t SMA\t MAD\t STDDEV\t MSE\t MAPE\n",
" 2022-03-14\t 150.62\t 150.62\t 0.00\t 0.00\t 0.00\t 0.00\t\n",
"2022-03-15\t 155.09\t 152.85\t 2.24\t 3.16\t 5.00\t 0.01\t\n",
"2022-03-16\t 159.59\t 155.10\t 2.99\t 4.49\t 13.41\t 0.02\t\n",
"2022-03-17\t 160.62\t 156.48\t 3.62\t 4.59\t 15.77\t 0.02\t\n",
"2022-03-18\t 163.98\t 157.98\t 4.10\t 5.20\t 21.62\t 0.03\t\n",
"2022-03-21\t 165.38\t 160.93\t 3.00\t 4.03\t 13.02\t 0.02\t\n",
"2022-03-22\t 168.82\t 163.68\t 2.86\t 3.72\t 11.10\t 0.02\t\n",
"2022-03-23\t 170.21\t 165.80\t 2.97\t 3.84\t 11.78\t 0.02\t\n",
"2022-03-24\t 174.07\t 168.49\t 3.05\t 4.01\t 12.84\t 0.02\t\n",
"2022-03-25\t 174.72\t 170.64\t 3.00\t 3.86\t 11.92\t 0.02\t\n",
"2022-03-28\t 175.60\t 172.68\t 2.54\t 2.98\t 7.12\t 0.01\t\n",
"2022-03-29\t 178.96\t 174.71\t 2.06\t 3.14\t 7.90\t 0.01\t\n",
"2022-03-30\t 177.77\t 176.22\t 1.71\t 2.07\t 3.43\t 0.01\t\n",
"2022-03-31\t 174.61\t 176.33\t 1.63\t 1.94\t 3.01\t 0.01\t\n"
]
}
],
"source": [
"TSeries data = new();\n",
"var history = await Yahoo.GetHistoricalAsync(\"AAPL\", DateTime.Today.AddDays(-19), DateTime.Now, Period.Daily);\n",
"SMA_Series sma = new(data, 5, false);\n",
"SUB_Series sub = new(sma.STDDEV,sma.MAD);\n",
"Console.Write($\"Date\\t\\t Value\\t SMA\\t MAD\\t STDDEV\\t MSE\\t MAPE\\n \");\n",
"foreach (var i in history) {\n",
" data.Add((i.DateTime, (double)i.Close));\n",
" Console.Write($\"{data[^1].t:yyyy-MM-dd}\\t {(double)data:f2}\\t {(double)sma:f2}\\t {(double)sma.MAD:f2}\\t {(double)sma.STDDEV:f2}\\t {(double)sma.MSE:f2}\\t {(double)sma.MAPE:f2}\\t\\n\");\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"date\t\t Value\t SMA\t WMA\t EMA\t HMA\t DEMA\t TEMA \tZLEMA \tJMA\r\n",
"2022-03-21\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\n",
"2022-03-22\t 168.82\t 167.10\t 167.67\t 166.53\t 166.91\t 167.29\t 167.80\t 167.67\t 168.29\n",
"2022-03-23\t 170.21\t 168.14\t 168.94\t 167.75\t 168.52\t 169.08\t 169.80\t 170.13\t 170.00\n",
"2022-03-24\t 174.07\t 169.62\t 170.99\t 169.86\t 171.53\t 172.15\t 173.27\t 173.19\t 173.30\n",
"2022-03-25\t 174.72\t 170.64\t 172.24\t 171.48\t 174.45\t 174.09\t 175.04\t 175.21\t 174.42\n",
"2022-03-28\t 175.60\t 172.68\t 173.89\t 172.85\t 175.90\t 175.51\t 176.18\t 175.85\t 175.23\n",
"2022-03-29\t 178.96\t 174.71\t 175.98\t 174.89\t 177.60\t 178.01\t 178.78\t 178.30\t 177.49\n",
"2022-03-30\t 177.77\t 176.22\t 177.00\t 175.85\t 178.50\t 178.57\t 178.81\t 178.85\t 177.95\n",
"2022-03-31\t 174.61\t 176.33\t 176.46\t 175.44\t 177.08\t 176.98\t 176.35\t 175.98\t 176.09\n"
]
}
],
"source": [
"TSeries data = new();\n",
"var history = await Yahoo.GetHistoricalAsync(\"AAPL\", DateTime.Today.AddDays(-10), DateTime.Now, Period.Daily);\n",
"SMA_Series sma = new(data, 5);\n",
"WMA_Series wma = new(data, 5);\n",
"EMA_Series ema = new(data, 5);\n",
"HMA_Series hma = new(data, 5);\n",
"DEMA_Series dema = new(data, 5);\n",
"TEMA_Series tema = new(data, 5);\n",
"ZLEMA_Series zlema = new(data, 5);\n",
"JMA_Series jma = new(data, 5);\n",
"\n",
"Console.WriteLine($\"date\\t\\t Value\\t SMA\\t WMA\\t EMA\\t HMA\\t DEMA\\t TEMA \\tZLEMA \\tJMA\");\n",
"foreach (var i in history) {\n",
" data.Add((i.DateTime, (double)i.Close)); // adding data will signal dependant indicators\n",
"\n",
" Console.Write($\"{data[^1].t:yyyy-MM-dd}\\t {(double)data:f2}\\t {(double)sma:f2}\\t {(double)wma:f2}\\t {(double)ema:f2}\\t {(double)hma:f2}\\t {(double)dema:f2}\\t {(double)tema:f2}\\t {(double)zlema:f2}\\t {(double)jma:f2}\\n\");\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>Item1</th><th>Item2</th></tr></thead><tbody><tr><td>0</td><td><span>2022-03-21 00:00:00Z</span></td><td><div class=\"dni-plaintext\">165.380005</div></td></tr><tr><td>1</td><td><span>2022-03-22 00:00:00Z</span></td><td><div class=\"dni-plaintext\">167.9823694096766</div></td></tr><tr><td>2</td><td><span>2022-03-23 00:00:00Z</span></td><td><div class=\"dni-plaintext\">170.06602047454277</div></td></tr><tr><td>3</td><td><span>2022-03-24 00:00:00Z</span></td><td><div class=\"dni-plaintext\">173.24670154378663</div></td></tr><tr><td>4</td><td><span>2022-03-25 00:00:00Z</span></td><td><div class=\"dni-plaintext\">174.81344756154755</div></td></tr><tr><td>5</td><td><span>2022-03-28 00:00:00Z</span></td><td><div class=\"dni-plaintext\">175.53949324963583</div></td></tr><tr><td>6</td><td><span>2022-03-29 00:00:00Z</span></td><td><div class=\"dni-plaintext\">177.89435364830672</div></td></tr><tr><td>7</td><td><span>2022-03-30 00:00:00Z</span></td><td><div class=\"dni-plaintext\">178.39609966493987</div></td></tr><tr><td>8</td><td><span>2022-03-31 00:00:00Z</span></td><td><div class=\"dni-plaintext\">176.03431272212282</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ADD_Series two = new(zlema, jma); // even when indicator is created later, it will grab the data from its source table\n",
"DIV_Series mean = new(two, 2); // this pair here calculates mean of ZLEMA and JMA indicators\n",
"\n",
"mean"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [],
"source": [
"public class ALMA_Series : TSeries\n",
"{\n",
" private readonly int _p;\n",
" private readonly bool _NaN;\n",
" private readonly TSeries _data;\n",
" private readonly double _offset, _sigma;\n",
" private double _norm;\n",
" private readonly System.Collections.Generic.List<double> _buffer = new();\n",
" private readonly System.Collections.Generic.List<double> _weights = new();\n",
"\n",
" public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false)\n",
" {\n",
" this._p = period;\n",
" this._data = source;\n",
" this._NaN = useNaN;\n",
" _offset = offset;\n",
" _sigma = sigma;\n",
"\n",
" double _m = _offset * (_p - 1);\n",
" double _s = _p / _sigma;\n",
"\n",
" _norm = 0;\n",
" for (int i = 0; i < this._p; i++)\n",
" {\n",
" double wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));\n",
" this._weights.Add(wt);\n",
" _norm += wt;\n",
" }\n",
"\n",
" source.Pub += this.Sub;\n",
" if (source.Count > 0)\n",
" {\n",
" for (int i = 0; i < source.Count; i++)\n",
" {\n",
" this.Add(source[i], false);\n",
" }\n",
" }\n",
"\n",
" }\n",
" public new void Add((System.DateTime t, double v) data, bool update = false)\n",
" {\n",
" if (update) { this._buffer[this._buffer.Count - 1] = data.v; } else { this._buffer.Add(data.v); }\n",
" if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }\n",
"\n",
" double _wma = 0;\n",
" for (int i = 0; i < this._buffer.Count; i++) { _wma += this._buffer[i] * this._weights[i]; }\n",
" if (this._buffer.Count < this._p) {\n",
" _norm = 0;\n",
" for (int i = 0; i < this._buffer.Count; i++) { _norm += this._weights[i];}\n",
" }\n",
" _wma /= _norm;\n",
"\n",
" (System.DateTime t, double v) result = (data.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _wma);\n",
" if (update) { base[base.Count - 1] = result; } else { base.Add(result); }\n",
" }\n",
" public void Add(bool update = false)\n",
" {\n",
" this.Add(this._data[this._data.Count - 1], update);\n",
" }\n",
" public new void Sub(object source, TSeriesEventArgs e) { this.Add(this._data[this._data.Count - 1], e.update); }\n",
"\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [],
"source": [
"TSeries data = new() {212.80, 214.06, 213.89, 214.66, 213.95, 213.95, 214.55, 214.02, 214.51, 213.75, 214.22, 213.43 };\n",
"ALMA_Series alma = new(data, period: 10, offset: 0.0, sigma: 6.0, useNaN: true);\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2022-03-31\t 212.80\t NaN\t \n",
"2022-03-31\t 214.06\t NaN\t \n",
"2022-03-31\t 213.89\t NaN\t \n",
"2022-03-31\t 214.66\t NaN\t \n",
"2022-03-31\t 213.95\t NaN\t \n",
"2022-03-31\t 213.95\t NaN\t \n",
"2022-03-31\t 214.55\t NaN\t \n",
"2022-03-31\t 214.02\t NaN\t \n",
"2022-03-31\t 214.51\t NaN\t \n",
"2022-03-31\t 213.75\t 213.58\t \n",
"2022-03-31\t 214.22\t 214.11\t \n",
"2022-03-31\t 213.43\t 214.17\t \n"
]
}
],
"source": [
"for (int i=0; i<data.Length; i++) {\n",
" Console.Write($\"{data[i].t:yyyy-MM-dd}\\t {(double)data[i].v:f2}\\t {alma[i].v:f2}\\t \\n\");\n",
"}"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "9.0"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#r \"nuget:YahooFinanceApi;\" \n",
"#r \"nuget:QuanTAlib;\" \n",
"using YahooFinanceApi;\n",
"using QuanTAlib;\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Date\t\t Value\t SMA\t MAD\t STDDEV\t MSE\t MAPE\n",
" 2022-03-14\t 150.62\t 150.62\t 0.00\t 0.00\t 0.00\t 0.00\t\n",
"2022-03-15\t 155.09\t 152.85\t 2.24\t 3.16\t 5.00\t 0.01\t\n",
"2022-03-16\t 159.59\t 155.10\t 2.99\t 4.49\t 13.41\t 0.02\t\n",
"2022-03-17\t 160.62\t 156.48\t 3.62\t 4.59\t 15.77\t 0.02\t\n",
"2022-03-18\t 163.98\t 157.98\t 4.10\t 5.20\t 21.62\t 0.03\t\n",
"2022-03-21\t 165.38\t 160.93\t 3.00\t 4.03\t 13.02\t 0.02\t\n",
"2022-03-22\t 168.82\t 163.68\t 2.86\t 3.72\t 11.10\t 0.02\t\n",
"2022-03-23\t 170.21\t 165.80\t 2.97\t 3.84\t 11.78\t 0.02\t\n",
"2022-03-24\t 174.07\t 168.49\t 3.05\t 4.01\t 12.84\t 0.02\t\n",
"2022-03-25\t 174.72\t 170.64\t 3.00\t 3.86\t 11.92\t 0.02\t\n",
"2022-03-28\t 175.60\t 172.68\t 2.54\t 2.98\t 7.12\t 0.01\t\n",
"2022-03-29\t 178.96\t 174.71\t 2.06\t 3.14\t 7.90\t 0.01\t\n",
"2022-03-30\t 177.77\t 176.22\t 1.71\t 2.07\t 3.43\t 0.01\t\n",
"2022-03-31\t 174.61\t 176.33\t 1.63\t 1.94\t 3.01\t 0.01\t\n"
]
}
],
"source": [
"TSeries data = new();\n",
"var history = await Yahoo.GetHistoricalAsync(\"AAPL\", DateTime.Today.AddDays(-19), DateTime.Now, Period.Daily);\n",
"SMA_Series sma = new(data, 5, false);\n",
"SUB_Series sub = new(sma.STDDEV,sma.MAD);\n",
"Console.Write($\"Date\\t\\t Value\\t SMA\\t MAD\\t STDDEV\\t MSE\\t MAPE\\n \");\n",
"foreach (var i in history) {\n",
" data.Add((i.DateTime, (double)i.Close));\n",
" Console.Write($\"{data[^1].t:yyyy-MM-dd}\\t {(double)data:f2}\\t {(double)sma:f2}\\t {(double)sma.MAD:f2}\\t {(double)sma.STDDEV:f2}\\t {(double)sma.MSE:f2}\\t {(double)sma.MAPE:f2}\\t\\n\");\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"date\t\t Value\t SMA\t WMA\t EMA\t HMA\t DEMA\t TEMA \tZLEMA \tJMA\r\n",
"2022-03-21\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\t 165.38\n",
"2022-03-22\t 168.82\t 167.10\t 167.67\t 166.53\t 166.91\t 167.29\t 167.80\t 167.67\t 168.29\n",
"2022-03-23\t 170.21\t 168.14\t 168.94\t 167.75\t 168.52\t 169.08\t 169.80\t 170.13\t 170.00\n",
"2022-03-24\t 174.07\t 169.62\t 170.99\t 169.86\t 171.53\t 172.15\t 173.27\t 173.19\t 173.30\n",
"2022-03-25\t 174.72\t 170.64\t 172.24\t 171.48\t 174.45\t 174.09\t 175.04\t 175.21\t 174.42\n",
"2022-03-28\t 175.60\t 172.68\t 173.89\t 172.85\t 175.90\t 175.51\t 176.18\t 175.85\t 175.23\n",
"2022-03-29\t 178.96\t 174.71\t 175.98\t 174.89\t 177.60\t 178.01\t 178.78\t 178.30\t 177.49\n",
"2022-03-30\t 177.77\t 176.22\t 177.00\t 175.85\t 178.50\t 178.57\t 178.81\t 178.85\t 177.95\n",
"2022-03-31\t 174.61\t 176.33\t 176.46\t 175.44\t 177.08\t 176.98\t 176.35\t 175.98\t 176.09\n"
]
}
],
"source": [
"TSeries data = new();\n",
"var history = await Yahoo.GetHistoricalAsync(\"AAPL\", DateTime.Today.AddDays(-10), DateTime.Now, Period.Daily);\n",
"SMA_Series sma = new(data, 5);\n",
"WMA_Series wma = new(data, 5);\n",
"EMA_Series ema = new(data, 5);\n",
"HMA_Series hma = new(data, 5);\n",
"DEMA_Series dema = new(data, 5);\n",
"TEMA_Series tema = new(data, 5);\n",
"ZLEMA_Series zlema = new(data, 5);\n",
"JMA_Series jma = new(data, 5);\n",
"\n",
"Console.WriteLine($\"date\\t\\t Value\\t SMA\\t WMA\\t EMA\\t HMA\\t DEMA\\t TEMA \\tZLEMA \\tJMA\");\n",
"foreach (var i in history) {\n",
" data.Add((i.DateTime, (double)i.Close)); // adding data will signal dependant indicators\n",
"\n",
" Console.Write($\"{data[^1].t:yyyy-MM-dd}\\t {(double)data:f2}\\t {(double)sma:f2}\\t {(double)wma:f2}\\t {(double)ema:f2}\\t {(double)hma:f2}\\t {(double)dema:f2}\\t {(double)tema:f2}\\t {(double)zlema:f2}\\t {(double)jma:f2}\\n\");\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>Item1</th><th>Item2</th></tr></thead><tbody><tr><td>0</td><td><span>2022-03-21 00:00:00Z</span></td><td><div class=\"dni-plaintext\">165.380005</div></td></tr><tr><td>1</td><td><span>2022-03-22 00:00:00Z</span></td><td><div class=\"dni-plaintext\">167.9823694096766</div></td></tr><tr><td>2</td><td><span>2022-03-23 00:00:00Z</span></td><td><div class=\"dni-plaintext\">170.06602047454277</div></td></tr><tr><td>3</td><td><span>2022-03-24 00:00:00Z</span></td><td><div class=\"dni-plaintext\">173.24670154378663</div></td></tr><tr><td>4</td><td><span>2022-03-25 00:00:00Z</span></td><td><div class=\"dni-plaintext\">174.81344756154755</div></td></tr><tr><td>5</td><td><span>2022-03-28 00:00:00Z</span></td><td><div class=\"dni-plaintext\">175.53949324963583</div></td></tr><tr><td>6</td><td><span>2022-03-29 00:00:00Z</span></td><td><div class=\"dni-plaintext\">177.89435364830672</div></td></tr><tr><td>7</td><td><span>2022-03-30 00:00:00Z</span></td><td><div class=\"dni-plaintext\">178.39609966493987</div></td></tr><tr><td>8</td><td><span>2022-03-31 00:00:00Z</span></td><td><div class=\"dni-plaintext\">176.03431272212282</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ADD_Series two = new(zlema, jma); // even when indicator is created later, it will grab the data from its source table\n",
"DIV_Series mean = new(two, 2); // this pair here calculates mean of ZLEMA and JMA indicators\n",
"\n",
"mean"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [],
"source": [
"public class ALMA_Series : TSeries\n",
"{\n",
" private readonly int _p;\n",
" private readonly bool _NaN;\n",
" private readonly TSeries _data;\n",
" private readonly double _offset, _sigma;\n",
" private double _norm;\n",
" private readonly System.Collections.Generic.List<double> _buffer = new();\n",
" private readonly System.Collections.Generic.List<double> _weights = new();\n",
"\n",
" public ALMA_Series(TSeries source, int period, double offset = 0.85, double sigma = 6.0, bool useNaN = false)\n",
" {\n",
" this._p = period;\n",
" this._data = source;\n",
" this._NaN = useNaN;\n",
" _offset = offset;\n",
" _sigma = sigma;\n",
"\n",
" double _m = _offset * (_p - 1);\n",
" double _s = _p / _sigma;\n",
"\n",
" _norm = 0;\n",
" for (int i = 0; i < this._p; i++)\n",
" {\n",
" double wt = Math.Exp(-((i - _m) * (i - _m)) / (2 * _s * _s));\n",
" this._weights.Add(wt);\n",
" _norm += wt;\n",
" }\n",
"\n",
" source.Pub += this.Sub;\n",
" if (source.Count > 0)\n",
" {\n",
" for (int i = 0; i < source.Count; i++)\n",
" {\n",
" this.Add(source[i], false);\n",
" }\n",
" }\n",
"\n",
" }\n",
" public new void Add((System.DateTime t, double v) data, bool update = false)\n",
" {\n",
" if (update) { this._buffer[this._buffer.Count - 1] = data.v; } else { this._buffer.Add(data.v); }\n",
" if (this._buffer.Count > this._p) { this._buffer.RemoveAt(0); }\n",
"\n",
" double _wma = 0;\n",
" for (int i = 0; i < this._buffer.Count; i++) { _wma += this._buffer[i] * this._weights[i]; }\n",
" if (this._buffer.Count < this._p) {\n",
" _norm = 0;\n",
" for (int i = 0; i < this._buffer.Count; i++) { _norm += this._weights[i];}\n",
" }\n",
" _wma /= _norm;\n",
"\n",
" (System.DateTime t, double v) result = (data.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _wma);\n",
" if (update) { base[base.Count - 1] = result; } else { base.Add(result); }\n",
" }\n",
" public void Add(bool update = false)\n",
" {\n",
" this.Add(this._data[this._data.Count - 1], update);\n",
" }\n",
" public new void Sub(object source, TSeriesEventArgs e) { this.Add(this._data[this._data.Count - 1], e.update); }\n",
"\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [],
"source": [
"TSeries data = new() {212.80, 214.06, 213.89, 214.66, 213.95, 213.95, 214.55, 214.02, 214.51, 213.75, 214.22, 213.43 };\n",
"ALMA_Series alma = new(data, period: 10, offset: 0.0, sigma: 6.0, useNaN: true);\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2022-03-31\t 212.80\t NaN\t \n",
"2022-03-31\t 214.06\t NaN\t \n",
"2022-03-31\t 213.89\t NaN\t \n",
"2022-03-31\t 214.66\t NaN\t \n",
"2022-03-31\t 213.95\t NaN\t \n",
"2022-03-31\t 213.95\t NaN\t \n",
"2022-03-31\t 214.55\t NaN\t \n",
"2022-03-31\t 214.02\t NaN\t \n",
"2022-03-31\t 214.51\t NaN\t \n",
"2022-03-31\t 213.75\t 213.58\t \n",
"2022-03-31\t 214.22\t 214.11\t \n",
"2022-03-31\t 213.43\t 214.17\t \n"
]
}
],
"source": [
"for (int i=0; i<data.Length; i++) {\n",
" Console.Write($\"{data[i].t:yyyy-MM-dd}\\t {(double)data[i].v:f2}\\t {alma[i].v:f2}\\t \\n\");\n",
"}"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "9.0"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
+155 -155
View File
@@ -1,155 +1,155 @@
# Coverage of indicators
| Indicator | QuanTAlib | TA-LIB | Skender | Pandas-TA |
|--|:--:|:--:|:--:|:--:|
| **Basics** |||||
| OC2 - (Open+Close)/2 |✔️|||✔️|
| HL2 - (High+Low)/2 |✔️|||✔️|
| HLC3 - Typical Price |✔️|||✔️|
| OHL3 - (Open+High+Low)/3 |✔️|||✔️|
| OHLC4 - (O+H+L+C)/4 |✔️|||✔️|
| HLCC4 - Weighted Price |✔️||✔️|✔️|
| ZL - Zero Lag - De-lagged price |✔️|||✔️|
| ADD - Addition |✔️|✔️|||
| SUB - Subtraction |✔️|✔️|||
| MUL - Multiplication |✔️|✔️|||
| DIV - Division |✔️|✔️|||
||||||
| **Statistics** |||||
| BETA - Beta coefficient |||✔️||
| BIAS - Bias |✔️|||✔️|
| ENTR - Entropy |✔️|||✔️|
| KUR - Kurtosis |✔️|||✔️|
| LINREG - Linear Regression |✔️|✔️|✔️||
| MAD - Mean Absolute Deviation |✔️||✔️|✔️|
| MAPE - Mean Absolute Percent Error |✔️||✔️||
| MAX - Max value |✔️|✔️|||
| MIN - Min value |✔️|✔️|||
| MED - Median value |✔️|✔️||✔️|
| MSE - Mean Squared Error |✔️||✔️||
| PSDEV - Population Standard Deviation |✔️||||
| PVAR - Population Variance |✔️||||
| QUANTILE ||||✔️|
| SKEW - Skewness ||||✔️|
| SMAPE - Symmetric Mean Absolute Percent Error |✔️||||
| SDEV - Sample Standard Deviation |✔️|✔️|✔️|✔️|
| VAR - Sample Variance |✔️|||✔️|
| WMAPE - Weighted Mean Absolute Percent Error |✔️||||
| ZSCORE |||✔️|✔️|
||||||
| **Moving Averages** |||||
| AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||
| ALMA - Arnaud Legoux Moving Average |✔️||✔️|✔️|
| ARIMA - Autoregressive Integrated Moving Average |||||
| ATR - Average True Range |✔️|✔️|✔️|✔️|
| ATRP - Average True Range Percent |✔️||✔️||
| DEMA - Double EMA |✔️|✔️|✔️|✔️|
| EMA - Exponential Moving Average |✔️|✔️|✔️|✔️|
| EPMA - Endpoint Moving Average |||✔️||
| FWMA - Fibonacci's Weighted Moving Average ||||✔️|
| HEMA - Hull Exponential Moving Average |✔️||||
| HMA - Hull Moving Average |✔️||✔️|✔️|
| HWMA - Holt-Winter Moving Average ||||✔️|
| JMA - Jurik Moving Average |✔️|||✔️|
| KAMA - Kaufman's Adaptive Moving Average |✔️|✔️|✔️|✔️|
| LSMA - Least Squares Moving Average |||✔️||
| MACD - Moving Average Convergence/Divergence |✔️|✔️|✔️|✔️|
| MAMA - MESA Adaptive Moving Average ||✔️|✔️||
| MMA - Modified Moving Average |||✔️||
| NATR - Normalized Average True Range ||✔️|✔️|✔️|
| PPMA - Pivot Point Moving Average |||✔️||
| PWMA - Pascal's Weighted Moving Average ||||✔️|
| RMA - WildeR's Moving Average |✔️|||✔️|
| SINWMA - Sine Weighted Moving Average ||||✔️|
| SMA - Simple Moving Average |✔️|✔️|✔️|✔️|
| SMMA - Smoothed Moving Average |✔️||✔️||
| STOCH - Stochastic Oscillator ||✔️|✔️|✔️|
| SSF - Ehler's Super Smoother Filter ||||✔️|
| SUP - Supertrend |||✔️|✔️|
| SWMA - Symmetric Weighted Moving Average ||||✔️|
| T3 - Tillson T3 Moving Average ||✔️|✔️|✔️|
| TEMA - Triple EMA |✔️|✔️|✔️|✔️|
| TRIMA - Triangular Moving Average ||✔️||✔️|
| VIDYA - Variable Index Dynamic Average ||||✔️|
| VWAP - Volume Weighted Average Price |||✔️|✔️|
| VWMA - Volume Weighted Moving Average |||✔️|✔️|
| WMA - Weighted Moving Average |✔️|✔️|✔️|✔️|
| ZLEMA - Zero Lag EMA |✔️|||✔️|
||||||
| **Oscillators and Indices** |||||
| AC - Acceleration Oscillator ||||✔️|
| AD - Chaikin Accumulation Distribution ||✔️|✔️|✔️|
| ADOSC - Chaikin Accumulation Distribution Oscillator ||✔️|✔️||
| ADX - Average Directional Movement Index ||✔️|✔️|✔️|
| ADXR - Average Directional Movement Index Rating ||✔️|✔️||
| AO - Awesome Oscillator |||✔️|✔️|
| APO - Absolute Price Oscillator ||✔️||✔️|
| AROON - Aroon oscillator ||✔️|✔️|✔️|
| BBANDS - Bollinger Bands ||✔️|✔️|✔️|
| BOP - Balance of Power ||✔️|✔️|✔️|
| CCI - Commodity Channel Index |✔️|✔️|✔️|✔️|
| CFO - Chande Forcast Oscillator ||||✔️|
| CMF - Chaikin Money Flow |||✔️|✔️|
| CMO - Chande Momentum Oscillator ||✔️||✔️|
| COG - Center of Gravity ||||✔️|
| CRSI - Connor RSI |||✔️||
| CTI - Ehler's Correlation Trend Indicator ||||✔️|
| DMI - Directional Movement Index ||✔️|✔️|✔️|
| EFI - Elder Ray's Force Index |||✔️|✔️|
| GAT - Alligator oscillator |||✔️||
| KRI - Kairi Relative Index |||||
| KVO - Klinger Volume Oscillator |||✔️|✔️|
| MFI - Money Flow Index ||✔️|✔️|✔️|
| MOM - Momentum |||✔️|✔️|
| NVI - Negative Volume Index ||||✔️|
| PO - Price Oscillator ||||✔️|
| PPO - Percentage Price Oscillator ||✔️||✔️|
| PVI - Positive Volume Index ||||✔️|
| RSI - Relative Strength Index |✔️|✔️|✔️|✔️|
| RVGI - Relative Vigor Index ||||✔️|
| SRSI - Stochastic RSI |||✔️|✔️|
| TRIX - 1-day ROC of TEMA ||✔️|✔️|✔️|
| TSI - True Strength Index |||✔️|✔️|
| UI - Ulcer Index |||✔️|✔️|
| UO - Ultimate Oscillator ||✔️|✔️|✔️|
| WGAT - Williams Alligator |||✔️||
||||||
| **Volume** |||||
| AOBV - Archer On-Balance Volume ||||✔️|
| OBV - On-Balance Volume ||✔️|✔️|✔️|
| PRS - Price Relative Strength |||✔️||
| PVOL - Price-Volume |||||
| PVR - Price Volume Rank ||||✔️|
| PVT - Price Volume Trend ||||✔️|
| VP - Volume Profile ||||✔️|
||||||
|**Unsorted**|||||
| CHN - Price Channel |||✔️||
| COPPOCK - Coppock Curve ||||✔️|
| CORREL - Pearson's Correlation Coefficient ||✔️|✔️||
| EOM - Ease of Movement ||||✔️|
| HILO - Gann High-Low Activator ||||✔️|
| HV - Historical Volatility |||✔️||
| HT - HT Trendline |||✔️||
| ICH - Ichimoku |||✔️|✔️|
| MCGD - McGinley Dynamic ||||✔️|
| ROC - Rate of Change ||✔️|✔️|✔️|
| SAR - Parabolic Stop and Reverse ||✔️|✔️|✔️|
| STC - Schaff Trend Cycle |||✔️|✔️|
| TR - True Range ||✔️|✔️|✔️|
| WILLR - Larry Williams' %R ||✔️|✔️|✔️|
| HURST - Hurst Exponent |||✔️||
| VOR - Vortex Indicator |||✔️|✔️|
| DON - Donchian Channels |||✔️|✔️|
| FCB - Fractal Chaos Bands |||✔️||
| KEL - Keltner Channels |||✔️|✔️|
| PVT - Pivot Points |||✔️||
| STARC - Starc Bands |||✔️||
| DPO - De-trended Price Oscillator |||✔️|✔️|
| KDJ - KDJ Index |||✔️|✔️|
| SMI - Stochastic Momentum Index |||✔️|✔️|
| CHAND - Chandelier Exit |||✔️||
| VSTOP - Volatility Stop |||✔️||
| PVO - Percentage Volume Oscillator |||✔️|✔️|
| Hilbert Transform Instantaneous Trendline |||||
| PMO - Price Momentum Oscillator |||✔️||
# Coverage of indicators
| Indicator | QuanTAlib | TA-LIB | Skender | Pandas-TA |
|--|:--:|:--:|:--:|:--:|
| **Basics** |||||
| OC2 - (Open+Close)/2 |✔️|||✔️|
| HL2 - (High+Low)/2 |✔️|||✔️|
| HLC3 - Typical Price |✔️|||✔️|
| OHL3 - (Open+High+Low)/3 |✔️|||✔️|
| OHLC4 - (O+H+L+C)/4 |✔️|||✔️|
| HLCC4 - Weighted Price |✔️||✔️|✔️|
| ZL - Zero Lag - De-lagged price |✔️|||✔️|
| ADD - Addition |✔️|✔️|||
| SUB - Subtraction |✔️|✔️|||
| MUL - Multiplication |✔️|✔️|||
| DIV - Division |✔️|✔️|||
||||||
| **Statistics** |||||
| BETA - Beta coefficient |||✔️||
| BIAS - Bias |✔️|||✔️|
| ENTR - Entropy |✔️|||✔️|
| KUR - Kurtosis |✔️|||✔️|
| LINREG - Linear Regression |✔️|✔️|✔️||
| MAD - Mean Absolute Deviation |✔️||✔️|✔️|
| MAPE - Mean Absolute Percent Error |✔️||✔️||
| MAX - Max value |✔️|✔️|||
| MIN - Min value |✔️|✔️|||
| MED - Median value |✔️|✔️||✔️|
| MSE - Mean Squared Error |✔️||✔️||
| PSDEV - Population Standard Deviation |✔️||||
| PVAR - Population Variance |✔️||||
| QUANTILE ||||✔️|
| SKEW - Skewness ||||✔️|
| SMAPE - Symmetric Mean Absolute Percent Error |✔️||||
| SDEV - Sample Standard Deviation |✔️|✔️|✔️|✔️|
| VAR - Sample Variance |✔️|||✔️|
| WMAPE - Weighted Mean Absolute Percent Error |✔️||||
| ZSCORE |||✔️|✔️|
||||||
| **Moving Averages** |||||
| AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||
| ALMA - Arnaud Legoux Moving Average |✔️||✔️|✔️|
| ARIMA - Autoregressive Integrated Moving Average |||||
| ATR - Average True Range |✔️|✔️|✔️|✔️|
| ATRP - Average True Range Percent |✔️||✔️||
| DEMA - Double EMA |✔️|✔️|✔️|✔️|
| EMA - Exponential Moving Average |✔️|✔️|✔️|✔️|
| EPMA - Endpoint Moving Average |||✔️||
| FWMA - Fibonacci's Weighted Moving Average ||||✔️|
| HEMA - Hull Exponential Moving Average |✔️||||
| HMA - Hull Moving Average |✔️||✔️|✔️|
| HWMA - Holt-Winter Moving Average ||||✔️|
| JMA - Jurik Moving Average |✔️|||✔️|
| KAMA - Kaufman's Adaptive Moving Average |✔️|✔️|✔️|✔️|
| LSMA - Least Squares Moving Average |||✔️||
| MACD - Moving Average Convergence/Divergence |✔️|✔️|✔️|✔️|
| MAMA - MESA Adaptive Moving Average ||✔️|✔️||
| MMA - Modified Moving Average |||✔️||
| NATR - Normalized Average True Range ||✔️|✔️|✔️|
| PPMA - Pivot Point Moving Average |||✔️||
| PWMA - Pascal's Weighted Moving Average ||||✔️|
| RMA - WildeR's Moving Average |✔️|||✔️|
| SINWMA - Sine Weighted Moving Average ||||✔️|
| SMA - Simple Moving Average |✔️|✔️|✔️|✔️|
| SMMA - Smoothed Moving Average |✔️||✔️||
| STOCH - Stochastic Oscillator ||✔️|✔️|✔️|
| SSF - Ehler's Super Smoother Filter ||||✔️|
| SUP - Supertrend |||✔️|✔️|
| SWMA - Symmetric Weighted Moving Average ||||✔️|
| T3 - Tillson T3 Moving Average ||✔️|✔️|✔️|
| TEMA - Triple EMA |✔️|✔️|✔️|✔️|
| TRIMA - Triangular Moving Average ||✔️||✔️|
| VIDYA - Variable Index Dynamic Average ||||✔️|
| VWAP - Volume Weighted Average Price |||✔️|✔️|
| VWMA - Volume Weighted Moving Average |||✔️|✔️|
| WMA - Weighted Moving Average |✔️|✔️|✔️|✔️|
| ZLEMA - Zero Lag EMA |✔️|||✔️|
||||||
| **Oscillators and Indices** |||||
| AC - Acceleration Oscillator ||||✔️|
| AD - Chaikin Accumulation Distribution ||✔️|✔️|✔️|
| ADOSC - Chaikin Accumulation Distribution Oscillator ||✔️|✔️||
| ADX - Average Directional Movement Index ||✔️|✔️|✔️|
| ADXR - Average Directional Movement Index Rating ||✔️|✔️||
| AO - Awesome Oscillator |||✔️|✔️|
| APO - Absolute Price Oscillator ||✔️||✔️|
| AROON - Aroon oscillator ||✔️|✔️|✔️|
| BBANDS - Bollinger Bands ||✔️|✔️|✔️|
| BOP - Balance of Power ||✔️|✔️|✔️|
| CCI - Commodity Channel Index |✔️|✔️|✔️|✔️|
| CFO - Chande Forcast Oscillator ||||✔️|
| CMF - Chaikin Money Flow |||✔️|✔️|
| CMO - Chande Momentum Oscillator ||✔️||✔️|
| COG - Center of Gravity ||||✔️|
| CRSI - Connor RSI |||✔️||
| CTI - Ehler's Correlation Trend Indicator ||||✔️|
| DMI - Directional Movement Index ||✔️|✔️|✔️|
| EFI - Elder Ray's Force Index |||✔️|✔️|
| GAT - Alligator oscillator |||✔️||
| KRI - Kairi Relative Index |||||
| KVO - Klinger Volume Oscillator |||✔️|✔️|
| MFI - Money Flow Index ||✔️|✔️|✔️|
| MOM - Momentum |||✔️|✔️|
| NVI - Negative Volume Index ||||✔️|
| PO - Price Oscillator ||||✔️|
| PPO - Percentage Price Oscillator ||✔️||✔️|
| PVI - Positive Volume Index ||||✔️|
| RSI - Relative Strength Index |✔️|✔️|✔️|✔️|
| RVGI - Relative Vigor Index ||||✔️|
| SRSI - Stochastic RSI |||✔️|✔️|
| TRIX - 1-day ROC of TEMA ||✔️|✔️|✔️|
| TSI - True Strength Index |||✔️|✔️|
| UI - Ulcer Index |||✔️|✔️|
| UO - Ultimate Oscillator ||✔️|✔️|✔️|
| WGAT - Williams Alligator |||✔️||
||||||
| **Volume** |||||
| AOBV - Archer On-Balance Volume ||||✔️|
| OBV - On-Balance Volume ||✔️|✔️|✔️|
| PRS - Price Relative Strength |||✔️||
| PVOL - Price-Volume |||||
| PVR - Price Volume Rank ||||✔️|
| PVT - Price Volume Trend ||||✔️|
| VP - Volume Profile ||||✔️|
||||||
|**Unsorted**|||||
| CHN - Price Channel |||✔️||
| COPPOCK - Coppock Curve ||||✔️|
| CORREL - Pearson's Correlation Coefficient ||✔️|✔️||
| EOM - Ease of Movement ||||✔️|
| HILO - Gann High-Low Activator ||||✔️|
| HV - Historical Volatility |||✔️||
| HT - HT Trendline |||✔️||
| ICH - Ichimoku |||✔️|✔️|
| MCGD - McGinley Dynamic ||||✔️|
| ROC - Rate of Change ||✔️|✔️|✔️|
| SAR - Parabolic Stop and Reverse ||✔️|✔️|✔️|
| STC - Schaff Trend Cycle |||✔️|✔️|
| TR - True Range ||✔️|✔️|✔️|
| WILLR - Larry Williams' %R ||✔️|✔️|✔️|
| HURST - Hurst Exponent |||✔️||
| VOR - Vortex Indicator |||✔️|✔️|
| DON - Donchian Channels |||✔️|✔️|
| FCB - Fractal Chaos Bands |||✔️||
| KEL - Keltner Channels |||✔️|✔️|
| PVT - Pivot Points |||✔️||
| STARC - Starc Bands |||✔️||
| DPO - De-trended Price Oscillator |||✔️|✔️|
| KDJ - KDJ Index |||✔️|✔️|
| SMI - Stochastic Momentum Index |||✔️|✔️|
| CHAND - Chandelier Exit |||✔️||
| VSTOP - Volatility Stop |||✔️||
| PVO - Percentage Volume Oscillator |||✔️|✔️|
| Hilbert Transform Instantaneous Trendline |||||
| PMO - Price Momentum Oscillator |||✔️||
+290 -290
View File
@@ -1,290 +1,290 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Quick Start\n",
"\n",
"In order to use this .NET Interactive Notebook and play along with QuanTAlib (outside of making your own app or plugging QuanTAlib into Quantower platform), you will need:\n",
"\n",
"- Installed <a href=\"https://code.visualstudio.com/\" target=\"_blank\">Visual Studio Code</a>\n",
"- Installed <a href=\"https://dotnet.microsoft.com/download/dotnet/6.0\" target=\"_blank\">.NET 6 SDK</a>\n",
"- Installed <a href=\"https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode\" target=\"_blank\">.NET Interactive Notebooks</a> extension\n",
"\n",
"**For impatient**, here is a simple example of calculating three moving averages - SMA(data), EMA(SMA(data)) and WMA(EMA(SMA(data))) from 10 days of AAPL stock data using QuanTAlib:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"index\t data\t\t sma(data)\t ema(sma(data))\t wma(ema(sma(data)))\n",
"0\t 2022-03-23\t 170.21\t\t 170.21\t\t NaN\n",
"1\t 2022-03-24\t 172.14\t\t 170.85\t\t NaN\n",
"2\t 2022-03-25\t 173.00\t\t 171.57\t\t NaN\n",
"3\t 2022-03-28\t 173.65\t\t 172.26\t\t NaN\n",
"4\t 2022-03-29\t 174.71\t\t 173.08\t\t 172.07\n",
"5\t 2022-03-30\t 176.22\t\t 174.13\t\t 172.92\n",
"6\t 2022-03-31\t 176.33\t\t 174.86\t\t 173.74\n",
"7\t 2022-04-01\t 176.25\t\t 175.32\t\t 174.46\n",
"8\t 2022-04-04\t 176.82\t\t 175.82\t\t 175.09\n",
"9\t 2022-04-05\t 176.04\t\t 175.89\t\t 175.51\n",
"10\t 2022-04-06\t 174.85\t\t 175.55\t\t 175.62\n",
"11\t 2022-04-07\t 174.36\t\t 175.15\t\t 175.51\n"
]
}
],
"source": [
"#r \"nuget:QuanTAlib;\"\n",
"using QuanTAlib;\n",
"\n",
"YAHOO_Feed aapl = new(15, \"AAPL\");\n",
"TSeries data = aapl.Close;\n",
"SMA_Series sma = new(source: data, period: 5, useNaN: false);\n",
"EMA_Series ema = new(sma, period: 5); // by default, indicators expose all data, no NaN values\n",
"WMA_Series wma = new(ema, 5, useNaN: true); // for the final calculation we can hide early data with NaNs\n",
"\n",
"Console.Write($\"index\\t data\\t\\t sma(data)\\t ema(sma(data))\\t wma(ema(sma(data)))\\n\");\n",
"for (int i=0; i<data.Count; i++)\n",
" Console.Write($\"{i}\\t {data[i].t:yyyy-MM-dd}\\t {sma[i].v:f2}\\t\\t {ema[i].v:f2}\\t\\t {wma[i].v:f2}\\n\");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Understanding QuanTAlib data model\n",
"\n",
"QuanTAlib expects that every data item is a tuple (TimeDate t, double v) and TSeries is a list of (t,v) tuples. There are several helpers built into the TSeries class to simplify adding elements:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>Item1</th><th>Item2</th></tr></thead><tbody><tr><td>0</td><td><span>2022-04-07 00:00:00Z</span></td><td><div class=\"dni-plaintext\">105.3</div></td></tr><tr><td>1</td><td><span>2022-04-07 21:57:46Z</span></td><td><div class=\"dni-plaintext\">293.1</div></td></tr><tr><td>2</td><td><span>2022-04-07 21:57:46Z</span></td><td><div class=\"dni-plaintext\">0</div></td></tr><tr><td>3</td><td><span>2022-04-04 21:57:46Z</span></td><td><div class=\"dni-plaintext\">10</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"var item1 = (DateTime.Today, 105.3); // (DateTime, Value) tuple\n",
"double item2 = 293.1; // a simple double\n",
"\n",
"TSeries data = new();\n",
"data.Add(item1); // adding tuple variable\n",
"data.Add(item2); // QuanTAlib stamps the (double) with current time\n",
"data.Add(0); // directly adding a number (stamped with current time)\n",
"data.Add((DateTime.Now.AddDays(-3), 10)); // adding a tuple with timestamp 3 days ago\n",
"\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"TSeries list can display only values (without timestamps) or only timestamps (without values) by using `.v` or `.t` properties"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>value</th></tr></thead><tbody><tr><td>0</td><td><div class=\"dni-plaintext\">105.3</div></td></tr><tr><td>1</td><td><div class=\"dni-plaintext\">293.1</div></td></tr><tr><td>2</td><td><div class=\"dni-plaintext\">0</div></td></tr><tr><td>3</td><td><div class=\"dni-plaintext\">10</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"data.v"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The last element on the list can be accessed by .Last() or by [^1] - and using `.t` (time) and `.v` (value) properties. Also, casting a TSeries into (double) will return the value of the last element"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div class=\"dni-plaintext\">10</div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"bool IsTheSame = data.Last().v == data[^1].v;\n",
"double lastvalue = data;\n",
"\n",
"lastvalue"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All indicators are just modified TSeries classes; they get all required input during class construction (source of the datafeed, period...) and they automatically subscribe to events of the datafeed. Whenever datafeed gets a new value, indicator will calculate its own value. Indicators are also event publishers, so other indicators can subscribe to their results, chaining indicators together:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>value</th></tr></thead><tbody><tr><td>0</td><td><div class=\"dni-plaintext\">Infinity</div></td></tr><tr><td>1</td><td><div class=\"dni-plaintext\">0.6666666666666666</div></td></tr><tr><td>2</td><td><div class=\"dni-plaintext\">0.3076923076923077</div></td></tr><tr><td>3</td><td><div class=\"dni-plaintext\">0.1951219512195122</div></td></tr><tr><td>4</td><td><div class=\"dni-plaintext\">0.1415929203539823</div></td></tr><tr><td>5</td><td><div class=\"dni-plaintext\">0.11072664359861592</div></td></tr><tr><td>6</td><td><div class=\"dni-plaintext\">0.09078014184397164</div></td></tr><tr><td>7</td><td><div class=\"dni-plaintext\">0.07687687687687687</div></td></tr><tr><td>8</td><td><div class=\"dni-plaintext\">0.06664931007550118</div></td></tr><tr><td>9</td><td><div class=\"dni-plaintext\">0.05881677197013211</div></td></tr><tr><td>10</td><td><div class=\"dni-plaintext\">0.2499389797412741</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"TSeries t1 = new() {0,1,2,3,4,5,6,7,8,9}; // t1 is loaded with data and activated as a publisher\n",
"EMA_Series t2 = new(t1, 3); // t2 will auto-load all history of t1 and wait for events from t1\n",
"ADD_Series t3 = new(t1, t2); // t3 is an ADDition of t1 and t2 - will also load history and wait for t2 events\n",
"DIV_Series t4 = new(1, t3); // t4 is calculating 1/t3 - and waiting for t3 events\n",
"\n",
"TSeries t5 = new(); // a wild indicator appeared! And it is empty!\n",
"t4.Pub += t5.Sub; // let us add a manual subscription to events coming from t4 - t5 is now listening to t4\n",
"t1.Add(0); // we add one new value to t1 - and trigger the full cascade of calculation! t5 is now full!\n",
"\n",
"t5.v"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# MACD compounded indicator\n",
"\n",
"With QuanTAlib we can chain indicators together, creating complex compounded indicators. For example, we can create Moving Average Convergence/Divergence (MACD) indicators by chaining all required operations in a sequence:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>value</th></tr></thead><tbody><tr><td>0</td><td><div class=\"dni-plaintext\">0</div></td></tr><tr><td>1</td><td><div class=\"dni-plaintext\">0.08934530370370339</div></td></tr><tr><td>2</td><td><div class=\"dni-plaintext\">0.3599908358509947</div></td></tr><tr><td>3</td><td><div class=\"dni-plaintext\">0.5984373224068585</div></td></tr><tr><td>4</td><td><div class=\"dni-plaintext\">0.9604679820661939</div></td></tr><tr><td>5</td><td><div class=\"dni-plaintext\">1.17393637722238</div></td></tr><tr><td>6</td><td><div class=\"dni-plaintext\">1.295101583309171</div></td></tr><tr><td>7</td><td><div class=\"dni-plaintext\">1.5073770108948183</div></td></tr><tr><td>8</td><td><div class=\"dni-plaintext\">1.4718244887751928</div></td></tr><tr><td>9</td><td><div class=\"dni-plaintext\">1.1537265475126177</div></td></tr><tr><td>10</td><td><div class=\"dni-plaintext\">0.8550987734004014</div></td></tr><tr><td>11</td><td><div class=\"dni-plaintext\">0.8650928385987653</div></td></tr><tr><td>12</td><td><div class=\"dni-plaintext\">0.5867583008849087</div></td></tr><tr><td>13</td><td><div class=\"dni-plaintext\">0.15053155636913873</div></td></tr><tr><td>14</td><td><div class=\"dni-plaintext\">-0.13622024638714825</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"YAHOO_Feed aapl = new(20, \"AAPL\");\n",
"TSeries close = aapl.Close; // close will get data from history\n",
"EMA_Series slow = new(close,26); // slow gets data from slow through pub-sub eventing\n",
"EMA_Series fast = new(close,12); // fast gets data from slow (via eventing)\n",
"SUB_Series macd = new(fast,slow); // macd is a SUBtraction: fast-slow\n",
"EMA_Series signal = new(macd,9); // signal is EMA of macd\n",
"SUB_Series histogram = new(macd, signal); // histogram is SUBtraction macd-signal\n",
"\n",
"histogram.v\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "9.0"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Quick Start\n",
"\n",
"In order to use this .NET Interactive Notebook and play along with QuanTAlib (outside of making your own app or plugging QuanTAlib into Quantower platform), you will need:\n",
"\n",
"- Installed <a href=\"https://code.visualstudio.com/\" target=\"_blank\">Visual Studio Code</a>\n",
"- Installed <a href=\"https://dotnet.microsoft.com/download/dotnet/6.0\" target=\"_blank\">.NET 6 SDK</a>\n",
"- Installed <a href=\"https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode\" target=\"_blank\">.NET Interactive Notebooks</a> extension\n",
"\n",
"**For impatient**, here is a simple example of calculating three moving averages - SMA(data), EMA(SMA(data)) and WMA(EMA(SMA(data))) from 10 days of AAPL stock data using QuanTAlib:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div><div></div><div></div><div></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"index\t data\t\t sma(data)\t ema(sma(data))\t wma(ema(sma(data)))\n",
"0\t 2022-03-23\t 170.21\t\t 170.21\t\t NaN\n",
"1\t 2022-03-24\t 172.14\t\t 170.85\t\t NaN\n",
"2\t 2022-03-25\t 173.00\t\t 171.57\t\t NaN\n",
"3\t 2022-03-28\t 173.65\t\t 172.26\t\t NaN\n",
"4\t 2022-03-29\t 174.71\t\t 173.08\t\t 172.07\n",
"5\t 2022-03-30\t 176.22\t\t 174.13\t\t 172.92\n",
"6\t 2022-03-31\t 176.33\t\t 174.86\t\t 173.74\n",
"7\t 2022-04-01\t 176.25\t\t 175.32\t\t 174.46\n",
"8\t 2022-04-04\t 176.82\t\t 175.82\t\t 175.09\n",
"9\t 2022-04-05\t 176.04\t\t 175.89\t\t 175.51\n",
"10\t 2022-04-06\t 174.85\t\t 175.55\t\t 175.62\n",
"11\t 2022-04-07\t 174.36\t\t 175.15\t\t 175.51\n"
]
}
],
"source": [
"#r \"nuget:QuanTAlib;\"\n",
"using QuanTAlib;\n",
"\n",
"YAHOO_Feed aapl = new(15, \"AAPL\");\n",
"TSeries data = aapl.Close;\n",
"SMA_Series sma = new(source: data, period: 5, useNaN: false);\n",
"EMA_Series ema = new(sma, period: 5); // by default, indicators expose all data, no NaN values\n",
"WMA_Series wma = new(ema, 5, useNaN: true); // for the final calculation we can hide early data with NaNs\n",
"\n",
"Console.Write($\"index\\t data\\t\\t sma(data)\\t ema(sma(data))\\t wma(ema(sma(data)))\\n\");\n",
"for (int i=0; i<data.Count; i++)\n",
" Console.Write($\"{i}\\t {data[i].t:yyyy-MM-dd}\\t {sma[i].v:f2}\\t\\t {ema[i].v:f2}\\t\\t {wma[i].v:f2}\\n\");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Understanding QuanTAlib data model\n",
"\n",
"QuanTAlib expects that every data item is a tuple (TimeDate t, double v) and TSeries is a list of (t,v) tuples. There are several helpers built into the TSeries class to simplify adding elements:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>Item1</th><th>Item2</th></tr></thead><tbody><tr><td>0</td><td><span>2022-04-07 00:00:00Z</span></td><td><div class=\"dni-plaintext\">105.3</div></td></tr><tr><td>1</td><td><span>2022-04-07 21:57:46Z</span></td><td><div class=\"dni-plaintext\">293.1</div></td></tr><tr><td>2</td><td><span>2022-04-07 21:57:46Z</span></td><td><div class=\"dni-plaintext\">0</div></td></tr><tr><td>3</td><td><span>2022-04-04 21:57:46Z</span></td><td><div class=\"dni-plaintext\">10</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"var item1 = (DateTime.Today, 105.3); // (DateTime, Value) tuple\n",
"double item2 = 293.1; // a simple double\n",
"\n",
"TSeries data = new();\n",
"data.Add(item1); // adding tuple variable\n",
"data.Add(item2); // QuanTAlib stamps the (double) with current time\n",
"data.Add(0); // directly adding a number (stamped with current time)\n",
"data.Add((DateTime.Now.AddDays(-3), 10)); // adding a tuple with timestamp 3 days ago\n",
"\n",
"data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"TSeries list can display only values (without timestamps) or only timestamps (without values) by using `.v` or `.t` properties"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>value</th></tr></thead><tbody><tr><td>0</td><td><div class=\"dni-plaintext\">105.3</div></td></tr><tr><td>1</td><td><div class=\"dni-plaintext\">293.1</div></td></tr><tr><td>2</td><td><div class=\"dni-plaintext\">0</div></td></tr><tr><td>3</td><td><div class=\"dni-plaintext\">10</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"data.v"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The last element on the list can be accessed by .Last() or by [^1] - and using `.t` (time) and `.v` (value) properties. Also, casting a TSeries into (double) will return the value of the last element"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<div class=\"dni-plaintext\">10</div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"bool IsTheSame = data.Last().v == data[^1].v;\n",
"double lastvalue = data;\n",
"\n",
"lastvalue"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All indicators are just modified TSeries classes; they get all required input during class construction (source of the datafeed, period...) and they automatically subscribe to events of the datafeed. Whenever datafeed gets a new value, indicator will calculate its own value. Indicators are also event publishers, so other indicators can subscribe to their results, chaining indicators together:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>value</th></tr></thead><tbody><tr><td>0</td><td><div class=\"dni-plaintext\">Infinity</div></td></tr><tr><td>1</td><td><div class=\"dni-plaintext\">0.6666666666666666</div></td></tr><tr><td>2</td><td><div class=\"dni-plaintext\">0.3076923076923077</div></td></tr><tr><td>3</td><td><div class=\"dni-plaintext\">0.1951219512195122</div></td></tr><tr><td>4</td><td><div class=\"dni-plaintext\">0.1415929203539823</div></td></tr><tr><td>5</td><td><div class=\"dni-plaintext\">0.11072664359861592</div></td></tr><tr><td>6</td><td><div class=\"dni-plaintext\">0.09078014184397164</div></td></tr><tr><td>7</td><td><div class=\"dni-plaintext\">0.07687687687687687</div></td></tr><tr><td>8</td><td><div class=\"dni-plaintext\">0.06664931007550118</div></td></tr><tr><td>9</td><td><div class=\"dni-plaintext\">0.05881677197013211</div></td></tr><tr><td>10</td><td><div class=\"dni-plaintext\">0.2499389797412741</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"TSeries t1 = new() {0,1,2,3,4,5,6,7,8,9}; // t1 is loaded with data and activated as a publisher\n",
"EMA_Series t2 = new(t1, 3); // t2 will auto-load all history of t1 and wait for events from t1\n",
"ADD_Series t3 = new(t1, t2); // t3 is an ADDition of t1 and t2 - will also load history and wait for t2 events\n",
"DIV_Series t4 = new(1, t3); // t4 is calculating 1/t3 - and waiting for t3 events\n",
"\n",
"TSeries t5 = new(); // a wild indicator appeared! And it is empty!\n",
"t4.Pub += t5.Sub; // let us add a manual subscription to events coming from t4 - t5 is now listening to t4\n",
"t1.Add(0); // we add one new value to t1 - and trigger the full cascade of calculation! t5 is now full!\n",
"\n",
"t5.v"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# MACD compounded indicator\n",
"\n",
"With QuanTAlib we can chain indicators together, creating complex compounded indicators. For example, we can create Moving Average Convergence/Divergence (MACD) indicators by chaining all required operations in a sequence:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"vscode": {
"languageId": "dotnet-interactive.csharp"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>value</th></tr></thead><tbody><tr><td>0</td><td><div class=\"dni-plaintext\">0</div></td></tr><tr><td>1</td><td><div class=\"dni-plaintext\">0.08934530370370339</div></td></tr><tr><td>2</td><td><div class=\"dni-plaintext\">0.3599908358509947</div></td></tr><tr><td>3</td><td><div class=\"dni-plaintext\">0.5984373224068585</div></td></tr><tr><td>4</td><td><div class=\"dni-plaintext\">0.9604679820661939</div></td></tr><tr><td>5</td><td><div class=\"dni-plaintext\">1.17393637722238</div></td></tr><tr><td>6</td><td><div class=\"dni-plaintext\">1.295101583309171</div></td></tr><tr><td>7</td><td><div class=\"dni-plaintext\">1.5073770108948183</div></td></tr><tr><td>8</td><td><div class=\"dni-plaintext\">1.4718244887751928</div></td></tr><tr><td>9</td><td><div class=\"dni-plaintext\">1.1537265475126177</div></td></tr><tr><td>10</td><td><div class=\"dni-plaintext\">0.8550987734004014</div></td></tr><tr><td>11</td><td><div class=\"dni-plaintext\">0.8650928385987653</div></td></tr><tr><td>12</td><td><div class=\"dni-plaintext\">0.5867583008849087</div></td></tr><tr><td>13</td><td><div class=\"dni-plaintext\">0.15053155636913873</div></td></tr><tr><td>14</td><td><div class=\"dni-plaintext\">-0.13622024638714825</div></td></tr></tbody></table>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"YAHOO_Feed aapl = new(20, \"AAPL\");\n",
"TSeries close = aapl.Close; // close will get data from history\n",
"EMA_Series slow = new(close,26); // slow gets data from slow through pub-sub eventing\n",
"EMA_Series fast = new(close,12); // fast gets data from slow (via eventing)\n",
"SUB_Series macd = new(fast,slow); // macd is a SUBtraction: fast-slow\n",
"EMA_Series signal = new(macd,9); // signal is EMA of macd\n",
"SUB_Series histogram = new(macd, signal); // histogram is SUBtraction macd-signal\n",
"\n",
"histogram.v\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "9.0"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}
+25 -25
View File
@@ -1,25 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css">
</head>
<body>
<div id="app"></div>
<script>
window.$docsify = {
name: 'QuanTAlib',
repo: 'mihakralj/quantalib'
}
</script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-csharp.min.js"></script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-themeable@0/dist/js/docsify-themeable.min.js"></script>
<script src="//unpkg.com/@rakutentech/docsify-code-inline/dist/index.min.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple.css">
</head>
<body>
<div id="app"></div>
<script>
window.$docsify = {
name: 'QuanTAlib',
repo: 'mihakralj/quantalib'
}
</script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-csharp.min.js"></script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-themeable@0/dist/js/docsify-themeable.min.js"></script>
<script src="//unpkg.com/@rakutentech/docsify-code-inline/dist/index.min.js"></script>
</body>
</html>
+244
View File
@@ -0,0 +1,244 @@
#!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
File diff suppressed because one or more lines are too long