diff --git a/Tests/test_eventing.cs b/Tests/test_eventing.cs index 69cde8a..2fcd551 100644 --- a/Tests/test_eventing.cs +++ b/Tests/test_eventing.cs @@ -68,6 +68,9 @@ private static readonly (string Name, object[] DirectParams, object[] EventParam ("Zscore", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }), ("Beta", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }), ("Corr", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }), + ("Covar", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }), + ("Kendall", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }), + ("Spearman", new object[] { DefaultPeriod }, new object[] { new TSeries(), DefaultPeriod }), ("Hv", new object[] { DefaultPeriod, false }, new object[] { new TSeries(), DefaultPeriod, false }), ("Jvolty", new object[] { DefaultPeriod, 0 }, new object[] { new TSeries(), DefaultPeriod, 0 }), ("Rv", new object[] { DefaultPeriod, false }, new object[] { new TSeries(), DefaultPeriod, false }), diff --git a/Tests/test_updates_statistics.cs b/Tests/test_updates_statistics.cs index c28bc28..d33f57f 100644 --- a/Tests/test_updates_statistics.cs +++ b/Tests/test_updates_statistics.cs @@ -18,6 +18,13 @@ public void Corr_Update() TestDualTValueUpdate(indicator, indicator.Calc); } + [Fact] + public void Covar_Update() + { + var indicator = new Covar(period: 14); + TestDualTValueUpdate(indicator, indicator.Calc); + } + [Fact] public void Curvature_Update() { @@ -39,6 +46,13 @@ public void Hurst_Update() TestTBarUpdate(indicator, indicator.Calc); } + [Fact] + public void Kendall_Update() + { + var indicator = new Kendall(period: 14); + TestDualTValueUpdate(indicator, indicator.Calc); + } + [Fact] public void Kurtosis_Update() { @@ -95,6 +109,13 @@ public void Slope_Update() TestTValueUpdate(indicator, indicator.Calc); } + [Fact] + public void Spearman_Update() + { + var indicator = new Spearman(period: 14); + TestDualTValueUpdate(indicator, indicator.Calc); + } + [Fact] public void Stddev_Update() { diff --git a/lib/_list.md b/lib/_list.md new file mode 100644 index 0000000..bd54fd2 --- /dev/null +++ b/lib/_list.md @@ -0,0 +1,173 @@ +# QuanTAlib Indicators Status + +## Implementation Status + +| Category | Done | Todo | Total | +|------------|------|------|-------| +| Averages | 33 | 0 | 33 | +| Momentum | 17 | 0 | 17 | +| Oscillators| 24 | 5 | 29 | +| Patterns | 0 | 8 | 8 | +| Statistics | 21 | 2 | 23 | +| Volatility | 31 | 4 | 35 | +| Total | 126 | 19 | 145 | + +## Indicators by Category + +### Averages (33/33) +✔️ AFIRMA - Adaptive FIR Moving Average +✔️ ALMA - Arnaud Legoux Moving Average +✔️ CONVOLUTION - 1D Convolution with sliding kernel +✔️ DEMA - Double Exponential Moving Average +✔️ DSMA - Dynamic Simple Moving Average +✔️ DWMA - Dynamic Weighted Moving Average +✔️ EMA - Exponential Moving Average +✔️ EPMA - Endpoint Moving Average +✔️ FRAMA - Fractal Adaptive Moving Average +✔️ FWMA - Forward Weighted Moving Average +✔️ GMA - Gaussian Moving Average +✔️ HMA - Hull Moving Average +✔️ HTIT - Hilbert Transform Instantaneous Trendline +✔️ HWMA - Hann Weighted Moving Average +✔️ JMA - Jurik Moving Average +✔️ KAMA - Kaufman Adaptive Moving Average +✔️ LTMA - Linear Time Moving Average +✔️ MAAF - Moving Average Adaptive Filter +✔️ MAMA - MESA Adaptive Moving Average (MAMA, FAMA) +✔️ MGDI - McGinley Dynamic Indicator +✔️ MMA - Modified Moving Average +✔️ PWMA - Parabolic Weighted Moving Average +✔️ QEMA - Quick Exponential Moving Average +✔️ REMA - Regularized Exponential Moving Average +✔️ RMA - Running Moving Average +✔️ SINEMA - Sine-weighted Moving Average +✔️ SMA - Simple Moving Average +✔️ SMMA - Smoothed Moving Average +✔️ T3 - Triple Exponential Moving Average (T3) +✔️ TEMA - Triple Exponential Moving Average +✔️ TRIMA - Triangular Moving Average +✔️ VIDYA - Variable Index Dynamic Average +✔️ WMA - Weighted Moving Average +✔️ ZLEMA - Zero-Lag Exponential Moving Average + +### Momentum (17/17) +✔️ ADX - Average Directional Movement Index +✔️ ADXR - Average Directional Movement Index Rating +✔️ APO - Absolute Price Oscillator +✔️ DMI - Directional Movement Index (DI+, DI-) +✔️ DMX - Jurik Directional Movement Index +✔️ DPO - Detrended Price Oscillator +✔️ MACD - Moving Average Convergence/Divergence (MACD, Signal, Histogram) +✔️ MOM - Momentum +✔️ PMO - Price Momentum Oscillator +✔️ PO - Price Oscillator +✔️ PPO - Percentage Price Oscillator +✔️ PRS - Price Relative Strength +✔️ ROC - Rate of Change +✔️ TSI - True Strength Index +✔️ TRIX - 1-day ROC of TEMA +✔️ VEL - Jurik Signal Velocity +✔️ VORTEX - Vortex Indicator (VI+, VI-) + +### Oscillators (24/29) +✔️ AC - Acceleration Oscillator +✔️ AO - Awesome Oscillator +✔️ AROON - Aroon oscillator (Up, Down) +✔️ BOP - Balance of Power +✔️ CCI - Commodity Channel Index +✔️ CFO - Chande Forcast Oscillator +✔️ CHOP - Choppiness Index +✔️ CMO - Chande Momentum Oscillator +✔️ COG - Ehler's Center of Gravity +✔️ COPPOCK - Coppock Curve +✔️ CRSI - Connor RSI +✔️ CTI - Ehler's Correlation Trend Indicator +✔️ DOSC - Derivative Oscillator +✔️ FISHER - Fisher Transform +✔️ EFI - Elder Ray's Force Index +✔️ RSI - Relative Strength Index +✔️ RSX - Jurik Trend Strength Index +✔️ SMI - Stochastic Momentum Index +✔️ SRSI - Stochastic RSI (SRSI, Signal) +✔️ STC - Schaff Trend Cycle +✔️ STOCH - Stochastic Oscillator (%K, %D) +✔️ TSI - True Strength Index +✔️ UO - Ultimate Oscillator +✔️ WILLR - Larry Williams' %R +FOSC - Forecast Oscillator +GATOR - Williams Alliator Oscillator (Upper Jaw, Lower Jaw, Teeth) +KDJ - KDJ Indicator (K, D, J lines) +KRI - Kairi Relative Index +RVGI - Relative Vigor Index (RVGI, Signal) + +### Patterns (0/8) +DOJI - Doji Candlestick Pattern +ER - Elder Ray Pattern (Bull Power, Bear Power) +MARU - Marubozu Candlestick Pattern +PIV - Pivot Points (Support 1-3, Pivot, Resistance 1-3) +PP - Price Pivots (Support 1-3, Pivot, Resistance 1-3) +RPP - Rolling Pivot Points (Support 1-3, Pivot, Resistance 1-3) +WF - Williams Fractal +ZZ - Zig Zag Pattern + +### Statistics (21/23) +✔️ BETA - Beta coefficient measuring volatility relative to market +✔️ CORR - Correlation coefficient between two series +✔️ COVAR - Covariance between two series +✔️ CURVATURE - Curvature of a time series +✔️ ENTROPY - Information entropy of a series +✔️ HURST - Hurst exponent for trend strength +✔️ KENDALL - Kendall rank correlation +✔️ KURTOSIS - Kurtosis measuring tail extremity +✔️ MAX - Maximum value over period +✔️ MEDIAN - Median value over period +✔️ MIN - Minimum value over period +✔️ MODE - Mode (most frequent value) +✔️ PERCENTILE - Percentile rank calculation +✔️ SKEW - Skewness measuring distribution asymmetry +✔️ SLOPE - Linear regression slope +✔️ SPEARMAN - Spearman rank correlation +✔️ STDDEV - Standard deviation +✔️ THEIL - Theil's U statistics for forecast accuracy +✔️ TSF - Time series forecast +✔️ VARIANCE - Statistical variance +✔️ ZSCORE - Z-score standardization +COINTEGRATION - Test for cointegrated series +GRANGER - Granger causality test + +### Volatility (31/35) +✔️ ADR - Average Daily Range +✔️ AP - Andrew's Pitchfork +✔️ ATR - Average True Range +✔️ ATRP - Average True Range Percent +✔️ ATRS - ATR Trailing Stop +✔️ BBAND - Bollinger Bands® (Upper, Middle, Lower) +✔️ CCV - Close-to-Close Volatility +✔️ CE - Chandelier Exit +✔️ CV - Conditional Volatility (ARCH/GARCH) +✔️ CVI - Chaikin's Volatility +✔️ DCHN - Donchian Channels (Upper, Middle, Lower) +✔️ EWMA - Exponential Weighted Moving Average Volatility +✔️ FCB - Fractal Chaos Bands +✔️ GKV - Garman-Klass Volatility +✔️ HLV - High-Low Volatility +✔️ HV - Historical Volatility +✔️ JVOLTY - Jurik Volatility (Jvolty, Upper band, Lower band) +✔️ NATR - Normalized Average True Range +✔️ PCH - Price Channel Indicator +✔️ PV - Parkinson Volatility +✔️ RSV - Rogers-Satchell Volatility +✔️ RV - Realized Volatility +✔️ RVI - Relative Volatility Index +✔️ SV - Stochastic Volatility +✔️ TR - True Range +✔️ UI - Ulcer Index +✔️ VC - Volatility Cone (Mean, Upper Bound, Lower Bound) +✔️ VOV - Volatility of Volatility +✔️ VR - Volatility Ratio +✔️ VS - Volatility Stop (Long Stop, Short Stop) +✔️ YZV - Yang-Zhang Volatility +ICH - Ichimoku Cloud (Conversion, Base, Leading Span A, Leading Span B, Lagging Span) +KC - Keltner Channels (Upper, Middle, Lower) +PSAR - Parabolic Stop and Reverse (Value, Trend) +STARC - Starc Bands (Upper, Middle, Lower) diff --git a/lib/_todolist.md b/lib/_todolist.md deleted file mode 100644 index 035ce46..0000000 --- a/lib/_todolist.md +++ /dev/null @@ -1,142 +0,0 @@ -# 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 | diff --git a/lib/momentum/_list.md b/lib/momentum/_list.md index ccfdf58..a73f18e 100644 --- a/lib/momentum/_list.md +++ b/lib/momentum/_list.md @@ -6,7 +6,7 @@ ✔️ DMI - Directional Movement Index (DI+, DI-) ✔️ DMX - Jurik Directional Movement Index ✔️ DPO - Detrended Price Oscillator -✔️ *MACD - Moving Average Convergence/Divergence (MACD, Signal, Histogram) +✔️ MACD - Moving Average Convergence/Divergence (MACD, Signal, Histogram) ✔️ MOM - Momentum ✔️ PMO - Price Momentum Oscillator ✔️ PO - Price Oscillator @@ -16,4 +16,4 @@ ✔️ TSI - True Strength Index ✔️ TRIX - 1-day ROC of TEMA ✔️ VEL - Jurik Signal Velocity -✔️ *VORTEX - Vortex Indicator (VI+, VI-) +✔️ VORTEX - Vortex Indicator (VI+, VI-) diff --git a/lib/oscillators/_list.md b/lib/oscillators/_list.md index dc310c4..e042314 100644 --- a/lib/oscillators/_list.md +++ b/lib/oscillators/_list.md @@ -16,13 +16,8 @@ Done: 24, Todo: 5 ✔️ DOSC - Derivative Oscillator ✔️ FISHER - Fisher Transform ✔️ EFI - Elder Ray's Force Index -FOSC - Forecast Oscillator -*GATOR - Williams Alliator Oscillator (Upper Jaw, Lower Jaw, Teeth) -*KDJ - KDJ Indicator (K, D, J lines) -KRI - Kairi Relative Index ✔️ RSI - Relative Strength Index ✔️ RSX - Jurik Trend Strength Index -*RVGI - Relative Vigor Index (RVGI, Signal) ✔️ SMI - Stochastic Momentum Index ✔️ SRSI - Stochastic RSI (SRSI, Signal) ✔️ STC - Schaff Trend Cycle @@ -30,3 +25,8 @@ KRI - Kairi Relative Index ✔️ TSI - True Strength Index ✔️ UO - Ultimate Oscillator ✔️ WILLR - Larry Williams' %R +FOSC - Forecast Oscillator +GATOR - Williams Alliator Oscillator (Upper Jaw, Lower Jaw, Teeth) +KDJ - KDJ Indicator (K, D, J lines) +KRI - Kairi Relative Index +RVGI - Relative Vigor Index (RVGI, Signal) diff --git a/lib/patterns/_list.md b/lib/patterns/_list.md index 99a7836..3da4ea8 100644 --- a/lib/patterns/_list.md +++ b/lib/patterns/_list.md @@ -2,10 +2,10 @@ Done: 0, Todo: 8 DOJI - Doji Candlestick Pattern -*ER - Elder Ray Pattern (Bull Power, Bear Power) +ER - Elder Ray Pattern (Bull Power, Bear Power) MARU - Marubozu Candlestick Pattern -*PIV - Pivot Points (Support 1-3, Pivot, Resistance 1-3) -*PP - Price Pivots (Support 1-3, Pivot, Resistance 1-3) -*RPP - Rolling Pivot Points (Support 1-3, Pivot, Resistance 1-3) +PIV - Pivot Points (Support 1-3, Pivot, Resistance 1-3) +PP - Price Pivots (Support 1-3, Pivot, Resistance 1-3) +RPP - Rolling Pivot Points (Support 1-3, Pivot, Resistance 1-3) WF - Williams Fractal ZZ - Zig Zag Pattern diff --git a/lib/statistics/Covar.cs b/lib/statistics/Covar.cs new file mode 100644 index 0000000..1622d2c --- /dev/null +++ b/lib/statistics/Covar.cs @@ -0,0 +1,142 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// COVAR: Covariance +/// A statistical measure that quantifies how two variables change together. Unlike correlation, +/// covariance is not normalized and therefore is scale-dependent. A positive covariance indicates +/// that variables tend to move in the same direction, while a negative covariance indicates +/// opposite movement. +/// +/// +/// The Covariance calculation process: +/// 1. Calculates mean of both variables +/// 2. For each pair of points, multiply their deviations from their respective means +/// 3. Sum these products and divide by the number of observations +/// +/// Key characteristics: +/// - Measures linear relationship +/// - Scale-dependent measure +/// - Sign indicates direction of relationship +/// - Magnitude depends on scale of variables +/// - Basis for correlation coefficient +/// +/// Formula: +/// Cov(X,Y) = Σ((x - μx)(y - μy)) / n +/// where: +/// X, Y = variables +/// μx, μy = means of X and Y +/// n = number of observations +/// +/// Market Applications: +/// - Portfolio risk analysis +/// - Pairs trading strategy development +/// - Asset relationship analysis +/// - Risk factor sensitivity analysis +/// - Multi-asset portfolio optimization +/// +/// Sources: +/// https://en.wikipedia.org/wiki/Covariance +/// "Modern Portfolio Theory" - Harry Markowitz +/// +/// Note: Scale-dependent nature means values should be interpreted in context of the data scales +/// +[SkipLocalsInit] +public sealed class Covar : AbstractBase +{ + private readonly int Period; + private readonly CircularBuffer _xValues; + private readonly CircularBuffer _yValues; + private const int MinimumPoints = 2; + + /// The number of points to consider for covariance calculation. + /// Thrown when period is less than 2. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Covar(int period) + { + if (period < MinimumPoints) + { + throw new ArgumentOutOfRangeException(nameof(period), + "Period must be greater than or equal to 2 for covariance calculation."); + } + Period = period; + WarmupPeriod = MinimumPoints; + _xValues = new CircularBuffer(period); + _yValues = new CircularBuffer(period); + Name = $"Covar(period={period})"; + Init(); + } + + /// The data source object that publishes updates. + /// The number of points to consider for covariance calculation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Covar(object source, int period) : this(period) + { + var pubEvent = source.GetType().GetEvent("Pub"); + pubEvent?.AddEventHandler(source, new ValueSignal(Sub)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Init() + { + base.Init(); + _xValues.Clear(); + _yValues.Clear(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected override void ManageState(bool isNew) + { + if (isNew) + { + _lastValidValue = Input.Value; + _index++; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static double CalculateMean(ReadOnlySpan values) + { + double sum = 0; + for (int i = 0; i < values.Length; i++) + { + sum += values[i]; + } + return sum / values.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static double CalculateCovariance(ReadOnlySpan xValues, ReadOnlySpan yValues, double xMean, double yMean) + { + double covariance = 0; + for (int i = 0; i < xValues.Length; i++) + { + covariance += (xValues[i] - xMean) * (yValues[i] - yMean); + } + return covariance / xValues.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(Input.IsNew); + + _xValues.Add(Input.Value, Input.IsNew); + _yValues.Add(Input2.Value, Input.IsNew); + + double covariance = 0; + if (_xValues.Count >= MinimumPoints && _yValues.Count >= MinimumPoints) + { + ReadOnlySpan xValues = _xValues.GetSpan(); + ReadOnlySpan yValues = _yValues.GetSpan(); + + double xMean = CalculateMean(xValues); + double yMean = CalculateMean(yValues); + + covariance = CalculateCovariance(xValues, yValues, xMean, yMean); + } + + IsHot = _xValues.Count >= Period && _yValues.Count >= Period; + return covariance; + } +} diff --git a/lib/statistics/Kendall.cs b/lib/statistics/Kendall.cs new file mode 100644 index 0000000..cf6a73e --- /dev/null +++ b/lib/statistics/Kendall.cs @@ -0,0 +1,182 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// KENDALL: Kendall's Rank Correlation Coefficient (Tau) +/// A nonparametric measure that evaluates the degree of similarity between two sets +/// of rankings by analyzing concordant and discordant pairs. Unlike Spearman correlation, +/// Kendall's tau measures the ordinal association between two variables. +/// +/// +/// The Kendall calculation process: +/// 1. Compares each pair of observations +/// 2. Counts concordant and discordant pairs +/// 3. Handles ties in both variables +/// +/// Key characteristics: +/// - Measures ordinal association +/// - Range: -1 to +1 +/// - Robust to outliers +/// - More intuitive probabilistic interpretation +/// - Less sensitive to error than Spearman +/// +/// Formula: +/// τ = (nc - nd) / sqrt((n0 - n1)(n0 - n2)) +/// where: +/// nc = number of concordant pairs +/// nd = number of discordant pairs +/// n0 = n(n-1)/2 +/// n1 = sum(u(u-1)/2) for ties in x +/// n2 = sum(v(v-1)/2) for ties in y +/// +/// Market Applications: +/// - Rank correlation analysis +/// - Portfolio diversification +/// - Risk assessment +/// - Market trend analysis +/// - Pattern recognition +/// +/// Sources: +/// https://en.wikipedia.org/wiki/Kendall_rank_correlation_coefficient +/// "Rank Correlation Methods" - Maurice G. Kendall +/// +/// Note: More robust to outliers and errors than other correlation measures +/// +[SkipLocalsInit] +public sealed class Kendall : AbstractBase +{ + private readonly int Period; + private readonly CircularBuffer _xValues; + private readonly CircularBuffer _yValues; + private const double Epsilon = 1e-10; + private const int MinimumPoints = 2; + + /// The number of points to consider for Kendall correlation calculation. + /// Thrown when period is less than 2. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Kendall(int period) + { + if (period < MinimumPoints) + { + throw new ArgumentOutOfRangeException(nameof(period), + "Period must be greater than or equal to 2 for Kendall correlation calculation."); + } + Period = period; + WarmupPeriod = MinimumPoints; + _xValues = new CircularBuffer(period); + _yValues = new CircularBuffer(period); + Name = $"Kendall(period={period})"; + Init(); + } + + /// The data source object that publishes updates. + /// The number of points to consider for Kendall correlation calculation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Kendall(object source, int period) : this(period) + { + var pubEvent = source.GetType().GetEvent("Pub"); + pubEvent?.AddEventHandler(source, new ValueSignal(Sub)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Init() + { + base.Init(); + _xValues.Clear(); + _yValues.Clear(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected override void ManageState(bool isNew) + { + if (isNew) + { + _lastValidValue = Input.Value; + _index++; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static (int concordant, int discordant, int tiesX, int tiesY) CountPairs(ReadOnlySpan x, ReadOnlySpan y) + { + int n = x.Length; + int concordant = 0; + int discordant = 0; + int tiesX = 0; + int tiesY = 0; + + for (int i = 0; i < n - 1; i++) + { + if (double.IsNaN(x[i]) || double.IsNaN(y[i])) continue; + + for (int j = i + 1; j < n; j++) + { + if (double.IsNaN(x[j]) || double.IsNaN(y[j])) continue; + + double xDiff = x[i] - x[j]; + double yDiff = y[i] - y[j]; + + if (Math.Abs(xDiff) < Epsilon && Math.Abs(yDiff) < Epsilon) + { + tiesX++; + tiesY++; + } + else if (Math.Abs(xDiff) < Epsilon) + { + tiesX++; + } + else if (Math.Abs(yDiff) < Epsilon) + { + tiesY++; + } + else + { + int xSign = xDiff > 0 ? 1 : -1; + int ySign = yDiff > 0 ? 1 : -1; + if (xSign == ySign) + { + concordant++; + } + else + { + discordant++; + } + } + } + } + + return (concordant, discordant, tiesX, tiesY); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(Input.IsNew); + + _xValues.Add(Input.Value, Input.IsNew); + _yValues.Add(Input2.Value, Input.IsNew); + + double correlation = 0; + if (_xValues.Count >= MinimumPoints && _yValues.Count >= MinimumPoints) + { + ReadOnlySpan xValues = _xValues.GetSpan(); + ReadOnlySpan yValues = _yValues.GetSpan(); + + var (concordant, discordant, tiesX, tiesY) = CountPairs(xValues, yValues); + + int n = xValues.Length; + int n0 = (n * (n - 1)) / 2; + + // Calculate denominator considering ties + double denominator = Math.Sqrt((n0 - tiesX) * (n0 - tiesY)); + + if (denominator > Epsilon) + { + correlation = (concordant - discordant) / denominator; + } + } + + IsHot = _xValues.Count >= Period && _yValues.Count >= Period; + return correlation; + } +} diff --git a/lib/statistics/Spearman.cs b/lib/statistics/Spearman.cs new file mode 100644 index 0000000..9fd6035 --- /dev/null +++ b/lib/statistics/Spearman.cs @@ -0,0 +1,224 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// SPEARMAN: Spearman's Rank Correlation Coefficient +/// A nonparametric measure of rank correlation that assesses the monotonic relationship +/// between two variables. Unlike Pearson correlation, Spearman correlation evaluates +/// the relationship based on ranked values rather than raw data. +/// +/// +/// The Spearman calculation process: +/// 1. Ranks both sets of values +/// 2. Calculates correlation between ranks +/// 3. Handles ties by averaging ranks +/// +/// Key characteristics: +/// - Resistant to outliers +/// - Detects monotonic relationships +/// - Range: -1 to +1 +/// - Distribution-free measure +/// - Handles non-linear relationships +/// +/// Formula: +/// ρ = Cov(rank(X), rank(Y)) / (σrank(X) * σrank(Y)) +/// where: +/// X, Y = variables +/// rank() = ranking function +/// Cov = covariance +/// σ = standard deviation +/// +/// Market Applications: +/// - Technical analysis +/// - Risk assessment +/// - Market correlation studies +/// - Trend analysis +/// - Pattern recognition +/// +/// Sources: +/// https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient +/// "Nonparametric Statistics for Non-Statisticians" - Gregory W. Corder +/// +/// Note: More robust to outliers than Pearson correlation +/// +[SkipLocalsInit] +public sealed class Spearman : AbstractBase +{ + private readonly int Period; + private readonly CircularBuffer _xValues; + private readonly CircularBuffer _yValues; + private readonly CircularBuffer _xRanks; + private readonly CircularBuffer _yRanks; + private const double Epsilon = 1e-10; + private const int MinimumPoints = 2; + + /// The number of points to consider for Spearman correlation calculation. + /// Thrown when period is less than 2. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Spearman(int period) + { + if (period < MinimumPoints) + { + throw new ArgumentOutOfRangeException(nameof(period), + "Period must be greater than or equal to 2 for Spearman correlation calculation."); + } + Period = period; + WarmupPeriod = MinimumPoints; + _xValues = new CircularBuffer(period); + _yValues = new CircularBuffer(period); + _xRanks = new CircularBuffer(period); + _yRanks = new CircularBuffer(period); + Name = $"Spearman(period={period})"; + Init(); + } + + /// The data source object that publishes updates. + /// The number of points to consider for Spearman correlation calculation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Spearman(object source, int period) : this(period) + { + var pubEvent = source.GetType().GetEvent("Pub"); + pubEvent?.AddEventHandler(source, new ValueSignal(Sub)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Init() + { + base.Init(); + _xValues.Clear(); + _yValues.Clear(); + _xRanks.Clear(); + _yRanks.Clear(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected override void ManageState(bool isNew) + { + if (isNew) + { + _lastValidValue = Input.Value; + _index++; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static double[] CalculateRanks(ReadOnlySpan values) + { + int n = values.Length; + var pairs = new (double value, int index)[n]; + for (int i = 0; i < n; i++) + { + pairs[i] = double.IsNaN(values[i]) ? (double.NaN, i) : (values[i], i); + } + + // Sort non-NaN values + var validPairs = pairs.Where(p => !double.IsNaN(p.value)).OrderBy(p => p.value).ToArray(); + var ranks = new double[n]; + Array.Fill(ranks, double.NaN); + + for (int i = 0; i < validPairs.Length;) + { + int j = i; + // Find ties + while (j < validPairs.Length - 1 && Math.Abs(validPairs[j].value - validPairs[j + 1].value) < Epsilon) + { + j++; + } + + // Average rank for ties + double rank = (i + j) / 2.0 + 1; + for (int k = i; k <= j; k++) + { + ranks[validPairs[k].index] = rank; + } + i = j + 1; + } + + return ranks; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static double CalculateCovariance(CircularBuffer xBuffer, CircularBuffer yBuffer, double xMean, double yMean) + { + var xSpan = xBuffer.GetSpan(); + var ySpan = yBuffer.GetSpan(); + double covariance = 0; + int count = 0; + + for (int i = 0; i < xSpan.Length; i++) + { + if (!double.IsNaN(xSpan[i]) && !double.IsNaN(ySpan[i])) + { + covariance += (xSpan[i] - xMean) * (ySpan[i] - yMean); + count++; + } + } + + return count > 0 ? covariance / count : double.NaN; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static double CalculateStandardDeviation(CircularBuffer buffer, double mean) + { + var span = buffer.GetSpan(); + double sumSquaredDeviations = 0; + int count = 0; + + for (int i = 0; i < span.Length; i++) + { + if (!double.IsNaN(span[i])) + { + double deviation = span[i] - mean; + sumSquaredDeviations += deviation * deviation; + count++; + } + } + + return count > 0 ? Math.Sqrt(sumSquaredDeviations / count) : double.NaN; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(Input.IsNew); + + _xValues.Add(Input.Value, Input.IsNew); + _yValues.Add(Input2.Value, Input.IsNew); + + double correlation = 0; + if (_xValues.Count >= MinimumPoints && _yValues.Count >= MinimumPoints) + { + // Convert values to ranks + var xRanks = CalculateRanks(_xValues.GetSpan()); + var yRanks = CalculateRanks(_yValues.GetSpan()); + + // Store ranks in buffers for statistical calculations + _xRanks.Clear(); + _yRanks.Clear(); + for (int i = 0; i < xRanks.Length; i++) + { + _xRanks.Add(xRanks[i], true); + _yRanks.Add(yRanks[i], true); + } + + // Use CircularBuffer's optimized Average() method + double xMean = _xRanks.Average(); + double yMean = _yRanks.Average(); + + if (!double.IsNaN(xMean) && !double.IsNaN(yMean)) + { + double covariance = CalculateCovariance(_xRanks, _yRanks, xMean, yMean); + double xStdDev = CalculateStandardDeviation(_xRanks, xMean); + double yStdDev = CalculateStandardDeviation(_yRanks, yMean); + + if (!double.IsNaN(covariance) && xStdDev > Epsilon && yStdDev > Epsilon) + { + correlation = covariance / (xStdDev * yStdDev); + } + } + } + + IsHot = _xValues.Count >= Period && _yValues.Count >= Period; + return correlation; + } +} diff --git a/lib/statistics/_list.md b/lib/statistics/_list.md index 3ca1af8..3212e98 100644 --- a/lib/statistics/_list.md +++ b/lib/statistics/_list.md @@ -1,32 +1,26 @@ -# Statistics +# Statistics indicators +Done: 21, Todo: 2 -Statistical functions and indicators for financial analysis. - -## Implemented - -- [Beta](Beta.cs) - Beta coefficient measuring volatility relative to market -- [Corr](Corr.cs) - Correlation coefficient between two series -- [Curvature](Curvature.cs) - Curvature of a time series -- [Entropy](Entropy.cs) - Information entropy of a series -- [Hurst](Hurst.cs) - Hurst exponent for trend strength -- [Kurtosis](Kurtosis.cs) - Kurtosis measuring tail extremity -- [Max](Max.cs) - Maximum value over period -- [Median](Median.cs) - Median value over period -- [Min](Min.cs) - Minimum value over period -- [Mode](Mode.cs) - Mode (most frequent value) -- [Percentile](Percentile.cs) - Percentile rank calculation -- [Skew](Skew.cs) - Skewness measuring distribution asymmetry -- [Slope](Slope.cs) - Linear regression slope -- [Stddev](Stddev.cs) - Standard deviation -- [Theil](Theil.cs) - Theil's U statistics for forecast accuracy -- [Tsf](Tsf.cs) - Time series forecast -- [Variance](Variance.cs) - Statistical variance -- [Zscore](Zscore.cs) - Z-score standardization - -## Planned - -- Cointegration - Test for cointegrated series -- Granger - Granger causality test -- Jarque-Bera - Normality test -- Kendall - Kendall rank correlation -- Spearman - Spearman rank correlation +✔️ BETA - Beta coefficient measuring volatility relative to market +✔️ CORR - Correlation coefficient between two series +✔️ COVAR - Covariance between two series +✔️ CURVATURE - Curvature of a time series +✔️ ENTROPY - Information entropy of a series +✔️ HURST - Hurst exponent for trend strength +✔️ KENDALL - Kendall rank correlation +✔️ KURTOSIS - Kurtosis measuring tail extremity +✔️ MAX - Maximum value over period +✔️ MEDIAN - Median value over period +✔️ MIN - Minimum value over period +✔️ MODE - Mode (most frequent value) +✔️ PERCENTILE - Percentile rank calculation +✔️ SKEW - Skewness measuring distribution asymmetry +✔️ SLOPE - Linear regression slope +✔️ SPEARMAN - Spearman rank correlation +✔️ STDDEV - Standard deviation +✔️ THEIL - Theil's U statistics for forecast accuracy +✔️ TSF - Time series forecast +✔️ VARIANCE - Statistical variance +✔️ ZSCORE - Z-score standardization +COINTEGRATION - Test for cointegrated series +GRANGER - Granger causality test diff --git a/lib/volatility/_list.md b/lib/volatility/_list.md index 59fa882..bb1c8d0 100644 --- a/lib/volatility/_list.md +++ b/lib/volatility/_list.md @@ -1,5 +1,5 @@ # Volatility indicators -Done: 25, Todo: 10 +Done: 31, Todo: 4 ✔️ ADR - Average Daily Range ✔️ AP - Andrew's Pitchfork @@ -17,22 +17,22 @@ Done: 25, Todo: 10 ✔️ GKV - Garman-Klass Volatility ✔️ HLV - High-Low Volatility ✔️ HV - Historical Volatility -*ICH - Ichimoku Cloud (Conversion, Base, Leading Span A, Leading Span B, Lagging Span) -✔️ *JVOLTY - Jurik Volatility (Jvolty, Upper band, Lower band) -*KC - Keltner Channels (Upper, Middle, Lower) +✔️ JVOLTY - Jurik Volatility (Jvolty, Upper band, Lower band) ✔️ NATR - Normalized Average True Range ✔️ PCH - Price Channel Indicator -*PSAR - Parabolic Stop and Reverse (Value, Trend) ✔️ PV - Parkinson Volatility ✔️ RSV - Rogers-Satchell Volatility ✔️ RV - Realized Volatility ✔️ RVI - Relative Volatility Index -*STARC - Starc Bands (Upper, Middle, Lower) ✔️ SV - Stochastic Volatility ✔️ TR - True Range ✔️ UI - Ulcer Index -✔️ *VC - Volatility Cone (Mean, Upper Bound, Lower Bound) +✔️ VC - Volatility Cone (Mean, Upper Bound, Lower Bound) ✔️ VOV - Volatility of Volatility ✔️ VR - Volatility Ratio ✔️ *VS - Volatility Stop (Long Stop, Short Stop) ✔️ YZV - Yang-Zhang Volatility +ICH - Ichimoku Cloud (Conversion, Base, Leading Span A, Leading Span B, Lagging Span) +KC - Keltner Channels (Upper, Middle, Lower) +PSAR - Parabolic Stop and Reverse (Value, Trend) +STARC - Starc Bands (Upper, Middle, Lower)