mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-23 04:58:08 +00:00
TR and ATR
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/html": [
|
"text/html": [
|
||||||
"<div><div></div><div></div><div><strong>Installed Packages</strong><ul><li><span>QuantLib, 1.0.7</span></li><li><span>TALib.NETCore, 0.4.4</span></li></ul></div></div>"
|
"<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": {},
|
"metadata": {},
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"#r \"nuget: TALib.NETCore, 0.4.4\" \n",
|
"#r \"nuget: TALib.NETCore, 0.4.4\" \n",
|
||||||
"#r \"nuget:QuanTAlib\" \n",
|
"#r \"nuget: QuanTAlib, 0.1.10-beta\" \n",
|
||||||
"\n",
|
"\n",
|
||||||
"using QuanTAlib;\n",
|
"using QuanTAlib;\n",
|
||||||
"using TALib;\n"
|
"using TALib;\n"
|
||||||
@@ -43,13 +43,12 @@
|
|||||||
},
|
},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"ename": "Error",
|
||||||
"text/html": [
|
"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?)",
|
||||||
"<div class=\"dni-plaintext\">1394</div>"
|
"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?)"
|
||||||
"metadata": {},
|
]
|
||||||
"output_type": "display_data"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
|
|||||||
+2
-1
@@ -42,7 +42,8 @@
|
|||||||
| AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||
|
| AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||
|
||||||
| ALMA - Arnaud Legoux Moving Average |||✔️|✔️|
|
| ALMA - Arnaud Legoux Moving Average |||✔️|✔️|
|
||||||
| ARIMA - Autoregressive Integrated Moving Average |||||
|
| ARIMA - Autoregressive Integrated Moving Average |||||
|
||||||
| ATR - Average True Range ||✔️|✔️|✔️|
|
| ATR - Average True Range |✔️|✔️|✔️|✔️|
|
||||||
|
| ATRP - Average True Range Percent |✔️||✔️||
|
||||||
| DEMA - Double EMA |✔️|✔️|✔️|✔️|
|
| DEMA - Double EMA |✔️|✔️|✔️|✔️|
|
||||||
| EMA - Exponential Moving Average |✔️|✔️|✔️|✔️|
|
| EMA - Exponential Moving Average |✔️|✔️|✔️|✔️|
|
||||||
| EPMA - Endpoint Moving Average |||✔️||
|
| EPMA - Endpoint Moving Average |||✔️||
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
// ADD - adding TSeries+TSeries together, or TSeries+double, or double+TSeries
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
ADD - adding TSeries+TSeries together, or TSeries+double, or double+TSeries
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
Most of scaffolding is packaged in abstracty class Pair_TSeries_Indicator.
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class ADD_Series : Pair_TSeries_Indicator
|
public class ADD_Series : Pair_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,18 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
using System;
|
using System;
|
||||||
|
/* <summary>
|
||||||
|
Abstract classes with all scaffolding required to build indicators.
|
||||||
|
All abstracts support period, NaN, and all permutations of Add() methods.
|
||||||
|
Indicator classess need to implement:
|
||||||
|
- Chaining constructor (Abstract's constructor executes first)
|
||||||
|
- Default Add(value) class
|
||||||
|
- optional Add(series) bulk insert class (for optimization of historical analysis)
|
||||||
|
|
||||||
|
Single_TSeries_Indicator - one single-value TSeries in, one TSeries out.
|
||||||
|
Pair_TSeries_Indicator - Two TSeries in, one TSeries out. (includes simple semaphoring)
|
||||||
|
Single_TBars_Indicator - One OHLCV TBars in, one TSeries out.
|
||||||
|
|
||||||
|
</summary> */
|
||||||
public abstract class Single_TSeries_Indicator : TSeries
|
public abstract class Single_TSeries_Indicator : TSeries
|
||||||
{
|
{
|
||||||
protected readonly int _p;
|
protected readonly int _p;
|
||||||
@@ -124,8 +136,9 @@ public abstract class Single_TBars_Indicator : TSeries
|
|||||||
protected readonly TBars _bars;
|
protected readonly TBars _bars;
|
||||||
|
|
||||||
// Chainable Constructor - add it at the end of primary constructor :base(source: source, period: period, useNaN: useNaN)
|
// Chainable Constructor - add it at the end of primary constructor :base(source: source, period: period, useNaN: useNaN)
|
||||||
protected Single_TBars_Indicator(TBars source, bool useNaN)
|
protected Single_TBars_Indicator(TBars source, int period, bool useNaN)
|
||||||
{
|
{
|
||||||
|
this._p = period;
|
||||||
this._bars = source;
|
this._bars = source;
|
||||||
this._NaN = useNaN;
|
this._NaN = useNaN;
|
||||||
this._bars.Close.Pub += this.Sub;
|
this._bars.Close.Pub += this.Sub;
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
// DIV - divide TSeries/TSeries , or TSeries/double, or double/TSeries
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
DIV - divide TSeries/TSeries , or TSeries/double, or double/TSeries
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
Most of scaffolding is packaged in abstracty class Pair_TSeries_Indicator.
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class DIV_Series : Pair_TSeries_Indicator
|
public class DIV_Series : Pair_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
/*
|
|
||||||
MAX - Maximum value in the given period in the series.
|
|
||||||
|
|
||||||
If period = 0 => period = full length of the series
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
/* <summary>
|
||||||
|
MAX - Maximum value in the given period in the series.
|
||||||
|
If period = 0 => period = full length of the series
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class MAX_Series : Single_TSeries_Indicator
|
public class MAX_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
public MAX_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
|
public MAX_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||||
{
|
{
|
||||||
if (base._data.Count > 0) { base.Add(base._data); }
|
if (base._data.Count > 0) { base.Add(base._data); }
|
||||||
}
|
}
|
||||||
private readonly List<double> _buffer = new();
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
|
|
||||||
public override void Add((DateTime t, double v) d, bool update)
|
public override void Add((DateTime t, double v) d, bool update)
|
||||||
{
|
{
|
||||||
@@ -24,7 +22,7 @@ public class MAX_Series : Single_TSeries_Indicator
|
|||||||
|
|
||||||
double _max = d.v;
|
double _max = d.v;
|
||||||
for (int i = 0; i < this._buffer.Count; i++)
|
for (int i = 0; i < this._buffer.Count; i++)
|
||||||
{ _max = this._buffer[i] > _max ? this._buffer[i] : _max; }
|
{ _max = (this._buffer[i] > _max) ? this._buffer[i] : _max; }
|
||||||
|
|
||||||
var result = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max);
|
var result = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max);
|
||||||
|
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
/*
|
|
||||||
MIN - Minimum value in the given period in the series.
|
|
||||||
|
|
||||||
If period = 0 => period = full length of the series
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
MIN - Minimum value in the given period in the series.
|
||||||
|
If period = 0 => period = full length of the series
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class MIN_Series : Single_TSeries_Indicator
|
public class MIN_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
// MUL - multiply TSeries*TSeries together, or TSeries*double, or double*TSeries
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
MUL - multiply TSeries*TSeries together, or TSeries*double, or double*TSeries
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class MUL_Series : Pair_TSeries_Indicator
|
public class MUL_Series : Pair_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,28 @@
|
|||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
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 class RND_Feed : TBars
|
||||||
{
|
{
|
||||||
public RND_Feed(int days, double volatility = 0.05, double startvalue = 100.0)
|
public RND_Feed(int bars, double volatility = 0.05, double startvalue = 100.0)
|
||||||
{
|
{
|
||||||
Random rnd = new();
|
Random rnd = new();
|
||||||
double c = startvalue;
|
double c = startvalue;
|
||||||
for (int i = 0; i < days; i++)
|
for (int i = 0; i < bars; i++)
|
||||||
{
|
{
|
||||||
double o = Math.Round(c + c * (volatility * 0.1 * rnd.NextDouble() - 0.005), 2);
|
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 h = Math.Round(o + c * volatility * rnd.NextDouble(), 2);
|
||||||
double l = 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);
|
c = Math.Round(l + (h - l) * rnd.NextDouble(), 2);
|
||||||
double v = Math.Round(1000 * rnd.NextDouble(), 2);
|
double v = Math.Round(1000 * rnd.NextDouble(), 2);
|
||||||
this.Add(DateTime.Today.AddDays(i - days), o, h, l, c, v);
|
this.Add(DateTime.Today.AddDays(i - bars), o, h, l, c, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
// SUB - subtracting TSeries-TSeries, or TSeries-double, or double-TSeries
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
SUB - subtracting TSeries-TSeries, or TSeries-double, or double-TSeries
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
|
||||||
public class SUB_Series : Pair_TSeries_Indicator
|
public class SUB_Series : Pair_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
TBars class - includes all series for common data used in indicators and other calculations.
|
||||||
|
Has a bit limited overloading and casting (compared to TSeries)
|
||||||
|
Includes Select(int) method to simplify choosing the most optimal data source for indicators
|
||||||
|
Includes the most basic pricing calcs: HL2, OC2, OHL3, HLC3, OHLC4, HLCC4
|
||||||
|
(it is 'cheaper' to calculate them once during data capture than each time during data analysis)
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class TBars : System.Collections.Generic.List<(DateTime t, double o, double h, double l, double c, double v)>
|
public class TBars : System.Collections.Generic.List<(DateTime t, double o, double h, double l, double c, double v)>
|
||||||
{
|
{
|
||||||
private readonly TSeries _open = new();
|
private readonly TSeries _open = new();
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
TR: True Range
|
||||||
|
True Range was introduced by J. Welles Wilder in his book New Concepts in Technical Trading Systems.
|
||||||
|
It measures the daily range plus any gap from the closing price of the preceding day.
|
||||||
|
|
||||||
|
Calculation:
|
||||||
|
d1 = ABS(High - Low)
|
||||||
|
d2 = ABS(High - Previous close)
|
||||||
|
d3 = ABS(Previous close - Low)
|
||||||
|
TR = MAX(d1,d2,d3)
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
https://www.macroption.com/true-range/
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
public class TR_Series : Single_TBars_Indicator
|
||||||
|
{
|
||||||
|
private double _cm1 = double.NaN;
|
||||||
|
public TR_Series(TBars source, bool useNaN = false) : base(source, period:0, useNaN:useNaN) {
|
||||||
|
if (this._bars.Count > 0) { base.Add(this._bars); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add((DateTime t, double o, double h, double l, double c, double v) TValue, bool update = false)
|
||||||
|
{
|
||||||
|
if (_cm1 is double.NaN) { _cm1 = TValue.c; }
|
||||||
|
|
||||||
|
double d1 = Math.Abs(TValue.h - TValue.l);
|
||||||
|
double d2 = Math.Abs(_cm1 - TValue.h);
|
||||||
|
double d3 = Math.Abs(_cm1 - TValue.l);
|
||||||
|
var ret = (TValue.t, (base.Count==0 && base._NaN) ? double.NaN : Math.Max(d1,Math.Max(d2,d3)) );
|
||||||
|
base.Add(ret, update);
|
||||||
|
_cm1 = TValue.c;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,18 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
TSeries is the cornerstone of all QuanTAlib classess.
|
||||||
|
TSeries is a single List of tuples (time, value) and contains several operators, casts, overloads
|
||||||
|
and other helpers that simplify usage of library.
|
||||||
|
Think of TSeries as an equivalent of Numpy array.
|
||||||
|
|
||||||
|
- includes Length property (to mimic array's method)
|
||||||
|
- includes publishing and subscribing methods that attach to events
|
||||||
|
- uses Linq only for two transmutations - needs to be refactored out eventually (for speed)
|
||||||
|
|
||||||
|
</summary> */
|
||||||
public class TSeries : System.Collections.Generic.List<(DateTime t, double v)>
|
public class TSeries : System.Collections.Generic.List<(DateTime t, double v)>
|
||||||
{
|
{
|
||||||
// when asked for a (t,v) tuple, return the last (t,v) on the List
|
// when asked for a (t,v) tuple, return the last (t,v) on the List
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
ATR: wildeR Moving Average
|
||||||
|
The average true range (ATR) is a price volatility indicator
|
||||||
|
showing the average price variation of assets within a given time period.
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
https://en.wikipedia.org/wiki/Average_true_range
|
||||||
|
https://www.tradingview.com/wiki/Average_True_Range_(ATR)
|
||||||
|
https://www.investopedia.com/terms/a/atr.asp
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
|
||||||
|
public class ATR_Series : Single_TBars_Indicator
|
||||||
|
{
|
||||||
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
|
private readonly double _k, _k1m;
|
||||||
|
private double _lastema, _lastlastema, _lastcm1;
|
||||||
|
private double _cm1 = double.NaN;
|
||||||
|
|
||||||
|
public ATR_Series(TBars source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||||
|
{
|
||||||
|
this._k = 1.0 / (double)(this._p);
|
||||||
|
this._k1m = 1.0 - this._k;
|
||||||
|
this._lastema = this._lastlastema = double.NaN;
|
||||||
|
if (_bars.Count > 0) { base.Add(_bars); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update = false)
|
||||||
|
{
|
||||||
|
if (update) {
|
||||||
|
this._lastema = this._lastlastema;
|
||||||
|
this._cm1 = this._lastcm1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cm1 is double.NaN) { _cm1 = TBar.c; }
|
||||||
|
double d1 = Math.Abs(TBar.h - TBar.l);
|
||||||
|
double d2 = Math.Abs(_cm1 - TBar.h);
|
||||||
|
double d3 = Math.Abs(_cm1 - TBar.l);
|
||||||
|
(DateTime t, double v)d = (TBar.t, Math.Max(d1,Math.Max(d2,d3))); //TR value for RMA below
|
||||||
|
_lastcm1 = _cm1;
|
||||||
|
_cm1 = TBar.c;
|
||||||
|
|
||||||
|
double _ema = 0;
|
||||||
|
if (this.Count < this._p)
|
||||||
|
{
|
||||||
|
if (update) { _buffer[_buffer.Count - 1] = d.v; }
|
||||||
|
else { _buffer.Add(d.v); }
|
||||||
|
if (_buffer.Count > this._p) { _buffer.RemoveAt(0); }
|
||||||
|
for (int i = 0; i < _buffer.Count; i++) { _ema += _buffer[i]; }
|
||||||
|
_ema /= this._buffer.Count;
|
||||||
|
}
|
||||||
|
else { _ema = d.v * _k + _lastema * _k1m; }
|
||||||
|
|
||||||
|
this._lastlastema = this._lastema;
|
||||||
|
this._lastema = _ema;
|
||||||
|
|
||||||
|
var ret = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _ema);
|
||||||
|
base.Add(ret, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
ATRP: Average True Range Percent
|
||||||
|
Average True Range Percent is (ATR/Close Price)*100.
|
||||||
|
This normalizes so it can be compared to other stocks.
|
||||||
|
|
||||||
|
Sources:
|
||||||
|
https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/atrp
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
|
public class ATRP_Series : Single_TBars_Indicator
|
||||||
|
{
|
||||||
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
|
private readonly double _k, _k1m;
|
||||||
|
private double _lastema, _lastlastema, _lastcm1;
|
||||||
|
private double _cm1 = double.NaN;
|
||||||
|
|
||||||
|
public ATRP_Series(TBars source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||||
|
{
|
||||||
|
this._k = 1.0 / (double)(this._p);
|
||||||
|
this._k1m = 1.0 - this._k;
|
||||||
|
this._lastema = this._lastlastema = double.NaN;
|
||||||
|
if (_bars.Count > 0) { base.Add(_bars); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add((DateTime t, double o, double h, double l, double c, double v) TBar, bool update = false)
|
||||||
|
{
|
||||||
|
if (update) {
|
||||||
|
this._lastema = this._lastlastema;
|
||||||
|
this._cm1 = this._lastcm1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cm1 is double.NaN) { _cm1 = TBar.c; }
|
||||||
|
double d1 = Math.Abs(TBar.h - TBar.l);
|
||||||
|
double d2 = Math.Abs(_cm1 - TBar.h);
|
||||||
|
double d3 = Math.Abs(_cm1 - TBar.l);
|
||||||
|
(DateTime t, double v)d = (TBar.t, Math.Max(d1,Math.Max(d2,d3))); //TR value for RMA below
|
||||||
|
_lastcm1 = _cm1;
|
||||||
|
_cm1 = TBar.c;
|
||||||
|
|
||||||
|
double _ema = 0;
|
||||||
|
if (this.Count < this._p)
|
||||||
|
{
|
||||||
|
if (update) { _buffer[_buffer.Count - 1] = d.v; }
|
||||||
|
else { _buffer.Add(d.v); }
|
||||||
|
if (_buffer.Count > this._p) { _buffer.RemoveAt(0); }
|
||||||
|
for (int i = 0; i < _buffer.Count; i++) { _ema += _buffer[i]; }
|
||||||
|
_ema /= this._buffer.Count;
|
||||||
|
}
|
||||||
|
else { _ema = d.v * _k + _lastema * _k1m; }
|
||||||
|
|
||||||
|
this._lastlastema = this._lastema;
|
||||||
|
this._lastema = _ema;
|
||||||
|
|
||||||
|
double _atrp = 100 * (_ema / TBar.c);
|
||||||
|
|
||||||
|
var ret = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _atrp);
|
||||||
|
base.Add(ret, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
DEMA: Double Exponential Moving Average
|
DEMA: Double Exponential Moving Average
|
||||||
DEMA uses EMA(EMA()) to calculate smoother Exponential moving average.
|
DEMA uses EMA(EMA()) to calculate smoother Exponential moving average.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/double-exponential-moving-average-dema/
|
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/double-exponential-moving-average-dema/
|
||||||
@@ -11,13 +12,12 @@ Remark:
|
|||||||
ema1 = EMA(close, length)
|
ema1 = EMA(close, length)
|
||||||
ema2 = EMA(ema1, length)
|
ema2 = EMA(ema1, length)
|
||||||
DEMA = 2 * ema1 - ema2
|
DEMA = 2 * ema1 - ema2
|
||||||
**/
|
|
||||||
|
|
||||||
using System;
|
</summary> */
|
||||||
using System.Collections.Generic;
|
|
||||||
public class DEMA_Series : Single_TSeries_Indicator
|
public class DEMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
private readonly List<double> _buffer = new();
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
private readonly double _k, _k1m;
|
private readonly double _k, _k1m;
|
||||||
private double _lastema1, _lastlastema1;
|
private double _lastema1, _lastlastema1;
|
||||||
private double _lastema2, _lastlastema2;
|
private double _lastema2, _lastlastema2;
|
||||||
@@ -1,26 +1,27 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
EMA: Exponential Moving Average
|
EMA: Exponential Moving Average
|
||||||
|
EMA needs very short history buffer and calculates the EMA value using just the
|
||||||
|
previous EMA value. The weight of the new datapoint (k) is k = 2 / (period-1)
|
||||||
|
|
||||||
EMA needs very short history buffer and calculates the EMA value using just the
|
|
||||||
previous EMA value. The weight of the new datapoint (k) is k = 2 / (period-1)
|
|
||||||
Sources:
|
Sources:
|
||||||
https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
|
https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
|
||||||
https://www.investopedia.com/ask/answers/122314/what-exponential-moving-average-ema-formula-and-how-ema-calculated.asp
|
https://www.investopedia.com/ask/answers/122314/what-exponential-moving-average-ema-formula-and-how-ema-calculated.asp
|
||||||
https://blog.fugue88.ws/archives/2017-01/The-correct-way-to-start-an-Exponential-Moving-Average-EMA
|
https://blog.fugue88.ws/archives/2017-01/The-correct-way-to-start-an-Exponential-Moving-Average-EMA
|
||||||
|
|
||||||
Issues:
|
Issues:
|
||||||
There is no consensus what the first EMA value should be - a zero, a first
|
There is no consensus what the first EMA value should be - a zero, a first
|
||||||
datapoint, or an average of the initial Period bars. All three starting methods
|
datapoint, or an average of the initial Period bars. All three starting methods
|
||||||
converge within 20+ bars to the same moving average. Most implementations (including this one)
|
converge within 20+ bars to the same moving average. Most implementations (including this one)
|
||||||
use SMA() for the first Period bars as a seeding value for EMA.
|
use SMA() for the first Period bars as a seeding value for EMA.
|
||||||
**/
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
public class EMA_Series : Single_TSeries_Indicator
|
public class EMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
private readonly List<double> _buffer = new();
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
private readonly double _k, _k1m;
|
private readonly double _k, _k1m;
|
||||||
private double _lastema, _lastlastema;
|
private double _lastema, _lastlastema;
|
||||||
|
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
using System;
|
namespace QuanTAlib;
|
||||||
namespace QuanTAlib;
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
HEMA: Hull-EMA Moving Average
|
HEMA: Hull-EMA Moving Average
|
||||||
Modified HUll Moving Average; instead of using WMA (Weighted MA) for a
|
Modified HUll Moving Average; instead of using WMA (Weighted MA) for acalculation,
|
||||||
calculation, HEMA uses EMA for Hull's formula:
|
HEMA uses EMA for Hull's formula:
|
||||||
|
|
||||||
EMA1 = EMA(n/2) of price - where k = 4/(n/2 +1)
|
EMA1 = EMA(n/2) of price - where k = 4/(n/2 +1)
|
||||||
EMA2 = EMA(n) of price - where k = 3/(n+1)
|
EMA2 = EMA(n) of price - where k = 3/(n+1)
|
||||||
Raw HMA = (2 * EMA1) - EMA2
|
Raw HMA = (2 * EMA1) - EMA2
|
||||||
EMA3 = EMA(sqrt(n)) of Raw HMA - where k = 2/(sqrt(n)+1)
|
EMA3 = EMA(sqrt(n)) of Raw HMA - where k = 2/(sqrt(n)+1)
|
||||||
**/
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class HEMA_Series : Single_TSeries_Indicator
|
public class HEMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
@@ -1,19 +1,21 @@
|
|||||||
using System;
|
namespace QuanTAlib;
|
||||||
namespace QuanTAlib;
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
HMA: Hull Moving Average
|
HMA: Hull Moving Average
|
||||||
Developed by Alan Hull, an extremely fast and smooth moving average; almost
|
Developed by Alan Hull, an extremely fast and smooth moving average; almost
|
||||||
eliminates lag altogether and manages to improve smoothing at the same time.
|
eliminates lag altogether and manages to improve smoothing at the same time.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://alanhull.com/hull-moving-average
|
https://alanhull.com/hull-moving-average
|
||||||
https://school.stockcharts.com/doku.php?id=technical_indicators:hull_moving_average
|
https://school.stockcharts.com/doku.php?id=technical_indicators:hull_moving_average
|
||||||
|
|
||||||
WMA1 = WMA(n/2) of price
|
WMA1 = WMA(n/2) of price
|
||||||
WMA2 = WMA(n) of price
|
WMA2 = WMA(n) of price
|
||||||
Raw HMA = (2 * WMA1) - WMA2
|
Raw HMA = (2 * WMA1) - WMA2
|
||||||
HMA = WMA(sqrt(n)) of Raw HMA
|
HMA = WMA(sqrt(n)) of Raw HMA
|
||||||
**/
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class HMA_Series : TSeries
|
public class HMA_Series : TSeries
|
||||||
{
|
{
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
namespace QuanTAlib;
|
||||||
namespace QuanTAlib;
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
JMA: Jurik Moving Average
|
JMA: Jurik Moving Average
|
||||||
Mark Jurik's Moving Average (JMA) attempts to eliminate noise to see the
|
Mark Jurik's Moving Average (JMA) attempts to eliminate noise to see the
|
||||||
underlying activity. It has extremely low lag, is very smooth and is responsive
|
underlying activity. It has extremely low lag, is very smooth and is responsive
|
||||||
to market gaps.
|
to market gaps.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://c.mql5.com/forextsd/forum/164/jurik_1.pdf
|
https://c.mql5.com/forextsd/forum/164/jurik_1.pdf
|
||||||
@@ -13,10 +13,12 @@ Sources:
|
|||||||
|
|
||||||
Issues:
|
Issues:
|
||||||
Real JMA algorithm is not published and this formula is derived through
|
Real JMA algorithm is not published and this formula is derived through
|
||||||
deduction and reverse analysis of JMA behavior. It is really close, but not
|
deduction and reverse analysis of JMA behavior. It is really close, but not
|
||||||
exact - published JMA tests against JMA.CSV fail with small deviation. The
|
exact - published JMA tests against JMA.CSV fail with small deviation. The
|
||||||
original algo is slightly different, yet this approximation is close enough.
|
original algo is slightly different, yet this approximation is close enough.
|
||||||
**/
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class JMA_Series : Single_TSeries_Indicator
|
public class JMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
private readonly System.Collections.Generic.List<double> vbuffer10;
|
private readonly System.Collections.Generic.List<double> vbuffer10;
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
RMA: wildeR Moving Average
|
RMA: wildeR Moving Average
|
||||||
|
J. Welles Wilder introduced RMA as an alternative to EMA. RMA's weight (k) is
|
||||||
|
set as 1/period, giving less weight to the new data compared to EMA.
|
||||||
|
|
||||||
J. Welles Wilder introduced RMA as an alternative to EMA. RMA's weight (k) is
|
Sources:
|
||||||
set as 1/period, giving less weight to the new data compared to EMA. Sources:
|
|
||||||
https://archive.org/details/newconceptsintec00wild/page/23/mode/2up
|
https://archive.org/details/newconceptsintec00wild/page/23/mode/2up
|
||||||
|
|
||||||
https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/V-Z/WildersSmoothing
|
https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/V-Z/WildersSmoothing
|
||||||
https://www.incrediblecharts.com/indicators/wilder_moving_average.php
|
https://www.incrediblecharts.com/indicators/wilder_moving_average.php
|
||||||
|
|
||||||
@@ -15,13 +16,11 @@ Issues:
|
|||||||
pandas.ewm().mean() and returns incorrect first (period) of bars compared to
|
pandas.ewm().mean() and returns incorrect first (period) of bars compared to
|
||||||
published formula. This implementation passess the validation test in Wilder's book.
|
published formula. This implementation passess the validation test in Wilder's book.
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
public class RMA_Series : Single_TSeries_Indicator
|
public class RMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
private readonly List<double> _buffer = new();
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
private readonly double _k, _k1m;
|
private readonly double _k, _k1m;
|
||||||
private double _lastema, _lastlastema;
|
private double _lastema, _lastlastema;
|
||||||
|
|
||||||
@@ -1,17 +1,20 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
SMA: Simple Moving Average
|
SMA: Simple Moving Average
|
||||||
The weights are equally distributed across the period, resulting in a mean() of
|
The weights are equally distributed across the period, resulting in a mean() of
|
||||||
the data within the period/
|
the data within the period/
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/simple-moving-average-sma/
|
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/simple-moving-average-sma/
|
||||||
https://stats.stackexchange.com/a/24739
|
https://stats.stackexchange.com/a/24739
|
||||||
|
|
||||||
Remark:
|
Remark:
|
||||||
This calc doesn't use LINQ or SUM() or any of iterative methods.
|
This calc doesn't use LINQ or SUM() or any of (slow) iterative methods. It is not as fast as TA-LIB
|
||||||
**/
|
implementation, but it does allow incremental additions of inputs and real-time calculations of SMA()
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class SMA_Series : Single_TSeries_Indicator
|
public class SMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
TEMA: Triple Exponential Moving Average
|
TEMA: Triple Exponential Moving Average
|
||||||
TEMA uses EMA(EMA(EMA())) to calculate less laggy Exponential moving average.
|
TEMA uses EMA(EMA(EMA())) to calculate less laggy Exponential moving average.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triple-exponential-moving-average-tema/
|
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triple-exponential-moving-average-tema/
|
||||||
@@ -12,13 +13,12 @@ Remark:
|
|||||||
ema2 = EMA(ema1, length)
|
ema2 = EMA(ema1, length)
|
||||||
ema3 = EMA(ema2, length)
|
ema3 = EMA(ema2, length)
|
||||||
TEMA = 3 * (ema1 - ema2) + ema3
|
TEMA = 3 * (ema1 - ema2) + ema3
|
||||||
**/
|
|
||||||
|
|
||||||
using System;
|
</summary> */
|
||||||
using System.Collections.Generic;
|
|
||||||
public class TEMA_Series : Single_TSeries_Indicator
|
public class TEMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
private readonly List<double> _buffer = new();
|
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||||
private readonly double _k, _k1m;
|
private readonly double _k, _k1m;
|
||||||
private double _lastema1, _lastlastema1;
|
private double _lastema1, _lastlastema1;
|
||||||
private double _lastema2, _lastlastema2;
|
private double _lastema2, _lastlastema2;
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
namespace QuanTAlib;
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
WMA: (linearly) Weighted Moving Average
|
WMA: (linearly) Weighted Moving Average
|
||||||
The weights are linearly decreasing over the period and the most recent data has
|
The weights are linearly decreasing over the period and the most recent data has
|
||||||
the heaviest weight.
|
the heaviest weight.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/weighted-moving-average-wma/
|
https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/weighted-moving-average-wma/
|
||||||
https://www.technicalindicators.net/indicators-technical-analysis/83-moving-averages-simple-exponential-weighted
|
https://www.technicalindicators.net/indicators-technical-analysis/83-moving-averages-simple-exponential-weighted
|
||||||
**/
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class WMA_Series : Single_TSeries_Indicator
|
public class WMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
@@ -1,22 +1,23 @@
|
|||||||
using System;
|
namespace QuanTAlib;
|
||||||
namespace QuanTAlib;
|
using System;
|
||||||
|
|
||||||
/**
|
/* <summary>
|
||||||
ZLEMA: Zero Lag Exponential Moving Average
|
ZLEMA: Zero Lag Exponential Moving Average
|
||||||
|
The Zero lag exponential moving average (ZLEMA) indicator was created by John
|
||||||
The Zero lag exponential moving average (ZLEMA) indicator was created by John
|
Ehlers and Ric Way.
|
||||||
Ehlers and Ric Way.
|
|
||||||
|
|
||||||
The formula for a given N-Day period and for a given Data series is:
|
The formula for a given N-Day period and for a given Data series is:
|
||||||
Lag = (Period-1)/2
|
Lag = (Period-1)/2
|
||||||
Ema Data = {Data+(Data-Data(Lag days ago))
|
Ema Data = {Data+(Data-Data(Lag days ago))
|
||||||
ZLEMA = EMA (EmaData,Period)
|
ZLEMA = EMA (EmaData,Period)
|
||||||
|
|
||||||
The idea is do a regular exponential moving average (EMA) calculation but on a
|
Remark:
|
||||||
de-lagged data instead of doing it on the regular data. Data is de-lagged by
|
The idea is do a regular exponential moving average (EMA) calculation but on a
|
||||||
removing the data from "lag" days ago thus removing (or attempting to remove)
|
de-lagged data instead of doing it on the regular data. Data is de-lagged by
|
||||||
the cumulative lag effect of the moving average.
|
removing the data from "lag" days ago thus removing (or attempting to remove)
|
||||||
**/
|
the cumulative lag effect of the moving average.
|
||||||
|
|
||||||
|
</summary> */
|
||||||
|
|
||||||
public class ZLEMA_Series : Single_TSeries_Indicator
|
public class ZLEMA_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>0.1.10-beta</Version>
|
<Version>0.1.11</Version>
|
||||||
<releaseNotes></releaseNotes>
|
<releaseNotes></releaseNotes>
|
||||||
<Title>QuanTAlib</Title>
|
<Title>QuanTAlib</Title>
|
||||||
<Product>Library of Technical Indicators for .NET</Product>
|
<Product>Library of Technical Indicators for .NET</Product>
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
BIAS: Rate of change between the source and a moving average.
|
using System;
|
||||||
|
|
||||||
Bias is a statistical term which means a systematic deviation from the actual value.
|
/* <summary>
|
||||||
|
BIAS: Rate of change between the source and a moving average.
|
||||||
|
Bias is a statistical term which means a systematic deviation from the actual value.
|
||||||
|
|
||||||
BIAS = (close - SMA) / SMA
|
BIAS = (close - SMA) / SMA
|
||||||
= (close / SMA) - 1
|
= (close / SMA) - 1
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Bias_of_an_estimator
|
https://en.wikipedia.org/wiki/Bias_of_an_estimator
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class BIAS_Series : Single_TSeries_Indicator
|
public class BIAS_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
ENTP: Entropy
|
using System;
|
||||||
|
|
||||||
Introduced by Claude Shannon in 1948, entropy measures the unpredictability
|
/* <summary>
|
||||||
of the data, or equivalently, of its average information.
|
ENTP: Entropy
|
||||||
|
Introduced by Claude Shannon in 1948, entropy measures the unpredictability
|
||||||
|
of the data, or equivalently, of its average information.
|
||||||
|
|
||||||
Calculation:
|
Calculation:
|
||||||
P = close / Σ(close)
|
P = close / Σ(close)
|
||||||
@@ -12,9 +14,8 @@ Sources:
|
|||||||
https://en.wikipedia.org/wiki/Entropy_(information_theory)
|
https://en.wikipedia.org/wiki/Entropy_(information_theory)
|
||||||
https://math.stackexchange.com/questions/3428693/how-to-calculate-entropy-from-a-set-of-correlated-samples
|
https://math.stackexchange.com/questions/3428693/how-to-calculate-entropy-from-a-set-of-correlated-samples
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
namespace QuanTAlib;
|
|
||||||
using System;
|
|
||||||
public class ENTP_Series : Single_TSeries_Indicator
|
public class ENTP_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
public ENTP_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
|
public ENTP_Series(TSeries source, int period, double logbase = 2.0, bool useNaN = false) : base(source, period, useNaN)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
KURT: Kurtosis of population
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
|
KURT: Kurtosis of population
|
||||||
Kurtosis characterizes the relative peakedness or flatness of a distribution
|
Kurtosis characterizes the relative peakedness or flatness of a distribution
|
||||||
compared with the normal distribution. Positive kurtosis indicates a relatively
|
compared with the normal distribution. Positive kurtosis indicates a relatively
|
||||||
peaked distribution. Negative kurtosis indicates a relatively flat distribution.
|
peaked distribution. Negative kurtosis indicates a relatively flat distribution.
|
||||||
@@ -19,12 +21,7 @@ Sources:
|
|||||||
https://en.wikipedia.org/wiki/Kurtosis
|
https://en.wikipedia.org/wiki/Kurtosis
|
||||||
https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
|
https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
// https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
|
|
||||||
|
|
||||||
public class KURT_Series : Single_TSeries_Indicator
|
public class KURT_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
MAD: Mean Absolute Deviation
|
using System;
|
||||||
|
|
||||||
Also known as AAD - Average Absolute Deviation, to differentiate it from Median Absolute Deviation
|
/* <summary>
|
||||||
MAD defines the degree of variation across the series.
|
MAD: Mean Absolute Deviation
|
||||||
|
Also known as AAD - Average Absolute Deviation, to differentiate it from Median Absolute Deviation
|
||||||
|
MAD defines the degree of variation across the series.
|
||||||
|
|
||||||
Calculation:
|
Calculation:
|
||||||
MAD = Σ(|close-SMA|) / period
|
MAD = Σ(|close-SMA|) / period
|
||||||
@@ -10,10 +12,7 @@ Calculation:
|
|||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Average_absolute_deviation
|
https://en.wikipedia.org/wiki/Average_absolute_deviation
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class MAD_Series : Single_TSeries_Indicator
|
public class MAD_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
MAPE: Mean Absolute Percentage Error
|
using System;
|
||||||
|
|
||||||
Measures the size of the error in percentage terms
|
/* <summary>
|
||||||
|
MAPE: Mean Absolute Percentage Error
|
||||||
|
Measures the size of the error in percentage terms
|
||||||
|
|
||||||
Calculation:
|
Calculation:
|
||||||
MAPE = Σ(|close – SMA| / |close|) / n
|
MAPE = Σ(|close – SMA| / |close|) / n
|
||||||
@@ -9,13 +11,11 @@ Calculation:
|
|||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
|
https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
|
||||||
|
|
||||||
Remark: returns infinity if any of observations is 0.
|
Remark:
|
||||||
Use SMAPE or WMAPE instead to avoid division-by-zero in MAPE
|
returns infinity if any of observations is 0.
|
||||||
|
Use SMAPE or WMAPE instead to avoid division-by-zero in MAPE
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class MAPE_Series : Single_TSeries_Indicator
|
public class MAPE_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
/*
|
namespace QuanTAlib;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
/* <summary>
|
||||||
MED - Median value
|
MED - Median value
|
||||||
|
Median of numbers is the middlemost value of the given set of numbers.
|
||||||
|
It separates the higher half and the lower half of a given data sample.
|
||||||
|
At least half of the observations are smaller than or equal to median
|
||||||
|
and at least half of the observations are greater than or equal to the median.
|
||||||
|
|
||||||
Median of numbers is the middlemost value of the given set of numbers.
|
If the number of values is odd, the middlemost observation of the sorted
|
||||||
It separates the higher half and the lower half of a given data sample.
|
list is the median of the given data. If the number of values is even,
|
||||||
At least half of the observations are smaller than or equal to median
|
median is the average of (n/2)th and [(n/2) + 1]th values of the sorted list.
|
||||||
and at least half of the observations are greater than or equal to the median.
|
|
||||||
|
|
||||||
If the number of values is odd, the middlemost observation of the sorted
|
If period = 0 => period is max
|
||||||
list is the median of the given data. If the number of values is even,
|
|
||||||
median is the average of (n/2)th and [(n/2) + 1]th values of the sorted list.
|
|
||||||
|
|
||||||
If period = 0 => period is max
|
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://corporatefinanceinstitute.com/resources/knowledge/other/median/
|
https://corporatefinanceinstitute.com/resources/knowledge/other/median/
|
||||||
https://en.wikipedia.org/wiki/Median
|
https://en.wikipedia.org/wiki/Median
|
||||||
|
|
||||||
*/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class MED_Series : Single_TSeries_Indicator
|
public class MED_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
MSE: Mean Square Error
|
using System;
|
||||||
|
|
||||||
Defined as a Mean (Average) of the Square of the difference between actual and estimated values.
|
/* <summary>
|
||||||
|
MSE: Mean Square Error
|
||||||
|
Defined as a Mean (Average) of the Square of the difference between actual and estimated values.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Mean_squared_error
|
https://en.wikipedia.org/wiki/Mean_squared_error
|
||||||
|
|
||||||
Remark:
|
</summary> */
|
||||||
|
|
||||||
**/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class MSE_Series : Single_TSeries_Indicator
|
public class MSE_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
PSDEV: Population Standard Deviation
|
using System;
|
||||||
|
|
||||||
Population Standard Deviation is the square root of the biased variance, also knons as
|
/* <summary>
|
||||||
Uncorrected Sample Standard Deviation
|
PSDEV: Population Standard Deviation
|
||||||
|
Population Standard Deviation is the square root of the biased variance, also knons as
|
||||||
|
Uncorrected Sample Standard Deviation
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Standard_deviation#Uncorrected_sample_standard_deviation
|
https://en.wikipedia.org/wiki/Standard_deviation#Uncorrected_sample_standard_deviation
|
||||||
@@ -11,10 +13,7 @@ Remark:
|
|||||||
PSDEV (Population Standard Deviation) is also known as a biased/uncorrected Standard Deviation.
|
PSDEV (Population Standard Deviation) is also known as a biased/uncorrected Standard Deviation.
|
||||||
For unbiased version that uses Bessel's correction, use SDEV instead.
|
For unbiased version that uses Bessel's correction, use SDEV instead.
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class PSDEV_Series : Single_TSeries_Indicator
|
public class PSDEV_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
PVAR: Population Variance
|
using System;
|
||||||
|
|
||||||
Population variance....
|
/* <summary>
|
||||||
|
PVAR: Population Variance
|
||||||
|
Population variance without Bessel's correction
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Variance
|
https://en.wikipedia.org/wiki/Variance
|
||||||
@@ -11,10 +13,7 @@ Remark:
|
|||||||
PVAR (Population Variance) is also known as a biased Sample Variance. For unbiased
|
PVAR (Population Variance) is also known as a biased Sample Variance. For unbiased
|
||||||
sample variance use SVAR instead.
|
sample variance use SVAR instead.
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class PVAR_Series : Single_TSeries_Indicator
|
public class PVAR_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
SDEV: (Corrected) Sample Standard Deviation
|
using System;
|
||||||
|
|
||||||
Sample Standard Deviaton uses Bessel's correction to correct the bias in the variance.
|
/* <summary>
|
||||||
|
SDEV: (Corrected) Sample Standard Deviation
|
||||||
|
Sample Standard Deviaton uses Bessel's correction to correct the bias in the variance.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Standard_deviation#Corrected_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
|
Bessel's correction: https://en.wikipedia.org/wiki/Bessel%27s_correction
|
||||||
|
|
||||||
Remark:
|
Remark:
|
||||||
|
|
||||||
SSDEV (Sample Standard Deviation) is also known as a unbiased/corrected Standard Deviation.
|
SSDEV (Sample Standard Deviation) is also known as a unbiased/corrected Standard Deviation.
|
||||||
For a population/biased/uncorrected Standard Deviation, use PSDEV instead
|
For a population/biased/uncorrected Standard Deviation, use PSDEV instead
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class SDEV_Series : Single_TSeries_Indicator
|
public class SDEV_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
SMAPE: Symmetric Mean Absolute Percentage Error
|
using System;
|
||||||
|
|
||||||
Measures the size of the error in percentage terms
|
/* <summary>
|
||||||
|
SMAPE: Symmetric Mean Absolute Percentage Error
|
||||||
|
Measures the size of the error in percentage terms
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error
|
https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class SMAPE_Series : Single_TSeries_Indicator
|
public class SMAPE_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
VAR: Sample Variance
|
using System;
|
||||||
|
|
||||||
Sample variance uses Bessel's correction to correct the bias in the estimation of population variance.
|
/* <summary>
|
||||||
|
VAR: Sample Variance
|
||||||
|
Sample variance uses Bessel's correction to correct the bias in the estimation of population variance.
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/Variance
|
https://en.wikipedia.org/wiki/Variance
|
||||||
@@ -11,10 +13,7 @@ Remark:
|
|||||||
VAR is also known as the Unbiased Sample Variance, while PVAR (Population Variance) is known as
|
VAR is also known as the Unbiased Sample Variance, while PVAR (Population Variance) is known as
|
||||||
the Biased Sample Variance.
|
the Biased Sample Variance.
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class VAR_Series : Single_TSeries_Indicator
|
public class VAR_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
/**
|
namespace QuanTAlib;
|
||||||
WMAPE: Weighted Mean Absolute Percentage Error
|
using System;
|
||||||
|
|
||||||
Measures the size of the error in percentage terms
|
/* <summary>
|
||||||
|
WMAPE: Weighted Mean Absolute Percentage Error
|
||||||
|
Measures the size of the error in percentage terms
|
||||||
|
|
||||||
Sources:
|
Sources:
|
||||||
https://en.wikipedia.org/wiki/WMAPE
|
https://en.wikipedia.org/wiki/WMAPE
|
||||||
|
|
||||||
**/
|
</summary> */
|
||||||
|
|
||||||
using System;
|
|
||||||
namespace QuanTAlib;
|
|
||||||
|
|
||||||
public class WMAPE_Series : Single_TSeries_Indicator
|
public class WMAPE_Series : Single_TSeries_Indicator
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,4 +90,22 @@ public class Skender_Stock
|
|||||||
Assert.Equal(Math.Round((double)SK.Last().Mape!, 8), Math.Round(QL.Last().v, 8));
|
Assert.Equal(Math.Round((double)SK.Last().Mape!, 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ATR()
|
||||||
|
{
|
||||||
|
ATR_Series QL = new(this.bars, this.period, false);
|
||||||
|
var SK = this.quotes.GetAtr(this.period);
|
||||||
|
|
||||||
|
Assert.Equal(Math.Round((double)SK.Last().Atr!, 8), Math.Round(QL.Last().v, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ATRP()
|
||||||
|
{
|
||||||
|
ATRP_Series QL = new(this.bars, this.period, false);
|
||||||
|
var SK = this.quotes.GetAtr(this.period);
|
||||||
|
|
||||||
|
Assert.Equal(Math.Round((double)SK.Last().Atrp!, 8), Math.Round(QL.Last().v, 8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,22 @@ public class TA_LIB
|
|||||||
private readonly Random rnd = new();
|
private readonly Random rnd = new();
|
||||||
private readonly int period;
|
private readonly int period;
|
||||||
private readonly double[] TALIB;
|
private readonly double[] TALIB;
|
||||||
private readonly double[] input;
|
private readonly double[] inopen;
|
||||||
|
private readonly double[] inhigh;
|
||||||
|
private readonly double[] inlow;
|
||||||
|
private readonly double[] inclose;
|
||||||
|
private readonly double[] involume;
|
||||||
|
|
||||||
public TA_LIB()
|
public TA_LIB()
|
||||||
{
|
{
|
||||||
this.bars = new(1000);
|
this.bars = new(1000);
|
||||||
this.period = this.rnd.Next(28) + 3;
|
this.period = this.rnd.Next(28) + 3;
|
||||||
this.TALIB = new double[this.bars.Count];
|
this.TALIB = new double[this.bars.Count];
|
||||||
this.input = this.bars.Close.v.ToArray();
|
this.inopen = this.bars.Open.v.ToArray();
|
||||||
|
this.inhigh = this.bars.High.v.ToArray();
|
||||||
|
this.inlow = this.bars.Low.v.ToArray();
|
||||||
|
this.inclose = this.bars.Close.v.ToArray();
|
||||||
|
this.involume = this.bars.Volume.v.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
@@ -26,7 +34,7 @@ public class TA_LIB
|
|||||||
public void SMA()
|
public void SMA()
|
||||||
{
|
{
|
||||||
SMA_Series QL = new(this.bars.Close, this.period, false);
|
SMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Sma(this.input, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Sma(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));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
@@ -35,7 +43,7 @@ public class TA_LIB
|
|||||||
public void EMA()
|
public void EMA()
|
||||||
{
|
{
|
||||||
EMA_Series QL = new(this.bars.Close, this.period, false);
|
EMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Ema(this.input, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Ema(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));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
@@ -44,7 +52,7 @@ public class TA_LIB
|
|||||||
public void WMA()
|
public void WMA()
|
||||||
{
|
{
|
||||||
WMA_Series QL = new(this.bars.Close, this.period, false);
|
WMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Wma(this.input, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Wma(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));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
@@ -53,7 +61,7 @@ public class TA_LIB
|
|||||||
public void DEMA()
|
public void DEMA()
|
||||||
{
|
{
|
||||||
DEMA_Series QL = new(this.bars.Close, this.period, false);
|
DEMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Dema(this.input, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Dema(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));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
@@ -62,7 +70,7 @@ public class TA_LIB
|
|||||||
public void TEMA()
|
public void TEMA()
|
||||||
{
|
{
|
||||||
TEMA_Series QL = new(this.bars.Close, this.period, false);
|
TEMA_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Tema(this.input, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Tema(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));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
@@ -71,7 +79,7 @@ public class TA_LIB
|
|||||||
public void MAX()
|
public void MAX()
|
||||||
{
|
{
|
||||||
MAX_Series QL = new(this.bars.Close, this.period, false);
|
MAX_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Max(this.input, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Max(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));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
@@ -80,9 +88,17 @@ public class TA_LIB
|
|||||||
public void MIN()
|
public void MIN()
|
||||||
{
|
{
|
||||||
MIN_Series QL = new(this.bars.Close, this.period, false);
|
MIN_Series QL = new(this.bars.Close, this.period, false);
|
||||||
Core.Min(this.input, 0, this.bars.Count - 1, this.TALIB, out int outBegIdx, out _, this.period);
|
Core.Min(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));
|
Assert.Equal(Math.Round(this.TALIB[this.TALIB.Length - outBegIdx - 1], 8), Math.Round(QL.Last().v, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ATR()
|
||||||
|
{
|
||||||
|
ATR_Series QL = new(this.bars, this.period, false);
|
||||||
|
Core.Atr(this.inhigh, this.inlow, 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user