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
I don't know if I correctly understand your issue, but if you know the barindex of your pivots, you could also do a selective search, something like this:
BarRefLeg_B = BarCount -50; // example value
BarRefLeg_0 = BarCount -80; // example value
bi = BarIndex();
condition = bi <= BarRefLeg_B AND bi >= BarRefLeg_0;
searchArray = IIf(condition, H, Null);
Avalue = LastValue(Highest(searchArray));
Abarindex = LastValue(BarCount - HighestBars(searchArray)) - 1;
ArelativePosition = LastValue(BarCount - Abarindex);
PlotOHLC(O, H, L, C, "", IIf(condition, colorBlack, ColorRGB(200,200, 200)), styleBar);
PlotShapes(IIf(bi == BarRefLeg_B OR bi == BarRefLeg_0, shapeUpTriangle, shapeNone), colorRed,0,L,-12,0);
PlotShapes( IIf(bi == Abarindex , shapeDownTriangle, shapeNone), colorSeaGreen,0,H, -12, 0);
@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?
You don't understand. BarsSinceCompare already provides this functionality.
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?
Post the code that can be copy-pasted and run. You can't expect anyone to "decode" your inner thinking. Posting working code is the only way others can have 100% image of what you are after.
_TRACE( "!CLEAR!" );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}} ", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
SetChartOptions( 0, chartShowArrows | chartShowDates | chartWrapTitle );
PlotOHLC( O, H, L, C, "Close", colorRed, styleBar , Null, Null, 0, 1, 1 );
patternLengthMax=30;
distOfAFromB=0;
BarRefLeg_0=LLVBars(L, patternLengthMax);
BarRefLeg_B=14;
BarRefLeg_C=HHVBars(H, patternLengthMax);
BarRefLeg_D=LLVBars(L, BarRefLeg_C);
//can this for loop be removed?
for(i=0;i<patternLengthMax;i++)
distOfAFromB=IIf(i==BarRefLeg_B, Ref(HHVBars(H, Ref(BarRefLeg_0-BarRefLeg_B, i)), -i), distOfAFromB);
BarRefLeg_A=distOfAFromB+ BarRefLeg_B;
_TRACE("BarRefLeg_0="+BarRefLeg_0+", BarRefLeg_A="+BarRefLeg_A+", BarRefLeg_B="+BarRefLeg_B+", BarRefLeg_C="+BarRefLeg_C+", BarRefLeg_D="+BarRefLeg_D);
below is the link to data file (not spam)
See post below
Once you upload the data. Open a chart and click the bar 13:37. My goal is to get BarRefLeg_A without the for loop. can this done with barsSinceCompare() ?
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.
https://filebin.net/uavz5qciyr8fv6ou/M_M06082021.csv
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().