I had posted a thread a few days back with similar topic but i was unable to explain my issue clearly. In this post I shall try to be more clear. Consider the below chart
Lets Say we are at patternFound bar and we have bar distances of leg_D, leg_C, leg_B and leg_0 at this bar.
We have to find distance of leg_A. We know that leg_A is the highest point between leg_0 and leg_B. so we calculate by first going to leg_b and then calculating the HHVBars between leg_B and leg_0. right? BarRefLeg_A=Ref( HHVBars(H, BarRefLeg_0 - BarRegLeg_B), -BarRefLegB);
Pretty straight forward you would think, right?. But his will not work. why? Because Leg_B does not have the correct values of BarRefLeg_0 and BarRefLeg_B. It's the patternFound bar that has the correct values for these arrays. When we do a Ref(something, -n) all the references are now taken from bar_n (one that is n bars before from current bar).
My question is very simple
Is there any way in this world that amibroker can be instructed to refer to the calling bar arrays instead of the referred bar array.
So essentially this BarRefLeg_A=Ref( HHVBars(H, BarRefLeg_0_from_calling_bar - BarRegLeg_B_from_calling_bar), -BarRefLegB);
I know you would say do a valuewhen(patternFound, BarRefLeg_0 - BarRegLeg_B, 0) to get the values from the callingBar(patternFound Bar). Yes that may work. But that is not an option for me as I don't know, at runtime, how may patternFound bars exist between Leg_B and the Patternfound bar concerned. there may be 0, 10, 16, etc Patternfound bars between currentBar and Leg_B
Yes I can do a loop that goes back, lets say 50 bars, from patternFound to Leg_B and do the job. Yes I am doing that now. But is there any way to do this without loops? thankyou for reading. Hope I have been able to explain my issue. thanks
@Tomasz have you thought about making a function that always returns currentBar/callingBar values even when used inside Ref(). such as Ref(BarsSince(H>CurrentBar(H)), -20);
Here currentBar(H) returns the High of the currentBar (not the high of the bar 20 bars before) even though it has been called inside a Ref(). I am saying this because this has a lot of potential usage. This being low level function one may use it in variety of scenarios and further create custom wrapper functions that suits their specific need.
You just need to re-read Understanding how AFL works
Data are processed using entire vectors at once in parallel and for this reason, you can't have serial dependence.
If you are processing vectors in PARALLEL way (as AFL does) you have O(N) complexity. If you are processing using double nested loops you have O(N2) complexity. That's huge difference. You don't want N2 term.
CallingBar(H) inside a ref(callingBar(H), n) returns H and not ref(H, n).
Are you saying that this will create serial dependency and as such creating such a function is not possible?
My logic is that barsSinceCompare(), which is a higher level function, uses such a function. If it is possible to create barsSinceCompare() then it must be possible to create CallingBar(). Am i not right?
What you have imagined with CallingBar() is against the fundamental principle of vector processing and introduces O(N2) computational complexity (second nested loop) I was writing about and that is specifically what we want to AVOID.
Can you post your best attempt? I usually find that using boolean arrays for the individual events (0, A, B, C, D, PatternFound) combined with BarsSince() and ValueWhen() will get me what I need. However, I'm not sure I fully understand your example.
My solution uses a loop from i=1 to i=50(max size of pattern). It moves from patternFound bar towards leg_0 and does the job. The result is perfect. but I want to get rid of the loop as much as possible. My afl is 5k lines so loops are to be avoided. tomasz claims that BarsSinceCompare(), most likely eliminating the need for the loop, can be used to solve the problem. I want to know how?
The data you uploaded is for 5-minute bars. That makes it rather difficult to select the 13:37 bar. Please see the previous comments from @Tomasz about posting code and working examples. It's still really unclear what you're trying to achieve.
Sorry Matt. I made a mistake in uploading the file. I have now uploaded the correct file. Apologies again.
you have to assume that BarRefLeg_B is an array although it is scalar in my example. so to calculate Leg_A first we go to Leg_B and then calculate the highest value between it and Leg_0.
It is very easy to do this using a loop like the one in my code But is it possible to do this without a loop?
That is a fair point you made that valueWhen (patternFound, barRef_B, 0) can be used but what if there are many patternFound(s) within the pattern itself. Then we wont be able to know which future reference patternFound to get using valueWhen().