mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-28 01:37:43 +00:00
TR and ATR
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
{
|
||||
"data": {
|
||||
"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": {},
|
||||
@@ -24,7 +24,7 @@
|
||||
],
|
||||
"source": [
|
||||
"#r \"nuget: TALib.NETCore, 0.4.4\" \n",
|
||||
"#r \"nuget:QuanTAlib\" \n",
|
||||
"#r \"nuget: QuanTAlib, 0.1.10-beta\" \n",
|
||||
"\n",
|
||||
"using QuanTAlib;\n",
|
||||
"using TALib;\n"
|
||||
@@ -43,13 +43,12 @@
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div class=\"dni-plaintext\">1394</div>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
"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": [
|
||||
|
||||
+2
-1
@@ -42,7 +42,8 @@
|
||||
| AFIRMA - Autoregressive Finite Impulse Response Moving Average |||||
|
||||
| ALMA - Arnaud Legoux Moving Average |||✔️|✔️|
|
||||
| ARIMA - Autoregressive Integrated Moving Average |||||
|
||||
| ATR - Average True Range ||✔️|✔️|✔️|
|
||||
| ATR - Average True Range |✔️|✔️|✔️|✔️|
|
||||
| ATRP - Average True Range Percent |✔️||✔️||
|
||||
| DEMA - Double EMA |✔️|✔️|✔️|✔️|
|
||||
| EMA - Exponential 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;
|
||||
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
|
||||
{
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
namespace QuanTAlib;
|
||||
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
|
||||
{
|
||||
protected readonly int _p;
|
||||
@@ -124,8 +136,9 @@ public abstract class Single_TBars_Indicator : TSeries
|
||||
protected readonly TBars _bars;
|
||||
|
||||
// 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._NaN = useNaN;
|
||||
this._bars.Close.Pub += this.Sub;
|
||||
@@ -1,6 +1,12 @@
|
||||
// DIV - divide TSeries/TSeries , or TSeries/double, or double/TSeries
|
||||
using System;
|
||||
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
|
||||
{
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
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.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 MAX_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -24,7 +22,7 @@ public class MAX_Series : Single_TSeries_Indicator
|
||||
|
||||
double _max = d.v;
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
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
|
||||
{
|
||||
@@ -1,6 +1,10 @@
|
||||
// MUL - multiply TSeries*TSeries together, or TSeries*double, or double*TSeries
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/* <summary>
|
||||
MUL - multiply TSeries*TSeries together, or TSeries*double, or double*TSeries
|
||||
|
||||
</summary> */
|
||||
|
||||
public class MUL_Series : Pair_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
using System;
|
||||
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 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();
|
||||
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 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 - 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;
|
||||
using System;
|
||||
|
||||
/* <summary>
|
||||
SUB - subtracting TSeries-TSeries, or TSeries-double, or double-TSeries
|
||||
|
||||
</summary> */
|
||||
|
||||
|
||||
public class SUB_Series : Pair_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
namespace QuanTAlib;
|
||||
|
||||
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)>
|
||||
{
|
||||
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;
|
||||
|
||||
using System;
|
||||
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)>
|
||||
{
|
||||
// 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;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
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:
|
||||
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/double-exponential-moving-average-dema/
|
||||
@@ -11,13 +12,12 @@ Remark:
|
||||
ema1 = EMA(close, length)
|
||||
ema2 = EMA(ema1, length)
|
||||
DEMA = 2 * ema1 - ema2
|
||||
**/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
</summary> */
|
||||
|
||||
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 double _lastema1, _lastlastema1;
|
||||
private double _lastema2, _lastlastema2;
|
||||
@@ -1,26 +1,27 @@
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
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:
|
||||
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://blog.fugue88.ws/archives/2017-01/The-correct-way-to-start-an-Exponential-Moving-Average-EMA
|
||||
|
||||
Issues:
|
||||
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
|
||||
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.
|
||||
**/
|
||||
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)
|
||||
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
|
||||
{
|
||||
private readonly List<double> _buffer = new();
|
||||
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||
private readonly double _k, _k1m;
|
||||
private double _lastema, _lastlastema;
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
HEMA: Hull-EMA Moving Average
|
||||
Modified HUll Moving Average; instead of using WMA (Weighted MA) for a
|
||||
calculation, HEMA uses EMA for Hull's formula:
|
||||
Modified HUll Moving Average; instead of using WMA (Weighted MA) for acalculation,
|
||||
HEMA uses EMA for Hull's formula:
|
||||
|
||||
EMA1 = EMA(n/2) of price - where k = 4/(n/2 +1)
|
||||
EMA2 = EMA(n) of price - where k = 3/(n+1)
|
||||
Raw HMA = (2 * EMA1) - EMA2
|
||||
EMA3 = EMA(sqrt(n)) of Raw HMA - where k = 2/(sqrt(n)+1)
|
||||
**/
|
||||
|
||||
</summary> */
|
||||
|
||||
public class HEMA_Series : Single_TSeries_Indicator
|
||||
{
|
||||
@@ -1,19 +1,21 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
HMA: Hull Moving Average
|
||||
Developed by Alan Hull, an extremely fast and smooth moving average; almost
|
||||
eliminates lag altogether and manages to improve smoothing at the same time.
|
||||
Developed by Alan Hull, an extremely fast and smooth moving average; almost
|
||||
eliminates lag altogether and manages to improve smoothing at the same time.
|
||||
|
||||
Sources:
|
||||
https://alanhull.com/hull-moving-average
|
||||
https://school.stockcharts.com/doku.php?id=technical_indicators:hull_moving_average
|
||||
|
||||
WMA1 = WMA(n/2) of price
|
||||
WMA2 = WMA(n) of price
|
||||
Raw HMA = (2 * WMA1) - WMA2
|
||||
HMA = WMA(sqrt(n)) of Raw HMA
|
||||
**/
|
||||
|
||||
</summary> */
|
||||
|
||||
public class HMA_Series : TSeries
|
||||
{
|
||||
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
JMA: Jurik Moving Average
|
||||
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
|
||||
to market gaps.
|
||||
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
|
||||
to market gaps.
|
||||
|
||||
Sources:
|
||||
https://c.mql5.com/forextsd/forum/164/jurik_1.pdf
|
||||
@@ -13,10 +13,12 @@ Sources:
|
||||
|
||||
Issues:
|
||||
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
|
||||
exact - published JMA tests against JMA.CSV fail with small deviation. The
|
||||
original algo is slightly different, yet this approximation is close enough.
|
||||
**/
|
||||
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
|
||||
original algo is slightly different, yet this approximation is close enough.
|
||||
|
||||
</summary> */
|
||||
|
||||
public class JMA_Series : Single_TSeries_Indicator
|
||||
{
|
||||
private readonly System.Collections.Generic.List<double> vbuffer10;
|
||||
@@ -1,12 +1,13 @@
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
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
|
||||
set as 1/period, giving less weight to the new data compared to EMA. Sources:
|
||||
Sources:
|
||||
https://archive.org/details/newconceptsintec00wild/page/23/mode/2up
|
||||
|
||||
https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/V-Z/WildersSmoothing
|
||||
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
|
||||
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
|
||||
{
|
||||
private readonly List<double> _buffer = new();
|
||||
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||
private readonly double _k, _k1m;
|
||||
private double _lastema, _lastlastema;
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
SMA: Simple Moving Average
|
||||
The weights are equally distributed across the period, resulting in a mean() of
|
||||
the data within the period/
|
||||
The weights are equally distributed across the period, resulting in a mean() of
|
||||
the data within the period/
|
||||
|
||||
Sources:
|
||||
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/simple-moving-average-sma/
|
||||
https://stats.stackexchange.com/a/24739
|
||||
|
||||
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
|
||||
{
|
||||
@@ -1,8 +1,9 @@
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
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:
|
||||
https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triple-exponential-moving-average-tema/
|
||||
@@ -12,13 +13,12 @@ Remark:
|
||||
ema2 = EMA(ema1, length)
|
||||
ema3 = EMA(ema2, length)
|
||||
TEMA = 3 * (ema1 - ema2) + ema3
|
||||
**/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
</summary> */
|
||||
|
||||
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 double _lastema1, _lastlastema1;
|
||||
private double _lastema2, _lastlastema2;
|
||||
@@ -1,14 +1,16 @@
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/**
|
||||
/* <summary>
|
||||
WMA: (linearly) Weighted Moving Average
|
||||
The weights are linearly decreasing over the period and the most recent data has
|
||||
the heaviest weight.
|
||||
The weights are linearly decreasing over the period and the most recent data has
|
||||
the heaviest weight.
|
||||
|
||||
Sources:
|
||||
https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/weighted-moving-average-wma/
|
||||
https://www.technicalindicators.net/indicators-technical-analysis/83-moving-averages-simple-exponential-weighted
|
||||
**/
|
||||
|
||||
</summary> */
|
||||
|
||||
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
|
||||
|
||||
The Zero lag exponential moving average (ZLEMA) indicator was created by John
|
||||
Ehlers and Ric Way.
|
||||
The Zero lag exponential moving average (ZLEMA) indicator was created by John
|
||||
Ehlers and Ric Way.
|
||||
|
||||
The formula for a given N-Day period and for a given Data series is:
|
||||
Lag = (Period-1)/2
|
||||
Ema Data = {Data+(Data-Data(Lag days ago))
|
||||
ZLEMA = EMA (EmaData,Period)
|
||||
Lag = (Period-1)/2
|
||||
Ema Data = {Data+(Data-Data(Lag days ago))
|
||||
ZLEMA = EMA (EmaData,Period)
|
||||
|
||||
The idea is do a regular exponential moving average (EMA) calculation but on a
|
||||
de-lagged data instead of doing it on the regular data. Data is de-lagged by
|
||||
removing the data from "lag" days ago thus removing (or attempting to remove)
|
||||
the cumulative lag effect of the moving average.
|
||||
**/
|
||||
Remark:
|
||||
The idea is do a regular exponential moving average (EMA) calculation but on a
|
||||
de-lagged data instead of doing it on the regular data. Data is de-lagged by
|
||||
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
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Version>0.1.10-beta</Version>
|
||||
<Version>0.1.11</Version>
|
||||
<releaseNotes></releaseNotes>
|
||||
<Title>QuanTAlib</Title>
|
||||
<Product>Library of Technical Indicators for .NET</Product>
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
/**
|
||||
BIAS: Rate of change between the source and a moving average.
|
||||
namespace QuanTAlib;
|
||||
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
|
||||
|
||||
Sources:
|
||||
https://en.wikipedia.org/wiki/Bias_of_an_estimator
|
||||
https://en.wikipedia.org/wiki/Bias_of_an_estimator
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class BIAS_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/**
|
||||
ENTP: Entropy
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
Introduced by Claude Shannon in 1948, entropy measures the unpredictability
|
||||
of the data, or equivalently, of its average information.
|
||||
/* <summary>
|
||||
ENTP: Entropy
|
||||
Introduced by Claude Shannon in 1948, entropy measures the unpredictability
|
||||
of the data, or equivalently, of its average information.
|
||||
|
||||
Calculation:
|
||||
P = close / Σ(close)
|
||||
@@ -12,9 +14,8 @@ Sources:
|
||||
https://en.wikipedia.org/wiki/Entropy_(information_theory)
|
||||
https://math.stackexchange.com/questions/3428693/how-to-calculate-entropy-from-a-set-of-correlated-samples
|
||||
|
||||
**/
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
</summary> */
|
||||
|
||||
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)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/**
|
||||
KURT: Kurtosis of population
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/* <summary>
|
||||
KURT: Kurtosis of population
|
||||
Kurtosis characterizes the relative peakedness or flatness of a distribution
|
||||
compared with the normal distribution. Positive kurtosis indicates a relatively
|
||||
peaked distribution. Negative kurtosis indicates a relatively flat distribution.
|
||||
@@ -19,12 +21,7 @@ Sources:
|
||||
https://en.wikipedia.org/wiki/Kurtosis
|
||||
https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
|
||||
// https://stats.oarc.ucla.edu/other/mult-pkg/faq/general/faq-whats-with-the-different-formulas-for-kurtosis/
|
||||
</summary> */
|
||||
|
||||
public class KURT_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/**
|
||||
MAD: Mean Absolute Deviation
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
Also known as AAD - Average Absolute Deviation, to differentiate it from Median Absolute Deviation
|
||||
MAD defines the degree of variation across the series.
|
||||
/* <summary>
|
||||
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:
|
||||
MAD = Σ(|close-SMA|) / period
|
||||
@@ -10,10 +12,7 @@ Calculation:
|
||||
Sources:
|
||||
https://en.wikipedia.org/wiki/Average_absolute_deviation
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class MAD_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/**
|
||||
MAPE: Mean Absolute Percentage Error
|
||||
namespace QuanTAlib;
|
||||
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:
|
||||
MAPE = Σ(|close – SMA| / |close|) / n
|
||||
@@ -9,13 +11,11 @@ Calculation:
|
||||
Sources:
|
||||
https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
|
||||
|
||||
Remark: returns infinity if any of observations is 0.
|
||||
Use SMAPE or WMAPE instead to avoid division-by-zero in MAPE
|
||||
Remark:
|
||||
returns infinity if any of observations is 0.
|
||||
Use SMAPE or WMAPE instead to avoid division-by-zero in MAPE
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class MAPE_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
/*
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/* <summary>
|
||||
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.
|
||||
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.
|
||||
If the number of values is odd, the middlemost observation of the sorted
|
||||
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 the number of values is odd, the middlemost observation of the sorted
|
||||
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
|
||||
If period = 0 => period is max
|
||||
|
||||
Sources:
|
||||
https://corporatefinanceinstitute.com/resources/knowledge/other/median/
|
||||
https://en.wikipedia.org/wiki/Median
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class MED_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
/**
|
||||
MSE: Mean Square Error
|
||||
namespace QuanTAlib;
|
||||
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:
|
||||
https://en.wikipedia.org/wiki/Mean_squared_error
|
||||
|
||||
Remark:
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class MSE_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/**
|
||||
PSDEV: Population Standard Deviation
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
Population Standard Deviation is the square root of the biased variance, also knons as
|
||||
Uncorrected Sample Standard Deviation
|
||||
/* <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
|
||||
@@ -11,10 +13,7 @@ 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.
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class PSDEV_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/**
|
||||
PVAR: Population Variance
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
Population variance....
|
||||
/* <summary>
|
||||
PVAR: Population Variance
|
||||
Population variance without Bessel's correction
|
||||
|
||||
Sources:
|
||||
https://en.wikipedia.org/wiki/Variance
|
||||
@@ -11,10 +13,7 @@ Remark:
|
||||
PVAR (Population Variance) is also known as a biased Sample Variance. For unbiased
|
||||
sample variance use SVAR instead.
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class PVAR_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
/**
|
||||
SDEV: (Corrected) Sample Standard Deviation
|
||||
namespace QuanTAlib;
|
||||
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:
|
||||
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 PSDEV instead
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class SDEV_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
SMAPE: Symmetric Mean Absolute Percentage Error
|
||||
namespace QuanTAlib;
|
||||
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:
|
||||
https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class SMAPE_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/**
|
||||
VAR: Sample Variance
|
||||
namespace QuanTAlib;
|
||||
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:
|
||||
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
|
||||
the Biased Sample Variance.
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
public class VAR_Series : Single_TSeries_Indicator
|
||||
{
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
WMAPE: Weighted Mean Absolute Percentage Error
|
||||
namespace QuanTAlib;
|
||||
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:
|
||||
https://en.wikipedia.org/wiki/WMAPE
|
||||
|
||||
**/
|
||||
|
||||
using System;
|
||||
namespace QuanTAlib;
|
||||
</summary> */
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
[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 int period;
|
||||
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()
|
||||
{
|
||||
this.bars = new(1000);
|
||||
this.period = this.rnd.Next(28) + 3;
|
||||
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()
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -35,7 +43,7 @@ public class TA_LIB
|
||||
public void EMA()
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -44,7 +52,7 @@ public class TA_LIB
|
||||
public void WMA()
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -53,7 +61,7 @@ public class TA_LIB
|
||||
public void DEMA()
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -62,7 +70,7 @@ public class TA_LIB
|
||||
public void TEMA()
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -71,7 +79,7 @@ public class TA_LIB
|
||||
public void MAX()
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -80,9 +88,17 @@ public class TA_LIB
|
||||
public void MIN()
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
[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