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.
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;
}
}
}
shlbnd.ms
Joined on 10.06.2016
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: ForceAcceleration.algo
- Rating: 0
- Installs: 2716
- Modified: 13/10/2021 09:54
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.