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();
THANKS. GOOD INITIATIVE TO HELP.
Sir, i tred a lot to backtest this halftrend AFL in Amibroker, but it is not giving any output / result, how to backtest this?
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??
Backtest is not working for me as well. Any suggestions? Thank you very much.