Rajandran R Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, USDINR and High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in and Co-Creator of Algomojo (Algorithmic Trading Platform for DIY Traders)

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

4 min read

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.algomojo.com
//One Stop Shop for Traders - www.traderskart.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( "[email protected]" + 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();
Rajandran R Telecom Engineer turned Full-time Derivative Trader. Mostly Trading Nifty, Banknifty, USDINR and High Liquid Stock Derivatives. Trading the Markets Since 2006 onwards. Using Market Profile and Orderflow for more than a decade. Designed and published 100+ open source trading systems on various trading tools. Strongly believe that market understanding and robust trading frameworks are the key to the trading success. Writing about Markets, Trading System Design, Market Sentiment, Trading Softwares & Trading Nuances since 2007 onwards. Author of Marketcalls.in and Co-Creator of Algomojo (Algorithmic Trading Platform for DIY Traders)

Plotting Day Wise Equity Curve using Amibroker

We know that Amibroker provides an equity curve for the whole strategy. Is there a way where we can build a simple Day Wise...
Rajandran R
1 min read

Simple Open Range Breakout Trading System with Exploration –…

Opening Range is very often a measure of security high and low generally monitored by breakout traders to gauge the sentiment of the market....
Rajandran R
5 min read

Range Filter – Trading Strategy – Amibroker – Better…

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...
Rajandran R
4 min read

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

  1. thank you sir but shows some error .

    if( Buy[i] ) PlotText(“Buy”,i,L[i],colorWhite,colorLime,-70);
    error16 toomany arguements.

    -S.Ghaneshakumar

Leave a Reply

Get Notifications, Alerts on Market Updates, Trading Tools, Automation & More