AFL for iterating Candles

I am coding for a scanner in AmiBroker, however have stuck with below point:

In 15-min timeframe, I have to check if Doji is formed in last five candles only. And if yes then I need the High and Low of the candle which made Doji. In the previous candle (prior to the current in-progress candle), I have to check if the close is either greater than High of Doji candle or close is lower than low of Doji candle. If yes, then I want that symbol to be reflected in scanner. While I have been able to code Doji but when I run below code, it gives me all symbols and for all candles:

SetChartOptions(0,chartShowArrows|chartShowDates);
Plot( C, "Close", ParamColor("Color", colorBlack ), ParamStyle("Style") | GetPriceStyle() ); 
doji = (Ref(Open,-1) -Ref(Close,-1))<=((Ref(H,-1)-Ref(L,-1))*0.08);
showDoji = ParamToggle("Doji ","SHOW|HIDE",1);
if( showDoji )
  {
    PlotShapes( shapeDigit0*doji , colorGreen, 0, H, 45 );  
    }
Filter=doji;
AddColumn (doji ,"Doji ",1);

Thanks.

@dailytradealerts perhaps try this small change,

doji = abs(Ref(Open,-1) -Ref(Close,-1))<=((Ref(H,-1)-Ref(L,-1))*0.08);
2 Likes

FWIW, there is just single call of Ref() function required since all use same lookback period.

doji = Ref(abs(O-C) <= ((H-L)*0.08), -1);
6 Likes

Wow!!, thanks @fxshrat, didn't know that Ref() can be used this way too.

@NowToLook, it is quite more efficient than the original (corrected) one, but essentially it is like to write:

dojis = abs(O-C) <= ((H-L)*0.08);  
prevBarDojis = Ref(dojis, -1); // btw, this line, based on the description, probably is not needed

If I had to implement the OP request, I would probably rewrite it in this way.
Just a bit slower but clearer in scope, with the first line clearly defining what are the "doji" candles.
For the rest of code, I would probably use Hold() to examine the 5 bars following any doji.

5 Likes

Thanks for the explanation (as always) @beppe , my comment was an "exclamation of amazement" ( i was totally unaware) that the Ref() can be used directly the way @fxshrat demonstrated above and had i known earlier , could have trimmed a lot of lines , saved a lot of time and gained a lot of speed (collective) in my AFLs :smile:

1 Like

@NowToLook, both @portfoliobuilder and @fxshrat replies are useful for improving the knowledge of the OP by helping it overcome his problem.

And it is certainly a good thing that many other readers, like you and me, can benefit from their observations: we are all here to learn!

Re my post, in general, in my code, I prefer to be more verbose than many other developers, favoring easy to understand statements than performance.

Splitting the code over multiple lines and using "redundant" variables allows me to write detailed explorations to understand better if the logic I'm writing is actually doing what I want to achieve or not. It is just a matter of personal preference.

5 Likes

Absolutely @beppe , in fact, i been following your advice (about using exploration to debug) so much so that perhaps that IS the very reason i remained unaware about the direct use of some functions :smile:
P.S:
I have had so many incidents where your "Exploration to Debug" advice/method humbled me by showing me that my Afl results were dangerously unreal :smile:

4 Likes

That is very good habit indeed.

Just in case you wondered, variable assignment in AFL (even if it is array) is very cheap computationally since AmiBroker does not copy arrays on assignment. It just copies pointer and increases reference count. So using extra variables does not slow things down.

7 Likes