# Valuewhen count first occurrence of an array

Hi,
I'm looking for some guidance around the formula Valuewhen. Basically when the indicator (in blue) is pointing down, I would like to plot the first occurrence of another indicator, when it peaks in red.
Now I have used FIRST = ValueWhen( down,peakdown,1); So the condition is when the indicator is down, and the array is the peaks in the other indicator, with a comma 1, for the first occurrence. All this seems to do is give me all Peaks when the other indicator is pointing down.
These formulas are timeframe set in the daily timeframe, and viewing this in a two hour timeframe.

Thanks for any help in advance.

``````TimeFrameSet(inDaily);
SIGNALzig = Zig(Signal(12,26,9),1);
SIGNALzig1=IIf(SIGNALzig>0,SIGNALzig,Zig(abs(SIGNALzig),1)*-1);
Stoch = Zig(StochD(14,3,3),1);
TimeFrameRestore();

StochEXPAND = TimeFrameExpand(Stoch,inDaily,expandFirst);
StochEXPANDzig = Zig(StochEXPAND,1);
SIGNALzigEXPAND= TimeFrameExpand(SIGNALzig,inDaily,expandFirst);
koko= Zig(SIGNALzigEXPAND,1);
koko1 = IIf(koko>0,koko,Zig(abs(koko),1)*-1);
SIGNALzigdaily = TimeFrameExpand(SIGNALzig1,inDaily,expandFirst);

down = koko1 < Ref(koko1,-1);
peakdown = StochEXPANDzig < Ref(StochEXPANDzig,-1)
AND Ref(StochEXPANDzig,-1)> Ref(StochEXPANDzig,-2);

FIRST    = ValueWhen( down,peakdown,1);

Plot(SIGNALzigdaily,"blue", colorBlue,0,0,0,0,0,3 );
Plot( koko1,"", colorRed,0,0,0,1,3 );
Plot( StochEXPANDzig,"", colorRed,styleOwnScale,0,0,1,3 );
PlotShapes( IIf( FIRST, shapeCircle, shapeNone ), colorWhite, 0, 0, -40 );type or paste code here
``````

I think you have misunderstood how the `ValueWhen()` function works, so begin by reviewing the documentation: https://www.amibroker.com/guide/afl/valuewhen.html

Because both your expression (down) and your array (peakdown) contain boolean values, the logic you have written is equivalent to:

``````FIRST = down AND peakdown;
``````

You may want to explore the `BarsSince()` function to determine the order in which events are occurring.

2 Likes

Thanks mradtke,
Solved it. Thanks for putting me in the right direction.
I added this

``````down = koko1 < Ref(koko1,-1);
peakdown = StochEXPANDzig < Ref(StochEXPANDzig,-1)
AND Ref(StochEXPANDzig,-1)> Ref(StochEXPANDzig,-2)
AND down;
ResetHIConditionMT = koko1 > Ref(koko1,-1);
peakdownsum =    Sum( peakdown, BarsSince( ResetHIConditionMT ) + 1 );
FirtPEAK = peakdown AND peakdownsum==1;
``````

That’s a good solution. You could also use `SumSince()` instead of combining `Sum()` and `BarsSince()`.

1 Like

Hi,
Please could I get some help on a follow on from the original problem above.
In the screen shot, The white circle shapes plot when the Blue line is down AND when the red line is above 40. It resets when the blue line points up.
My problem is this, I'm trying to code 1st , 2nd 3rd etc etc occurrences for when the array is true.
So for example.
PlotShapes( IIf( peakdownsum == 1 , shapeCircle, shapeNone ), colorRed, 0, 0, 10);
Should return the first yellow square and peakdownsum == 2 the second and so on and so on.
I can't to get this to work, please could anyone help.
Thanks
Kevin

``````TimeFrameSet(inDaily);
SIGNALzig = Zig(StochD(20,30,9),1);
SIGNALzig1=IIf(SIGNALzig>0,SIGNALzig,Zig(abs(SIGNALzig),1)*-1);
Stoch = Zig(StochD(3,5,2),1);
TimeFrameRestore();

StochEXPAND = TimeFrameExpand(Stoch,inDaily,expandFirst);
StochEXPANDzig = Zig(StochEXPAND,1);
SIGNALzigEXPAND= TimeFrameExpand(SIGNALzig,inDaily,expandFirst);
koko= Zig(SIGNALzigEXPAND,1);
koko1 = IIf(koko>0,koko,Zig(abs(koko),1)*-1);
SIGNALzigdaily = TimeFrameExpand(SIGNALzig1,inDaily,expandFirst);

down = koko1 < Ref(koko1,-1);
peakdown = Down
AND StochEXPANDzig > 40;

ResetHIConditionMT = koko1 > Ref(koko1,-1);
peakdownsum =    Sum( peakdown, BarsSince( ResetHIConditionMT ) + 1 ) AND StochEXPANDzig > 40;

Plot( koko1,"BLUE", colorBlue,0,0,0,1,3 );
Plot( StochEXPANDzig,"RED", colorRed,styleLine,0,0,1,3 );
Plot( 40,"White", colorWhite,styleLine,0,0,0,0,5 );

PlotShapes( IIf( peakdownsum  , shapeCircle, shapeNone ), colorWhite, 0, 0, 0);
PlotShapes( IIf( peakdownsum == 1  , shapeCircle, shapeNone ), colorRed, 0, 0, 10);
``````

This code is not correct:

``````peakdownsum =    Sum( peakdown, BarsSince( ResetHIConditionMT ) + 1 ) AND StochEXPANDzig > 40;
``````

