mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-13 08:08:05 +00:00
TR and ATR
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace QuanTAlib;
|
||||
using System;
|
||||
|
||||
/* <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 System.Collections.Generic.List<double> _buffer = new();
|
||||
|
||||
public override void Add((DateTime t, double v) d, bool update)
|
||||
{
|
||||
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
|
||||
else { this._buffer.Add(d.v); }
|
||||
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
|
||||
|
||||
double _max = d.v;
|
||||
for (int i = 0; i < this._buffer.Count; i++)
|
||||
{ _max = (this._buffer[i] > _max) ? this._buffer[i] : _max; }
|
||||
|
||||
var result = (d.t, this.Count < this._p - 1 && this._NaN ? double.NaN : _max);
|
||||
|
||||
base.Add(result, update);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
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 MIN_Series(TSeries source, int period, bool useNaN = false) : base(source, period, useNaN)
|
||||
{
|
||||
if (base._data.Count > 0) { base.Add(base._data); }
|
||||
}
|
||||
private readonly System.Collections.Generic.List<double> _buffer = new();
|
||||
|
||||
public override void Add((System.DateTime t, double v) d, bool update)
|
||||
{
|
||||
if (update) { this._buffer[this._buffer.Count - 1] = d.v; }
|
||||
else { this._buffer.Add(d.v); }
|
||||
if (this._buffer.Count > this._p && this._p != 0) { this._buffer.RemoveAt(0); }
|
||||
|
||||
double _min = d.v;
|
||||
for (int i = 0; i < this._buffer.Count; i++)
|
||||
{ _min = (this._buffer[i] < _min) ? this._buffer[i] : _min; }
|
||||
|
||||
var result = (d.t, (this.Count < this._p - 1 && this._NaN) ? double.NaN : _min);
|
||||
|
||||
base.Add(result, update);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user