# Range Filter – Trading Strategy – Amibroker – Better Trend Following Indicator

Range Filter is a non-ATR-based trend following strategy inspired by Tradingview Pinescript coder – DonovanWall. According to him, Range Filter is an experimental study designed to filter out minor price action for a clearer view of trends. Here is the Amibroker Trend Following Strategy code based on the Range Filter.

How Range Filter is Calculated?

1), a smooth average price range is calculated for the basis of the filter and multiplied by a specified amount.
2)the filter is calculated by gating price movements that do not exceed the specified range.
3)the target ranges are plotted to display the prices that will trigger filter movement.

Strategy Timeframe : 15mins

Trading Commissions Used : 0.02% per leg

Historical Data Backtesting Period: 2011 – 2022

Position Sizing : 1 Lot (Fixed Lot)

Equity Curve

Drawdown Curve

Backtesting Report

Absolute Profit Table (in Thousands)

Range Filter – Amibroker AFL Code

``````//Coded by Rajandran R - www.marketcalls.in / www.openalgo.in
//Original Coded by : DonovanWall
//Coded Date : 23rd - Aug 2022

SetPositionSize(1*RoundLotSize,spsShares);

src = ParamField("Source",3);

// Sampling Period

per = param("Sampling Period",15,5,200,5);

// Range Multiplier

mult = param("Range Multiplier",2.5,1,5,0.5);

upward = 0;
dnward = 0;

// Smooth Average Range

function smoothrange(x, t, m)
{

wper = t * 2 - 1;
avrng = ema(abs(x - Ref(x,-1)), t);
smoothrng = ema(avrng, wper) * m;
return smoothrng;

}

smrng = smoothrange(src, per, mult);

// Range Filter

function rngfilter(x, r)
{

rngfilt = x;
//rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r : x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
for(i=1;i<BarCount;i++)
{

if(x[i] > rngfilt[i-1])
{
if((x[i] - r[i]) < rngfilt[i-1])
{
rngfilt[i] = rngfilt[i-1];
}
else
{
rngfilt[i] = x[i]-r[i];

}
}
else
{

if((x[i] + r[i])  > rngfilt[i-1])
{

rngfilt[i] = rngfilt[i-1];

}
else
{
rngfilt[i] =  x[i] + r[i];
}
}
}//end of for loop
return rngfilt;
}

filt = rngfilter(src, smrng);
upward = 0;
downward = 0;
// Filter Direction

for(i=1;i<BarCount;i++)
{

if(filt[i] > filt[i-1])
{
upward[i] = upward[i-1] + 1;
}
else{

if(filt[i] < filt[i-1])
{
upward[i] = 0;

}

else
{
upward[i] = upward[i-1];
}

}

}//end of for loop

for(i=1;i<BarCount;i++)
{

if(filt[i] < filt[i-1])
{
downward[i] = downward[i-1] + 1;
}
else{

if(filt[i] < filt[i-1])
{
dnward[i] = 0;

}

else
{
dnward[i] = dnward[i-1];
}

}//end of for loop

}//end of range filter function

// Target Bands

hband = filt + smrng;
lband = filt - smrng;

Plot(hband,"H-Band",colorBlue,styleLine);
Plot(lband,"L-Band",colorRed,styleLine);

longCond = (src > filt and src > Ref(src,-1) and upward > 0) or (src > filt and src < Ref(src,-1) and upward > 0);
shortCond = (src < filt and src <  Ref(src,-1) and downward > 0) or (src < filt and src > Ref(src,-1) and downward > 0);

Sell = ExRem(shortCond,longCond);
Short = Sell;

Sell = Ref(Sell,-1);
Short = Ref(Short,-1);
Cover = Ref(Cover,-1);

SellPrice = ValueWhen(Sell,Open);
ShortPrice = ValueWhen(Short,Open);
CoverPrice = ValueWhen(Cover,Open);

shortcontinue = Flip(Short,Cover);

for( i = 0; i < BarCount; i++ )
{
if( Short[i] ) PlotText("Short",i,H[i],colorWhite,colorRed,70);
//if( Sell[i] ) PlotText( "Selln@" + C[ i ], i, H[ i ]+dist[i], colorRed, colorYellow );
}

/* Plot Buy and Sell Signal Arrows */
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Sell, shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);

sig=0;
bars=0;
tar1=tar2=tar3=null;

for(i=BarCount-1;i>1;i--)

{

{

entry = open[i];

sig = 1;  //flag contains 1 when buy is valid

tar1 = entry + (entry * .0050);

tar2 = entry + (entry * .0092);

tar3 = entry + (entry * .0179);

bars = i;

i = 0;

}

if(Short[i] == 1)

{

sig = -1; //flag contains -1 wjhen short is valid

entry = open[i];

tar1 = entry - (entry * .0050);

tar2 = entry - (entry * .0112);

tar3 = entry - (entry * .0212);

bars = i;  // i - holds the value of bar index, computing the barindex value when the signal happened

i = 0;

}

}//for loop

