Rajandran R Founder of Marketcalls and Co-Founder Algomojo. Full-Time Derivative Trader. Expert in Designing Trading Systems (Amibroker, Ninjatrader, Metatrader, Python, Pinescript). Trading the markets since 2006. Mentoring Traders on Trading System Designing, Market Profile, Orderflow and Trade Automation.

HalfTrend – Amibroker AFL Code – Better than Supertrend

3 min read

Marketcalls had published Supertrend with multiple variations from 2012 onwards. And this time a very popular ATR based strategy Halftrend which is considered a better version of supertrend to manage sideways markets with lesser whipsaws is coded in Amibroker totally inspired by Tradingview Halftrend and MQL4 Halftrend Strategy source codes.

Strategy Timeframe : 15mins

Trading Symbol: Nifty Futures

Trading Commissions Used : 0.02% per leg

Historical Data Backtesting Period: 2011 – 2021

Position Sizing : 1 Lot (Fixed Lot)

Equity Curve

Drawdown Curve

Backtesting Report

Amibroker – Halftrend AFL Code

_SECTION_BEGIN("Half Trend Strategy");

SetPositionSize(1*RoundLotSize,spsShares);

amplitude = Param("Amplitude",2,1,10,1);
channelDeviation = Param("Channel Deviation",2,1,10,1);
showChannels = ParamToggle("Show ATR Channels","SHOW|HIDE",1);

main = Null;
trend = 0;
upLine = Null;
downLine = Null;
upperBand = Null;
lowerBand = Null;

atrHigh = Null;
atrLow = Null;


atr2 = ATR(100)/2;
dev = channelDeviation * atr2;

currentHigh = Ref(High, -abs(HHVBars(High,amplitude)));
currentLow =  Ref(low, -abs(LLVBars(Low,amplitude)));

upperBand = MA(High,amplitude);
lowerBand = MA(Low,amplitude);


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

	// update trend direction and main Support Resistance values
      if (trend[i-1] > 0) {
         main[i] = max(main[i-1], currentLow[i]);
         if (upperBand[i] < main[i] && Close[i] < Low[i-1]) {
            trend[i] = -1;
            main[i] = min(main[i-1], currentHigh[i]);
         }
         else trend[i] = trend[i-1] + 1;
      }
      else if (trend[i-1] < 0) {
         main[i] = min(main[i-1], currentHigh[i]);
         if (lowerBand[i] > main[i] && Close[i] > High[i-1]) {
            trend[i] = 1;
            main [i] = max(main[i-1], currentLow[i]);
         }
         else trend[i] = trend[i-1] - 1;
      }
      else {
         // initialize the first, left-most value
         if (Close[i] > Close[i-1]) {
            trend[i] = 1;
            main[i] = currentLow[i];
         }
         else {
            trend[i] = -1;
            main [i] = currentHigh[i];
         }
      }

      // update Support Resistance sections
      if (trend[i] > 0) {
         upLine[i] = main[i];
         downLine[i] = null;
         
         atrHigh[i] = upLine[i] + dev[i];
		 atrLow[i] = upLine[i] - dev[i];
         if (showChannels) {                       // make sure reversals become visible
            upLine[i-1] = main[i-1];
            if (trend[i-1] > 0)
               downLine[i-1] = null;
         }
      }
      else /*(trend[i] < 0)*/{
         upLine[i] = null;
         downLine[i] = main[i];
         
         atrHigh[i] = downLine[i] + dev[i];
		 atrLow[i] = downLine[i] - dev[i];
         if (showChannels) {                       // make sure reversals become visible
            if (trend[i-1] < 0)
               upLine[i-1] = Null;
            downLine[i-1] = main[i-1];
         }
      }
   


}//end of for loop





Plot(upLine,"UpLine",colorgreen,styleThick);
Plot(downLine,"DownLine",colorRed,styleThick);

Plot(atrHigh,"ATR High",colorgreen,styleThick|styleDashed);
Plot(atrLow,"ATR Low",colorRed,styleThick|styleDashed);



Buy = trend == 1 ;
Sell = trend == -1 ;



Buy = ExRem(Buy,Sell);
Sell = ExRem(Sell,Buy);

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);




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);




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 - Halftrend"),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", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
_SECTION_END();
Rajandran R Founder of Marketcalls and Co-Founder Algomojo. Full-Time Derivative Trader. Expert in Designing Trading Systems (Amibroker, Ninjatrader, Metatrader, Python, Pinescript). Trading the markets since 2006. Mentoring Traders on Trading System Designing, Market Profile, Orderflow and Trade Automation.

Mini Certification Course on Algorithmic Trading Strategies

If you are new to Automated trading? This certification course will help you to kickstart your automated trading with your broker and get to...
Rajandran R
1 min read

HalfTrend – Amibroker AFL Code – Better than Supertrend

Marketcalls had published Supertrend with multiple variations from 2012 onwards. And this time a very popular ATR based strategy Halftrend which is considered a...
Rajandran R
3 min read

AllinOneAlerts – Amibroker Alerts Module for Amibroker Users

AllinOneAlerts is one of the most important and most requested modules to bring all sorts of alerts with no extra coding efforts. Now even...
Rajandran R
5 min read

Leave a Reply

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