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)