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)

Non Repainting NMA Swing Trading System AFL code

5 min read

The core logic of the “NICK Swing Trading System” system implemented in the AFL code provided below revolves around a trend-following strategy that utilizes a variation of the Average True Range (ATR) and a custom smoothing of price data to determine market direction and generate trading signals.

Code is Implemented with Following Features

1)Non Repainting Signals
2)Trading Dashboard
3)Exploration Features
4)Trading Dashboard
5)Arbitrary Target Levels

NMA Swing Trading System – Amibroker AFL Code

_SECTION_BEGIN("NICK MA Swing");
SetBarsRequired(200,0);

GraphXSpace = 5;
SetChartOptions(0,chartShowArrows|chartShowDates);
k =  Optimize("K",Param("K",2,0.25,5,0.25),0.25,5,0.25);
Per= Optimize("atr",Param("atr",20,3,20,1),3,20,1);
HACLOSE=(O+H+L+C)/4;
HaOpen = AMA( Ref( HaClose,  -1 ),  0.5 );
HaHigh = Max( H,  Max( HaClose,  HaOpen ) );
HaLow = Min( L,  Min( HaClose,  HaOpen ) );
PlotOHLC( HaOpen, HaHigh, HaLow, HaClose, "" + Name(), colorBlack, styleCandle | styleNoLabel );
j=Haclose;

//=======================================================================================================================
//=========================Indicator==============================================================================================
f=ATR(15);

rfsctor = WMA(H-L, Per);

revers = k * rfsctor;

Trend = 1;  
NW[0] = 0;  



for(i = 1; i < BarCount; i++)
{
 if(Trend[i-1] == 1)                
 {
  if(j[i] < NW[i-1])                 
  {
   Trend[i] = -1;                   
   NW[i] = j[i] + Revers[i];        
  }
  else                              
  {
   Trend[i] = 1;
   if((j[i] - Revers[i]) > NW[i-1])
   {
    NW[i] = j[i] - Revers[i]; 
   }
   else
   {
    NW[i] = NW[i-1];
   }
  } 
 }
 if(Trend[i-1] == -1)               
 {
  if(j[i] > NW[i-1])                
  {
   Trend[i] = 1;                    
   NW[i] = j[i] - Revers[i];        
  }
  else                              
  {
   Trend[i] = -1;
   if((j[i] + Revers[i]) < NW[i-1]) 
   {
    NW[i] = j[i] + Revers[i]; 
   }
   else
   {
    NW[i] = NW[i-1];
   }
  }
 }
}

//===============system================

Plot(NW, "", IIf(Trend == 1, 27, 4), 4);
Buy=NW<HACLOSE;
Sell=NW>HACLOSE;
SellPrice=ValueWhen(Sell,C,1);
BuyPrice=ValueWhen(Buy,C,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);


NMAB= NW<HACLOSE;
NMAS= NW>HACLOSE;

NMA_status= WriteIf(NMAB, "BUY MODE", WriteIf(NMAS, "SELL MODE", "NEUTRAL"));
NMAS_Col=IIf(NMAB, colorGreen, IIf(NMAS, colorRed, colorLightGrey));
Filter=1;
AddColumn( NW[BarCount-1], "SAR", 1.2 );
AddColumn( HACLOSE, "HA Close", 1.2 );
AddColumn( C, "Close", 1.2 );
AddTextColumn(NMA_status, "MODE", 1, colorWhite, NMAS_Col);
AddColumn( DateTime(), "Date / Time", formatDateTime ); 
_SECTION_END();
//=================TITLE================================================================================================
_SECTION_BEGIN("Title");
if( Status("action") == actionIndicator ) 
(
Title = EncodeColor(colorWhite)+ "NICK MA Swing System" + " - " +  Name() + " - " + EncodeColor(colorRed)+ Interval(2) + EncodeColor(colorWhite) +
 "  - " + Date() +" - "+"\n" +EncodeColor(colorRed) +"Op-"+O+"  "+"Hi-"+H+"  "+"Lo-"+L+"  "+
"Cl-"+C+"  "+ "Vol= "+ WriteVal(V)+"\n"+ 
EncodeColor(colorLime)+
WriteIf (Buy , " GO LONG / Reverse Signal at "+C+"  ","")+
WriteIf (Sell , " EXIT LONG / Reverse Signal at "+C+"  ","")+"\n"+EncodeColor(colorWhite)+
WriteIf(Sell , "Total Profit/Loss for the Last Trade Rs."+(C-BuyPrice)+"","")+
WriteIf(Buy  , "Total Profit/Loss for the Last trade Rs."+(SellPrice-C)+"",""));
//WriteIf(Long AND NOT Buy, "Trade : Long - Entry price Rs."+(BuyPrice),"")+
//WriteIf(shrt AND NOT Sell, "Trade : Short - Entry price Rs."+(SellPrice),"")+"\n"+ 
//WriteIf(Long AND NOT Buy, "Current Profit/Loss Rs."+(C-BuyPrice)+"","")+
//WriteIf(shrt AND NOT Sell, "Current Profit/Loss Rs."+(SellPrice-C)+"",""));
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 = H[i];
sig = "BUY";
sl = Ref(NW,-1);
tar1 = entry + (entry * .0050);
tar2 = entry + (entry * .0092);
tar3 = entry + (entry * .0179);
 
