Multi Moving Average free

by jani in category Trend at 04/02/2020
Description

This is the one and only MA you ever need!

 

The indicator includes all standard moving averages as well as Tilson T3 Moving Average
and KijunSen line
  
Standard moving averages can be smoothed by the MA Factor (values range: 1-6)
For example, EMA with Factor 1 is normal EMA, by using factor 2 we get EMA of EMA,
by using factor 3 gives EMA of EMA of EMA etc.

Min Threshold feature filters out MA/T3 slopes that are less than the threshold value. 
This feature can be used for example to filter out flat/non-trending period with higher period MAs
 
Slope LookBack feature (used with Min Threshold feature) calculates the number of bars that
must qualify the Min Threshold value. With this feature we can filter out periods where slope is 
turned up or down for a short period of time. E.g. If Slope LookBack value is set to 5, feature 
will filter out all non-qualifying up or down slopes that are equal or less than 5 bars in length.

The Kijun-sen(Japanese for Reference / Baseline) is an indicator and a component
of the Ichimoku Kinko Hyo method of technical analysis, which is also known as the Ichimoku cloud.
The original Kijun-sen is the midpoint price of the last 26-periods, and therefore an indicator of 
short- to medium-term price momentum. The indicator aids in assessing the trend.

Calculation of the KijunSen Line

Find the highest price over the last determined periods.
Find the lowest price over the last determined periods.
Combine the high and low, then divide by two.
Update the calculation after each period ends.


ATR Channels can be added to any moving average. ATR Channels can also be added to KijunSen line 
if "Use ATR Channels" and "Allow ATR on KijunSen" are both true.

The Triple Exponential Moving Average (T3) developed by Tim Tillson attempts to offers
a moving average with better smoothing then traditional exponential moving average.
It incorporates a smoothing technique which allows it to plot curves more gradual than
ordinary moving averages and with a smaller lag. 
Its smoothness is derived from the fact that it is a weighted sum of a single EMA, 
is formed, the price action will stay above or below the trend during most of its 
progression and will hardly be touched by any swings. Thus, a confirmed penetration of 
the T3 MA and the lack of a following reversal often indicates the end of a trend.

Many custom moving averages and/or MA crossovers can be synthesized by adjusting T3 Period & Factor

 

                                          !!! NOTE !!!

                The  Min Threshold &  Slope LookBack features do not apply to KijunSen.
                KijunSen line can be used in addition to an MA/T3-line.
                Use MA & Use T3 are mutually exclusive.

         !!! When using T3 to get correct values use MA Type as Exponential !!!

 

 

Notification Publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section you may use the Copyright Infringement Notification form to submit a claim.
Formula / Source Code
Language: C#
Trading Platform: cAlgocTrader
// ---------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------
/*
The indicator includes all standard moving averages as well as Tilson T3 Moving Average
and KijunSen line
  
Standard moving averages can be smoothed by the MA Factor (values range: 1-6)
For example, EMA with Factor 1 is normal EMA, by using factor 2 we get EMA of EMA,
by using factor 3 gives EMA of EMA of EMA etc.

Min Threshold feature filters out MA/T3 slopes that are less than the threshold value. 
This feature can be used for example to filter out flat/non-trending period with higher period MAs
 
Slope LookBack feature (used with Min Threshold feature) calculates the number of bars that
must qualify the Min Threshold value. With this feature we can filter out periods where slope is 
turned up or down for a short period of time. E.g. If Slope LookBack value is set to 5, feature 
will filter out all non-qualifying up or down slopes that are equal or less than 5 bars in length.

The Kijun-sen(Japanese for Reference / Baseline) is an indicator and a component
of the Ichimoku Kinko Hyo method of technical analysis, which is also known as the Ichimoku cloud.
The original Kijun-sen is the midpoint price of the last 26-periods, and therefore an indicator of 
short- to medium-term price momentum. The indicator aids in assessing the trend.

Calculation of the KijunSen Line

Find the highest price over the last determined periods.
Find the lowest price over the last determined periods.
Combine the high and low, then divide by two.
Update the calculation after each period ends.


ATR Channels can be added to any moving average. ATR Channels can also be added to KijunSen line 
if "Use ATR Channels" and "Allow ATR on KijunSen" are both true.

The Triple Exponential Moving Average (T3) developed by Tim Tillson attempts to offers
a moving average with better smoothing then traditional exponential moving average.
It incorporates a smoothing technique which allows it to plot curves more gradual than
ordinary moving averages and with a smaller lag. 
Its smoothness is derived from the fact that it is a weighted sum of a single EMA, 
is formed, the price action will stay above or below the trend during most of its 
progression and will hardly be touched by any swings. Thus, a confirmed penetration of 
the T3 MA and the lack of a following reversal often indicates the end of a trend.

Many custom moving averages and/or MA crossovers can be synthesized by adjusting T3 Period & Factor



                                     !!! NOTE !!!

                The  Min Threshold &  Slope LookBack features do not apply to KijunSen.
                KijunSen line can be used in addition to an MA/T3-line.
                Use MA & Use T3 are mutually exclusive.
*/
// --------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------
//
//   Version Updates:
//
//   2020.1.9  - Added all moving averages, ATR Channels and EMA factor feature (EMA, TEMA, DEMA etc. till 6th factor)
//   2020.2.4  - Added KijunSen
//
// ---------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------


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

