ValueWhen - how to use

ValueWhen(EXPRESSION, ARRAY, n = 1)

Is the function is supposed to return a value which can be used in if stamt not an array when n=1. However i am getting error message saying I cannot use array.
What about if n=2,3,4 etc, then it return an array I supposed.

Thanks for answering,

novice user
jimmy

2 Likes

Only two first arguments: Expression (1st) and Array (2nd) have array type. Third argument is a scalar (just a number, not array)

The β€œn” arguments says which N-th occurrence you need. If it is set to 1 (the default) means that you want most recent occurrence.

You will find this article useful in understanding how ValueWhen works: http://www.amibroker.com/kb/2014/09/29/debugging-techniques-part-1-exploration/
Running Exploration really opens eyes and helps tremendously.

And also http://www.amibroker.com/f?valuewhen

8 Likes

Jimmy,

Checking the User’s Guide - Function Reference you can find lots of info on the functions.

As you can imagine, if you test for a Cross of indicator lines, there will be many over the course of a long data stream. So the β€œn” is the nth occurrence looking back. So you might want the 3rd previous occurrence for some reason, and this function allows you to get that.

From the reference, it shows that the RETURN is an Array.

If you are new to AmiBroker and AFL, you might think of it more like a Row in Excel.
Each Cell can only reference cells above and to the left (no looking into the future).
If you can program it in Excel, using the Up/Left idea, then you can do it in AFL.

Hope this helps.
Snoopy

1 Like

Thank you Thomaz and Snoopy for the reply. I really appreciate the helping hands.

From the link Thomasz provide, the return of valuewhen() is clearly a scalar. in the example, n was not provided so I assume the default is one.

My problem was that when i compare the valuewhen() return with a number, the compiler give an error message saying i cannot compare an array with a number. It is hard to understand what went wrong.

Please help.

Jimmy

No it is NOT.
You need to go back to reading β€œUnderstand AFL” section of the manual.
Re-read it. Rinse and repeat until you get β€œaha!” moment. That moment will come and from that point things would be much easier.

Return value of majority AFL functions is ARRAY, as written in the guide
Did you run that exploration I pointed out? Please run it.
ValueWhen returns an ARRAY - it is clearly shown as a column with different values in in the Exploration. In Exploration, a column represents an ARRAY variable content. Each row in such column represents single element of the array.

2 Likes

[quote="etcjkam, post:4, topic:170, full:true"]
From the link Thomasz provide, the return of valuewhen() is clearly a scalar. in the example, n was not provided so I assume the default is one.[/quote]

No, it is not returning number.

First of all if you are unsure what a function does return then look up the function reference guide https://www.amibroker.com/guide/a_funref.html

If you go to ValueWhen entry there then you can clearly see that it is mentioned "Returns Array"

Secondly you can easily check return value of a variable by using typeof operator
https://www.amibroker.com/guide/keyword/typeof.html

Code example

var = ValueWhen( True, Close ); printf( "type of var: %s", typeof(var) );// %s (string format specifier) requires AB 6.2+ //printf( "type of var: " + typeof(var) );// for older AB versions

Execute that code and then open the Interpretation window of AmiBroker (Window->Interpretation) in order to see output of printf.

Other method of seeing type of variable is using AmiBroker's inbuilt debugger.
https://www.amibroker.com/guide/h_debugger.html

You simply drag and drop a variable to the Watch window of Formula Editor and set breakpoints and then start the debugger.

Side note: In case you should wonder why not entire array of a symbol is shown in debugger Watch output window... BarCount is set to 200 by AmiBroker if using debugger (or if using "Verify syntax", "Apply" of formula editor) no matter what is the real BarCount of a symbol.

You may check that yourself using _TraceF

_TRACEF( "Barcount: %g", BarCount );

For debugger that fixed Barcount can be set to a higher value via "Tools-Preferences-Debugger-Limit Barcount to".

There are other fixed BarCount settings... but that's not the topic here. It's just a side note related to debugger.

Were you trying to use ValueWhen in "if" statement? For example,

var = ValueWhen( True, Close ); // if( var == 3 ) printf( "Not allowed" );

Yes?
This is wrong. Either use loop or use IIf function.
www.amibroker.com/guide/afl/iif.html

Also see coding mistakes
https://www.amibroker.com/guide/a_mistakes.html

12 Likes

Additional note:

A variable would return a number instead of array if outputting an element of the array.
Known functions returning element of an array are SelectedValue(...), LastValue(...), BeginValue(...), EndValue(...).

var = ValueWhen( True, Close );

varelement = SelectedValue( var );

printf( "type of varelement: %s", typeof(varelement) );// %s (string format specifier) requires AB 6.2+
//printf( "type of varelement: " + typeof(varelement) );// for older AB versions

or in loop

var = ValueWhen( True, Close );
//
printf( "Before Loop:\n" );
printf( "type of var: %s\n\n", typeof(var) );// %s (string format specifier) requires AB 6.2+
//printf( "type of var\n\n: " + typeof(var) );// for older AB versions
//
printf( "In Loop (elements 1 to 10):" );
for( i = 0; i < BarCount; i++ )
{
	if( i < 10 ) {
		varelement = var[i];
		printf( "\ntype of varelement %g: %s", i, typeof(varelement) );// %s (string format specifier) requires AB 6.2+
		//printf( "\ntype of varelement: " typeof(varelement) );// for older AB versions
	}
}

10 Likes

Hi Tomasz. It is clear to me now. Thanks.

Hi fxshrat. It is precisely the coding mistake I made. Thank you so much for showing me the practical tips and debugging technique as well.

Thank you all for the patience and spending the time teaching me.

Really appreciate this forum. Thank you Tomasc. It is definitely going to help all of us in AFL.

Thanks to all,
Jimmy

2 Likes