bars = i;
i = 0;
}
if(Sell[i] == 1)
{
sig = "SELL";
entry = L[i];
sl = Ref(NW,-1);
tar1 = entry - (entry * .0050);
tar2 = entry - (entry * .0112);
tar3 = entry - (entry * .0212);
 
 
bars = i;
i = 0;
}
}
Offset = 20;
Clr = IIf(sig == "BUY", colorLime, colorRed);
ssl = IIf(bars == BarCount-1, NW[BarCount-1], Ref(NW, -1));
sl = ssl[BarCount-1];

Plot(LineArray(bars-Offset, tar1, BarCount, tar1,1), "", Clr, styleLine|styleDots, Null, Null, Offset);
Plot(LineArray(bars-Offset, tar2, BarCount, tar2,1), "", Clr, styleLine|styleDots, Null, Null, Offset);
Plot(LineArray(bars-Offset, tar3, BarCount, tar3,1), "", Clr, styleLine|styleDots, Null, Null, Offset);



messageboard = ParamToggle("Message Board","Show|Hide",1);
if (messageboard == 1 )
{
GfxSelectFont( "Tahoma", 13, 100 );
GfxSetBkMode( 1 );
GfxSetTextColor( colorWhite );
 
if ( sig =="BUY")
{
GfxSelectSolidBrush( colorBlue ); // this is the box background color
}
else
{
GfxSelectSolidBrush( colorRed ); // this is the box background color
}
pxHeight = Status( "pxchartheight" ) ;
xx = Status( "pxchartwidth");
Left = 1100;
width = 310;
x = 5;
x2 = 290;
 
y = pxHeight;
 
GfxSelectPen( colorGreen, 1); // broader color
GfxRoundRect( x, y - 98, x2, y , 7, 7 ) ;
GfxTextOut( ( "NMA Trading System"),13,y-100);
GfxTextOut( (" "),27,y-100);
GfxTextOut( ("Last " + sig + " Signal came " + (BarCount-bars-1) * Interval()/60 + " mins ago"), 13, y-80) ; // The text format location
GfxTextOut( ("" + WriteIf(sig =="BUY",sig + " @ ",sig + " @") + " : " + entry), 13, y-60);
GfxTextOut( ("Trailing SL : " + sl + " (" + WriteVal(IIf(sig == "SELL",entry-sl,sl-entry), 2.2) + ")"), 13, y-40);
/*GfxTextOut( ("TGT:1 : " + tar1), 13, y -80);
GfxTextOut( ("TGT:2 : " + tar2), 13,y-60);
GfxTextOut( ("TGT:3 : " + tar3), 13,y-40);*/
GfxTextOut( ("Current P/L : " + WriteVal(IIf(sig == "BUY",(C-entry),(entry-C)),2.2)), 13, y-22);

}

_SECTION_END();



_SECTION_BEGIN("Magfied Market Price");

//Magfied Market Price
FS=Param("Font Size",30,11,100,1);
GfxSelectFont("Times New Roman", FS, 700, True ); 
GfxSetBkMode( colorWhite );  
GfxSetTextColor( ParamColor("Color",colorGreen) ); 
Hor=Param("Horizontal Position",800,1,1200,1);
Ver=Param("Vertical Position",12,1,830,1); 
GfxTextOut(""+C, Hor , Ver );
YC=TimeFrameGetPrice("C",inDaily,-1);
DD=Prec(C-YC,2);
xx=Prec((DD/YC)*100,2);
GfxSelectFont("Times New Roman", 11, 700, True ); 
GfxSetBkMode( colorBlack );  
GfxSetTextColor(ParamColor("Color",colorYellow) ); 
GfxTextOut(""+DD+"  ("+xx+"%)", Hor , Ver+45 );
 


_SECTION_END();

