Force Acceleration

by shlbnd.ms in category Trend at 07/01/2018
Description

Force & Resistance acceleration using a tripple weighted moving average

For references here ths is a change to the original snake force indicator. With one difference and one addition.

- Indicator uses the HULL average which is tripple weighted instead of a standard weighted average. 
- An additional setting has been added to set the periods of the HULL average.  the snake force implementation has a default period setting of 24 and a hard coded value of 6 ( 1/4 of the periods ) as the period setter for the moving average. This implementation allows both periods to be set. 

The thinking behind the tripple weighting is to make this a more relevant indicator for higher frequency scalp trading. 

An interesting Robot algo might be to create a trade signal based on the Force or Resistance rate of change. 

All thoughts or opinions are welcome. 

Download
609 downloads
How to install
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
using System;
using cAlgo.API;


namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]

    public class ForceAcceleration : Indicator
    {
        [Parameter()]
        public DataSeries Source { get; set; }

        [Parameter("Force Periods", DefaultValue = 24)]
        public int Periods { get; set; }


        [Parameter("Weighted Average Peridos", DefaultValue = 6)]
        public int WAPeriods { get; set; }

        [Output("Positive Force", Color = Colors.White, PlotType = PlotType.Histogram, Thickness = 5)]
        public IndicatorDataSeries ForceUp { get; set; }

        [Output("ForceDown", Color = Colors.Purple, PlotType = PlotType.Histogram, Thickness = 5)]
        public IndicatorDataSeries ForceDown { get; set; }

        [Output("ResistanceUp", Color = Colors.White, PlotType = PlotType.Histogram)]
        public IndicatorDataSeries ResistanceUp { get; set; }

        [Output("ResistanceDown", Color = Colors.Purple, PlotType = PlotType.Histogram)]
        public IndicatorDataSeries ResistanceDown { get; set; }

        private IndicatorDataSeries Mart;
        private HullMovingAverage iMA;

        double Force_Sum_Plus;
        double Force_Sum_Minus;
        double Force_Weight;
        double Force_Sum;

        protected override void Initialize()
        {
            Mart = CreateDataSeries();
            iMA = Indicators.GetIndicator<HullMovingAverage>(Source, WAPeriods);
        }

        public override void Calculate(int index)
        {
            int i = 0;
            int FirstPos = 0;

            if (index <= 50)
                return;

            if (Periods < 21)
                return;

            FirstPos = 1;
            if (FirstPos > index - Periods - 7)
            {
                FirstPos = index - Periods - 7;
                Mart[FirstPos + Periods] = ForceFirstCalc(FirstPos + Periods, index);

                for (i = FirstPos; i < FirstPos - Periods - 1; i++)
                    ForceNextCalc(i);
            }
            Force(FirstPos, index);
        }

        void Force(int Pos, int index)
        {
            if (Pos < 6)
                Pos = index - 6;

            Mart[Pos] = ForceFirstCalc(Pos, index);
            Drawing(Pos);
            Pos++;
            while (Pos <= index - 5)
            {
                Mart[Pos] = ForceNextCalc(Pos);
                Drawing(Pos);
                Pos++;
            }
            while (Pos < index)
            {
                Mart[Pos] = ForceFirstCalc(Pos, index);
                Drawing(Pos);
                Pos++;
            }
            if (Pos == index)
            {
                Mart[Pos] = iMA.Result.LastValue;
                Drawing(Pos);
            }
            return;
        }

        double ForcePrice(int Shift)
        {
            return MarketSeries.Close[Shift];
        }

        double ForceFirstCalc(int Shift, int index)
        {
            int w = 0;
            int j = 0;
            int i = 0;

            Force_Sum = 0.0;
            if (Shift > (index - 5))
            {
                Force_Weight = 0.0;
                i = 0;
                w = Shift - 5;
                while (w <= Shift)
                {
                    i++;
                    Force_Sum = Force_Sum + i * ForcePrice(w);
                    Force_Weight = Force_Weight + i;
                    w++;
                }
                while (w <= index)
                {
                    i--;
                    Force_Sum = Force_Sum + i * ForcePrice(w);
                    Force_Weight = Force_Weight + i;
                    w++;
                }
            }
            else
            {
                Force_Sum_Minus = 0.0;
                Force_Sum_Plus = 0.0;
                for (j = Shift + 5,i = Shift - 5,w = 1; w <= 5; j--,i++,w++)
                {
                    Force_Sum = Force_Sum + w * (ForcePrice(i) + ForcePrice(j));
                    Force_Sum_Minus = Force_Sum_Minus + ForcePrice(i);
                    Force_Sum_Plus = Force_Sum_Plus + ForcePrice(j);
                }
                Force_Sum = Force_Sum + 6 * ForcePrice(Shift);
                Force_Sum_Minus = Force_Sum_Minus + ForcePrice(Shift);
                Force_Weight = 36;
            }
            return (Force_Sum / Force_Weight);
        }

        double ForceNextCalc(int Shift)
        {
            Force_Sum_Plus = Force_Sum_Plus + ForcePrice(Shift + 5);
            Force_Sum = Force_Sum - Force_Sum_Minus + Force_Sum_Plus;
            Force_Sum_Minus = Force_Sum_Minus - ForcePrice(Shift - 6) + ForcePrice(Shift);
            Force_Sum_Plus = Force_Sum_Plus - ForcePrice(Shift);
            return Force_Sum / Force_Weight;
        }

        void Drawing(int Shift)
        {
            double Dval = 0;
            double val = 0;

            val = 5 * (Mart[Shift] - Mart[ArrayMinimum(Mart, Periods, Shift)]) / 9;
            Dval = 5 * (Mart[Shift] - Mart[Shift - 1] + Mart[ArrayMinimum(Mart, Periods, Shift - 1)] - Mart[ArrayMinimum(Mart, Periods, Shift)]) / 9;
            if (Dval > 0)
            {
                ForceUp[Shift] = val;
                ResistanceUp[Shift] = 0;
            }
            else
            {
                ForceUp[Shift] = 0;
                ResistanceUp[Shift] = val;
            }
            val = 5 * (Mart[Shift] - Mart[ArrayMaximum(Mart, Periods, Shift)]) / 9;
            Dval = 5 * (Mart[Shift] - Mart[Shift - 1] + Mart[ArrayMaximum(Mart, Periods, Shift - 1)] - Mart[ArrayMaximum(Mart, Periods, Shift)]) / 9;
            if (Dval < 0)
            {
                ForceDown[Shift] = val;
                ResistanceDown[Shift] = 0;
            }
            else
            {
                ForceDown[Shift] = 0;
                ResistanceDown[Shift] = val;
            }
            return;
        }

        int ArrayMaximum(IndicatorDataSeries array, int count = 0, int start = 0)
        {
            var result = start;
            for (var i = start - count + 1; i <= start - 1; i++)
            {
                if (array[i] > array[result])
                    result = i;
            }
            return result;
        }

        int ArrayMinimum(IndicatorDataSeries array, int count = 0, int start = 0)
        {
            var result = start;
            for (var i = start - count + 1; i <= start - 1; i++)
            {
                if (array[i] < array[result])
                    result = i;
            }
            return result;
        }

    }
}
Comments

simonv76 - January 19, 2018 @ 14:50

Is it a repainting Indicator?

shlbnd.ms - January 23, 2018 @ 18:46

No

tob_wolf - March 07, 2018 @ 09:31

Yes, it repaints the last 6 candles. Using future values it must repaint and there is no nrp-version possible, at least not without making the indicator lagging heavily and that would make it pretty useless.

0