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 Symbol: Nifty Futures
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
//Code Inspired from Tradingview Pinescript
//Original Coded by : DonovanWall
//Tradingview Source Code : https://in.tradingview.com/script/lut7sBgG-Range-Filter-DW/
//Coded Date : 23rd - Aug 2022
_SECTION_BEGIN("Range Filter - Trading Strategy");
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);
Buy = ExRem(longCond,shortCond);
Sell = ExRem(shortCond,longCond);
Short = Sell;
Cover = Buy;
Buy = Ref(Buy,-1);
Sell = Ref(Sell,-1);
Short = Ref(Short,-1);
Cover = Ref(Cover,-1);
BuyPrice = ValueWhen(Buy,Open);
SellPrice = ValueWhen(Sell,Open);
ShortPrice = ValueWhen(Short,Open);
CoverPrice = ValueWhen(Cover,Open);
buycontinue = Flip(Buy,Sell);
shortcontinue = Flip(Short,Cover);
barcolor = IIf(buycontinue,colorGreen,colorRed);
for( i = 0; i < BarCount; i++ )
{
if( Buy[i] ) PlotText("Buy",i,L[i],colorWhite,colorLime,-70);
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(Buy, shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Buy, shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
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--)
{
if(Buy[i] == 1)
{
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;
sigstatus = WriteIf(buycontinue,"Buy Signal @ ","Sell Signal @");
GfxSelectPen( colorGreen, 1); // broader color
GfxRoundRect( x, y - 98, x2, y , 7, 7 ) ;
GfxTextOut( ( "Marketcalls - Range Filter"),13,y-90);
GfxTextOut( (" "),27,y-100);
if(SelectedValue(Buycontinue))
{
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);
GfxTextOut( ("Profit/Loss : " + NumToStr(Close-ValueWhen(Buy,BuyPrice),1.2)), 13, y-30);
}
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();
thank you sir but shows some error .
if( Buy[i] ) PlotText(“Buy”,i,L[i],colorWhite,colorLime,-70);
error16 toomany arguements.
-S.Ghaneshakumar
Consider using Amibroker 6.0 or higher versions.
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
how to make it atr based seen as a trading view same in amibroker?
please guide