diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 9c8f64e6..40084778 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,24 +1,24 @@ * [Home](/) -* [Available Indicators](indicators/indicators.md) +* [List of Indicators](indicators/indicators.md) -* Introduction +* ๐Ÿšง Introduction * [Overview]() * [Features]() * [Historical vs Real-time analysis](essays/realtime.md) -* Core Concepts +* ๐Ÿšง Core Concepts * [Time Series Data Handling]() * [Calculation classes]() * [Presentation Classes]() -* QuanTAlib C# Library +* ๐Ÿšง QuanTAlib C# Library * [Installation]() * [Quick Start Guide]() * [Usage Examples]() * [Tests and Validation]() -* Quantower Charts +* ๐Ÿšง Quantower Charts * [Installation]() * [Quick Start Guide]() * [Using VS Code for QuanTower coding](setup/vscode.md) @@ -26,7 +26,7 @@ * [Creating Custom Indicators]() * [Inspecting Quantower Internals]() -* [Available Indicators](indicators/indicators.md) +* [๐Ÿšง Available Indicators](indicators/indicators.md) * Momentum * [ADX - Average Directional Index](indicators/momentum/adx/description.md) * [ADXR - Average Directional Index Rating](indicators/momentum/adxr/description.md) diff --git a/docs/index.html b/docs/index.html index 00fb80ce..23a7f5e8 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,57 +3,140 @@ QuanTAlib Documentation + + - - + + + + +
+ + - - - - - - - - - + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/docs/indicators/indicators.md b/docs/indicators/indicators.md index 81cfc570..4d97d32c 100644 --- a/docs/indicators/indicators.md +++ b/docs/indicators/indicators.md @@ -1,30 +1,27 @@ # Indicators in QuanTAlib -\* = Returns multiple values +| **Category** | **Status** | **Completion** | +|--------------|:----------:|:--------------:| +| Basic Transforms | 6 of 6 | 100% | +| Averages & Trends | 33 of 33 | 100% | +| Momentum | 17 of 17 | 100% | +| Oscillators | 12 of 29 | 41% | +| Volatility | 15 of 35 | 43% | +| Volume | 19 of 19 | 100% | +| Numerical Analysis | 13 of 20 | 65% | +| Errors | 16 of 16 | 100% | +| **Total** | **131 of 175** | **75%** | -**Implementation Status:** -- Basic Transforms: 6 of 6 complete -- Averages & Trends: 33 of 33 complete -- Momentum: 17 of 17 complete -- Oscillators: 11 of 29 complete -- Volatility: 11 of 35 complete -- Volume: 15 of 19 complete -- Numerical Analysis: 13 of 20 complete -- Errors: 16 of 16 complete -- Total: 122 of 175 indicators implemented (70%) - - -|**BASIC TRANSFORMS**|**Class Name**| -|---|:--:| +|Technical Indicator Name| Class Name| +|-----------|:----------:| +|**BASIC TRANSFORMS**|| |OC2 - Midpoint price|`.OC2`| |HL2 - Median Price|`.HL2`| |HLC3 - Typical Price|`.HLC3`| |OHL3 - Mean Price|`.OHL3`| |OHLC4 - Average Price|`.OHLC4`| |HLCC4 - Weighted Price|`.HLCC4`| - -|**AVERAGES & TRENDS**|**Class Name**| -|--|:--:| +|**AVERAGES & TRENDS**|| |AFIRMA - Adaptive FIR Moving Average|`Afirma`| |ALMA - Arnaud Legoux Moving Average|`Alma`| |DEMA - Double Exponential Moving Average|`Dema`| @@ -58,9 +55,7 @@ |VIDYA - Variable Index Dynamic Average|`Vidya`| |WMA - Weighted Moving Average|`Wma`| |ZLEMA - Zero-Lag Exponential Moving Average|`Zlema`| - -|**MOMENTUM INDICATORS**|**Class Name**| -|--|:--:| +|**MOMENTUM INDICATORS**|| |ADX - Average Directional Movement Index|`Adx`| |ADXR - Average Directional Movement Index Rating|`Adxr`| |APO - Absolute Price Oscillator|`Apo`| @@ -78,79 +73,73 @@ |TRIX - 1-day ROC of TEMA|`Trix`| |VEL - Jurik Signal Velocity|`Vel`| |VORTEX* - Vortex Indicator (VI+, VI-)|`Vortex`| - -|**OSCILLATORS**|**Class Name**| -|--|:--:| +|**OSCILLATORS**|| |AC - Acceleration Oscillator|`Ac`| |AO - Awesome Oscillator|`Ao`| |AROON* - Aroon oscillator (Up, Down)|`Aroon`| -|๐Ÿšง BOP - Balance of Power|`Bop`| +|BOP - Balance of Power|`Bop`| |CCI - Commodity Channel Index|`Cci`| |CFO - Chande Forcast Oscillator|`Cfo`| |CMO - Chande Momentum Oscillator|`Cmo`| |CHOP - Choppiness Index|`Chop`| |COG - Ehler's Center of Gravity|`Cog`| -|๐Ÿšง COPPOCK - Coppock Curve|`Coppock`| -|๐Ÿšง CRSI - Connor RSI|`Crsi`| -|๐Ÿšง CTI - Ehler's Correlation Trend Indicator|`Cti`| -|๐Ÿšง DOSC - Derivative Oscillator|`Dosc`| -|๐Ÿšง EFI - Elder Ray's Force Index|`Efi`| -|๐Ÿšง FISHER - Fisher Transform|`Fisher`| -|๐Ÿšง FOSC - Forecast Oscillator|`Fosc`| -|๐Ÿšง GATOR* - Williams Alliator Oscillator (Upper Jaw, Lower Jaw, Teeth)|`Gator`| -|๐Ÿšง KDJ* - KDJ Indicator (K, D, J lines)|`Kdj`| -|๐Ÿšง KRI - Kairi Relative Index|`Kri`| +|๐Ÿšง COPPOCK - Coppock Curve|`Coppock`| +|๐Ÿšง CRSI - Connor RSI|`Crsi`| +|๐Ÿšง CTI - Ehler's Correlation Trend Indicator|`Cti`| +|๐Ÿšง DOSC - Derivative Oscillator|`Dosc`| +|๐Ÿšง EFI - Elder Ray's Force Index|`Efi`| +|๐Ÿšง FISHER - Fisher Transform|`Fisher`| +|๐Ÿšง FOSC - Forecast Oscillator|`Fosc`| +|๐Ÿšง GATOR* - Williams Alliator Oscillator (Upper Jaw, Lower Jaw, Teeth)|`Gator`| +|๐Ÿšง KDJ* - KDJ Indicator (K, D, J lines)|`Kdj`| +|๐Ÿšง KRI - Kairi Relative Index|`Kri`| |RSI - Relative Strength Index|`Rsi`| |RSX - Jurik Trend Strength Index|`Rsx`| -|๐Ÿšง RVGI* - Relative Vigor Index (RVGI, Signal)|`Rvgi`| -|๐Ÿšง SMI - Stochastic Momentum Index|`Smi`| -|๐Ÿšง SRSI* - Stochastic RSI (SRSI, Signal)|`Srsi`| -|๐Ÿšง STC - Schaff Trend Cycle|`Stc`| -|๐Ÿšง STOCH* - Stochastic Oscillator (%K, %D)|`Stoch`| -|๐Ÿšง TSI - True Strength Index|`Tsi`| -|๐Ÿšง UO - Ultimate Oscillator|`Uo`| -|๐Ÿšง WILLR - Larry Williams' %R|`Willr`| - -|**VOLATILITY INDICATORS**|**Class Name**| -|--|:--:| -|๐Ÿšง ADR - Average Daily Range|`Adr`| -|๐Ÿšง AP - Andrew's Pitchfork|`Ap`| +|๐Ÿšง RVGI* - Relative Vigor Index (RVGI, Signal)|`Rvgi`| +|๐Ÿšง SMI - Stochastic Momentum Index|`Smi`| +|๐Ÿšง SRSI* - Stochastic RSI (SRSI, Signal)|`Srsi`| +|๐Ÿšง STC - Schaff Trend Cycle|`Stc`| +|๐Ÿšง STOCH* - Stochastic Oscillator (%K, %D)|`Stoch`| +|๐Ÿšง TSI - True Strength Index|`Tsi`| +|๐Ÿšง UO - Ultimate Oscillator|`Uo`| +|๐Ÿšง WILLR - Larry Williams' %R|`Willr`| +|**VOLATILITY INDICATORS**|| +|ADR - Average Daily Range|`Adr`| +|AP - Andrew's Pitchfork|`Ap`| |ATR - Average True Range|`Atr`| -|๐Ÿšง ATRP - Average True Range Percent|`Atrp`| -|๐Ÿšง ATRS - ATR Trailing Stop|`Atrs`| -|๐Ÿšง BB* - Bollinger Bandsยฎ (Upper, Middle, Lower)|`Bb`| -|๐Ÿšง CCV - Close-to-Close Volatility|`Ccv`| -|๐Ÿšง CE - Chandelier Exit|`Ce`| -|๐Ÿšง CV - Conditional Volatility (ARCH/GARCH)|`Cv`| -|๐Ÿšง CVI - Chaikin's Volatility|`Cvi`| -|๐Ÿšง DC* - Donchian Channels (Upper, Middle, Lower)|`Dc`| -|๐Ÿšง EWMA - Exponential Weighted Moving Average Volatility|`Ewma`| -|๐Ÿšง FCB - Fractal Chaos Bands|`Fcb`| -|๐Ÿšง GKV - Garman-Klass Volatility|`Gkv`| -|๐Ÿšง HLV - High-Low Volatility|`Hlv`| +|ATRP - Average True Range Percent|`Atrp`| +|ATRS - ATR Trailing Stop|`Atrs`| +|๐Ÿšง BB* - Bollinger Bandsยฎ (Upper, Middle, Lower)|`Bb`| +|๐Ÿšง CCV - Close-to-Close Volatility|`Ccv`| +|๐Ÿšง CE - Chandelier Exit|`Ce`| +|๐Ÿšง CV - Conditional Volatility (ARCH/GARCH)|`Cv`| +|๐Ÿšง CVI - Chaikin's Volatility|`Cvi`| +|๐Ÿšง DC* - Donchian Channels (Upper, Middle, Lower)|`Dc`| +|๐Ÿšง EWMA - Exponential Weighted Moving Average Volatility|`Ewma`| +|๐Ÿšง FCB - Fractal Chaos Bands|`Fcb`| +|๐Ÿšง GKV - Garman-Klass Volatility|`Gkv`| +|๐Ÿšง HLV - High-Low Volatility|`Hlv`| |HV - Historical Volatility|`Hv`| -|๐Ÿšง ICH* - Ichimoku Cloud (Conversion, Base, Leading Span A, Leading Span B, Lagging Span)|`Ich`| +|๐Ÿšง ICH* - Ichimoku Cloud (Conversion, Base, Leading Span A, Leading Span B, Lagging Span)|`Ich`| |JVOLTY - Jurik Volatility|`Jvolty`| -|๐Ÿšง KC* - Keltner Channels (Upper, Middle, Lower)|`Kc`| -|๐Ÿšง NATR - Normalized Average True Range|`Natr`| -|๐Ÿšง PCH - Price Channel Indicator|`Pch`| -|๐Ÿšง PSAR* - Parabolic Stop and Reverse (Value, Trend)|`Psar`| -|๐Ÿšง PV - Parkinson Volatility|`Pv`| -|๐Ÿšง RSV - Rogers-Satchell Volatility|`Rsv`| +|๐Ÿšง KC* - Keltner Channels (Upper, Middle, Lower)|`Kc`| +|๐Ÿšง NATR - Normalized Average True Range|`Natr`| +|๐Ÿšง PCH - Price Channel Indicator|`Pch`| +|๐Ÿšง PSAR* - Parabolic Stop and Reverse (Value, Trend)|`Psar`| +|๐Ÿšง PV - Parkinson Volatility|`Pv`| +|๐Ÿšง RSV - Rogers-Satchell Volatility|`Rsv`| |RV - Realized Volatility|`Rv`| |RVI - Relative Volatility Index|`Rvi`| -|๐Ÿšง STARC* - Starc Bands (Upper, Middle, Lower)|`Starc`| -|๐Ÿšง SV - Stochastic Volatility|`Sv`| +|๐Ÿšง STARC* - Starc Bands (Upper, Middle, Lower)|`Starc`| +|๐Ÿšง SV - Stochastic Volatility|`Sv`| |TR - True Range|`Tr`| |UI - Ulcer Index|`Ui`| |VC* - Volatility Cone (Mean, Upper Bound, Lower Bound)|`Vc`| |VOV - Volatility of Volatility|`Vov`| |VR - Volatility Ratio|`Vr`| |VS* - Volatility Stop (Long Stop, Short Stop)|`Vs`| -|๐Ÿšง YZV - Yang-Zhang Volatility|`Yzv`| - -|**VOLUME INDICATORS**|**Class Name**| -|--|:--:| +|๐Ÿšง YZV - Yang-Zhang Volatility|`Yzv`| +|**VOLUME INDICATORS**|| |ADL - Chaikin Accumulation Distribution Line|`Adl`| |ADOSC - Chaikin Accumulation Distribution Oscillator|`Adosc`| |AOBV - Archer On-Balance Volume|`Aobv`| @@ -166,36 +155,32 @@ |PVR - Price Volume Rank|`Pvr`| |PVT - Price Volume Trend|`Pvt`| |TVI - Trade Volume Index|`Tvi`| -|๐Ÿšง VF - Volume Force|`Vf`| -|๐Ÿšง VP - Volume Profile|`Vp`| -|๐Ÿšง VWAP - Volume Weighted Average Price|`Vwap`| -|๐Ÿšง VWMA - Volume Weighted Moving Average|`Vwma`| - -|**NUMERICAL ANALYSIS**|**Class Name**| -|--|:--:| -|๐Ÿšง BETA* - Beta coefficient (Beta, R-squared)|`Beta`| -|๐Ÿšง CORR* - Correlation Coefficient (Correlation, P-value)|`Corr`| +|VF - Volume Force|`Vf`| +|VP - Volume Profile|`Vp`| +|VWAP - Volume Weighted Average Price|`Vwap`| +|VWMA - Volume Weighted Moving Average|`Vwma`| +|**NUMERICAL ANALYSIS**|| +|๐Ÿšง BETA* - Beta coefficient (Beta, R-squared)|`Beta`| +|๐Ÿšง CORR* - Correlation Coefficient (Correlation, P-value)|`Corr`| |CURVATURE - Rate of Change in Direction or Slope|`Curvature`| |ENTROPY - Measure of Uncertainty or Disorder|`Entropy`| -|๐Ÿšง HUBER - Huber Loss|`Huber`| -|๐Ÿšง HURST - Hurst Exponent|`Hurst`| +|๐Ÿšง HUBER - Huber Loss|`Huber`| +|๐Ÿšง HURST - Hurst Exponent|`Hurst`| |KURTOSIS - Measure of Tails/Peakedness|`Kurtosis`| |MAX - Maximum with exponential decay|`Max`| |MEDIAN - Middle value|`Median`| |MIN - Minimum with exponential decay|`Min`| |MODE - Most Frequent Value|`Mode`| |PERCENTILE - Rank Order|`Percentile`| -|๐Ÿšง RSQUARED* - Coefficient of Determination (R-squared, Adjusted R-squared)|`Rsquared`| +|๐Ÿšง RSQUARED* - Coefficient of Determination (R-squared, Adjusted R-squared)|`Rsquared`| |SKEW - Skewness, asymmetry of distribution|`Skew`| |SLOPE - Rate of Change, Linear Regression|`Slope`| |STDDEV - Standard Deviation, Measure of Spread|`Stddev`| -|๐Ÿšง THEIL* - Theil's U Statistics (U1, U2)|`Theil`| -|๐Ÿšง TSF* - Time Series Forecast (Forecast, Confidence Interval)|`Tsf`| +|๐Ÿšง THEIL* - Theil's U Statistics (U1, U2)|`Theil`| +|๐Ÿšง TSF* - Time Series Forecast (Forecast, Confidence Interval)|`Tsf`| |VARIANCE - Average of Squared Deviations|`Variance`| |ZSCORE - Standardized Score|`Zscore`| - -|**ERRORS**|**Class Name**| -|--|:--:| +|**ERRORS**|| |HUBER - Huber Loss|`Huber`| |MAE - Mean Absolute Error|`Mae`| |MAPD - Mean Absolute Percentage Deviation|`Mapd`| diff --git a/lib/oscillators/_list.md b/lib/oscillators/_list.md index e4cf7f2a..718edbf5 100644 --- a/lib/oscillators/_list.md +++ b/lib/oscillators/_list.md @@ -4,7 +4,7 @@ Done: 11, Todo: 18 โœ”๏ธ AC - Acceleration Oscillator โœ”๏ธ AO - Awesome Oscillator โœ”๏ธ *AROON - Aroon oscillator (Up, Down) -BOP - Balance of Power +โœ”๏ธ BOP - Balance of Power โœ”๏ธ CCI - Commodity Channel Index โœ”๏ธ CFO - Chande Forcast Oscillator โœ”๏ธ CMO - Chande Momentum Oscillator diff --git a/lib/volatility/Adr.cs b/lib/volatility/Adr.cs new file mode 100644 index 00000000..9e394dae --- /dev/null +++ b/lib/volatility/Adr.cs @@ -0,0 +1,83 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// ADR: Average Daily Range +/// A volatility indicator that measures the average range of price movement over +/// a specified period. It helps identify normal trading ranges and potential +/// breakout levels. +/// +/// +/// The ADR calculation process: +/// 1. Calculate daily range (High - Low) +/// 2. Apply SMA to daily ranges +/// 3. Updates with each new price bar +/// +/// Key characteristics: +/// - Simple volatility measure +/// - Period-based average +/// - Trend independent +/// - Absolute price measure +/// - Support/resistance aid +/// +/// Formula: +/// Daily Range = High - Low +/// ADR = SMA(Daily Range, period) +/// +/// Market Applications: +/// - Position sizing +/// - Volatility analysis +/// - Support/resistance levels +/// - Breakout identification +/// - Risk assessment +/// +/// Note: Simpler alternative to ATR, doesn't consider gaps +/// + +[SkipLocalsInit] +public sealed class Adr : AbstractBase +{ + private readonly Sma _ma; + private const int DefaultPeriod = 14; + + /// The number of periods for ADR calculation (default 14). + /// Thrown when period is less than 1. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Adr(int period = DefaultPeriod) + { + if (period < 1) + throw new ArgumentOutOfRangeException(nameof(period)); + + _ma = new(period); + WarmupPeriod = period; + Name = $"ADR({period})"; + } + + /// The data source object that publishes updates. + /// The number of periods for ADR calculation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Adr(object source, int period = DefaultPeriod) : 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++; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + // Calculate daily range + double range = BarInput.High - BarInput.Low; + + // Apply SMA smoothing + return _ma.Calc(range, BarInput.IsNew); + } +} diff --git a/lib/volatility/Ap.cs b/lib/volatility/Ap.cs new file mode 100644 index 00000000..5ce827fb --- /dev/null +++ b/lib/volatility/Ap.cs @@ -0,0 +1,120 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// AP: Andrew's Pitchfork +/// A trend channel tool that uses three points to create a channel with a median +/// line and two parallel lines. It helps identify potential support and resistance +/// levels based on market pivots. +/// +/// +/// The AP calculation process: +/// 1. Use three pivot points (P0, P1, P2) +/// 2. Calculate median line from P0 to midpoint of P1-P2 +/// 3. Draw parallel lines at P1 and P2 +/// 4. Project all lines forward +/// +/// Key characteristics: +/// - Trend channel tool +/// - Support/resistance levels +/// - Price projection +/// - Market geometry +/// - Pivot-based analysis +/// +/// Formula: +/// Median Line = Line from P0 to (P1 + P2)/2 +/// Upper Line = Parallel to median at P1 +/// Lower Line = Parallel to median at P2 +/// +/// Market Applications: +/// - Trend analysis +/// - Support/resistance +/// - Price targets +/// - Channel trading +/// - Market structure +/// +/// Sources: +/// Dr. Alan Andrews +/// https://www.investopedia.com/terms/a/andrewspitchfork.asp +/// +/// Note: Returns median line value for current price level +/// + +[SkipLocalsInit] +public sealed class Ap : AbstractBase +{ + private readonly CircularBuffer _highs; + private readonly CircularBuffer _lows; + private readonly CircularBuffer _closes; + private const int DefaultPeriod = 20; + + /// The lookback period for pivot points (default 20). + /// Thrown when period is less than 3. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Ap(int period = DefaultPeriod) + { + if (period < 3) + throw new ArgumentOutOfRangeException(nameof(period)); + + _highs = new(period); + _lows = new(period); + _closes = new(period); + WarmupPeriod = period; + Name = $"AP({period})"; + } + + /// The data source object that publishes updates. + /// The lookback period for pivot points. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Ap(object source, int period = DefaultPeriod) : 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++; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static (double x, double y) FindPivot(CircularBuffer highs, CircularBuffer lows, CircularBuffer closes, int offset) + { + double high = highs[offset]; + double low = lows[offset]; + double close = closes[offset]; + return (offset, (high + low + close) / 3.0); // Simple pivot point calculation + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + // Store price data + _highs.Add(BarInput.High, BarInput.IsNew); + _lows.Add(BarInput.Low, BarInput.IsNew); + _closes.Add(BarInput.Close, BarInput.IsNew); + + if (_index < WarmupPeriod) + return BarInput.Close; + + // Find three pivot points + var p0 = FindPivot(_highs, _lows, _closes, 2); + var p1 = FindPivot(_highs, _lows, _closes, 1); + var p2 = FindPivot(_highs, _lows, _closes, 0); + + // Calculate midpoint of P1-P2 + double midX = (p1.x + p2.x) / 2.0; + double midY = (p1.y + p2.y) / 2.0; + + // Calculate slope of median line + double slope = (midY - p0.y) / (midX - p0.x); + + // Project median line to current bar + double currentX = _index - p0.x; + return p0.y + slope * currentX; + } +} diff --git a/lib/volatility/Atrp.cs b/lib/volatility/Atrp.cs new file mode 100644 index 00000000..a5546e77 --- /dev/null +++ b/lib/volatility/Atrp.cs @@ -0,0 +1,85 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// ATRP: Average True Range Percent +/// A volatility indicator that expresses ATR as a percentage of current price. +/// This normalization allows for comparison across different price levels and +/// instruments. +/// +/// +/// The ATRP calculation process: +/// 1. Calculate ATR normally +/// 2. Divide by current price +/// 3. Multiply by 100 for percentage +/// +/// Key characteristics: +/// - Normalized volatility measure +/// - Price-independent comparison +/// - Percentage output +/// - Cross-market analysis +/// - Relative volatility measure +/// +/// Formula: +/// ATRP = (ATR / Close) * 100 +/// +/// Market Applications: +/// - Cross-market comparison +/// - Position sizing +/// - Volatility analysis +/// - Risk assessment +/// - Market comparison +/// +/// Note: More suitable for comparing different instruments than raw ATR +/// + +[SkipLocalsInit] +public sealed class Atrp : AbstractBase +{ + private readonly Atr _atr; + private const int DefaultPeriod = 14; + private const double ScalingFactor = 100.0; + + /// The number of periods for ATR calculation (default 14). + /// Thrown when period is less than 1. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Atrp(int period = DefaultPeriod) + { + if (period < 1) + throw new ArgumentOutOfRangeException(nameof(period)); + + _atr = new(period); + WarmupPeriod = period; + Name = $"ATRP({period})"; + } + + /// The data source object that publishes updates. + /// The number of periods for ATR calculation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Atrp(object source, int period = DefaultPeriod) : 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++; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + // Calculate ATR + double atr = _atr.Calc(BarInput); + + // Convert to percentage of price + return Math.Abs(BarInput.Close) > double.Epsilon + ? (atr / BarInput.Close) * ScalingFactor + : 0.0; + } +} diff --git a/lib/volatility/Atrs.cs b/lib/volatility/Atrs.cs new file mode 100644 index 00000000..803cdb0f --- /dev/null +++ b/lib/volatility/Atrs.cs @@ -0,0 +1,159 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// ATRS: ATR Trailing Stop +/// A volatility-based trailing stop indicator that uses ATR to dynamically adjust +/// stop levels. It helps maintain position while allowing for normal market +/// fluctuations. +/// +/// +/// The ATRS calculation process: +/// 1. Calculate ATR +/// 2. Multiply ATR by factor +/// 3. Apply trailing logic based on trend +/// 4. Update stop levels +/// +/// Key characteristics: +/// - Dynamic stop levels +/// - Trend-following +/// - Volatility-based +/// - Position protection +/// - Risk management +/// +/// Formula: +/// Long Stop = High - (ATR * Factor) +/// Short Stop = Low + (ATR * Factor) +/// where Factor is multiplier for ATR (default 2.0) +/// +/// Market Applications: +/// - Stop loss placement +/// - Position management +/// - Trend following +/// - Risk control +/// - Exit strategy +/// +/// Note: Returns stop level based on current trend +/// + +[SkipLocalsInit] +public sealed class Atrs : AbstractBase +{ + private readonly Atr _atr; + private double _prevStop; + private double _p_prevStop; + private bool _isLong; + private bool _p_isLong; + private const int DefaultPeriod = 14; + private const double DefaultFactor = 2.0; + + /// + /// Gets the current trend direction (true for long, false for short) + /// + public bool IsLong => _isLong; + + /// The number of periods for ATR calculation (default 14). + /// The multiplier for ATR (default 2.0). + /// Thrown when period is less than 1 or factor is less than or equal to 0. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Atrs(int period = DefaultPeriod, double factor = DefaultFactor) + { + if (period < 1) + throw new ArgumentOutOfRangeException(nameof(period)); + if (factor <= 0) + throw new ArgumentOutOfRangeException(nameof(factor)); + + _atr = new(period); + Factor = factor; + WarmupPeriod = period; + Name = $"ATRS({period},{factor:F1})"; + } + + /// The data source object that publishes updates. + /// The number of periods for ATR calculation. + /// The multiplier for ATR. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Atrs(object source, int period = DefaultPeriod, double factor = DefaultFactor) : this(period, factor) + { + var pubEvent = source.GetType().GetEvent("Pub"); + pubEvent?.AddEventHandler(source, new BarSignal(Sub)); + } + + /// + /// Gets or sets the ATR multiplier factor + /// + public double Factor { get; set; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Init() + { + base.Init(); + _atr.Init(); + _prevStop = double.NaN; + _isLong = true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected override void ManageState(bool isNew) + { + if (isNew) + { + _index++; + _p_prevStop = _prevStop; + _p_isLong = _isLong; + } + else + { + _prevStop = _p_prevStop; + _isLong = _p_isLong; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + // Calculate ATR + double atr = _atr.Calc(BarInput); + double atrBand = atr * Factor; + + if (_index == 1 || double.IsNaN(_prevStop)) + { + // Initialize stop level + _isLong = BarInput.Close > BarInput.Open; + _prevStop = _isLong ? BarInput.Low - atrBand : BarInput.High + atrBand; + return _prevStop; + } + + // Update stop level based on trend + if (_isLong) + { + double newStop = BarInput.High - atrBand; + if (BarInput.Close < _prevStop) + { + _isLong = false; + _prevStop = BarInput.High + atrBand; + } + else if (newStop > _prevStop) + { + _prevStop = newStop; + } + } + else + { + double newStop = BarInput.Low + atrBand; + if (BarInput.Close > _prevStop) + { + _isLong = true; + _prevStop = BarInput.Low - atrBand; + } + else if (newStop < _prevStop) + { + _prevStop = newStop; + } + } + + return _prevStop; + } +} diff --git a/lib/volatility/_list.md b/lib/volatility/_list.md index 65243f2c..49854141 100644 --- a/lib/volatility/_list.md +++ b/lib/volatility/_list.md @@ -1,11 +1,11 @@ # Volatility indicators -Done: 11, Todo: 24 +Done: 15, Todo: 20 -ADR - Average Daily Range -AP - Andrew's Pitchfork +โœ”๏ธ ADR - Average Daily Range +โœ”๏ธ AP - Andrew's Pitchfork โœ”๏ธ ATR - Average True Range -ATRP - Average True Range Percent -ATRS - ATR Trailing Stop +โœ”๏ธ ATRP - Average True Range Percent +โœ”๏ธ ATRS - ATR Trailing Stop *BB - Bollinger Bandsยฎ (Upper, Middle, Lower) CCV - Close-to-Close Volatility CE - Chandelier Exit diff --git a/lib/volume/Vf.cs b/lib/volume/Vf.cs new file mode 100644 index 00000000..f987bfd1 --- /dev/null +++ b/lib/volume/Vf.cs @@ -0,0 +1,110 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// VF: Volume Force +/// A volume-based indicator that measures the strength of volume relative to price +/// movement. It helps identify whether volume is supporting or contradicting the +/// current price trend. +/// +/// +/// The VF calculation process: +/// 1. Calculate price change +/// 2. Calculate volume force as volume * price change +/// 3. Optionally smooth the result with EMA +/// +/// Key characteristics: +/// - Volume-weighted measure +/// - Trend strength indicator +/// - No upper/lower bounds +/// - Raw and smoothed versions +/// - Divergence indicator +/// +/// Formula: +/// VF = Volume * (Close - Close[1]) +/// Smoothed VF = EMA(VF, period) +/// +/// Market Applications: +/// - Volume analysis +/// - Trend confirmation +/// - Price/volume divergence +/// - Market participation +/// - Momentum confirmation +/// +/// Note: Higher values indicate stronger volume force +/// + +[SkipLocalsInit] +public sealed class Vf : AbstractBase +{ + private readonly Ema _ema; + private double _prevClose; + private double _p_prevClose; + private const int DefaultPeriod = 13; + + /// The smoothing period for EMA calculation (default 13). + /// Thrown when period is less than 1. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vf(int period = DefaultPeriod) + { + if (period < 1) + throw new ArgumentOutOfRangeException(nameof(period)); + + _ema = new(period); + WarmupPeriod = period + 1; + Name = $"VF({period})"; + } + + /// The data source object that publishes updates. + /// The smoothing period for EMA calculation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vf(object source, int period = DefaultPeriod) : this(period) + { + var pubEvent = source.GetType().GetEvent("Pub"); + pubEvent?.AddEventHandler(source, new BarSignal(Sub)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Init() + { + base.Init(); + _ema.Init(); + _prevClose = double.NaN; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected override void ManageState(bool isNew) + { + if (isNew) + { + _index++; + _p_prevClose = _prevClose; + } + else + { + _prevClose = _p_prevClose; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + if (_index == 1) + { + _prevClose = BarInput.Close; + return 0; + } + + // Calculate raw volume force + double priceChange = BarInput.Close - _prevClose; + double volumeForce = BarInput.Volume * priceChange; + + // Update previous close + _prevClose = BarInput.Close; + + // Apply EMA smoothing + return _ema.Calc(volumeForce, BarInput.IsNew); + } +} diff --git a/lib/volume/Vp.cs b/lib/volume/Vp.cs new file mode 100644 index 00000000..d923f588 --- /dev/null +++ b/lib/volume/Vp.cs @@ -0,0 +1,105 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// VP: Volume Profile +/// A volume-based indicator that analyzes volume distribution across price levels. +/// It helps identify significant price levels where most trading activity occurs. +/// +/// +/// The VP calculation process: +/// 1. Track volume at each price level within a period +/// 2. Calculate Point of Control (POC) - price with highest volume +/// 3. Calculate Value Area (70% of total volume) +/// +/// Key characteristics: +/// - Price level analysis +/// - Volume distribution +/// - Support/resistance identification +/// - Trading activity concentration +/// - Market structure analysis +/// +/// Formula: +/// VP = ฮฃ Volume at each price level +/// POC = Price level with max volume +/// Value Area = Price range containing 70% of volume +/// +/// Market Applications: +/// - Support/resistance levels +/// - Market structure analysis +/// - Trading activity patterns +/// - Price level significance +/// - Volume concentration +/// +/// Note: Returns Point of Control (price level with highest volume) +/// + +[SkipLocalsInit] +public sealed class Vp : AbstractBase +{ + private readonly CircularBuffer _volumes; + private readonly CircularBuffer _prices; + private const int DefaultPeriod = 14; + + /// The number of periods to analyze volume distribution (default 14). + /// Thrown when period is less than 1. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vp(int period = DefaultPeriod) + { + if (period < 1) + throw new ArgumentOutOfRangeException(nameof(period)); + + _volumes = new(period); + _prices = new(period); + WarmupPeriod = period; + Name = $"VP({period})"; + } + + /// The data source object that publishes updates. + /// The number of periods to analyze volume distribution. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vp(object source, int period = DefaultPeriod) : 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++; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + private static int FindMaxVolumeIndex(CircularBuffer volumes) + { + int maxIndex = 0; + double maxVolume = volumes[0]; + + for (int i = 1; i < volumes.Count; i++) + { + if (volumes[i] > maxVolume) + { + maxVolume = volumes[i]; + maxIndex = i; + } + } + + return maxIndex; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + // Store volume and price + _volumes.Add(BarInput.Volume, BarInput.IsNew); + _prices.Add(BarInput.Close, BarInput.IsNew); + + // Find price level with highest volume (Point of Control) + int pocIndex = FindMaxVolumeIndex(_volumes); + return _prices[pocIndex]; + } +} diff --git a/lib/volume/Vwap.cs b/lib/volume/Vwap.cs new file mode 100644 index 00000000..b07a64b5 --- /dev/null +++ b/lib/volume/Vwap.cs @@ -0,0 +1,93 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// VWAP: Volume Weighted Average Price +/// A trading benchmark that shows the ratio of the value traded to total volume +/// traded over a specific period. VWAP equals the dollar value of all trading +/// periods divided by the total trading volume for the current day. +/// +/// +/// The VWAP calculation process: +/// 1. Calculate typical price for each period +/// 2. Multiply typical price by volume +/// 3. Calculate cumulative values +/// 4. Divide cumulative (price * volume) by cumulative volume +/// +/// Key characteristics: +/// - Intraday trading benchmark +/// - Volume-weighted measure +/// - Institutional trading reference +/// - Price momentum indicator +/// - Trading efficiency measure +/// +/// Formula: +/// VWAP = ฮฃ(Price * Volume) / ฮฃVolume +/// where Price = (High + Low + Close)/3 +/// +/// Market Applications: +/// - Best execution analysis +/// - Trading algorithms +/// - Price momentum +/// - Market impact analysis +/// - Order timing +/// +/// Sources: +/// https://www.investopedia.com/terms/v/vwap.asp +/// +/// Note: Commonly used by institutional traders +/// + +[SkipLocalsInit] +public sealed class Vwap : AbstractBase +{ + private double _cumulativeTPV; // Cumulative (Typical Price * Volume) + private double _cumulativeVolume; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vwap() + { + WarmupPeriod = 1; + Name = "VWAP"; + Init(); + } + + /// The data source object that publishes updates. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vwap(object source) : this() + { + var pubEvent = source.GetType().GetEvent("Pub"); + pubEvent?.AddEventHandler(source, new BarSignal(Sub)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override void Init() + { + base.Init(); + _cumulativeTPV = 0; + _cumulativeVolume = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected override void ManageState(bool isNew) + { + if (isNew) + _index++; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + // Update cumulative values only for new bars + if (BarInput.IsNew) + { + _cumulativeTPV += BarInput.HLC3 * BarInput.Volume; + _cumulativeVolume += BarInput.Volume; + } + + // Calculate VWAP + return _cumulativeVolume > 0 ? _cumulativeTPV / _cumulativeVolume : BarInput.HLC3; + } +} diff --git a/lib/volume/Vwma.cs b/lib/volume/Vwma.cs new file mode 100644 index 00000000..3c1892c9 --- /dev/null +++ b/lib/volume/Vwma.cs @@ -0,0 +1,92 @@ +using System.Runtime.CompilerServices; +namespace QuanTAlib; + +/// +/// VWMA: Volume Weighted Moving Average +/// A technical indicator that combines price and volume to show the average price +/// weighted by volume over a period. It gives more weight to prices with higher +/// volume, making it more responsive to high-volume price movements. +/// +/// +/// The VWMA calculation process: +/// 1. Multiply price by volume for each period +/// 2. Sum (price * volume) over the period +/// 3. Sum volume over the period +/// 4. Divide sums to get weighted average +/// +/// Key characteristics: +/// - Volume-sensitive average +/// - Trend indicator +/// - Support/resistance levels +/// - Price momentum +/// - Volume emphasis +/// +/// Formula: +/// VWMA = ฮฃ(Price * Volume) / ฮฃVolume +/// where sums are taken over the specified period +/// +/// Market Applications: +/// - Trend identification +/// - Support/resistance levels +/// - Volume analysis +/// - Price momentum +/// - Trading signals +/// +/// Note: More responsive to high-volume price movements +/// + +[SkipLocalsInit] +public sealed class Vwma : AbstractBase +{ + private readonly CircularBuffer _priceVolume; + private readonly CircularBuffer _volume; + private const int DefaultPeriod = 20; + + /// The number of periods for VWMA calculation (default 20). + /// Thrown when period is less than 1. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vwma(int period = DefaultPeriod) + { + if (period < 1) + throw new ArgumentOutOfRangeException(nameof(period)); + + _priceVolume = new(period); + _volume = new(period); + WarmupPeriod = period; + Name = $"VWMA({period})"; + } + + /// The data source object that publishes updates. + /// The number of periods for VWMA calculation. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vwma(object source, int period = DefaultPeriod) : 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++; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + protected override double Calculation() + { + ManageState(BarInput.IsNew); + + // Calculate and store price * volume + double priceVolume = BarInput.Close * BarInput.Volume; + _priceVolume.Add(priceVolume, BarInput.IsNew); + _volume.Add(BarInput.Volume, BarInput.IsNew); + + // Calculate sums + double sumPriceVolume = _priceVolume.Sum(); + double sumVolume = _volume.Sum(); + + // Calculate VWMA + return sumVolume > 0 ? sumPriceVolume / sumVolume : BarInput.Close; + } +} diff --git a/lib/volume/_list.md b/lib/volume/_list.md index 8fdb2f14..dce6b41d 100644 --- a/lib/volume/_list.md +++ b/lib/volume/_list.md @@ -1,5 +1,5 @@ # Volume indicators -Done: 15, Todo: 3 +Done: 19, Todo: 0 โœ”๏ธ ADL - Chaikin Accumulation Distribution Line โœ”๏ธ ADOSC - Chaikin Accumulation Distribution Oscillator @@ -16,7 +16,7 @@ Done: 15, Todo: 3 โœ”๏ธ PVR - Price Volume Rank โœ”๏ธ PVT - Price Volume Trend โœ”๏ธ TVI - Trade Volume Index -VF - Volume Force -VP - Volume Profile -VWAP - Volume Weighted Average Price -VWMA - Volume Weighted Moving Average +โœ”๏ธ VF - Volume Force +โœ”๏ธ VP - Volume Profile +โœ”๏ธ VWAP - Volume Weighted Average Price +โœ”๏ธ VWMA - Volume Weighted Moving Average