You are intending peakdownsum to be an array of numeric values, but the AND operator joins two logical values. I have not tested, but my guess is that using AND will force AmiBroker to interpret both arguments as logicals, and give you a result that is a logical (True or False) as well. Therefore, the value of `peakdownsum` will always be either 0 or 1.

Since you’ve already incorporated the `StochEXPANDzig > 40` clause previously in the logic for `peakdown`, you can just remove it from the `peakdownsum` assignment, like this:

``````peakdownsum =    Sum( peakdown, BarsSince( ResetHIConditionMT ) + 1 );
``````

Also, you can always use an Exploration to see what the actual values of `peakdown` and `peakdownsum` are. In cases like this, you will almost always discover that one or more variables have “unexpected” values.

Hi Matt,
Thanks very much for the insight. I have now corrected that part of the code.
Would you have any idea on a solution to the original problem?
It should be easy peakdownsum ==1 or peakdownsum ==2 etc, to control which yellow block you would want, but looks like this is not the way.
Thanks
Kevin

Actually Matt, I have played around with the peakdownsum = Sum( peakdown, BarsSince( ResetHIConditionMT ) + 1 ) AND StochEXPANDzig > 40; part, and perhaps there is a right way to code it, but it is needed. Here is why.
White plots (with the AND StochEXPANDzig > 40) is returning what I want, I just need the control of 1st 2nd 3rd etc instances.
The Red plots (without the AND StochEXPANDzig > 40) ignores when StochEXPANDzig is below 40, which is incorrect.

``````down = koko1 < Ref(koko1,-1);
peakdown = Down
AND StochEXPANDzig > 40;

ResetHIConditionMT = koko1 > Ref(koko1,-1);
peakdownsum =    Sum( peakdown, BarsSince( ResetHIConditionMT ) + 1 );

PlotShapes( IIf(peakdownsum AND StochEXPANDzig > 40, shapeCircle, shapeNone ), colorWhite, 0, 0, 0);
PlotShapes( IIf(peakdownsum  , shapeCircle, shapeNone ), colorRed, 0, 0, 10);
``````

Ok, after many attempts and reading, I have finally gotten closer to solving this problem, by reading about pulse and state form.Anyway still not there yet. This code works now, (but only if the red line has crossed 40 (pulse form), but if the red line does not have this Cross(StochEXPANDzig,40) event it obviously does not register, which is not right. So in summary this works but only if there is a "cross" or pulse event involved. So my question now, is how to include a state form into this code?

``````TimeFrameSet(inDaily);
SIGNALzig = Zig(StochD(20,30,9),1);
SIGNALzig1=IIf(SIGNALzig>0,SIGNALzig,Zig(abs(SIGNALzig),1)*-1);
Stoch = Zig(StochD(3,5,2),1);
TimeFrameRestore();

StochEXPAND = TimeFrameExpand(Stoch,inDaily,expandFirst);
StochEXPANDzig = Zig(StochEXPAND,1);
SIGNALzigEXPAND= TimeFrameExpand(SIGNALzig,inDaily,expandFirst);
koko= Zig(SIGNALzigEXPAND,1);
koko1 = IIf(koko>0,koko,Zig(abs(koko),1)*-1);
SIGNALzigdaily = TimeFrameExpand(SIGNALzig1,inDaily,expandFirst);

down = koko1 < Ref(koko1,-1);
peakdown = Down
//AND StochEXPANDzig > 40
AND Cross(StochEXPANDzig,40);
ResetHIConditionMT = koko1 > Ref(koko1,-1);
peakdownsum =    Sum( peakdown, BarsSince( ResetHIConditionMT ) + 1 );

//PlotShapes( IIf(peakdownsum AND StochEXPANDzig > 40, shapeCircle, shapeNone ),colorWhite,0,0,0);
PlotShapes( IIf(peakdownsum ==1 AND StochEXPANDzig > 40, shapeCircle, shapeNone ), colorRed, 0, 0, 10);

Plot( koko1,"BLUE", colorBlue,0,0,0,1,3 );
Plot( StochEXPANDzig,"RED", colorRed,styleLine,0,0,1,3 );
Plot( 40,"White", colorWhite,styleLine,0,0,0,0,5 );
``````

Sorry @Kevin, I’m not clear on exactly what you’re trying to achieve. However, as I mentioned previously, I think it would help you to add code to make your AFL run as an Exploration so that you can see your variable values at each bar.

Hi Guys,
I need to come back to this problem. Please could anyone help with this. I would like to control a count. In this screenshot I would like to control when zig is down in an uptrend, with this line
peakdownsum ==1 . This would show all bars of zig down in the 1st occurrence in an uptrend, then peakdownsum ==2 , the 2nd time zig was down in the uptrend, etc etc.

``````ZIGG = Zig(C, 0.8);
Plot(ZIGG , _DEFAULT_NAME(), ParamColor( "Color", colorCycle ), ParamStyle("Style") );

MAS     = MA(C,300);
DOWN_MA = MAS < Ref(MAS,-1);
UP_MA   = MAS > Ref(MAS,-1);
Plot( MAS, _DEFAULT_NAME(), colorBlue, ParamStyle("Style") );

Zig_down           = ZIGG < Ref(ZIGG,-1) AND UP_MA;
Reset              = ZIGG > Ref(ZIGG,-1);
peakdownsum        = Sum( Zig_down, BarsSince( Reset ) + 1 );

PlotShapes( IIf(peakdownsum ==1 , shapeCircle, shapeNone ), colorRed, 0, L, 10);
``````