using System.IO;
namespace cAlgo.Indicators
{

    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]

    public class MultiMA : Indicator
    {
        [Parameter("Fibonacci: ", Group = "-- For Reference Only ---", DefaultValue = "5,8,13,21,34,55,89,144,233,377,610")]
        public string indicatorinfo { get; set; }

        [Parameter()]
        public DataSeries Source { get; set; }
        [Parameter("Use MA", Group = " --- Use MA ---", DefaultValue = true)]
        public bool UseMA { get; set; }

        [Parameter("Method", Group = " --- MA Method ---", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType MAType { get; set; }

        [Parameter("Period ", Group = " --- MA Period ---", DefaultValue = 21)]
        public int Period { get; set; }

        [Parameter("Min Threshold", Group = " --- MA Slope ---", DefaultValue = 0.0, Step = 0.0001)]
        public double minthr { get; set; }

        [Parameter("Slope LookBack, Void if 0", Group = " --- MA Slope LookBack ---", DefaultValue = 0, MinValue = 0)]
        public int slopeLB { get; set; }

        [Parameter("Use T3", Group = " --- T3 ---", DefaultValue = false)]
        public bool UseT3 { get; set; }

        [Parameter("Volume Factor (T3 only) ", Group = " --- T3 ---", DefaultValue = 0.7)]
        public double Volume_Factor { get; set; }

        [Parameter("Use KijunSen", Group = "--- KijunSen ---", DefaultValue = false)]
        public bool UseKijunSen { get; set; }

        [Parameter("Allow ATR on KijunSen", Group = "--- KijunSen ---", DefaultValue = false)]
        public bool AllowATR { get; set; }

        [Parameter("KijunSen Period", Group = "--- KijunSen ---", DefaultValue = 21)]
        public int KijunPeriod { get; set; }

        [Parameter("Smoothing Period", Group = "--- KijunSen ---", DefaultValue = 10)]
        public int KijunMaPeriod { get; set; }

        [Parameter("MA Factor (1-6) ", Group = " --- MA Smoothing Factor ---", DefaultValue = 1, MinValue = 1, MaxValue = 6)]
        public int MAFactor { get; set; }

        [Parameter("Use ATR Channels", Group = " --- ATR Channel ---", DefaultValue = false)]
        public bool UseChannel { get; set; }

        [Parameter("ATR Period", Group = " --- ATR Channel ---", DefaultValue = 50)]
        public int AtrPeriod { get; set; }

        [Parameter("ATR Band Distance", Group = " --- ATR Channel ---", DefaultValue = 2.0)]
        public double BandDistance { get; set; }

        [Output("MA steady", LineColor = "Gray", PlotType = PlotType.DiscontinuousLine, Thickness = 3)]
        public IndicatorDataSeries steady { get; set; }

        [Output("MA rise", LineColor = "Lime", PlotType = PlotType.DiscontinuousLine, Thickness = 3)]
        public IndicatorDataSeries rise { get; set; }

        [Output("MA fall", LineColor = "Red", PlotType = PlotType.DiscontinuousLine, Thickness = 3)]
        public IndicatorDataSeries fall { get; set; }

        [Output("Channel Up", LineColor = "Yellow", Thickness = 1, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries ChannelUp { get; set; }

        [Output("Channel Down", LineColor = "Yellow", Thickness = 1, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries ChannelDw { get; set; }

        [Output("Kijunsen", LineColor = "Orange", PlotType = PlotType.DiscontinuousLine, Thickness = 2, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries KijunSen { get; set; }

        [Output("Kijunsen Up", LineColor = "Lime", PlotType = PlotType.DiscontinuousLine, Thickness = 3, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries KijunSenUp { get; set; }

        [Output("Kijunsen Down", LineColor = "Red", PlotType = PlotType.DiscontinuousLine, Thickness = 3, LineStyle = LineStyle.Lines)]
        public IndicatorDataSeries KijunSenDown { get; set; }

        private MovingAverage ma1;
        private MovingAverage ma2;
        private MovingAverage ma3;
        private MovingAverage ma4;
        private MovingAverage ma5;
        private MovingAverage ma6;

        private MovingAverage MaKijun;
        private IndicatorDataSeries Kijun;

        private IndicatorDataSeries atr;
        private TrueRange tri;
        private MovingAverage MA;
        private IndicatorDataSeries val2;
        private IndicatorDataSeries avg2;

        private double val;
        private double avg;
        private int mode;



        int lastindex = 0;

        protected override void Initialize()
        {
            ma1 = Indicators.MovingAverage(Source, Period, MAType);
            ma2 = Indicators.MovingAverage(ma1.Result, Period, MAType);
            ma3 = Indicators.MovingAverage(ma2.Result, Period, MAType);
            ma4 = Indicators.MovingAverage(ma3.Result, Period, MAType);
            ma5 = Indicators.MovingAverage(ma4.Result, Period, MAType);
            ma6 = Indicators.MovingAverage(ma5.Result, Period, MAType);

            Kijun = CreateDataSeries();

            MaKijun = Indicators.MovingAverage(Kijun, KijunMaPeriod, MAType);
            atr = CreateDataSeries();
            tri = Indicators.TrueRange();

            val2 = CreateDataSeries();
            avg2 = CreateDataSeries();

        }

        public override void Calculate(int index)
        {

            if (IsLastBar)
            {
                if (index != lastindex)
                    lastindex = index;
                else
                    return;
            }

            //------------
            if (index < AtrPeriod + 1)
            {
                atr[index] = tri.Result[index];
            }
            if (index >= AtrPeriod)
            {
                atr[index] = (atr[index - 1] * (AtrPeriod - 1) + tri.Result[index]) / AtrPeriod;
            }

            //------------           
            if (UseKijunSen)
            {
                var MaxHigh = MarketSeries.High.Maximum(KijunPeriod);
                var MinLow = MarketSeries.Low.Minimum(KijunPeriod);

                Kijun[index] = (MaxHigh + MinLow) / 2;


                KijunSen[index] = MaKijun.Result[index];

                if (MaKijun.Result.IsFalling())
                    KijunSenDown[index] = MaKijun.Result[index];

                if (MaKijun.Result.IsRising())
                    KijunSenUp[index] = MaKijun.Result[index];

                if (UseChannel && AllowATR)
                {
                    ChannelUp[index] = MaKijun.Result[index] + BandDistance * atr[index];
                    ChannelDw[index] = MaKijun.Result[index] - BandDistance * atr[index];
                }


            }



            //------------
            if (UseMA || UseT3)
            {
                val = UseT3 ? maketema(index) : UseMA ? ma(index) : double.NaN;
                avg = UseT3 ? averageslope(index) : UseMA ? maaverageslope(index) : double.NaN;

                val2[index] = UseT3 ? maketema(index) : ma(index);
                avg2[index] = UseT3 ? averageslope(index) : maaverageslope(index);

                int countrise = 0;
                int countfall = 0;
                int totalcount = 0;

                // If slope lookback is active, slopeLB checks if MA line qualify for either red or green (fall or rise) for the select slopeLB period
                if (slopeLB > 0)
                {
                    for (var i = 0; i < slopeLB; i++)
                    {
                        if (avg2[index - i] >= minthr)
                            countrise++;
                        if (avg2[index - i] < -minthr)
                            countfall++;
                        totalcount++;
                    }
                    mode = (countrise == totalcount) ? 1 : (countfall == totalcount) ? -1 : 0;
                }
                else
                    // if slopeLB lookback inactive count MA line color 
                    mode = (avg >= minthr) ? 1 : (avg < -minthr) ? -1 : 0;

                rise[index] = (mode == 1) ? val : double.NaN;
                fall[index] = (mode == -1) ? val : double.NaN;
                steady[index] = val;

                if (UseChannel)
                {
                    ChannelUp[index] = val + BandDistance * atr[index];
                    ChannelDw[index] = val - BandDistance * atr[index];
                }
            }
            //------------
        }

        //////////////////////////////////////////////////////

        double averageslope(int index)
        {
            var sum = 0.0;
            var count = 0;

            for (var i = index - 1; i < index - 0; i++)
            {
                var p0 = maketema(i + 1);
                var p1 = maketema(i);
                var per = (p0 - p1) / p0 * 100;

                sum += per;
                count++;
            }
            return sum / count;
        }

        double maaverageslope(int index)
        {
            var sum = 0.0;
            var count = 0;

            for (var i = index - 1; i < index - 0; i++)
            {
                var p0 = ma(i + 1);
                var p1 = ma(i);
                var per = (p0 - p1) / p0 * 100;

                sum += per;
                count++;
            }
            return sum / count;
        }
        /*
        double _averageslope(int index)
        {
            var sum = 0.0;
            var count = 0;
            double p0 = 0;
            double p1 = 0;
            var i = 0;

            for (i = index - 1; i < index - 0; i++)
            {
                p0 = MA.Result[i + 1];
                p1 = MA.Result[i];

                var per = (p0 - p1) / p0 * 100;
                sum += per;
                count++;
            }
            return sum / count;
        }
*/
        double maketema(int index)
        {
            double b, b2, b3, c1, c2, c3, c4;
            double result = 0;
            b = Volume_Factor;
            b2 = Math.Pow(b, 2);
            // Volume Factor Squared
            b3 = Math.Pow(b, 3);
            // Volume Factor Cubed
            c1 = -b3;
            c2 = 3 * b2 + 3 * b3;
            c3 = -6 * b2 - 3 * b - 3 * b3;
            c4 = 1 + 3 * b + b3 + 3 * b2;

            result = c1 * ma6.Result[index] + c2 * ma5.Result[index] + c3 * ma4.Result[index] + c4 * ma3.Result[index];

            return result;
        }
        double ma(int index)
        {
            double result = 0;

            if (MAFactor == 6)
                result = (ma6.Result[index] + ma5.Result[index] + ma4.Result[index] + ma3.Result[index] + ma2.Result[index] + ma1.Result[index]) / 6;
            if (MAFactor == 5)
                result = (ma5.Result[index] + ma4.Result[index] + ma3.Result[index] + ma2.Result[index] + ma1.Result[index]) / 5;
            if (MAFactor == 4)
                result = (ma4.Result[index] + ma3.Result[index] + ma2.Result[index] + ma1.Result[index]) / 4;
            if (MAFactor == 3)
                result = (ma3.Result[index] + ma2.Result[index] + ma1.Result[index]) / 3;
            if (MAFactor == 2)
                result = (ma2.Result[index] + ma1.Result[index]) / 2;
            if (MAFactor == 1)
                result = ma1.Result[index];

            return result;
        }

    }
}
Comments
2.5