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)

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

//Coded by Rajandran R - www.marketcalls.in / www.algomojo.com
//Code Inspired from Tradingview Pinescript
//Orginal Credits : Everget 
//Tradingview Url : https://www.tradingview.com/script/U1SJ8ubc-HalfTrend/


_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( "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);




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

[Live Coding Webinar] Build Your First Trading Bridge for…

In this course, you will be learning to build your own trading bridge using Python. This 60-minute session is perfect for traders, Python enthusiasts,...
Rajandran R
1 min read

[Webinar] Understanding and Mitigating Curve Fitting in System Trading

"Understanding and Mitigating Curve Fitting in System Trading"! This dynamic session aims to equip novice to intermediate traders, quantitative analysts, and financial engineers with...
Rajandran R
1 min read

P-Signal Strategy Long Only Strategy – Amibroker AFL Code

This tutorial provides an overview of the P-Signal reversal strategy, a quantitative trading strategy that utilizes statistical parameters and error functions to generate probabilistic...
Rajandran R
2 min read

4 Replies to “HalfTrend – Amibroker AFL Code – Better than Supertrend”

  1. Sir, i tred a lot to backtest this halftrend AFL in Amibroker, but it is not giving any output / result, how to backtest this?

  2. Hi sir,
    I want to add some buffer points to take entry, Whenever we get signal we add some buffer points in High or Low price of signal candle, once price break high or low level with buffer we enter in trade. is it possible??

Leave a Reply

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