mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-28 01:37:43 +00:00
feat: Trix, Aroon
This commit is contained in:
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,4 +1,5 @@
|
||||
# Statistics indicators
|
||||
Done: 13, Todo: 6
|
||||
|
||||
BETA - Beta coefficient
|
||||
CORR - Correlation Coefficient
|
||||
|
||||
@@ -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,4 +1,5 @@
|
||||
# Volume indicators
|
||||
Done: 6, Todo: 12
|
||||
|
||||
✔️ ADL - Chaikin Accumulation Distribution Line
|
||||
✔️ ADOSC - Chaikin Accumulation Distribution Oscillator
|
||||
|
||||
Reference in New Issue
Block a user