Category Trend  Published on 18/04/2024

All Moving Averages

Description

 

All Moving Averages (all chat Gpt formula)

Concept:

Introducing "All Moving Averages," an innovative and community-driven indicator designed for algorithmic trading enthusiasts on the cAlgo platform. This remarkable tool incorporates over 50 different types of moving averages, ranging from the classic to the more sophisticated, each meticulously programmed to explore various market aspects.

Key Features:

  • Impressive Variety: Access over 50 different moving averages, including simple, exponential, weighted, Hull, and many others, offering a wealth of choices for traders at all levels.
  • Flexible Sources: Leverage all possible data sources for your calculations, including close, typical, median prices, and more, allowing precise adaptation to your analytical needs.
  • Formula Access: Each moving average is built from a specific formula available to users, facilitating understanding and customization according to trading strategies.

Community and Collaboration: This project is crafted with a community spirit in mind. The goal is not only to provide a powerful and flexible tool but also to bring together a community of traders who contribute to enriching the moving average library and continually improving the code. Whether you're a curious beginner or a seasoned professional, your participation can help turn this tool into an even more invaluable resource for everyone.

Have fun, and for any collaboration, contact me !!!

On telegram : https://t.me/nimi012 (direct messaging)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None, IsOverlay = true)]
    public class MovingAverargeAll : Indicator
    {
        [Parameter("Bars Type", DefaultValue = "Close", Group = "Base Setting")]
        public EnumBarsType BarsType { get; set; }
        public enum EnumBarsType
        {
            ClosePrices,
            HighPrices,
            LowPrices,
            OpenPrices,
            MedianPrices,
            TypicalPrices,
            WeightedPrices,
        }

        [Parameter("MA Periods", DefaultValue = 34, MinValue = 1, Group = "Base Setting")]
        public int Period { get; set; }

        [Parameter("Bars Type", DefaultValue = "Close", Group = "Base Setting")]
        public EnumMaType MaType { get; set; }
        public enum EnumMaType
        {
            Alexander_Moving_Average_xX_Output_Xx,
            Anchored_Momentum_Moving_Average_xX_Output_Xx,
            Arnaud_Legoux_Moving_Average_xX_Output_Xx,
            Barycentric_Moving_Average,
            Chande_Moving_Average,
            Digital_Filter_Moving_Average_xX_Output_Xx,
            Double_Exponential_Moving_Average,
            Dynamic_Moving_Average,
            Elastic_Volume_Weighted_Moving_Average,
            End_Point_Moving_Average,
            Equilibrium_Moving_Average,
            Exponential_Adaptive_Moving_Average,
            Exponential_Hull_Moving_Average,
            Exponential_Moving_Average,
            Fractal_Adaptive_Moving_Average,
            Gann_Moving_Average,
            Gaussian_Moving_Average_xX_Output_Xx,
            Geometric_Moving_Average,
            Gravity_Moving_Average,
            Harmonic_Moving_Average,
            Hull_Moving_Average,
            Hull_of_Averages_Moving_Average,
            Infinite_Impulse_Response_xX_Output_Xx,
            Jurik_Moving_Average_xX_Output_Xx,
            Kaufman_s_Adaptive_Moving_Average_xX_Output_Xx,
            Laguerre_Moving_Average_xX_Output_Xx,
            Least_Squares_Moving_Average,
            Linear_Weighted_Moving_Average,
            McGinley_Dynamic_xX_Output_Xx,
            Modified_Dietz_Method_Moving_Average,
            Moving_Average_with_Predictive_Edge,
            Predictive_Moving_Average,
            Price_Action_Moving_Average_xX_Output_Xx,
            Quadratic_Moving_Average,
            Quantum_Moving_Average_xX_Output_Xx,
            Recursive_Moving_Average,
            Risk_Adjusted_Moving_Average_xX_Output_Xx,
            Simple_Moving_Average,
            Sine_Weighted_Moving_Average,
            Sinewave_Moving_Average_xX_Output_Xx,
            Smoothed_Moving_Average,
            T3_Moving_Average_xX_Output_Xx,
            Triangulare,
            Triple_Exponential_Moving_Average,
            Variable_Moving_Average,
            Variable_Period_Moving_Average,
            Variable_Window_Moving_Average_xX_Output_Xx,
            Volume_Adjusted_Moving_Average,
            Volume_Weighted_Moving_Average,
            Vortex_Moving_Average,
            Welles_Wilder_s_Moving_Average,
            Zero_Lag_Exponential_Moving_Average,
            Zero_Lag_Moving_Average,

        }
        [Parameter("Volatility Factor", DefaultValue = 0.1, Group = "Alexander Moving Average")]
        public double VolatilityFactor { get; set; }

        [Parameter("Offset", DefaultValue = 0.85, Group = "Arnaud Legoux Moving Average, ALMA ")]
        public double Offset { get; set; }
        [Parameter("Sigma", DefaultValue = 6, Group = "Arnaud Legoux Moving Average, ALMA ")]
        public double Sigma { get; set; }

        [Parameter("Alpha", DefaultValue = 0.15, MinValue = 0, Group = "Digital Filter Moving Average")]
        public double Alpha { get; set; }
        [Parameter("Min Period", DefaultValue = 5, Group = "Digital Filter Moving Average")]
        public int MinPeriod { get; set; }
        [Parameter("Max Period", DefaultValue = 30, Group = "Digital Filter Moving Average")]
        public int MaxPeriod { get; set; }

        [Parameter("Sigma", DefaultValue = 3.0, Group = "Gaussian Moving Average")]
        public double SigmaGaussian { get; set; }

        [Parameter("Phase", DefaultValue = 0, MinValue = -100, MaxValue = 100, Group = "Jurik Moving Average, JMA")]
        public double Phase { get; set; }

        [Parameter("Efficiency Ratio Length", DefaultValue = 10, Group = "Kaufman's Adaptive Moving Average, KAMA ")]
        public int EfficiencyRatioLength { get; set; }
        [Parameter("Fastest EMA Constant", DefaultValue = 2, Group = "Kaufman's Adaptive Moving Average, KAMA ")]
        public int FastestEMA { get; set; }
        [Parameter("Slowest EMA Constant", DefaultValue = 30, Group = "Kaufman's Adaptive Moving Average, KAMA ")]
        public int SlowestEMA { get; set; }

        [Parameter("Factor", DefaultValue = 0.6, Group = "McGinley Dynamic")]
        public double Factor { get; set; }

        [Parameter("Adjustment Factor", DefaultValue = 0, Group = "Price Action Moving Average")]
        public double AdjustmentFactor { get; set; }

        [Parameter("Amplitude", DefaultValue = 0.0001, MinValue = 0, MaxValue = 1, Step = 0.01, Group = "Sinewave Moving Average")]
        public double Amplitude { get; set; }

        [Parameter("Volume Factor", DefaultValue = 0.7, Group = "T3 Moving Average")]
        public double VolumeFactor { get; set; }
        [Parameter("Min Threshold ", DefaultValue = 0.0, Step = 0.001, MinValue = 0, Group = "T3 Moving Average")]
        public double minthr { get; set; }
        [Parameter("Start Bar ", DefaultValue = 1, MinValue = 0, Group = "T3 Moving Average")]
        public int startbar { get; set; }
        [Parameter("Stop Bar ", DefaultValue = 2, MinValue = 0, Group = "T3 Moving Average")]
        public int stopbar { get; set; }


        [Parameter("Gamma", DefaultValue = 0.5, MinValue = 0, MaxValue = 1, Group = "Laguerre Moving Averagee")]
        public double Gamma { get; set; }

        [Parameter("Fast EMA Period", DefaultValue = 5, Group = "Quantum Moving Average")]
        public int FastPeriodQuantum { get; set; }

        [Parameter("Slow EMA Period", DefaultValue = 21, Group = "Quantum Moving Average")]
        public int SlowPeriodQuantum { get; set; }

        [Parameter("LookbackPeriod", DefaultValue = 21, Group = "Anchored Momentum Moving Average")]
        public int LookbackPeriod { get; set; }

        [Parameter("Risk Adjustment Factor", DefaultValue = 2, Group = "Risk-Adjusted Moving Average")]
        public double RiskAdjustmentFactor { get; set; }

        [Parameter("Minimum Period", DefaultValue = 5, Group = "Variable Window Moving Average")]
        public int MinPeriodVariableWindow { get; set; }

        [Parameter("Maximum Period", DefaultValue = 30, Group = "Variable Window Moving Average")]
        public int MaxPeriodVariableWindow { get; set; }

        [Parameter("Alpha", DefaultValue = 0.1, MinValue = 0, MaxValue = 1, Step = 0.01, Group = "Infinite Impulse Response")]
        public double AlphaIIR { get; set; }



        [Output("Result", LineColor = "Aqua")]
        public IndicatorDataSeries Result { get; set; }



        // selected sources
        private DataSeries source;
        //Hull Ma series
        private IndicatorDataSeries hullSeries;
        //VMa series
        private double _k;
        private IndicatorDataSeries _iSeries;
        private IndicatorDataSeries _mdiSeries;
        private IndicatorDataSeries _mdmSeries;
        private IndicatorDataSeries _pdiSeries;
        private IndicatorDataSeries _pdmSeries;
        //Jurik
        private readonly double[] _list = new double[128];
        private readonly double[] _ring1 = new double[128];
        private readonly double[] _ring2 = new double[11];
        private readonly double[] _buffer = new double[62];
        private IndicatorDataSeries _jmaSeries;
        private IndicatorDataSeries _sourceSeries;
        private IndicatorDataSeries _series1;
        private IndicatorDataSeries _series2;
        private int _limitValue;
        private int _startValue;
        private int _loopIndex;
        private int _loopCriteria;
        private bool _initFlag;
        private double _phaseParam;
        private double _logParam;
        private double _sqrtParam;
        private double _lengthDivider;
        private double _lowDValue;
        private int _counterA;
        private double _dValue;
        private double _jmaValue;
        private int _counterB;
        private int _highLimit;
        private int _cycleLimit;
        private double _cycleDelta;
        //T3
        private IndicatorDataSeries e1, e2, e3, e4, e5, e6;
        //Triangulaire
        private IndicatorDataSeries firstSMA;
        //Laguerre
        private double[] laguerreArray = new double[4];
        //Elastic Volume Weighted Moving Average
        private IndicatorDataSeries cumulativeVP;
        private IndicatorDataSeries cumulativeVolume;
        //Quantum Moving Average   
        private IndicatorDataSeries fastEMAQuantum;
        private IndicatorDataSeries slowEMAQuantum;
        //Equilibrium Moving Average
        private IndicatorDataSeries volatilityEquilibrium;

        protected override void Initialize()
        {
            // selected sources
            source = BarsType == EnumBarsType.ClosePrices ? Bars.ClosePrices
                    : BarsType == EnumBarsType.HighPrices ? Bars.HighPrices
                    : BarsType == EnumBarsType.LowPrices ? Bars.LowPrices
                    : BarsType == EnumBarsType.OpenPrices ? Bars.OpenPrices
                    : BarsType == EnumBarsType.MedianPrices ? Bars.MedianPrices
                    : Bars.WeightedPrices;
            //Hull Ma series
            hullSeries = CreateDataSeries();
            //VMa series
            _pdmSeries = CreateDataSeries();
            _mdmSeries = CreateDataSeries();
            _pdiSeries = CreateDataSeries();
            _mdiSeries = CreateDataSeries();
            _iSeries = CreateDataSeries();
            _k = 1.0 / Period;
            //Jurik
            _jmaSeries = CreateDataSeries();
            _sourceSeries = CreateDataSeries();
            _series1 = CreateDataSeries();
            _series2 = CreateDataSeries();
            _limitValue = _list.Length / 2 - 1;
            _startValue = _limitValue + 1;
            for (int i = 0; i <= _limitValue; i++)
                _list[i] = -1000000;
            for (int i = _startValue; i < _list.Length; i++)
                _list[i] = 1000000;
            _initFlag = true;
            double lengthParam = (Period <= 1) ? 0.0000000001 : (Period - 1) / 2.0;
            _phaseParam = Phase / 100.0 + 1.5;
            _logParam = Math.Log(Math.Sqrt(lengthParam)) / Math.Log(2.0);
            if (_logParam + 2.0 < 0)
                _logParam = 0;
            else _logParam += 2.0;

            _sqrtParam = Math.Sqrt(lengthParam) * _logParam;
            lengthParam *= 0.9;
            _lengthDivider = lengthParam / (lengthParam + 2.0);
            //T3
            e1 = CreateDataSeries();
            e2 = CreateDataSeries();
            e3 = CreateDataSeries();
            e4 = CreateDataSeries();
            e5 = CreateDataSeries();
            e6 = CreateDataSeries();
            //Triangulaire
            firstSMA = CreateDataSeries();
            //Elastic Volume Weighted Moving Average
            cumulativeVP = CreateDataSeries();
            cumulativeVolume = CreateDataSeries();
            //Quantum Moving Average   
            fastEMAQuantum = CreateDataSeries();
            slowEMAQuantum = CreateDataSeries();
            //Equilibrium Moving Average
            volatilityEquilibrium = CreateDataSeries();
        }
        public override void Calculate(int index)
        {
            switch (MaType)
            {
                case EnumMaType.Simple_Moving_Average:
                    Result[index] = CalculateSMA(index, source, Period);
                    break;
                case EnumMaType.Double_Exponential_Moving_Average:
                    Result[index] = CalculateDEMA(index, source);
                    break;
                case EnumMaType.Hull_Moving_Average:
                    Result[index] = CalculateHMA(index, source, Period);
                    break;
                case EnumMaType.Kaufman_s_Adaptive_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateKAMA(index, source);
                    break;
                case EnumMaType.Linear_Weighted_Moving_Average:
                    Result[index] = CalculateLWMA(index, source, Period);
                    break;
                case EnumMaType.Exponential_Moving_Average:
                    Result[index] = CalculateEMA(index, source[index]);
                    break;
                case EnumMaType.Smoothed_Moving_Average:
                    Result[index] = CalculateSMMA(index, source, Period);
                    break;
                case EnumMaType.Triple_Exponential_Moving_Average:
                    Result[index] = CalculateTEMA(index, source);
                    break;
                case EnumMaType.Variable_Moving_Average:
                    Result[index] = CalculateVMA(index);
                    break;
                case EnumMaType.Volume_Weighted_Moving_Average:
                    Result[index] = CalculateVWMA(index);
                    break;
                case EnumMaType.Arnaud_Legoux_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateALMA(index);
                    break;
                case EnumMaType.Fractal_Adaptive_Moving_Average:
                    Result[index] = CalculateFRAMA(index);
                    break;
                case EnumMaType.Sine_Weighted_Moving_Average:
                    Result[index] = CalculateSWMA(index);
                    break;
                case EnumMaType.Zero_Lag_Moving_Average:
                    Result[index] = CalculateZLMA(index);
                    break;
                case EnumMaType.Jurik_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateJurik(index);
                    break;
                case EnumMaType.T3_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateT3(index);
                    break;
                case EnumMaType.McGinley_Dynamic_xX_Output_Xx:
                    Result[index] = CalculateMcGinleyDynamic(index);
                    break;
                case EnumMaType.Welles_Wilder_s_Moving_Average:
                    Result[index] = CalculateWildersMA(source, index, Period);
                    break;
                case EnumMaType.Alexander_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateAMA(index);
                    break;
                case EnumMaType.Chande_Moving_Average:
                    Result[index] = CalculateChandeMA(index);
                    break;
                case EnumMaType.End_Point_Moving_Average:
                    Result[index] = CalculateEPMA(index);
                    break;
                case EnumMaType.Triangulare:
                    Result[index] = CalculateTMA(source, index, Period);
                    break;
                case EnumMaType.Sinewave_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateSiWMA(index, Period);
                    break;
                case EnumMaType.Geometric_Moving_Average:
                    Result[index] = CalculateGMA(index);
                    break;
                case EnumMaType.Harmonic_Moving_Average:
                    Result[index] = CalculateHaMA(index);
                    break;
                case EnumMaType.Quadratic_Moving_Average:
                    Result[index] = CalculateQMA(index);
                    break;
                case EnumMaType.Least_Squares_Moving_Average:
                    Result[index] = CalculateLSMA(index);
                    break;
                case EnumMaType.Price_Action_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculatePAMA(index);
                    break;
                case EnumMaType.Barycentric_Moving_Average:
                    Result[index] = CalculateBMA(index);
                    break;
                case EnumMaType.Digital_Filter_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateDFMA(index);
                    break;
                case EnumMaType.Gann_Moving_Average:
                    Result[index] = CalculateGannMA(index);
                    break;
                case EnumMaType.Variable_Period_Moving_Average:
                    Result[index] = CalculateVPMA(index);
                    break;
                case EnumMaType.Gaussian_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateGaussianMA(index);
                    break;
                case EnumMaType.Zero_Lag_Exponential_Moving_Average:
                    Result[index] = CalculateZLEMA(index);
                    break;
                case EnumMaType.Laguerre_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateLaguerreMA(index, source[index]);
                    break;
                case EnumMaType.Hull_of_Averages_Moving_Average:
                    Result[index] = CalculateHOAMA(index);
                    break;
                case EnumMaType.Recursive_Moving_Average:
                    Result[index] = CalculateRMA(index);
                    break;
                case EnumMaType.Elastic_Volume_Weighted_Moving_Average:
                    Result[index] = CalculateElasticVWMA(index);
                    break;
                case EnumMaType.Predictive_Moving_Average:
                    Result[index] = CalculatePredictiveMA(index);
                    break;
                case EnumMaType.Quantum_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateQuantumMA(index);
                    break;
                case EnumMaType.Anchored_Momentum_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateAMMA(index);
                    break;
                case EnumMaType.Equilibrium_Moving_Average:
                    Result[index] = CalculateEMAq(index);
                    break;
                case EnumMaType.Gravity_Moving_Average:
                    Result[index] = CalculateGravityMA(index);
                    break;
                case EnumMaType.Vortex_Moving_Average:
                    Result[index] = CalculateVortexEMA(index);
                    break;
                case EnumMaType.Dynamic_Moving_Average:
                    Result[index] = CalculateDynamicMA(index);
                    break;
                case EnumMaType.Volume_Adjusted_Moving_Average:
                    Result[index] = CalculateVAMA(index);
                    break;
                case EnumMaType.Modified_Dietz_Method_Moving_Average:
                    Result[index] = CalculateMDMA(index);
                    break;
                case EnumMaType.Risk_Adjusted_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateRiMA(index);
                    break;
                case EnumMaType.Exponential_Hull_Moving_Average:
                    Result[index] = CalculateExpoHullEHMA(index);
                    break;
                case EnumMaType.Moving_Average_with_Predictive_Edge:
                    Result[index] = CalculatePredictiveMAPE(index);
                    break;
                case EnumMaType.Exponential_Adaptive_Moving_Average:
                    Result[index] = CalculateExAdEAMA(index, Period);
                    break;
                case EnumMaType.Variable_Window_Moving_Average_xX_Output_Xx:
                    Result[index] = CalculateVWindowMA(index);
                    break;
                case EnumMaType.Infinite_Impulse_Response_xX_Output_Xx:
                    Result[index] = CalculateIIRMA(index);
                    break;




            }
        }

        private double CalculateIIRMA(int index)
        {
            if (index == 0)
                return source[index];  // Initialize the first value

            // Calculate the IIR Moving Average
            return AlphaIIR * source[index] + (1 - AlphaIIR) * Result[index - 1];
        }

        private double CalculateVWindowMA(int index)
        {
            int period = DetermineWindowPeriod(index);
            double sum = 0;
            int actualPeriod = 0; // This will count the actual number of bars used, which might be less than 'period'

            for (int i = 0; i < period && index - i >= 0; i++)
            {
                sum += source[index - i];
                actualPeriod++;
            }

            return actualPeriod > 0 ? sum / actualPeriod : source[index];
        }

        private int DetermineWindowPeriod(int index)
        {
            // Example volatility-based dynamic period adjustment
            double volatility = CalculateWindowVolatility(index);
            // Normalize and scale the volatility to fit within the MinPeriod and MaxPeriod
            int dynamicPeriod = (int)(MinPeriodVariableWindow + (MaxPeriodVariableWindow - MinPeriodVariableWindow) * volatility);

            return Math.Max(MinPeriod, Math.Min(MaxPeriod, dynamicPeriod));
        }

        private double CalculateWindowVolatility(int index)
        {
            if (index < 14) return 0; // Not enough data to calculate a meaningful volatility

            double sumOfChanges = 0;
            for (int i = 1; i <= 14; i++) // Using a fixed window here to calculate volatility
            {
                sumOfChanges += Math.Abs(source[index - i] - source[index - i - 1]);
            }
            return sumOfChanges / 14;
        }

        private double CalculateExAdEAMA(int index, int period)
        {
            if (index < period)
            {
                return source[index]; // Not enough data to calculate EAMA
            }

            double alpha = CalculateExAdDynamicAlpha(index, period);
            double previousEAMA = index == 0 ? source[index] : Result[index - 1];
            return alpha * source[index] + (1 - alpha) * previousEAMA;
        }

        private double CalculateExAdDynamicAlpha(int index, int period)
        {
            double volatility = CalculateExAdVolatility(index, period);
            double scale = 10; // Scaling factor to adjust sensitivity
            double normalizedVolatility = Math.Exp(-scale * volatility); // Exponential decay to increase sensitivity
            double minAlpha = 0.01; // Minimum alpha to ensure some level of smoothing
            double maxAlpha = 0.2;  // Maximum alpha to prevent excessive reactivity
            return Math.Min(maxAlpha, Math.Max(minAlpha, normalizedVolatility));
        }

        private double CalculateExAdVolatility(int index, int period)
        {
            double mean = 0;
            double sumSquaredDiffs = 0;
            for (int i = 0; i < period; i++)
            {
                mean += source[index - i];
            }
            mean /= period;
            for (int i = 0; i < period; i++)
            {
                double diff = source[index - i] - mean;
                sumSquaredDiffs += diff * diff;
            }
            return Math.Sqrt(sumSquaredDiffs / period);
        }

        private double CalculatePredictiveMAPE(int index)
        {
            if (index < 2)
            {
                return source[index]; // Not enough data to calculate

            }

            double rateOfChange = source[index] - source[index - 1];
            double secondDerivative = rateOfChange - (source[index - 1] - source[index - 2]);

            double ema = CalculatePredictiveEMA(index, Period);
            double predictiveEdge = ema + (secondDerivative * 0.5); // Adjust the multiplier as needed

            return predictiveEdge;
        }

        private double CalculatePredictiveEMA(int index, int period)
        {
            double alpha = 2.0 / (period + 1);
            double previousEMA = index == 0 ? source[index] : Result[index - 1];
            return source[index] * alpha + previousEMA * (1 - alpha);
        }

        private double CalculateExpoHullEHMA(int index)
        {
            int halfLength = Period / 2;
            double sqrtLength = Math.Sqrt(Period);

            double emaHalf = CalculateExpoHullEMA(index, halfLength);
            double emaFull = CalculateExpoHullEMA(index, Period);
            double emaDiff = 2 * emaHalf - emaFull;

            return CalculateExpoHullEMA(index, (int)sqrtLength, emaDiff);
        }

        private double CalculateExpoHullEMA(int index, int length, double? emaDiff = null)
        {
            double alpha = 2.0 / (length + 1);
            double previousEMA = index == 0 ? (emaDiff ?? source[index]) : Result[index - 1];
            double price = emaDiff ?? source[index];

            return alpha * price + (1 - alpha) * previousEMA;
        }


        private double CalculateRiMA(int index)
        {
            double mean = CalculateRiAdSMA(index);
            double volatility = CalculateRiAdVolatility(index);

            // Adjust the SMA by reducing the effect of price changes proportional to increased volatility
            double adjustmentFactor = 1 / (1 + RiskAdjustmentFactor * volatility);
            double adjustedSMA = mean * adjustmentFactor;

            return adjustedSMA;
        }

        private double CalculateRiAdSMA(int index)
        {
            double sum = 0;
            for (int i = 0; i < Period; i++)
            {
                sum += source[index - i];
            }
            return sum / Period;
        }
        private double CalculateRiAdVolatility(int index)
        {
            double mean = CalculateRiAdSMA(index);
            double sumSquaredDiffs = 0;
            for (int i = 0; i < Period; i++)
            {
                double diff = source[index - i] - mean;
                sumSquaredDiffs += diff * diff;
            }
            return Math.Sqrt(sumSquaredDiffs / Period);
        }

        private double CalculateMDMA(int index)
        {
            double weightedSum = 0;  // Sum of weighted prices
            double totalVolume = 0;  // Sum of volumes

            for (int i = 0; i < Period; i++)
            {
                double weight = Bars.TickVolumes[index - i];
                weightedSum += source[index - i] * weight;
                totalVolume += weight;
            }

            return totalVolume != 0 ? weightedSum / totalVolume : source[index];
        }
        private double CalculateVAMA(int index)
        {
            double totalPV = 0;  // Total price * volume
            double totalVolume = 0;  // Total volume

            for (int i = 0; i < Period; i++)
            {
                totalPV += source[index - i] * Bars.TickVolumes[index - i];
                totalVolume += Bars.TickVolumes[index - i];
            }

            return totalVolume != 0 ? totalPV / totalVolume : source[index];
        }
        private double CalculateDynamicMA(int index)
        {
            double volatility = CalculateDynamicVolatility(index, Period);
            int dynamicPeriod = Math.Max(5, (int)(Period / (1 + volatility * 10))); // Adjusting period based on volatility

            return CalculateDynamicSMA(index, dynamicPeriod);
        }

        private double CalculateDynamicVolatility(int index, int period)
        {
            double sumOfChanges = 0;
            for (int i = 1; i < period; i++)
            {
                sumOfChanges += Math.Abs(source[index - i] - source[index - i + 1]);
            }
            return sumOfChanges / period;
        }

        private double CalculateDynamicSMA(int index, int period)
        {
            double sum = 0;
            for (int i = 0; i < period; i++)
            {
                sum += source[index - i];
            }
            return sum / period;
        }

        private double CalculatePlusVI(int index)
        {
            double tr = CalculateVortexTrueRange(index);
            return tr == 0 ? 0 : (Bars.HighPrices[index] - Bars.LowPrices[index - 1]) / tr;
        }

        private double CalculateMinusVI(int index)
        {
            double tr = CalculateVortexTrueRange(index);
            return tr == 0 ? 0 : (Bars.LowPrices[index] - Bars.HighPrices[index - 1]) / tr;
        }

        private double CalculateVortexTrueRange(int index)
        {
            double highLow = Bars.HighPrices[index] - Bars.LowPrices[index];
            double highClose = Math.Abs(Bars.HighPrices[index] - source[index - 1]);
            double lowClose = Math.Abs(Bars.LowPrices[index] - source[index - 1]);
            return Math.Max(highLow, Math.Max(highClose, lowClose));
        }

        private double CalculateDynamicVortexEMAPeriod(int index)
        {
            double plusVI = CalculatePlusVI(index);
            double minusVI = CalculateMinusVI(index);

            double vortexStrength = Math.Abs(plusVI - minusVI);
            return Math.Max(5, Period - (vortexStrength * 10)); // Example adjustment, modify as needed
        }

        private double CalculateVortexEMA(int index)
        {
            if (index < Period)
            {
                return source[index];  // Not enough data
            }
            double period = CalculateDynamicVortexEMAPeriod(index);

            double alpha = 2.0 / (period + 1);
            double previousEMA = index == 0 ? source[index] : Result[index - 1];
            return source[index] * alpha + previousEMA * (1 - alpha);
        }

        private double CalculateGravityMA(int index)
        {
            if (index < Period)
            {
                return source[index];  // Not enough data
            }

            double weightedSum = 0;
            double weightTotal = 0;
            for (int i = 0; i < Period; i++)
            {
                double weight = CalculateGravityMAWeight(index - i);
                weightedSum += source[index - i] * weight;
                weightTotal += weight;
            }

            return weightTotal > 0 ? weightedSum / weightTotal : source[index];
        }

        private double CalculateGravityMAWeight(int index)
        {
            double volatility = CalculateGravityMAVolatility(index);
            return 1 + volatility; // Base weight plus additional weight by volatility
        }

        private double CalculateGravityMAVolatility(int index)
        {
            // Simple measure of volatility as the absolute change from the previous close
            return index > 0 ? Math.Abs(source[index] - source[index - 1]) : 0;
        }

        private double CalculateEMAq(int index)
        {
            if (index < Period)
            {
                return source[index];  // Not enough data

            }

            volatilityEquilibrium[index] = CalculateEMAqVolatility(index, Period);

            double alpha = 2.0 / (Period * (1 + volatilityEquilibrium[index]));
            double previousEMAq = index == 0 ? source[index] : Result[index - 1];
            return alpha * source[index] + (1 - alpha) * previousEMAq;
        }

        private double CalculateEMAqVolatility(int index, int period)
        {
            double sumOfChanges = 0;
            for (int i = 1; i <= period; i++)
            {
                sumOfChanges += Math.Abs(source[index - i] - source[index - i + 1]);
            }
            return sumOfChanges / period;
        }

        private double CalculateAMMA(int index)
        {
            if (index < LookbackPeriod)
            {
                // Not enough data to calculate AMMA
                return source[index];
            }

            double sma = CalculateSMA(index, Period);
            double momentum = CalculateMomentum(index, LookbackPeriod);

            return sma + momentum;
        }

        private double CalculateSMA(int index, int period)
        {
            double sum = 0;
            for (int i = 0; i < period; i++)
            {
                sum += source[index - i];
            }
            return sum / period;
        }

        private double CalculateMomentum(int index, int lookbackPeriod)
        {
            return source[index] - source[index - lookbackPeriod];
        }

        private double CalculateQUANTUMFASTEMA(int index)
        {
            double alpha = 2.0 / (FastPeriodQuantum + 1);
            return source[index] * alpha + fastEMAQuantum[index - 1] * (1 - alpha);
        }

        private double CalculateQUANTUMSLOWEMA(int index)
        {
            double alpha = 2.0 / (SlowPeriodQuantum + 1);
            return source[index] * alpha + slowEMAQuantum[index - 1] * (1 - alpha);
        }

        private double CalculateQuantumMA(int index)
        {

            if (index == 0)
            {
                fastEMAQuantum[index] = source[index];
                slowEMAQuantum[index] = source[index];
                return source[index];

            }

            fastEMAQuantum[index] = CalculateQUANTUMFASTEMA(index);
            slowEMAQuantum[index] = CalculateQUANTUMSLOWEMA(index);

            double volatility = Math.Abs(fastEMAQuantum[index] - slowEMAQuantum[index]);
            double weight = volatility / (Math.Abs(source[index]) + 1); // Adding 1 to prevent division by zero
            return weight * fastEMAQuantum[index] + (1 - weight) * slowEMAQuantum[index];
        }

        private double CalculatePredictiveMA(int index)
        {
            if (index < Period)
            {
                return source[index]; // Not enough data to calculate PMA
            }

            // Adjust the period dynamically based on recent price volatility
            int dynamicPeriod = CalculatePredictiveMADynamicPeriod(index);
            return CalculatePredictiveMASMA(index, dynamicPeriod);
        }

        private int CalculatePredictiveMADynamicPeriod(int index)
        {
            double recentVolatility = CalculatePredictiveMAVolatility(index, Period);
            // Reduce the period when volatility is high to make the MA more responsive
            return Math.Max(5, (int)(Period / (1 + recentVolatility)));
        }

        private double CalculatePredictiveMAVolatility(int index, int period)
        {
            double sumOfChanges = 0;
            for (int i = index - period + 1; i <= index; i++)
            {
                sumOfChanges += Math.Abs(source[i] - source[i - 1]);
            }
            return sumOfChanges / period;
        }

        private double CalculatePredictiveMASMA(int index, int period)
        {
            double sum = 0;
            for (int i = index - period + 1; i <= index; i++)
            {
                sum += source[i];
            }
            return sum / period;
        }
        private double CalculateElasticVWMA(int index)
        {
            if (index == 0)
            {
                cumulativeVP[index] = source[index] * Bars.TickVolumes[index];
                cumulativeVolume[index] = Bars.TickVolumes[index];
                return source[index];
            }

            double alpha = 1.0 / Period;

            cumulativeVP[index] = source[index] * Bars.TickVolumes[index] + (1 - alpha) * cumulativeVP[index - 1];
            cumulativeVolume[index] = Bars.TickVolumes[index] + (1 - alpha) * cumulativeVolume[index - 1];

            return cumulativeVP[index] / cumulativeVolume[index];
        }

        private double CalculateRMA(int index)
        {
            if (index == 0)
            {
                // Initialize the first value of RMA to the first close price
                return source[index];
            }

            // Recursive calculation of the RMA
            double alpha = 1.0 / Period;
            return alpha * source[index] + (1 - alpha) * Result[index - 1];
        }

        private double CalculateHOAMA(int index)
        {
            double wmaShort = CalculateCalculateHOAMAWMA(index, Period / 2);
            double wmaLong = CalculateCalculateHOAMAWMA(index, Period);
            double diffWMA = 2 * wmaShort - wmaLong;
            int sqrtPeriod = (int)Math.Round(Math.Sqrt(Period));
            return CalculateCalculateHOAMAWMA(index, sqrtPeriod, diffWMA);
        }

        private double CalculateCalculateHOAMAWMA(int index, int period, double diffWMA = double.NaN)
        {
            if (double.IsNaN(diffWMA))
                diffWMA = source[index];

            double sum = 0;
            double weights = 0;
            for (int i = 0; i < period; i++)
            {
                double weight = period - i;
                sum += weight * source[index - i];
                weights += weight;
            }
            return sum / weights;
        }



        private double CalculateLaguerreMA(int index, double price)
        {
            // Update Laguerre filter coefficients
            laguerreArray[0] = (1 - Gamma) * price + Gamma * laguerreArray[0];
            for (int i = 1; i < 4; i++)
            {
                laguerreArray[i] = (1 - Gamma) * laguerreArray[i - 1] + Gamma * laguerreArray[i];
            }

            // Calculate the Laguerre MA
            double LMA = (laguerreArray[0] + 2 * laguerreArray[1] + 2 * laguerreArray[2] + laguerreArray[3]) / 6;
            return LMA;
        }

        private double CalculateAdjustedPrice(int index)
        {
            int lag = Period / 2;
            double priceLag = index >= lag ? source[index - lag] : source[0];
            return source[index] + (source[index] - priceLag);
        }

        private double CalculateZLEMA(int index)
        {

            double adjustedPrice = CalculateAdjustedPrice(index);

            // Use the smoothing factor alpha
            double alpha = 2.0 / (Period + 1);
            if (index == Period)
            {
                return adjustedPrice; // Initialize EMA at the first possible point
            }
            else
            {
                return alpha * adjustedPrice + (1 - alpha) * Result[index - 1]; // Apply EMA formula
            }
        }


        private double CalculateGaussianMA(int index)
        {
            double sum = 0;
            double weightSum = 0;
            double sigmaSquared = SigmaGaussian * SigmaGaussian;
            int start = index - Period + 1;

            for (int i = start; i <= index; i++)
            {
                // Calculate the Gaussian weight
                int x = i - start - Period / 2;
                double weight = Math.Exp(-x * x / (2 * sigmaSquared));
                sum += source[i] * weight;
                weightSum += weight;
            }

            return weightSum > 0 ? sum / weightSum : source[index];
        }

        private int CalculateDynamicPeriod(int index)
        {
            if (index < MaxPeriod)
                return MinPeriod;

            double volatility = 0;
            for (int i = index - MaxPeriod + 1; i <= index; i++)
            {
                volatility += Math.Abs(source[i] - source[i - 1]);
            }
            volatility /= MaxPeriod;

            // Calculate period based on volatility
            int dynamicPeriod = (int)(MinPeriod + (MaxPeriod - MinPeriod) * (volatility / (Bars.HighPrices.Maximum(MaxPeriod) - Bars.LowPrices.Minimum(MaxPeriod))));
            return Math.Max(MinPeriod, Math.Min(MaxPeriod, dynamicPeriod));
        }

        private double CalculateVPMA(int index)
        {

            int period = CalculateDynamicPeriod(index);

            if (index < period)
                return source[index];

            double sum = 0;
            for (int i = index - period + 1; i <= index; i++)
            {
                sum += source[i];
            }
            return sum / period;
        }

        private double CalculateGannMA(int index)
        {
            double sum = 0;
            double totalWeight = 0; // Initialize total weight to calculate the correct average
            for (int i = index - Period + 1; i <= index; i++)
            {
                // Apply Gann's principle by adjusting the weight of each price point
                double weight = 1; // Default weight
                if ((i - index + Period) % 2 == 0) // Adjust weight for even index positions
                {
                    weight = 1.5;
                }
                sum += source[i] * weight;
                totalWeight += weight; // Sum up the total weights used
            }
            return sum / totalWeight; // Use the total weight for calculating the average
        }


        private double CalculateDFMA(int index)
        {
            // Applying a simple low-pass filter formula
            if (index == 1)
            {
                Result[index - 1] = source[index];
                return source[index];  // Initialize the first value
            }
            else
            {
                double alpha = Alpha / (Period + 1);
                // DFMA = alpha * current price + (1 - alpha) * previous DFMA
                return alpha * source[index] + (1 - alpha) * Result[index - 1];
            }
        }
        private double CalculateBMA(int index)
        {
            double sum = 0;
            double weightsSum = 0;
            int halfPeriod = Period / 2;
            for (int i = 0; i < Period; i++)
            {
                // Calculate the weight (barycentric-like distribution)
                double weight = halfPeriod - Math.Abs(halfPeriod - i);
                sum += source[index - i] * weight;
                weightsSum += weight;
            }

            return sum / weightsSum;
        }

        private double CalculatePAMA(int index)
        {
            double sum = 0;
            double maxPrice = double.MinValue;
            double minPrice = double.MaxValue;

            for (int i = 0; i < Period; i++)
            {
                double currentHigh = Bars.HighPrices[index - i];
                double currentLow = Bars.LowPrices[index - i];
                double currentClose = Bars.ClosePrices[index - i];

                if (currentHigh > maxPrice) maxPrice = currentHigh;
                if (currentLow < minPrice) minPrice = currentLow;

                double typicalPrice = (currentHigh + currentLow + currentClose) / 3;
                sum += typicalPrice;
            }

            double average = sum / Period;
            double range = maxPrice - minPrice;
            double volatilityAdjustment = range * AdjustmentFactor;
            return average + volatilityAdjustment;
        }

        private double CalculateLSMA(int index)
        {
            double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
            for (int i = 0; i < Period; i++)
            {
                double x = i;
                double y = source[index - Period + i + 1];
                sumX += x;
                sumY += y;
                sumXY += x * y;
                sumX2 += x * x;
            }

            double n = Period;
            double slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
            double intercept = (sumY - slope * sumX) / n;

            return intercept + slope * (Period - 1);  // Predicting the value at the current index
        }

        private double CalculateQMA(int index)
        {
            double sumPrices = 0.0;
            double sumSquaredPrices = 0.0;

            for (int i = 0; i < Period; i++)
            {
                double price = source[index - i];
                sumPrices += price;
                sumSquaredPrices += price * price;
            }

            double averagePrice = sumPrices / Period;
            double averageSquaredPrice = sumSquaredPrices / Period;

            // Combine linear and quadratic components
            return 0.5 * averagePrice + 0.5 * Math.Sqrt(averageSquaredPrice);
        }

        private double CalculateHaMA(int index)
        {
            double sumOfInverses = 0.0;
            for (int i = 0; i < Period; i++)
            {
                double price = source[index - i];
                if (price == 0) continue;  // Avoid division by zero
                sumOfInverses += 1.0 / price;
            }
            return Period / sumOfInverses;  // n divided by the sum of inverses
        }

        private double CalculateGMA(int index)
        {
            double product = 1;
            for (int i = 0; i < Period; i++)
            {
                product *= source[index - i];
            }
            return Math.Pow(product, 1.0 / Period);  // n-th root of the product
        }

        private double CalculateSiWMA(int index, int period)

        {
            //if (index < Period) return;  // Ensure there's enough data

            double sma = CalculateSiWMASMA(index, period);
            double sineWave = CalculateSineWave(index, period);
            return sma + Amplitude * sineWave * sma;  // Applying sine wave transformation
        }

        private double CalculateSiWMASMA(int index, int period)
        {
            double sum = 0;
            for (int i = 0; i < period; i++)
            {
                sum += source[index - i];
            }
            return sum / period;
        }

        private double CalculateSineWave(int index, int period)
        {
            // Calculate a sine value based on the period and current index
            double phase = 2 * Math.PI * (index % period) / period;
            return Math.Sin(phase);
        }


        private double CalculateTMA(DataSeries prices, int index, int period)
        {
            double sum = 0;
            double sum2 = 0;
            for (int i = 0; i < period; i++)
            {
                sum += prices[index - i];
            }
            firstSMA[index] = sum / period;

            for (int i = 0; i < period; i++)
            {
                sum2 += firstSMA[index - i];
            }
            return sum2 / period;
        }
        private double CalculateEPMA(int index)
        {
            // Calculate the coefficients of the linear regression over the last 'Period' points
            var coefficients = LinearRegressionCoefficients(index);

            // Calculate EPMA using the formula:
            // y = mx + b where x = Period - 1 because we're predicting the next value after the last one
            return coefficients.Item1 * (Period - 1) + coefficients.Item2;
        }

        private Tuple<double, double> LinearRegressionCoefficients(int index)
        {
            double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
            for (int i = 0; i < Period; i++)
            {
                int x = i;
                double y = source[index - Period + i + 1];
                sumX += x;
                sumY += y;
                sumXY += x * y;
                sumX2 += x * x;
            }

            // Calculate slope (m) and intercept (b) of the linear regression line
            double n = Period;
            double slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
            double intercept = (sumY - slope * sumX) / n;

            return new Tuple<double, double>(slope, intercept);
        }

        private double CalculateChandeMA(int index)
        {
            // Calculating the momentum as the difference between the current close and the close n periods ago
            double momentum = source[index] - source[index - Period];

            // Simple moving average calculation for the baseline
            double sum = 0;
            for (int i = 0; i < Period; i++)
            {
                sum += source[index - i];
            }
            double sma = sum / Period;

            // Adjusting the SMA based on the momentum
            // The adjustment is a simple ratio of the current momentum to the SMA
            // This is a simple interpretative example and not based on a traditional formula
            return sma + (momentum / Period);
        }

        private double[] CalculateVolatilities(int index)
        {
            double[] volatilities = new double[Period];
            for (int i = 0; i < Period; i++)
            {
                volatilities[i] = Math.Abs(source[index - i] - source[index - i - 1]);
            }
            return volatilities;
        }

        private double CalculateAMA(int index)
        {

            double[] volatilities = CalculateVolatilities(index);
            double weightedSum = 0;
            double totalWeight = 0;

            for (int i = 0; i < Period; i++)
            {
                double weight = 1 / (1 + volatilities[i] * VolatilityFactor);
                weightedSum += source[index - i] * weight;
                totalWeight += weight;
            }

            return weightedSum / totalWeight;
        }

        private double CalculateWildersMA(DataSeries source, int index, int period)
        {
            if (index == 0)
                return source[index]; // Set the first data point as the initial average

            double previousWMA = Result[index - 1];
            double currentPrice = source[index];

            // Wilder's MA calculation uses a smoothing factor equivalent to the period
            double wildersMA = previousWMA + (currentPrice - previousWMA) / period;
            return wildersMA;
        }
        private double CalculateMcGinleyDynamic(int index)
        {
            if (index == 0)
            {
                return source[index];  // Initialize the first value to the close price
            }

            double previousMcGinley = Result[index - 1];
            double price = source[index];
            double mcGinleyDynamic = previousMcGinley +
                (price - previousMcGinley) / (Period * Math.Pow(price / previousMcGinley, Factor));

            return mcGinleyDynamic;
        }
        // Generic EMA calculation
        private double CalculateCustomT3EMA(DataSeries source, IndicatorDataSeries emaSeries, int index, int period)
        {
            double alpha = 2.0 / (period + 1);
            if (index == 0)
                return source[index];  // Use first available data point as the starting EMA value
            return alpha * source[index] + (1 - alpha) * emaSeries[index - 1];
        }

        private double CalculateT3(int index)
        {
            e1[index] = CalculateCustomT3EMA(source, e1, index, Period);
            e2[index] = CalculateCustomT3EMA(e1, e2, index, Period);
            e3[index] = CalculateCustomT3EMA(e2, e3, index, Period);
            e4[index] = CalculateCustomT3EMA(e3, e4, index, Period);
            e5[index] = CalculateCustomT3EMA(e4, e5, index, Period);
            e6[index] = CalculateCustomT3EMA(e5, e6, index, Period);

            double c1 = -Math.Pow(VolumeFactor, 3);
            double c2 = 3 * Math.Pow(VolumeFactor, 2) + 3 * Math.Pow(VolumeFactor, 3);
            double c3 = -6 * Math.Pow(VolumeFactor, 2) - 3 * VolumeFactor - 3 * Math.Pow(VolumeFactor, 3);
            double c4 = 1 + 3 * VolumeFactor + Math.Pow(VolumeFactor, 3) + 3 * Math.Pow(VolumeFactor, 2);

            return c1 * e6[index] + c2 * e5[index] + c3 * e4[index] + c4 * e3[index];
        }
        private double CalculateJurik(int index)
        {
            double jmaTempValue = index == 0 ? source[index] : _jmaSeries[index - 1];
            if (index < 1)
            {
                _jmaValue = source[index];
                _sourceSeries[index] = 0;
                _series1[index] = 0;
                _series2[index] = 0;

                return source[index];
            }
            if (_loopIndex < 61)
            {
                _loopIndex++;
                _buffer[_loopIndex] = source[index];
            }
            double paramA = 0;
            double paramB = 0;
            if (_loopIndex > 30)
            {
                if (_initFlag)
                {
                    _initFlag = false;
                    var diffFlag = 0;
                    for (int i = 1; i <= 29; i++)
                    {
                        if ((int)_buffer[i + 1] != (int)_buffer[i])
                        {
                            diffFlag = 1;
                            break;
                        }
                    }
                    _highLimit = diffFlag * 30;
                    paramB = (_highLimit == 0) ? source[index] : _buffer[index - 1];
                    paramA = paramB;

                    if (_highLimit > 29)
                    {
                        _highLimit = 29;
                    }
                }
                else
                {
                    _highLimit = 0;
                }

                for (int i = _highLimit; i >= 0; i--)
                {
                    double sValue = (i == 0) ? source[index] : _buffer[31 + i];
                    double absValue = (Math.Abs(sValue - paramA) > Math.Abs(sValue - paramB))
                                          ? Math.Abs(sValue - paramA)
                                          : Math.Abs(sValue - paramB);
                    _dValue = absValue + 0.0000000001;
                    if (_counterA <= 1)
                        _counterA = 127;
                    else
                        _counterA--;

                    if (_counterB <= 1)
                        _counterB = 10;
                    else
                        _counterB--;

                    if (_cycleLimit < 128)
                        _cycleLimit++;

                    _cycleDelta += (_dValue - _ring2[_counterB]);
                    _ring2[_counterB] = _dValue;
                    double highDValue = (_cycleLimit > 10) ? _cycleDelta / 10.0 : _cycleDelta / _cycleLimit;
                    int s68;
                    int s58;
                    int s38 = 0;
                    int s40 = 0;
                    if (_cycleLimit > 127)
                    {
                        _dValue = _ring1[_counterA];
                        _ring1[_counterA] = highDValue;
                        s68 = 64;
                        s58 = s68;
                        while (s68 > 1)
                        {
                            if (_list[s58] < _dValue)
                            {
                                s68 /= 2;
                                s58 += s68;
                            }
                            else if (_list[s58] <= _dValue)
                                s68 = 1;
                            else
                            {
                                s68 /= 2;
                                s58 -= s68;
                            }
                        }
                    }
                    else
                    {
                        _ring1[_counterA] = highDValue;
                        if ((_limitValue + _startValue) > 127)
                        {
                            _startValue--;
                            s58 = _startValue;
                        }
                        else
                        {
                            _limitValue++;
                            s58 = _limitValue;
                        }
                        s38 = (_limitValue > 96) ? 96 : _limitValue;
                        s40 = (_startValue < 32) ? 32 : _startValue;
                    }
                    s68 = 64;
                    int s60 = s68;
                    while (s68 > 1)
                    {
                        if (_list[s60] >= highDValue)
                        {
                            if (_list[s60 - 1] <= highDValue)
                                s68 = 1;
                            else
                            {
                                s68 /= 2;
                                s60 -= s68;
                            }
                        }
                        else
                        {
                            s68 /= 2;
                            s60 += s68;
                        }
                        if ((s60 == 127) && (highDValue > _list[127]))
                            s60 = 128;
                    }
                    if (_cycleLimit > 127)
                    {
                        if (s58 >= s60)
                        {
                            if (((s38 + 1) > s60) && ((s40 - 1) < s60))
                                _lowDValue += highDValue;
                            else if ((s40 > s60) && ((s40 - 1) < s58))
                                _lowDValue += _list[s40 - 1];
                        }
                        else if (s40 >= s60)
                        {
                            if (((s38 + 1) < s60) && ((s38 + 1) > s58))
                                _lowDValue += _list[s38 + 1];
                        }
                        else if ((s38 + 2) > s60)
                            _lowDValue += highDValue;
                        else if (((s38 + 1) < s60) && ((s38 + 1) > s58))
                            _lowDValue += _list[s38 + 1];

                        if (s58 > s60)
                        {
                            if (((s40 - 1) < s58) && ((s38 + 1) > s58))
                                _lowDValue -= _list[s58];
                            else if ((s38 < s58) && ((s38 + 1) > s60))
                                _lowDValue -= _list[s38];
                        }
                        else
                        {
                            if (((s38 + 1) > s58) && ((s40 - 1) < s58))
                                _lowDValue -= _list[s58];
                            else if ((s40 > s58) && (s40 < s60))
                                _lowDValue -= _list[s40];
                        }
                    }
                    if (s58 <= s60)
                    {
                        if (s58 >= s60)
                            _list[s60] = highDValue;
                        else
                        {
                            for (int j = s58 + 1; j <= (s60 - 1); j++)
                                _list[j - 1] = _list[j];

                            _list[s60 - 1] = highDValue;
                        }
                    }
                    else
                    {
                        for (int j = s58 - 1; j >= s60; j--)
                            _list[j + 1] = _list[j];

                        _list[s60] = highDValue;
                    }

                    if (_cycleLimit <= 127)
                    {
                        _lowDValue = 0;
                        for (int j = s40; j <= s38; j++)
                            _lowDValue += _list[j];
                    }
                    if ((_loopCriteria) > 31)
                        _loopCriteria = 31;
                    else
                        _loopCriteria++;
                    double sqrtDivider = _sqrtParam / (_sqrtParam + 1.0);
                    if (_loopCriteria <= 30)
                    {
                        paramA = (sValue - paramA > 0) ? sValue : sValue - (sValue - paramA) * sqrtDivider;
                        paramB = (sValue - paramB < 0) ? sValue : sValue - (sValue - paramB) * sqrtDivider;
                        jmaTempValue = source[index];

                        if (_loopCriteria == 30)
                        {
                            _sourceSeries[index] = source[index];
                            int intPart = (Math.Ceiling(_sqrtParam) >= 1.0) ? (int)Math.Ceiling(_sqrtParam) : 1;
                            int leftInt = intPart;
                            intPart = (Math.Floor(_sqrtParam) >= 1.0) ? (int)Math.Floor(_sqrtParam) : 1;
                            int rightPart = intPart;
                            _dValue = (leftInt == rightPart)
                                          ? 1.0
                                          : (_sqrtParam - rightPart) / (leftInt - rightPart);
                            int upShift = (rightPart <= 29) ? rightPart : 29;
                            int dnShift = (leftInt <= 29) ? leftInt : 29;
                            _series1[index] = (source[index] - _buffer[_loopIndex - upShift]) * (1 - _dValue) /
                                              rightPart +
                                              (source[index] - _buffer[_loopIndex - dnShift]) * _dValue / leftInt;
                        }
                    }
                    else
                    {
                        _dValue = _lowDValue / (s38 - s40 + 1);
                        double powerValue = (0.5 <= _logParam - 2.0) ? _logParam - 2.0 : 0.5;
                        _dValue = _logParam >= Math.Pow(absValue / _dValue, powerValue)
                                      ? Math.Pow(absValue / _dValue, powerValue)
                                      : _logParam;
                        if (_dValue < 1)
                            _dValue = 1;
                        powerValue = Math.Pow(sqrtDivider, Math.Sqrt(_dValue));
                        paramA = (sValue - paramA > 0) ? sValue : sValue - (sValue - paramA) * powerValue;
                        paramB = (sValue - paramB < 0) ? sValue : sValue - (sValue - paramB) * powerValue;
                    }
                }
                if (_loopCriteria > 30)
                {
                    double powerValue = Math.Pow(_lengthDivider, _dValue);
                    double squareValue = powerValue * powerValue;
                    if (double.IsNaN(_series1[index - 1]))
                        _series1[index - 1] = 0;
                    if (double.IsNaN(_series2[index - 1]))
                        _series2[index - 1] = 0;
                    _sourceSeries[index] = (1 - powerValue) * source[index] + powerValue * _sourceSeries[index - 1];
                    _series2[index] = (source[index] - _sourceSeries[index]) * (1.0 - _lengthDivider) +
                                     _lengthDivider * _series2[index - 1];
                    _series1[index] = (_phaseParam * _series2[index] + _sourceSeries[index] - jmaTempValue) *
                                      (powerValue * (-2.0) + squareValue + 1) + squareValue * _series1[index - 1];
                    jmaTempValue += _series1[index];
                }
            }
            _jmaValue = (_loopIndex < 30) ? source[index] : jmaTempValue;
            _jmaSeries[index] = _jmaValue;
            return _jmaValue;
        }

        private double CalculateZLMA(int index)
        {
            if (index < Period)
            {
                return source[index];  // Not enough data
            }

            double lag = (Period - 1) / 2.0;
            double sum = 0;

            for (int i = 0; i < Period; i++)
            {
                int lagIndex = index - Period + 1 + i;
                double price = source[lagIndex];
                double lagPrice = source[Math.Max(lagIndex - (int)Math.Round(lag), 0)];
                double zeroLagPrice = 2 * price - lagPrice;
                sum += zeroLagPrice;
            }

            return sum / Period;  // Zero Lag Moving Average
        }

        private double CalculateSWMA(int index)
        {
            if (index < Period - 1)
            {
                return source[index];  // Not enough data
            }

            double numerator = 0;
            double denominator = 0;
            double angleIncrement = Math.PI / (Period - 1);

            for (int i = 0; i < Period; i++)
            {
                double weight = Math.Sin(angleIncrement * i);
                numerator += source[index - Period +

YE
YesOrNot

Joined on 10.10.2022 Blocked

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: All Moving Averages v1.0.algo
  • Rating: 5
  • Installs: 266
Comments
Log in to add a comment.
BO
Bonkchoy · 2 months ago

Thank you for this!

 

YE
YesOrNot · 2 months ago

Thx Jim and Tommy !

Feel free to share formulas, ideas, or even strategies.

JI
jim.tollan · 2 months ago

whao - what an amazing contribution. these may not be used for common everyday situations, but are definitely going to plug the gap on those cases where the standard averages just don't cut the mustard.. excellent submission!!

TommyDee's avatar
TommyDee · 2 months ago

Thank you for sharing and also for putting in the time and effort to create this unique MA indicator for our community.