pine files

This commit is contained in:
Miha Kralj
2026-01-31 14:05:53 -08:00
parent 51e885a4a6
commit 5ed4b6c0fc
102 changed files with 2883 additions and 593 deletions
+5 -11
View File
@@ -8,19 +8,13 @@ namespace QuanTAlib;
/// DEMA: Double Exponential Moving Average
/// </summary>
/// <remarks>
/// DEMA reduces the lag of traditional EMA by subtracting the lag from the original EMA.
/// Reduces lag by applying double smoothing and subtracting the extra smoothing.
/// More responsive than EMA while maintaining smoothness.
///
/// Calculation:
/// EMA1 = EMA(input)
/// EMA2 = EMA(EMA1)
/// DEMA = 2 * EMA1 - EMA2
///
/// O(1) update:
/// Uses two EMA instances, each with O(1) update complexity.
///
/// IsHot:
/// Becomes true when the second EMA converges (approx. 2x EMA convergence time).
/// Calculation: <c>DEMA = 2×EMA(p) - EMA(EMA(p))</c>.
/// </remarks>
/// <seealso href="Dema.md">Detailed documentation</seealso>
/// <seealso href="dema.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Dema : AbstractBase
{
+7 -22
View File
@@ -4,31 +4,16 @@ using System.Runtime.InteropServices;
namespace QuanTAlib;
/// <summary>
/// Deviation-Scaled Moving Average (DSMA):
/// An adaptive moving average that uses standard deviation to dynamically adjust
/// its smoothing factor. Combines a 2-pole Super Smoother filter for trend estimation
/// with RMS-based deviation scaling for volatility adaptation.
/// DSMA: Deviation-Scaled Moving Average
/// </summary>
/// <remarks>
/// Key characteristics:
/// - Uses Super Smoother (Butterworth) 2-pole IIR filter for trend extraction
/// - RMS (Root Mean Square) of filtered deviations for volatility measurement
/// - Dynamic alpha scaling based on deviation ratio (|filtered| / RMS)
/// - O(1) streaming updates via circular buffer for RMS calculation
/// - Adapts smoothing: faster in trending markets, slower in ranging markets
///
/// Mathematical foundation:
/// 1. Super Smoother: H(z) = c₁(1 + z⁻¹) / (1 - b₁z⁻¹ + a₁²z⁻²)
/// where a₁ = exp(-√2·π/period), b₁ = 2a₁·cos(√2·π/period), c₁ = (1-b₁+a₁²)/2
/// 2. RMS = √(Σ(filt²)/period)
/// 3. alpha = min(scaleFactor · 5/period · |filt|/RMS, 1)
/// 4. DSMA = alpha·price + (1-alpha)·prevDSMA
///
/// Performance:
/// - Update: O(1) with FMA optimizations
/// - Memory: O(period) for RMS buffer
/// - SIMD: Calculate method uses vectorized RMS computation
/// Adaptive MA using 2-pole Super Smoother filter with RMS-based deviation scaling.
/// Faster in trending markets, slower in ranging conditions.
///
/// Calculation: <c>α = scaleFactor×5/period × |filt|/RMS; DSMA = α×P + (1-α)×DSMA_{t-1}</c>.
/// </remarks>
/// <seealso href="Dsma.md">Detailed documentation</seealso>
/// <seealso href="dsma.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Dsma : AbstractBase
{
+5 -15
View File
@@ -9,23 +9,13 @@ namespace QuanTAlib;
/// EMA: Exponential Moving Average
/// </summary>
/// <remarks>
/// EMA applies exponential weighting to data points, giving more weight to recent values.
/// Uses a single state variable for O(1) complexity per update.
/// Applies exponentially decreasing weights to give more importance to recent values.
/// Faster response to price changes than SMA; commonly used for trend identification.
///
/// Calculation:
/// alpha = 2 / (period + 1)
/// EMA_new = EMA_old + alpha * (newest - EMA_old)
///
/// Initialization:
/// Uses a compensator factor to correct early-stage bias (when n < period).
/// Output = EMA_state / (1 - (1-alpha)^n)
///
/// O(1) update:
/// No buffer required, only previous EMA value and compensator state.
///
/// IsHot:
/// Becomes true when n = ln(0.05) / ln(1 - alpha)
/// Calculation: <c>EMA_t = α × Price_t + (1-α) × EMA_{t-1}</c>, where <c>α = 2/(period+1)</c>.
/// </remarks>
/// <seealso href="Ema.md">Detailed documentation</seealso>
/// <seealso href="ema.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Ema : AbstractBase
{
+7 -6
View File
@@ -6,15 +6,16 @@ using System.Runtime.InteropServices;
namespace QuanTAlib;
/// <summary>
/// FRAMA: Ehlers Fractal Adaptive Moving Average
/// FRAMA: Fractal Adaptive Moving Average
/// </summary>
/// <remarks>
/// Classic Traders' Tips FRAMA:
/// - Ranges are computed from High/Low (not from source).
/// - Smoothed price is HL2.
/// - alpha = exp(-4.6 * (D - 1)), clamped to [0.01, 1].
/// - Period forced to even, >= 2.
/// Ehlers' adaptive MA using fractal dimension to compute smoothing factor.
/// Alpha derived from High/Low ranges; smoother in trends, reactive at reversals.
///
/// Calculation: <c>D = ln(N1+N2)-ln(N3) / ln(2); α = exp(-4.6×(D-1))</c>, clamped [0.01,1].
/// </remarks>
/// <seealso href="Frama.md">Detailed documentation</seealso>
/// <seealso href="frama.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Frama : ITValuePublisher, IDisposable
{
+7 -6
View File
@@ -4,15 +4,16 @@ using System.Runtime.InteropServices;
namespace QuanTAlib;
/// <summary>
/// HTIT: Ehlers Hilbert Transform Instantaneous Trend
/// A trend-following indicator that uses the Hilbert Transform to measure the dominant cycle period
/// and compute an instantaneous trendline. It adapts to market cycles to reduce lag while maintaining smoothness.
/// HTIT: Hilbert Transform Instantaneous Trendline
/// </summary>
/// <remarks>
/// Sources:
/// https://github.com/mihakralj/pinescript/blob/main/indicators/trends_IIR/htit.md
/// https://dotnet.stockindicators.dev/indicators/HtTrendline/
/// Ehlers' adaptive trendline using Hilbert Transform cycle measurement.
/// Averages price over the measured dominant cycle period for cycle-adaptive smoothing.
///
/// Key features: homodyne discriminator, period-adaptive averaging window.
/// </remarks>
/// <seealso href="Htit.md">Detailed documentation</seealso>
/// <seealso href="htit.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Htit : AbstractBase
{
+9 -6
View File
@@ -4,13 +4,16 @@ using System.Runtime.InteropServices;
namespace QuanTAlib;
/// <summary>
/// Jurik Moving Average (JMA):
/// - 10-bar SMA of local deviation
/// - 128-sample volatility distribution
/// - middle-65 trimmed mean as volatility reference
/// - Jurik dynamic exponent and 2-pole IIR core
/// - power parameter kept for API compatibility; ignored (matches Pine reference)
/// JMA: Jurik Moving Average
/// </summary>
/// <remarks>
/// Proprietary adaptive filter with minimal lag and overshoot using volatility-based smoothing.
/// Combines 2-pole IIR core with trimmed-mean volatility estimation.
///
/// Key features: phase control [-100,100], adaptive band tracking, dynamic exponent.
/// </remarks>
/// <seealso href="Jma.md">Detailed documentation</seealso>
/// <seealso href="jma.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Jma : AbstractBase
{
+5 -8
View File
@@ -7,16 +7,13 @@ namespace QuanTAlib;
/// KAMA: Kaufman's Adaptive Moving Average
/// </summary>
/// <remarks>
/// KAMA adapts to market volatility by adjusting its smoothing factor based on an Efficiency Ratio (ER).
/// ER is calculated as the ratio of the absolute price change over a period to the sum of absolute price changes (volatility).
/// Adapts smoothing based on efficiency ratio (signal/noise) to reduce whipsaws in ranging markets.
/// Faster in trends, slower during consolidation.
///
/// Formula:
/// ER = Change / Volatility
/// Change = Abs(Price - Price[period])
/// Volatility = Sum(Abs(Price[i] - Price[i-1]), period)
/// SC = (ER * (fast_alpha - slow_alpha) + slow_alpha)^2
/// KAMA = KAMA[prev] + SC * (Price - KAMA[prev])
/// Calculation: <c>ER = |Change|/Volatility; SC = (ER×(αfast-αslow)+αslow)²; KAMA += SC×(P-KAMA)</c>.
/// </remarks>
/// <seealso href="Kama.md">Detailed documentation</seealso>
/// <seealso href="kama.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Kama : AbstractBase
{
+9 -2
View File
@@ -4,9 +4,16 @@ using System.Runtime.InteropServices;
namespace QuanTAlib;
/// <summary>
/// MESA Adaptive Moving Average (MAMA)
/// A trend-following indicator that adapts to the market's phase rate of change.
/// MAMA: MESA Adaptive Moving Average
/// </summary>
/// <remarks>
/// Ehlers' dual-output adaptive filter using Hilbert Transform for cycle measurement.
/// MAMA tracks price closely; FAMA provides smoother confirmation signal.
///
/// Key features: homodyne discriminator, adaptive alpha from phase rate-of-change.
/// </remarks>
/// <seealso href="Mama.md">Detailed documentation</seealso>
/// <seealso href="mama.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Mama : AbstractBase
{
+5 -8
View File
@@ -5,17 +5,14 @@ namespace QuanTAlib;
/// <summary>
/// MGDI: McGinley Dynamic Indicator
/// A moving average that adjusts for shifts in market speed, designed to track the market better than existing indicators.
/// It looks like a moving average line, yet it is a smoothing mechanism for prices that turns out to track far better than any moving average.
/// It minimizes price separation and price hugs to avoid whipsaws.
/// </summary>
/// <remarks>
/// Sources:
/// https://www.investopedia.com/terms/m/mcginley-dynamic.asp
/// https://dotnet.stockindicators.dev/indicators/Dynamic/
/// Formula: MGDI = MGDI[1] + (Price - MGDI[1]) / (k * N * (Price/MGDI[1])^4)
/// Default k = 0.6
/// Self-adjusting MA that tracks price better by adapting to market speed shifts.
/// Uses price-to-MA ratio raised to 4th power for speed adjustment.
///
/// Calculation: <c>MGDI = MGDI_{t-1} + (P - MGDI_{t-1}) / (k×N×(P/MGDI)^4)</c>.
/// </remarks>
/// <seealso href="Mgdi.md">Detailed documentation</seealso>
[SkipLocalsInit]
public sealed class Mgdi : AbstractBase
{
+5 -16
View File
@@ -4,26 +4,15 @@ using System.Runtime.InteropServices;
namespace QuanTAlib;
/// <summary>
/// QEMA: Quad Exponential Moving Average with Progressive Alphas and Zero-Lag Weighting
/// QEMA: Quad Exponential Moving Average
/// </summary>
/// <remarks>
/// QEMA uses four cascaded EMAs with progressively increasing alphas (decreasing responsiveness)
/// and combines them using optimized weights that minimize energy while achieving zero DC lag.
/// Four cascaded EMAs with progressive alphas combined using zero-lag optimized weights.
/// Minimizes energy while achieving zero DC lag through Lagrange optimization.
///
/// Calculation:
/// 1. Base alpha: α₁ = 2 / (period + 1)
/// 2. Progressive alphas: r = (1/α₁)^(1/4), then α₂ = α₁·r, α₃ = α₂·r, α₄ = α₃·r
/// 3. Four cascaded EMAs: EMA1(input), EMA2(EMA1), EMA3(EMA2), EMA4(EMA3)
/// 4. Cumulative lags: L₁ = (1-α₁)/α₁, L₂ = L₁ + (1-α₂)/α₂, etc.
/// 5. Option A weights: Minimize energy subject to Σw=1 and Σw·L=0 (zero DC lag)
/// 6. Output: w₁·EMA1 + w₂·EMA2 + w₃·EMA3 + w₄·EMA4
///
/// O(1) update:
/// Uses four EMA state accumulators, each with O(1) update complexity.
///
/// IsHot:
/// Becomes true when the slowest EMA (stage 1) has converged to within 5% coverage.
/// Key features: progressive alpha ramp (α^(1/4) spacing), bias-corrected EMAs, O(1) streaming.
/// </remarks>
/// <seealso href="Qema.md">Detailed documentation</seealso>
[SkipLocalsInit]
public sealed class Qema : AbstractBase
{
+4 -18
View File
@@ -9,26 +9,12 @@ namespace QuanTAlib;
/// REMA: Regularized Exponential Moving Average
/// </summary>
/// <remarks>
/// REMA combines exponential smoothing with a regularization term that penalizes
/// deviations from the previous trend direction. This produces a smoother output
/// than standard EMA while maintaining responsiveness to genuine price changes.
/// Combines EMA smoothing with regularization term penalizing trend direction changes.
/// Lambda controls blend: 0 = pure momentum, 1 = standard EMA.
///
/// Calculation:
/// alpha = 2 / (period + 1)
/// ema_component = alpha * (source - rema) + rema
/// reg_component = rema + (rema - prev_rema) // momentum continuation
/// REMA = lambda * (ema_component - reg_component) + reg_component
///
/// Parameters:
/// - period: Controls the EMA decay rate (alpha = 2/(period+1))
/// - lambda: Regularization strength (0 = max regularization, 1 = standard EMA)
///
/// O(1) update:
/// Only requires previous REMA and prev_prev_REMA values.
///
/// IsHot:
/// Becomes true after sufficient warmup similar to EMA.
/// Calculation: <c>REMA = λ×(EMA_comp - REG_comp) + REG_comp</c>.
/// </remarks>
/// <seealso href="Rema.md">Detailed documentation</seealso>
[SkipLocalsInit]
public sealed class Rema : AbstractBase
{
+6 -9
View File
@@ -3,19 +3,16 @@ using System.Runtime.CompilerServices;
namespace QuanTAlib;
/// <summary>
/// RMA: Running Moving Average (also known as Wilder's Moving Average or SMMA)
/// RMA: Running Moving Average (Wilder's Moving Average)
/// </summary>
/// <remarks>
/// RMA is an Exponential Moving Average (EMA) with a different smoothing factor.
/// While EMA uses alpha = 2 / (period + 1), RMA uses alpha = 1 / period.
/// EMA variant using α=1/period for smoother, slower response than standard EMA.
/// Commonly used in ATR and RSI calculations per Wilder's original methodology.
///
/// Calculation:
/// alpha = 1 / period
/// RMA_new = RMA_old + alpha * (newest - RMA_old)
///
/// This implementation wraps the EMA implementation to ensure identical behavior and performance,
/// utilizing the same O(1) update complexity and zero-allocation architecture.
/// Calculation: <c>RMA_t = α×Price + (1-α)×RMA_{t-1}</c>, where <c>α = 1/period</c>.
/// </remarks>
/// <seealso href="Rma.md">Detailed documentation</seealso>
/// <seealso href="rma.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Rma : AbstractBase
{
+5 -14
View File
@@ -7,22 +7,13 @@ namespace QuanTAlib;
/// T3: Tillson T3 Moving Average
/// </summary>
/// <remarks>
/// T3 works by running price data through a series of six EMAs, then combining the outputs
/// of these EMAs using carefully calculated weights.
/// Six cascaded EMAs with weighted combination for ultra-smooth trend following.
/// The volume factor controls overshooting behavior; lower values reduce lag.
///
/// Formula:
/// T3 = c1*e6 + c2*e5 + c3*e4 + c4*e3
///
/// Where:
/// e1..e6 are cascaded EMAs
/// c1 = -v^3
/// c2 = 3(v^2 + v^3)
/// c3 = -3(2v^2 + v + v^3)
/// c4 = 1 + 3v + 3v^2 + v^3
///
/// v is volume factor (default 0.7)
/// alpha = 2 / (period + 1)
/// Calculation: <c>T3 = c1×e6 + c2×e5 + c3×e4 + c4×e3</c> (six EMAs with polynomial weights).
/// </remarks>
/// <seealso href="T3.md">Detailed documentation</seealso>
/// <seealso href="t3.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class T3 : AbstractBase
{
+5 -14
View File
@@ -7,22 +7,13 @@ namespace QuanTAlib;
/// TEMA: Triple Exponential Moving Average
/// </summary>
/// <remarks>
/// TEMA uses triple smoothing to reduce lag even further than DEMA.
/// Uses triple smoothing to further reduce lag beyond DEMA.
/// Excellent for fast trend identification with minimal overshoot.
///
/// Calculation:
/// EMA1 = EMA(input)
/// EMA2 = EMA(EMA1)
/// EMA3 = EMA(EMA2)
/// TEMA = 3 * EMA1 - 3 * EMA2 + EMA3
///
/// O(1) update:
/// Uses three EMA instances, each with O(1) update complexity.
///
/// IsHot:
/// Becomes true when the TEMA step response converges to within 5% error.
/// This happens when the third EMA's error factor drops below ~9% (approx 2.43/alpha steps),
/// which is faster than the standard EMA convergence (3/alpha steps).
/// Calculation: <c>TEMA = 3×EMA1 - 3×EMA2 + EMA3</c> (cascaded EMAs).
/// </remarks>
/// <seealso href="Tema.md">Detailed documentation</seealso>
/// <seealso href="tema.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Tema : AbstractBase
{
+4 -12
View File
@@ -7,20 +7,12 @@ namespace QuanTAlib;
/// VAMA: Volatility Adjusted Moving Average
/// </summary>
/// <remarks>
/// VAMA dynamically adjusts its smoothing period based on the ratio of long-term
/// to short-term volatility (measured via ATR). During low volatility periods,
/// the effective period increases for smoother output; during high volatility,
/// it decreases for faster response.
/// Adaptive MA that adjusts period based on long/short ATR volatility ratio.
/// Higher volatility → shorter period (faster); lower volatility → longer period (smoother).
///
/// Calculation:
/// 1. Short ATR = RMA(TR, short_period) with bias compensation
/// 2. Long ATR = RMA(TR, long_period) with bias compensation
/// 3. Volatility Ratio = Long_ATR / Short_ATR (clamped to avoid division by zero)
/// 4. Adjusted Length = base_length * volatility_ratio, clamped to [min_length, max_length]
/// 5. VAMA = SMA(source, adjusted_length)
///
/// O(1) ATR updates via RMA; O(adjusted_length) for SMA over the buffer.
/// Calculation: <c>length = baseLength × (LongATR/ShortATR)</c>, clamped to [min, max].
/// </remarks>
/// <seealso href="Vama.md">Detailed documentation</seealso>
[SkipLocalsInit]
public sealed class Vama : AbstractBase
{
+5 -14
View File
@@ -7,22 +7,13 @@ namespace QuanTAlib;
/// VIDYA: Variable Index Dynamic Average
/// </summary>
/// <remarks>
/// VIDYA is an adaptive moving average developed by Tushar Chande.
/// It adjusts the smoothing constant of an Exponential Moving Average (EMA) based on a volatility index.
/// The volatility index used is the Chande Momentum Oscillator (CMO).
/// Tushar Chande's adaptive MA using CMO as volatility index to modulate smoothing.
/// Flat in choppy markets, responsive in trending conditions.
///
/// Formula:
/// alpha = 2 / (period + 1)
/// CMO = (Sum(Up) - Sum(Down)) / (Sum(Up) + Sum(Down))
/// VI = Abs(CMO)
/// DynamicAlpha = alpha * VI
/// VIDYA = DynamicAlpha * Price + (1 - DynamicAlpha) * VIDYA_prev
///
/// Key characteristics:
/// - Adapts to market volatility
/// - Flattens in ranging markets (low volatility)
/// - Reacts quickly in trending markets (high volatility)
/// Calculation: <c>VI = |CMO|; α' = α×VI; VIDYA = α'×P + (1-α')×VIDYA_{t-1}</c>.
/// </remarks>
/// <seealso href="Vidya.md">Detailed documentation</seealso>
/// <seealso href="vidya.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Vidya : AbstractBase
{
+4 -8
View File
@@ -7,16 +7,12 @@ namespace QuanTAlib;
/// YZVAMA: Yang-Zhang Volatility Adjusted Moving Average
/// </summary>
/// <remarks>
/// YZVAMA adjusts the SMA length based on the percentile rank of short-term
/// Yang-Zhang volatility (YZV) observed over a rolling lookback window.
/// Adaptive MA using Yang-Zhang volatility percentile rank to adjust SMA length.
/// Higher volatility → shorter period; uses OHLC log returns for variance.
///
/// Calculation (per bar):
/// 1) Compute Yang-Zhang daily variance proxy from OHLC (log returns).
/// 2) Smooth variance with bias-compensated RMA for short and long periods (sqrt -> volatility).
/// 3) Compute percentile rank of current short YZV within the lookback window.
/// 4) Map percentile to adjusted SMA length: higher volatility -> shorter length.
/// 5) Output SMA(source, adjusted_length) over a circular buffer.
/// Calculation: <c>length = max - percentile×(max-min)</c>.
/// </remarks>
/// <seealso href="Yzvama.md">Detailed documentation</seealso>
[SkipLocalsInit]
public sealed class Yzvama : AbstractBase
{
+6 -3
View File
@@ -9,10 +9,13 @@ namespace QuanTAlib;
/// ZLEMA: Zero-Lag Exponential Moving Average
/// </summary>
/// <remarks>
/// ZLEMA reduces EMA lag by filtering a zero-lag signal:
/// signal = 2 * price - price_lag
/// zlema = EMA(signal)
/// Reduces lag by applying EMA to a detrended signal that subtracts lagged values.
/// Offers faster trend detection while maintaining smoothness.
///
/// Calculation: <c>ZLEMA = EMA(2×Price - Price[lag])</c>, where <c>lag = (period-1)/2</c>.
/// </remarks>
/// <seealso href="Zlema.md">Detailed documentation</seealso>
/// <seealso href="zlema.pine">Reference Pine Script implementation</seealso>
[SkipLocalsInit]
public sealed class Zlema : AbstractBase
{