
One of the challenges with automating trading strategies or monitoring trading systems is that buy or sell signals often appear during the formation of the current bar, but these signals may disappear before the candlestick is complete. This issue arises when the signal fluctuates across the threshold levels that determine the presence of a buy or sell signal, a phenomenon known as current bar repainting.
To address this issue, we’ll explore a method to prevent it. We’ll use a straightforward example of an EMA (Exponential Moving Average) crossover AFL (AmiBroker Formula Language) code to demonstrate how to transform a code that repaints into one that does not repaint.
The Current bar Repainting EMA crossoverAmibroker AFL code.
_SECTION_BEGIN("Simple EMA Crossover");
LongMA = EMA( C, Param("Long Period", 50, 30, 100, 5 ));
ShortMA = EMA( C, Param("Short Period", 5, 3, 50, 1 ));
Buy = Cross( ShortMA, LongMA );
Sell = Cross( LongMA, ShortMA );
Plot(LongMA,"LMA",colorGreen);
Plot(LongMA,"SMA",colorRed);
shape = Buy * shapeUpArrow + Sell * shapeDownArrow;
PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) );
GraphXSpace = 5;
_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();
To overcome the issue of current bar repainting, it’s essential to introduce a one-bar delay to the buy and sell variables. This approach ensures that signals are calculated based solely on the closing prices. Additionally, setting the trade delays to 0,0,0,0 and defining the buyprice and sellprice at the opening price can further enhance the accuracy and reliability of the signals.
The Non Repainting Amibroker AFL code.
_SECTION_BEGIN("Simple EMA Crossover");
LongMA = EMA( C, Param("Long Period", 50, 30, 100, 5 ));
ShortMA = EMA( C, Param("Short Period", 5, 3, 50, 1 ));
Buy = Cross( ShortMA, LongMA );
Sell = Cross( LongMA, ShortMA );
Buy = ref(buy,-1);
Sell = ref(sell,-1);
Buy = Exrem(buy,sell);
Sell = Exrem(sell,buy);
settradedelays(0,0,0,0);
buyprice = valuewhen(buy,open);
sellprice = valuewhen(sell,open);
Plot(LongMA,"LMA",colorGreen);
Plot(LongMA,"SMA",colorRed);
shape = Buy * shapeUpArrow + Sell * shapeDownArrow;
PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) );
GraphXSpace = 5;
_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();
Now after applying the indicator, you can see the current bar doesn’t have an indicator plotted and the Buy/Signal will appear only once the candle closes and the condition matches in real-time thus avoiding current bar repainting.
Can’t we simply chnage the to below after calculating LongMA and ShortMa
LongMA= ref (LongMA, -1);
ShortMA=ref (ShortMa, -1);
That will not work because after doing
LongMA= ref (LongMA, -1);
ShortMA=ref (ShortMa, -1);
that means still your last candle is not nullified.
LongMA[barcount-1]=LongMA[barcount-2]
ShortMA[barcount-1]=ShortMA[barcount-2]
one way you can handle is you can change the buy and sell condition like this
Buy = Cross( ref(ShortMA,-1), ref(LongMA,-1) );
Sell = Cross( ref(LongMA,-1), ref(ShortMA,-1) );
But still you have to nullify the last values of long and short MA
LongMA[barcount-1] = ShortMA[barcount-1] = null;
Hope you got it!
I am getting Syntax error 31 at the end of the Section End of Price.
Pls guide. Thanks
got the problem of Syntax resolved. Thanks !
What if someone use ?
Buy = lastvalue(Cross( ShortMA, LongMA ));
Sell = lastvalie(Cross( LongMA, ShortMA ));
Correction
Buy = lastvalue(Cross( ShortMA, LongMA ),-1);
Sell = lastvalue(Cross( LongMA, ShortMA ),-1);
Getting syntax error. Can you please correct afl?
Thanks
Delete the double quotes and replace with new double quotes. Sometimes issues happens when your perform copy + paste and the double quotes gets converted in to similar symbol but it is not exactly double quotes. Try replacing them.
Googled double quotes and found that it is double apostrophe “”
When copying and pasting the AFL, This “””” turns in different shape and creating syntax error
Now working fine . If shape down and up arrow mark like supertrend chart with HA Candles price is inserted , it would be better and visible easily
Thanks
This is just a prototype code to make your own code non repainting. Buy and Sell Arrows are nothing to do with that. Use this snippets to build your arrows better http://www.marketcalls.in/amibroker/code-snippets-plot-buy-sell-arrows-amibroker.html
This is a really smart idea. I never thought about it…
The only issue is that your signal is delayed till the bar closes, which will affect trading systems that use higher time frames. But then there is a tradeoff somewhere to avoid repainting.
Another choice is to use level thresholds to avoid repainting, but that involves re-inventing your trading logic.
Rajendran sir can u plz help me to solve the current bar repainting problem in my afl.here is the code.
http://www.traderji.com/amibroker/95779-polynomial-curve-2.html
Hi Rajandran, Thanks for this info, I was looking for this solution since many days.
I have a question,
Does this logic work if I simply put below code in the end of the script?
I have used several emas and adding null to individual ema looks tedious, I was wondering if this works?
Buy[BarCount-1]=Null;
Sell[BarCount-1]=Null;
Short[BarCount-1]=Null;
Cover[BarCount-1]=Null;
Thanks,
Babu
You are absolutely right. Yes it will work! Just try it out.
Rajendran sir,
Buy[BarCount-1]=Null;
Sell[BarCount-1]=Null;
Short[BarCount-1]=Null;
Cover[BarCount-1]=Null;
Will these settings work in my system .iam using adx, bollingerbandsqueeze and polynomial in my buy sell conditions.
can we conevert rsi div afl from repainting to non repainting ?
No you cant cause it is the nature of the trading system you cant avoid repainting there.
sir,
in my afl, when i run the replay, the signal is getting plotted in the desired candle but it showing after so many bar getting passed. is it also repainting?
plz reply
dear sir,
My system is based on high-low break out not on close basis, when i written the code based on it,when high gets broken say 14 is the trigger buy,
when market triggers 14, blue arrow signal appears and when it goes down below 13.90 like that signal disappears, how to make the signal stay without re-painting in this scenario as soon as it triggers buy should stay on, kindly show some light for traders like us.
sir can u modify this afl this is repaint
//——————————————————————————
//
// Kenzie SR System – 09/2010
// Modified By Kenzie Sebastian ([email protected])
// Shared for milis [email protected]
//
//——————————————————————————
SetBarsRequired(200,0);
GraphXSpace = 7;
SetChartOptions(0,chartShowArrows|chartShowDates);
//—————Color————————
per1=6;
per2=2;
Om=MA(O,per1);
hm=MA(H,per1);
lm=MA(L,per1);
Cm=MA(C,per1);
HACLOSE=(Om+Hm+Lm+Cm)/4;
HaOpen = AMA( Ref( HaClose, -1 ), 0.5 );
HaHigh = Max( Hm, Max( HaClose, HaOpen ) );
HaLow = Min( Lm, Min( HaClose, HaOpen ) );
Of=MA(Haopen,per2);
Cf=MA(Haclose,per2);
Lf=IIf(haOpen<haClose,MA(Halow,per2),MA(Hahigh,per2));
Hf=IIf(haOpen Of, colorGreen, colorRed );
//—————————————————-
TrailStop = HHV( C – 2 * ATR(10), 15 );
ProfitTaker = EMA( H, 13 ) + 2 * ATR(10);
/* **********************************
Code to automatically identify pivots
********************************** */
// — what will be our lookback range for the hh and ll?
farback=140; //How Far back to go
nBars = 12; //Number of bars
// — Create 0-initialized arrays the size of barcount
aHPivs = H – H;
aLPivs = L – L;
// — More for future use, not necessary for basic plotting
aHPivHighs = H – H;
aLPivLows = L – L;
aHPivIdxs = H – H;
aLPivIdxs = L – L;
nHPivs = 0;
nLPivs = 0;
lastHPIdx = 0;
lastLPIdx = 0;
lastHPH = 0;
lastLPL = 0;
curPivBarIdx = 0;
// — looking back from the current bar, how many bars
// back were the hhv and llv values of the previous
// n bars, etc.?
aHHVBars = HHVBars(H, nBars);
aLLVBars = LLVBars(L, nBars);
aHHV = HHV(H, nBars);
aLLV = LLV(L, nBars);
// — Would like to set this up so pivots are calculated back from
// last visible bar to make it easy to “go back” and see the pivots
// this code would find. However, the first instance of
// _Trace output will show a value of 0
aVisBars = Status(“barvisible”);
nLastVisBar = LastValue(Highest(IIf(aVisBars, BarIndex(), 0)));
_TRACE(“Last visible bar: ” + nLastVisBar);
// — Initialize value of curTrend
curBar = (BarCount-1);
curTrend = “”;
if (aLLVBars[curBar] <
aHHVBars[curBar]) {
curTrend = "D";
}
else {
curTrend = "U";
}
// — Loop through bars. Search for
// entirely array-based approach
// in future version
for (i=0; i<BarCount; i++) {
curBar = (BarCount – 1) – i;
// — Have we identified a pivot? If trend is down…
if (aLLVBars[curBar] lastHPIdx) {
// — Bar and price info for candidate pivot
candIdx = curBar – aHHVBars[curBar];
candPrc = aHHV[curBar];
if (
lastHPH lastLPIdx AND
candIdx < curBar) {
// — OK, we'll add this as a pivot…
aHPivs[candIdx] = 1;
// …and then rearrange elements in the
// pivot information arrays
for (j=0; j candPrc AND
candIdx > lastHPIdx AND
candIdx < curBar) {
// — OK, we'll add this as a pivot…
aLPivs[candIdx] = 1;
// …and then rearrange elements in the
// pivot information arrays
for (j=0; j (MA(H,n)+MA(L,n))/2;// then Buy next bar at market;
b = C < (MA(H,n)+MA(L,n))/2;// then Sell Short next bar at market;
state=IIf(BarsSince(a) 0,True, False);
TMM=IIf(LinRegSlope(MA(C, DTM),2) > 0,True, False);
TSS=IIf(LinRegSlope(MA(C, DTS),2) > 0,True, False);
//============== VOLUME ==============
Vlp=30; //Volume lookback period
Vrg=MA(V,Vlp);
St = StDev(Vrg,Vlp);
Vp3 = Vrg + 3*st;
Vp2 = Vrg + 2*st;;
Vp1 = Vrg + 1*st;;
Vn1 = Vrg -1*st;
Vn2 = Vrg -2*st;
//============== WILLIAM’S %R ==============
WR = ((HHV(H,14) – C) /(HHV (H,14) -LLV (L,14))) *-100;
//============== A/D ==============
TRH = IIf(Ref(C, -1) > H, Ref(C, -1), H);
TRL = IIf(Ref(C, -1) Ref(C, -1), C – TRL, IIf(C Ref(wad,-1);
wd = wad Signal();
MS1= MACD() StochD(10,5,5);
StSell=StochK(10,5) MDI(14);
adxsell1 = MDI(14)> PDI(14);
//============== TMA ==============
function ZeroLagTEMA( array, period )
{
TMA1 = TEMA( array, period );
TMA2 = TEMA( TMA1, period );
Diff = TMA1 – TMA2;
return TMA1 + Diff ;
}
haClose = ( haClose + haOpen + haHigh + haLow )/4;
periodtm = 55;
ZLHa = ZeroLagTEMA( haClose, periodtm );
ZLTyp = ZeroLagTEMA( Avg, periodtm );
TMBuy = Cross( ZLTyp, ZLHa );
TMSell = Cross( ZLHa, ZLTyp );
TMBuy1= ZLTyp> ZLHa ;
TMSell1=ZLHa> ZLTyp ;
//============== ZLW ==============
R = ((HHV(H,14) – C) /(HHV (H,14) -LLV (L,14))) *-100;
MaxGraph=10;
PeriodZ= 10;
EMA1= EMA(R,PeriodZ);
EMA2= EMA(EMA1,5);
Difference= EMA1 – EMA2;
ZeroLagEMA= EMA1 + Difference;
PR=100-abs(ZeroLagEMA);
MoveAvg=MA(PR,5);
ZBuy = Cross(PR,moveAvg) AND PR70;
ZBuy1= PR>= MoveAvg AND PR>= Ref(PR,-1) ;
ZSell1=(PR = MoveAvg AND PR EMA(RSI(14),9);
BrRSI = RSI(14) Vp2,EncodeColor(colorLime)+”(Very High)”,WriteIf(V>Vp1,EncodeColor(colorLime)+”(High)”,WriteIf
(V>Vrg,EncodeColor(colorLime)+”(Above Average)”,
WriteIf(VVn1,EncodeColor(ColorRGB(255,0,128))+”(Less than Average)”,WriteIf
(V0 AND TS=0.3 AND TS=0.6,EncodeColor(colorGreen)+”Strong Up Trend”,
WriteIf(TS-0.3,EncodeColor(colorPink)+”Weak Down Trend”,
WriteIf(TS-0.6 ,EncodeColor(ColorRGB(255,0,128))+”Medium Down Trend”,
WriteIf(TS0 AND TM=0.3 AND TM=0.6,EncodeColor(colorGreen)+”Strong Up Trend”,
WriteIf(TM-0.3,EncodeColor(colorPink)+”Weak Down Trend”,
WriteIf(TM-0.6 ,EncodeColor(ColorRGB(255,0,128))+”Medium Down Trend”,
WriteIf(TM0 AND TL=0.3 AND TL=0.6,EncodeColor(colorGreen)+”Strong Up Trend”,
WriteIf(TL-0.3,EncodeColor(colorPink)+”Weak Down Trend”,
WriteIf(TL-0.6 ,EncodeColor(ColorRGB(255,0,128))+”Medium Down Trend”,
WriteIf(TL30 AND RSI(14)<70,EncodeColor(colorBrightGreen),WriteIf
(RSI(14)30 AND RSI(14)<70," Range"+EncodeColor(colorBrightGreen),WriteIf(RSI(14)-100 AND CCI(14)<100,EncodeColor(colorBrightGreen),WriteIf
(CCI(14)-100 AND CCI(14)<100," Range"+EncodeColor(colorBrightGreen),WriteIf(CCI(14)-10 AND ROC(C,14)<10,EncodeColor
(colorBrightGreen),WriteIf(ROC(C,14)-10 AND ROC(C,14)<10," Range"+EncodeColor(colorBrightGreen),WriteIf(ROC(C,14)-80 AND WR<-20,EncodeColor(colorBrightGreen),WriteIf
(WR-80 AND WR<-20," Range"+EncodeColor(colorBrightGreen),WriteIf(WR<-80 ,"
OverSold"+EncodeColor(07)," OverBought"+EncodeColor(colorRed)))
+"n"+EncodeColor(colorGrey50)+"————————————–"
+"n"+EncodeColor(colorGold)+"• Signal(IBuy): " + WriteIf(Ibuy,EncodeColor
(colorBrightGreen)+"BuyWarning",WriteIf(Isell,EncodeColor(colorRed)+"SellWarning",WriteIf(BlRSI,EncodeColor
(colorBrightGreen)+"BullishZone",WriteIf(BrRSI,EncodeColor(colorRed)+"BearishZone","Neutral"))))
+"n"+EncodeColor(colorGold)+"• Signal(TMA): " + WriteIf(TMBuy,EncodeColor(colorBrightGreen)+"Buy",WriteIf
(TMSell,EncodeColor(colorRed)+"Sell",WriteIf(TMBuy1,EncodeColor(colorBrightGreen)+"Bullish",WriteIf
(TMSell1,EncodeColor(colorRed)+"Bearish","Neutral"))))
+"n"+EncodeColor(colorGold)+"• Signal(MACD): " + WriteIf(MB,EncodeColor(colorBrightGreen)+"Buy",WriteIf
(MS,EncodeColor(colorRed)+"Sell",WriteIf(MB1,EncodeColor(colorBrightGreen)+"Bullish",WriteIf(MS1,EncodeColor
(colorRed)+"Bearish","Neutral"))))
+"n"+EncodeColor(colorGold)+"• Signal(Stoch): " + WriteIf(StochBuy,EncodeColor(colorBrightGreen)+"Buy",WriteIf
(StochSell,EncodeColor(colorRed)+"Sell",WriteIf(StBuy,EncodeColor(colorBrightGreen)+"Bullish",WriteIf
(StSell,EncodeColor(colorRed)+"Bearish","Neutral"))))
+"n"+EncodeColor(colorGold)+"• Signal(ADX): " + WriteIf(adxBuy,EncodeColor(colorBrightGreen)+"Buy",WriteIf
(adxSell,EncodeColor(colorRed)+"Sell",WriteIf(adxBuy1,EncodeColor(colorBrightGreen)+"Bullish",WriteIf
(adxSell1,EncodeColor(colorRed)+"Bearish","Neutral"))))
+"n"+EncodeColor(colorGrey50)+"————————————–"
+"n"+ EncodeColor(47) +"• TrStop: " +EncodeColor(colorLime)+ WriteVal(TrailStop,format=1.0)
+ EncodeColor(47) +" TrgPrice: " + EncodeColor(colorLime)+WriteVal(Profittaker,format=1.0)
+"n"+ EncodeColor(47) +"• R1: " +EncodeColor(colorOrange)+ WriteVal(r1,format=1.0)
+ EncodeColor(47) +" R2: " + EncodeColor(colorOrange)+WriteVal(r2,format=1.0)
+ EncodeColor(47) +" R3: " + EncodeColor(colorOrange)+WriteVal(r3,format=1.0)
+"n"+ EncodeColor(47) +"• S1: " +EncodeColor(colorOrange)+ WriteVal(s1,format=1.0)
+ EncodeColor(47) +" S2: " + EncodeColor(colorOrange)+WriteVal(s2,format=1.0)
+ EncodeColor(47) +" S3: " + EncodeColor(colorOrange)+WriteVal(s3,format=1.0)
+"n"+EncodeColor(colorGrey50)+"————————————–"
);
//============== BACKGROUND NAME ==============
pxwidth = Status("pxwidth");
pxheight = Status("pxheight");
GfxSetOverlayMode(1);
GfxSetBkMode(0); // transparent
GfxSelectFont("Amienne", Status("pxheight")/15);
GfxSetTextColor( colorGrey40 );
//GfxTextOut( "Kenzie Sebastian", Status("pxwidth")/5.3, Status("pxheight")/5 );
//============================
////BACKGROUND COLOR////////////////////////////////////////////////////////
//SetChartBkColor(ColorRGB(255,200,255));
//SetChartBkGradientFill( colorPlum, colorPlum);
/////////////////////////////////////////////////////////////////////////////////////
_SECTION_END();
_SECTION_BEGIN("Keltner Bands");
P = ParamField("Price field",-1);
Periods = Param("Periods", 15, 2, 300, 1 );
Width = Param("Width", 2, 0, 10, 0.05 );
Color = ParamColor("Color", colorCycle );
Style = ParamStyle("Style");
CenterLine = MA( P, Periods );
KTop = CenterLine + Width * ATR( Periods );
KBot = CenterLine – Width * ATR( Periods );
Plot( KTop, "KBTop" + _PARAM_VALUES(), Color, Style );
Plot( KBot, "KBBot" + _PARAM_VALUES(), Color, Style );
_SECTION_END();
Hi Rajandran,
Is it possible to modify the code above posted by jitendra so that it does not repaint?
How to arrows unchanged? plz.
hello Rajandran,
kindly make this indicator as non repainting.
==================================================================
PositionSize = MarginDeposit = 1;
Z=Optimize(“Z”,Param(“Zig”,2,.1,10,0.1),.1,10,.1);
p=Param(“Volume EMA”,15,0,100,1);
Buy = Cover = C>Ref(C,-1) AND Ref(C,-1)>Ref(C,-2) AND V>EMA(V,p) AND Zig(C,Z)>Ref(Zig(C,Z),-1) ;
Sell = Short = C<Ref(C,-1) AND Ref(C,-1)EMA(V,p) AND Zig(C,Z)O,colorGreen,colorRed),styleBar|styleThick);
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);
/*http://www.traders.com/documentation…ackissues.html
go to 2009 Articles > June 2009 > Traders Tips
LISTING 1*/
Version(5.20); // requires v5.20
SetBarsRequired(sbrAll);
// get start date
Start = Cross( DateNum(), ParamDate(“Start date”, “2005-10-30” ) );
Started = Flip( Start, 0 );
StopMode = ParamList(“Stop Mode”, “Fixed|Chandelier|Modified ATR” );
StopLevel = Param(“Fixed perc %”, 14, 0.1, 50, 0.1)/100;
StopATRFactor = Param(“ATR multiple”, 4, 0.5, 10, 0.1 );
StopATRPeriod = Param(“ATR period”, 14, 3, 50 );
// calculate support and resistance levels
if( StopMode == “Fixed” ) // fixed percent trailing stop
{
sup = C * ( 1 – stoplevel );
res = C * ( 1 + stoplevel );
}
else // Chandelier ATR-based stop
if( StopMode == “Chandelier” )
{
sup = C – StopATRFactor * ATR( StopATRPeriod );
res = C + StopATRFactor * ATR( StopATRPeriod );
}
else
{
HL = H – L;
MAHL = 1.5 * MA( HL, StopATRPeriod );
HiLo = IIf( HL < MAHL, HL, MAHL );
H1 = Ref( H, -1 );
L1 = Ref( L, -1 );
C1 = Ref( C, -1 );
Href = IIf( L = L1, C1 – L, ( C1 – L ) – ( L1 – H ) / 2 );
diff1 = Max( HiLo, HRef );
diff2 = Max( diff1, LRef );
ATRmod = Wilders( diff2, StopATRPeriod );
sup = C – StopATRFactor * ATRmod ;
res = C + StopATRFactor * ATRmod ;
}
// calculate trailing stop line
trailARRAY = Null;
trailstop = 0;
for( i = 1; i trailstop AND C[ i – 1 ] > trailstop )
trailstop = Max( trailstop, sup[ i ] );
else
if( C[ i ] < trailstop AND C[ i – 1 ] trailstop, sup[ i ], res[ i ] );
trailARRAY[ i ] = trailstop;
}
// generate buy/sell signals based on crossover with trail stop line
Buy = Start OR Cross( C, trailArray );
Sell = Cross( trailArray, C );
PlotShapes(Buy*shapeUpArrow,colorGreen,0,trailarray);
PlotShapes(Sell*shapeDownArrow,colorRed,0,trailarray);
Plot( Close,”Price”,colorBlack,styleBar);
SetBarFillColor( colorYellow );
Plot( trailARRAY,”trailing stop level”, ParamColor( “Color”, colorCycle ), ParamStyle(“Style”));
It was very helpful for me. Thank You and God Bless You.