Offset = 20;

Clr = IIf(sig == 1, colorLime, colorRed);

//plot target lines

Plot(LineArray(bars-Offset, tar1, BarCount-1, tar1,1), "", Clr, styleLine|styleDots, Null, Null, Offset);

Plot(LineArray(bars-Offset, tar2, BarCount-1, tar2,1), "", Clr, styleLine|styleDots, Null, Null, Offset);

Plot(LineArray(bars-Offset, tar3, BarCount-1, tar3,1), "", Clr, styleLine|styleDots, Null, Null, Offset);

_SECTION_END();

_SECTION_BEGIN("Signal Dashboard");

messageboard = ParamToggle("Message Board","Show|Hide",1);
upcolor = ParamColor("Up Color",colorBlue);
dncolor = ParamColor("Down Color",colorRed);

if (messageboard == 1 )

{

GfxSelectFont( "Tahoma", 13, 100 );

GfxSetBkMode( 1 );

GfxSetTextColor( colorWhite );

//Dashboard color changes dynamically according to the signals continuation
color = IIf(buycontinue, upcolor, IIf(shortcontinue, dncolor, Null));

GfxSelectSolidBrush(SelectedValue(color));

pxHeight = Status( "pxchartheight" ) ;

xx = Status( "pxchartwidth");

Left = 1100;
width = 310;

x = 5;
x2 = 360;
y = pxHeight;

GfxSelectPen( colorGreen, 1); // broader color
GfxRoundRect( x, y - 98, x2, y , 7, 7 ) ;
GfxTextOut( ( "Marketcalls - Range Filter"),13,y-90);
GfxTextOut( (" "),27,y-100);

{
GfxTextOut( ("Last " + sigstatus + " Signal came " + BarsSince(Buy) * Interval()/60 + " mins ago"), 13, y-70) ; // The text format location
GfxTextOut( ("" + sigstatus + " : " + ValueWhen(Buy,BuyPrice)), 13, y-50);
}

if(SelectedValue(Shortcontinue))
{
GfxTextOut( ("Last " + sigstatus + " Signal came " + BarsSince(short) * Interval()/60 + " mins ago"), 13, y-70) ; // The text format location
GfxTextOut( ("" + sigstatus + " : " + ValueWhen(Short,ShortPrice)), 13, y-50);
GfxTextOut( ("Current P/L : " + NumToStr(ValueWhen(Short,ShortPrice)-Close,1.2)), 13, y-30);
}

//GfxTextOut( ("Trailing SL : " + Ref(TrendSL,-1) + " (" + WriteVal(IIf(sig == -1,entry-sl,sl-entry), 2.2) + ")"), 13, y-40);

}

_SECTION_END();

_SECTION_BEGIN("Top Dashboard");

X0 = 10;
Y0 = 20;

procedure DrawData (Text, x1, y1, x2, y2, colorFrom, colorTo)
{
GfxSetOverlayMode(0);
GfxSelectFont("Verdana", 8.5, 700);
GfxSetBkMode(1);
GfxGradientRect(x1, y1, x2, y2, colorFrom, colorTo);
GfxDrawText(Text, x1, y1, x2, y2, 32|1|4|16);
}

DrawData (Name(), X0, Y0, X0+150, Y0+20, colorGrey40, colorblack);
DrawData (Date(), X0+155, Y0, X0+320, Y0+20, colorGrey40, colorblack);
DrawData ("Open : " + Open, X0+325, Y0, X0+450, Y0+20, colorGrey40, colorblack);
DrawData ("Close : " + Close, X0+455, Y0, X0+580, Y0+20, colorGrey40, colorblack);
DrawData ("High : " + High, X0+585, Y0, X0+710, Y0+20, colorGrey40, colorblack);
DrawData ("Low : " + Low, X0+715, Y0, X0+840, Y0+20, colorGrey40, colorblack);

_SECTION_END();

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", barcolor, styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();``````

## Mini Certification Course on Algorithmic Trading

Welcome to the Mini Certification on Algorithmic Trading using Amibroker and OpenAlgo! This comprehensive 4-part series is designed to equip you with the knowledge...

## Pivot Reversal Strategy – Tradingview Pinescript to Amibroker AFL…

Pivot Reversal Strategy is a popular in-built strategy in Tradingview Platform. Here I had attempted to convert the pinescript v5 to Amibroker AFL Code....

## 4 Replies to “Range Filter – Trading Strategy – Amibroker – Better…”

1. sghanesha kumar says:

thank you sir but shows some error .

error16 toomany arguements.

-S.Ghaneshakumar

1. Consider using Amibroker 6.0 or higher versions.

2. sunil vedula says:

Sir, maybe using sell and cover signals as exit points for entries might work wonders. For ex if we are on SHORT side and it touches the Down color bar it would book profit in exit and wait. If a breakout happens to downside by breaking the down color bar area let it reenter with again the next downside color bar being the target. Same logc with upside as well

3. PUNIT says:

how to make it atr based seen as a trading view same in amibroker?