feat: Trix, Aroon

This commit is contained in:
Miha
2024-10-30 10:42:50 -07:00
parent 38793acc57
commit 06c6875970
11 changed files with 400 additions and 3 deletions
+15
View File
@@ -199,6 +199,21 @@ public class MomentumUpdateTests
Assert.Equal(initialValue, finalValue, precision);
}
[Fact]
public void Trix_Update()
{
var indicator = new Trix(period: 18);
double initialValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: true));
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TValue(DateTime.Now, GetRandomDouble() + 100, IsNew: false)); // Ensure positive prices
}
double finalValue = indicator.Calc(new TValue(DateTime.Now, ReferenceValue, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
}
[Fact]
public void Vel_Update()
{
+16
View File
@@ -93,4 +93,20 @@ public class OscillatorsUpdateTests
Assert.Equal(initialValue, finalValue, precision);
}
[Fact]
public void Aroon_Update()
{
var indicator = new Aroon(period: 25);
TBar r = new(DateTime.Now, ReferenceValue, ReferenceValue, ReferenceValue, ReferenceValue, 1000, IsNew: true);
double initialValue = indicator.Calc(r);
for (int i = 0; i < RandomUpdates; i++)
{
indicator.Calc(new TBar(DateTime.Now, GetRandomDouble(), GetRandomDouble(), GetRandomDouble(), GetRandomDouble(), 1000, IsNew: false));
}
double finalValue = indicator.Calc(new TBar(r.Time, r.Open, r.High, r.Low, r.Close, r.Volume, IsNew: false));
Assert.Equal(initialValue, finalValue, precision);
}
}
+142
View File
@@ -0,0 +1,142 @@
# Stock Indicators List
## Common Indicators (Both Libraries)
| Indicator Name | Skender Method | QuanTAlib Class |
|---------------|----------------|-----------------|
| ADL - Accumulation/Distribution Line | GetAdl | Adl |
| ADOSC - Accumulation/Distribution Oscillator | GetAdo | Adosc |
| ALMA - Arnaud Legoux Moving Average | GetAlma | Alma |
| AROON - Aroon Oscillator | GetAroon | Aroon |
| ADX - Average Directional Index | GetAdx | Adx |
| ATR - Average True Range | GetAtr | Atr |
| AO - Awesome Oscillator | GetAwesome | Ao |
| CMF - Chaikin Money Flow | GetCmf | Cmf |
| CMO - Chande Momentum Oscillator | GetCmo | Cmo |
| DEMA - Double Exponential Moving Average | GetDema | Dema |
| EOM - Ease of Movement | GetEom | Eom |
| EPMA - Endpoint Moving Average | GetEpma | Epma |
| EMA - Exponential Moving Average | GetEma | Ema |
| HTIT - Hilbert Transform Instantaneous Trendline | GetHtTrendline | Htit |
| HMA - Hull Moving Average | GetHma | Hma |
| KVO - Klinger Volume Oscillator | GetKvo | Kvo |
| OBV - On-Balance Volume | GetObv | Aobv |
| PMO - Price Momentum Oscillator | GetPmo | Pmo |
| PRS - Price Relative Strength | GetPrs | Prs |
| ROC - Rate of Change | GetRoc | Roc |
| RSI - Relative Strength Index | GetRsi | Rsi |
| SMA - Simple Moving Average | GetSma | Sma |
| SMMA - Smoothed Moving Average | GetSmma | Smma |
| SLOPE - Slope and Linear Regression | GetSlope | Slope |
| STDEV - Standard Deviation | GetStdDev | Stddev |
| TRIX - Triple EMA Oscillator | GetTrix | Trix |
| TEMA - Triple Exponential Moving Average | GetTema | Tema |
| WMA - Weighted Moving Average | GetWma | Wma |
## Skender-Only Indicators
| Indicator Name | Skender Method |
|---------------|----------------|
| ATRS - ATR Trailing Stop | GetAtrStop |
| BOP - Balance of Power | GetBop |
| BETA - Beta Coefficient | GetBeta |
| BB - Bollinger Bands | GetBollingerBands |
| CE - Chandelier Exit | GetChandelier |
| CHOP - Choppiness Index | GetChop |
| CCI - Commodity Channel Index | GetCci |
| CRSI - Connors RSI | GetConnorsRsi |
| CORR - Correlation Coefficient | GetCorrelation |
| DPO - Detrended Price Oscillator | GetDpo |
| DOJI - Doji Pattern | GetDoji |
| DC - Donchian Channel | GetDonchian |
| ER - Elder-Ray | GetElderRay |
| FISH - Fisher Transform | GetFisherTransform |
| FI - Force Index | GetForceIndex |
| FCB - Fractal Chaos Bands | GetFcb |
| GATOR - Gator Oscillator | GetGator |
| HA - Heikin-Ashi | GetHeikinAshi |
| HURST - Hurst Exponent | GetHurst |
| ICH - Ichimoku Cloud | GetIchimoku |
| KC - Keltner Channels | GetKeltner |
| MARU - Marubozu Pattern | GetMarubozu |
| MFI - Money Flow Index | GetMfi |
| MAE - Moving Average Envelopes | GetMaEnvelopes |
| PSAR - Parabolic SAR | GetParabolicSar |
| PP - Pivot Points | GetPivotPoints |
| PIV - Pivots | GetPivots |
| PVO - Price Volume Oscillator | GetPvo |
| RENKO-ATR - Renko Chart ATR | GetRenkoAtr |
| RENKO - Renko Chart Standard | GetRenko |
| RPP - Rolling Pivot Points | GetRollingPivots |
| STC - Schaff Trend Cycle | GetStc |
| SDC - Standard Deviation Channels | GetStdDevChannels |
| STARC - Starc Bands | GetStarcBands |
| SMI - Stochastic Momentum Index | GetSmi |
| STOCH - Stochastic Oscillator | GetStoch |
| STOCH-RSI - Stochastic RSI | GetStochRsi |
| ST - Supertrend | GetSuperTrend |
| TR - True Range | GetTr |
| TSI - True Strength Index | GetTsi |
| UI - Ulcer Index | GetUlcerIndex |
| UO - Ultimate Oscillator | GetUltimate |
| VSS - Volatility System/Stop | GetVolatilityStop |
| VWAP - Volume Weighted Average Price | GetVwap |
| VWMA - Volume Weighted Moving Average | GetVwma |
| VTX - Vortex Indicator | GetVortex |
| WAG - Williams Alligator | GetAlligator |
| WF - Williams Fractal | GetFractal |
| ZZ - Zig Zag | GetZigZag |
## QuanTAlib-Only Indicators
| Indicator Name | QuanTAlib Class |
|---------------|-----------------|
| AC - Acceleration Oscillator | Ac |
| AFIRMA - Adaptive Firman Moving Average | Afirma |
| APO - Absolute Price Oscillator | Apo |
| ADXR - ADX Rating | Adxr |
| CONV - Convolution Moving Average | Convolution |
| CURV - Curvature | Curvature |
| DMI - Directional Movement Index | Dmi |
| DMX - Directional Movement Extended | Dmx |
| DSMA - Double Smoothed Moving Average | Dsma |
| DWMA - Dynamic Weighted Moving Average | Dwma |
| ENT - Entropy | Entropy |
| FRAMA - Fractal Adaptive Moving Average | Frama |
| FWMA - Fibonacci Weighted Moving Average | Fwma |
| GMA - Gaussian Moving Average | Gma |
| HV - Historical Volatility | Hv |
| HWMA - Hybrid Weighted Moving Average | Hwma |
| JMA - Jurik Moving Average | Jma |
| JVOL - Jurik Volatility | Jvolty |
| KURT - Kurtosis | Kurtosis |
| KAMA - Kaufman Adaptive Moving Average | Kama |
| LTMA - Laguerre Time Moving Average | Ltma |
| MAX - Maximum Value | Max |
| MAAF - Median Adaptive Antifractal | Maaf |
| MAMA - Mesa Adaptive Moving Average | Mama |
| MGDI - McGinley Dynamic Indicator | Mgdi |
| MEDIAN - Median Value | Median |
| MIN - Minimum Value | Min |
| MMA - Modified Moving Average | Mma |
| MODE - Mode Value | Mode |
| MOM - Momentum | Mom |
| PCTL - Percentile | Percentile |
| PO - Price Oscillator | Po |
| PPO - Price Percentage Oscillator | Ppo |
| PWMA - Polynomial Weighted Moving Average | Pwma |
| QEMA - Quadratic Exponential Moving Average | Qema |
| REMA - Range-Normalized Exponential Moving Average | Rema |
| RSX - Relative Strength Extended | Rsx |
| RV - Realized Volatility | Rv |
| RVI - Relative Volatility Index | Rvi |
| RMA - Rolling Moving Average | Rma |
| SINEMA - Sine-Wave Exponential Moving Average | Sinema |
| SKEW - Skewness | Skew |
| T3 - Tillson T3 Moving Average | T3 |
| TRIMA - Triangular Moving Average | Trima |
| VAR - Variance | Variance |
| VIDYA - Variable Index Dynamic Average | Vidya |
| VEL - Velocity | Vel |
| ZLEMA - Zero-Lag Exponential Moving Average | Zlema |
| ZSCORE - Z-Score | Zscore |
+87
View File
@@ -0,0 +1,87 @@
using System.Runtime.CompilerServices;
namespace QuanTAlib;
/// <summary>
/// TRIX: Triple Exponential Average Rate of Change
/// A momentum oscillator that shows the percentage rate of change of a triple exponentially
/// smoothed moving average. TRIX filters out insignificant price movements and helps identify
/// overbought/oversold conditions and divergences.
/// </summary>
/// <remarks>
/// The TRIX calculation process:
/// 1. Calculate Triple Exponential Moving Average (TEMA)
/// 2. Calculate 1-day Rate of Change (ROC) of the TEMA
///
/// Key characteristics:
/// - Combines trend-following and momentum in one indicator
/// - Filters out price movements deemed insignificant
/// - Oscillates around zero line
/// - Useful for identifying divergences
/// - Helps spot overbought/oversold conditions
///
/// Formula:
/// TEMA = 3*EMA1 - 3*EMA2 + EMA3
/// TRIX = ROC(TEMA, 1) = ((TEMA - TEMA_prev) / TEMA_prev) * 100
///
/// Sources:
/// Jack Hutson - "Technical Analysis of Stocks and Commodities" magazine, 1983
/// John J. Murphy - "Technical Analysis of the Financial Markets"
/// </remarks>
[SkipLocalsInit]
public sealed class Trix : AbstractBase
{
private readonly Tema _tema;
private readonly CircularBuffer _temaBuffer;
private const double ScalingFactor = 100.0;
private const int DefaultPeriod = 18;
/// <param name="period">The lookback period for TEMA calculation (default 18).</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Trix(int period = DefaultPeriod)
{
if (period < 1)
throw new ArgumentOutOfRangeException(nameof(period));
_tema = new(period);
_temaBuffer = new(2); // We only need current and previous TEMA values
WarmupPeriod = period + 1; // TEMA period + 1 for ROC
Name = $"TRIX({period})";
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The lookback period for TEMA calculation.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Trix(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void ManageState(bool isNew)
{
if (isNew)
{
double temaValue = _tema.Calc(Input);
_temaBuffer.Add(temaValue);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected override double Calculation()
{
ManageState(Input.IsNew);
if (_temaBuffer.Count < _temaBuffer.Capacity)
return 0.0;
double oldTema = _temaBuffer[0];
if (oldTema <= double.Epsilon)
return 0.0;
double currentTema = _temaBuffer[^1];
return ((currentTema - oldTema) / oldTema) * ScalingFactor;
}
}
+3 -1
View File
@@ -1,4 +1,5 @@
# Momentum indicators
Done: 12, Todo: 5
✔️ ADX - Average Directional Movement Index
✔️ ADXR - Average Directional Movement Index Rating
@@ -13,6 +14,7 @@ MACD - Moving Average Convergence/Divergence
✔️ PPO - Percentage Price Oscillator
✔️ PRS - Price Relative Strength
✔️ ROC - Rate of Change
TRIX - 1-day ROC of TEMA
TSI - True Strength Index
✔️ TRIX - 1-day ROC of TEMA
✔️ VEL - Jurik Signal Velocity
VORTEX - Vortex Indicator
+120
View File
@@ -0,0 +1,120 @@
using System.Runtime.CompilerServices;
namespace QuanTAlib;
/// <summary>
/// AROON: Aroon Oscillator
/// A trend-following indicator that measures the strength of a trend and the likelihood
/// that the trend will continue. It consists of two lines (Aroon Up and Aroon Down) and
/// their difference forms the Aroon Oscillator.
/// </summary>
/// <remarks>
/// The Aroon calculation process:
/// 1. Tracks the number of periods since the last highest high (Aroon Up)
/// 2. Tracks the number of periods since the last lowest low (Aroon Down)
/// 3. Normalizes both values to a 0-100 scale
/// 4. Calculates the difference (Aroon Oscillator)
///
/// Key characteristics:
/// - Oscillates between -100 and +100
/// - Positive values indicate uptrend
/// - Negative values indicate downtrend
/// - Zero line crossovers signal trend changes
/// - Extreme readings suggest strong trends
///
/// Formula:
/// Aroon Up = ((period - days since highest high) / period) × 100
/// Aroon Down = ((period - days since lowest low) / period) × 100
/// Aroon Oscillator = Aroon Up - Aroon Down
///
/// Sources:
/// Tushar Chande - "The New Technical Trader" (1994)
/// https://www.investopedia.com/terms/a/aroonoscillator.asp
///
/// Note: Default period of 25 was recommended by Chande
/// </remarks>
[SkipLocalsInit]
public sealed class Aroon : AbstractBarBase
{
private readonly CircularBuffer _highPrices;
private readonly CircularBuffer _lowPrices;
private const double ScalingFactor = 100.0;
private const int DefaultPeriod = 25;
/// <param name="period">The number of periods used in the Aroon calculation (default 25).</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Aroon(int period = DefaultPeriod)
{
if (period < 1)
throw new ArgumentOutOfRangeException(nameof(period));
_highPrices = new(period);
_lowPrices = new(period);
_index = 0;
WarmupPeriod = period;
Name = $"AROON({period})";
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of periods used in the Aroon calculation.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Aroon(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new BarSignal(Sub));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void ManageState(bool isNew)
{
if (isNew)
{
_index++;
_highPrices.Add(Input.High);
_lowPrices.Add(Input.Low);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private static double CalculateAroonLine(int period, int daysSince)
{
return ((period - daysSince) * ScalingFactor) / period;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected override double Calculation()
{
ManageState(Input.IsNew);
if (_index < WarmupPeriod)
return double.NaN;
// Find highest high and lowest low positions
int highestIndex = 0;
int lowestIndex = 0;
double highestHigh = _highPrices[0];
double lowestLow = _lowPrices[0];
for (int i = 1; i < _highPrices.Count; i++)
{
if (_highPrices[i] > highestHigh)
{
highestHigh = _highPrices[i];
highestIndex = i;
}
if (_lowPrices[i] < lowestLow)
{
lowestLow = _lowPrices[i];
lowestIndex = i;
}
}
// Calculate Aroon Up and Down
double aroonUp = CalculateAroonLine(_highPrices.Count, highestIndex);
double aroonDown = CalculateAroonLine(_lowPrices.Count, lowestIndex);
// Return Aroon Oscillator
return aroonUp - aroonDown;
}
}
+2 -1
View File
@@ -1,8 +1,9 @@
# Oscillators indicators
Done: 6, Todo: 23
✔️ AC - Acceleration Oscillator
✔️ AO - Awesome Oscillator
AROON - Aroon oscillator
✔️ AROON - Aroon oscillator
BOP - Balance of Power
CCI - Commodity Channel Index
CFO - Chande Forcast Oscillator
+11
View File
@@ -0,0 +1,11 @@
# Pattern indicators
Done: 0, Todo: 8
DOJI - Doji Candlestick Pattern
ER - Elder Ray Pattern
MARU - Marubozu Candlestick Pattern
PIV - Pivot Points
PP - Price Pivots
RPP - Rolling Pivot Points
WF - Williams Fractal
ZZ - Zig Zag Pattern
+1
View File
@@ -1,4 +1,5 @@
# Statistics indicators
Done: 13, Todo: 6
BETA - Beta coefficient
CORR - Correlation Coefficient
+2 -1
View File
@@ -1,4 +1,5 @@
# Volatility indicators
Done: 6, Todo: 25
ADR - Average Daily Range
AP - Andrew's Pitchfork
@@ -33,4 +34,4 @@ VC - Volatility Cone
VOV - Volatility of Volatility
VR - Volatility Ratio
VS - Volatility Stop
YZV - Yang-Zhang Volatility
YZV - Yang-Zhang Volatility
+1
View File
@@ -1,4 +1,5 @@
# Volume indicators
Done: 6, Todo: 12
✔️ ADL - Chaikin Accumulation Distribution Line
✔️ ADOSC - Chaikin Accumulation Distribution Oscillator