_SECTION_BEGIN("Time Left");
function GetSecondNum()
{
Time = Now( 4 );
Seconds = int( Time % 100 );
Minutes = int( Time / 100 % 100 );
Hours = int( Time / 10000 % 100 );
SecondNum = int( Hours * 60 * 60 + Minutes * 60 + Seconds );
return SecondNum;
}
RequestTimedRefresh( 1,False );
TimeFrame = Interval();
SecNumber = GetSecondNum();
Newperiod = SecNumber % TimeFrame == 0;
SecsLeft = SecNumber - int( SecNumber / TimeFrame ) * TimeFrame;
SecsToGo = TimeFrame - SecsLeft;

x=Param("xposn",50,0,1000,1);
y=Param("yposn",350,0,1000,1);

GfxSelectSolidBrush( ColorRGB( 230, 230, 230 ) );
GfxSelectPen( ColorRGB( 230, 230, 230 ), 2 );
if ( NewPeriod )
{
GfxSelectSolidBrush( colorYellow );
GfxSelectPen( colorYellow, 2 );
Say( "New period" );
}
//GfxRoundRect( x+45, y+40, x-3, y-2, 0, 0 );
//GfxSetBkMode(1);
GfxSelectFont( "Arial", 14, 700, False );
GfxSetTextColor( colorRed );
GfxTextOut( "Time Left :"+SecsToGo+"", x, y );
_SECTION_END();  

Here’s a breakdown of the key components of the trend-following logic:

  1. Heikin-Ashi Smoothed Price Calculation:
    • The formula begins by calculating Heikin-Ashi candlesticks, which are a popular technique for smoothing price data to reduce market noise and make trends easier to identify. The Heikin-Ashi candlesticks are calculated using the open, high, low, and close prices (HACLOSE, HaOpen, HaHigh, HaLow).
  2. Trend Determination with Custom Indicator:
    • The core of the trend-following logic is encapsulated within the for loop that iterates through each bar of the price data.
    • A custom indicator is calculated using a combination of the ATR and a scaling factor k. This indicator (NW) is used to determine the trend direction and generate buy or sell signals.
  3. Trend and Reversal Conditions:
    • The system maintains a Trend state variable that tracks the current market trend (1 for uptrend, -1 for downtrend).
    • For each bar, if the trend is up (Trend[i-1] == 1), the algorithm checks if the current Heikin-Ashi close (j[i]) is less than the previous indicator value (NW[i-1]). If so, it signifies a potential trend reversal to down, and the Trend is set to -1.
    • Conversely, if the trend is down (Trend[i-1] == -1), and the current Heikin-Ashi close (j[i]) is greater than the previous indicator value, it suggests a potential reversal to up, setting the Trend to 1.
  4. Dynamic Adjustment of Indicator Based on Trend:
    • The indicator value NW is dynamically adjusted based on the current price and trend. In an uptrend, if the price minus a scaled ATR (Revers[i]) is greater than the previous indicator, it’s used to update NW; otherwise, NW retains its previous value. This logic helps to lock in profits by raising the threshold for trend continuation.
    • A similar adjustment is made in downtrends, lowering the threshold for trend continuation.
  5. Signal Generation:
    • Trading signals are generated based on the position of the Heikin-Ashi close relative to the indicator value NW. A buy signal (Buy) is generated when NW is below the Heikin-Ashi close (HACLOSE), indicating an uptrend. Conversely, a sell signal (Sell) is generated when NW is above the Heikin-Ashi close, indicating a downtrend.
  6. Exclusion and Delay of Signals:
    • The ExRem function is used to exclude opposite signals to prevent immediate reversal, enhancing the system’s robustness.
    • Signals are also delayed by one bar (Ref(Buy,-1); Ref(Sell,-1);) to confirm the trend before execution.
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

18 Replies to “Non Repainting NMA Swing Trading System AFL code”

  1. dear raj sir

    chance less afl

    thanks a lot raj sir

    price bar missing how to add? pls reply sir ji

  2. Sir, Thank you very much for updating such valuable codes, I don’t know programing. Thing is that dash board is not displaying in my amibroker for NMA Swing system. so plz either do something for that or kindly give the code as the TSL must be display in digits somewhere on the screen. Second request is kindly give the code to change the colour of candles. green for upwad and red for downward moves.

    thank you in anticipation

    best regards

    Junaid

    1. Hi Junaid,

      If you are using amibroker 5.5 version and above goto Tools->Preferences->Axes and uncheck all the option and Apply it. You will
      be able to see the dashboard

      Rajandran R

      1. Thank you very much sir for your time. My version is an unregistered version 5.00.1 and in this version there is not AXES tab in preferences Popup menu. Plz help.

        Thanks once again sir.

        Best regards
        Junaid

  3. Sir,
    Plz do something for TSL. changing colour of candles is not necessory.
    Kingly give me TSL in digits. PLZ

    Thanx

      1. Thank u sir ……

        good,It is possible then i will send mt4 coding plz tell me how to convert afl code.

Leave a Reply

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