Problem of referencing (with better example)

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 :grinning:

I guess that you could use recently introduced BarsSinceCompare

Also as far as loops are considered, a single loop (not nested) is not really evil.

1 Like

Thanks for adding this new function. I don't know how i can use this in my case. Let me play around with it. maybe it's what i need.

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);



@2DD Thanks, I will try this out.

@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.

What for new function?


x = BarsSinceCompare( Ref(H,-20), ">", H);
1 Like

Wouldn't it be a million times easier and clearer if a function like
CurrentBar(H) is created?

CurrentBar(H) is just H.

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?

Com'n man, this will be really usefull. This will take AB to a whole new level. Please consider. :pray:

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.

Ok, can you please give me a hint on how i could use barsSinceCompare() to solve my specific case? I tried my best but i am not able to. thanks

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.

1 Like

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.

Please follow this advice: How to ask a good question

Also @fxshrat already gave you the code using BarsSinceCompare Problem of referencing (with better example) - #6 by fxshrat If that is not what you asked for, you need to post the code, because at the moment apparently no-one knows what you want.

below is the code

				_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 );

		BarRefLeg_0=LLVBars(L, patternLengthMax); 
		BarRefLeg_C=HHVBars(H, patternLengthMax); 
		BarRefLeg_D=LLVBars(L, BarRefLeg_C);
//can this for loop be removed?
		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.

1 Like
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?

My post has been wrongly marked as spam.
It had a link to Easyupload to share the data file.

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().