user3848207
user3848207

Reputation: 4977

For loop doesn’t accept array. How to work around for this Amibroker code?

The following code will calculate the high-low range in percentage of certain bars when an event occurred and calculate the average of the high-low range.

event_up = get_event_up();
event_down = get_event_low();   
num_events_in_range = get_num_events_in_range();

sum_pct_updown_dist = 0;
for (i=1;i<num_events_in_range; i++) //for cannot accept array type 
{
    event_up_high_i = ValueWhen(event_up, High, i);
    event_down_low_i = ValueWhen(event_down, Low, i);
    pct_updown_dist_i = (event_up_high_i-event_down_low_i)/event_up_high_i*100;
    sum_pct_updown_dist = sum_pct_updown_dist + pct_updown_dist_i;
}
avg_pct_updown_dist = sum_pct_updown_dist/num_events_in_range;

The code doesn't work in Amibroker because of this line for (i=1;i<num_events_in_range; i++) which violates Amibroker syntax. For loop does not accept array type. num_events_in_range is an array.

How can this code be modified to work around this problem?

Upvotes: 1

Views: 1742

Answers (5)

fxshrat
fxshrat

Reputation: 89

Solution exists already in official AmiBroker forum. No BarCount loop required. https://forum.amibroker.com/t/for-loop-doesnt-accept-array-how-to-work-around-for-this-code/14466

Astonishing that @SCcagg5 used same variable name end_value plus conversion to number via LastValue().

Upvotes: 0

abnaceur
abnaceur

Reputation: 262

Try this

event_up = get_event_up();
event_down = get_event_low();   
num_events_in_range = get_num_events_in_range();

sum_pct_updown_dist = 0;
for (var i=1;i<num_events_in_range.length; i++) //for cannot accept array type 
{
    event_up_high_i = ValueWhen(event_up, High, i);
    event_down_low_i = ValueWhen(event_down, Low, i);
    pct_updown_dist_i = (event_up_high_i-event_down_low_i)/event_up_high_i*100;
    sum_pct_updown_dist = sum_pct_updown_dist + pct_updown_dist_i;
}
avg_pct_updown_dist = sum_pct_updown_dist/num_events_in_range;

You need to update last line where average is counted.

avg_pct_updown_dist = sum_pct_updown_dist/num_events_in_range;

Here, num_events_in_range will alo produce and error. According to the syntax of for loop you need an expression which can be true or false. As explained by @Shylajhaa, comparison can not be done between single integer value and array.

Upvotes: 2

SCcagg5
SCcagg5

Reputation: 648

For your specific probleme you could use

end_value = LastValue(num_events_in_range);
for (i = 1; i < end_value; i++);

The other way around:

Syntax

for ( init-expression ; cond-expression ; loop-expression ) statement

Execution of a for statement proceeds as follows:

The init-expression, is evaluated. This specifies the initialization for the loop. There is no restriction on the type of init-expression.

The cond-expression, is evaluated. This expression must have arithmetic type. It is evaluated before each iteration. Three results are possible: If cond-expression is true (nonzero), statement is executed; then loop-expression, if any, is evaluated. The loop-expression is evaluated after each iteration. There is no restriction on its type. Side effects will execute in order. The process then begins again with the evaluation of cond-expression.

If cond-expression is false (0), execution of the for statement terminates and control passes to the next statement in the program.

For order to have a valid cond-expression, you should compare variable of the same type integer for exemple, in AFL you should look after the BarCount

Here is a quick recap about arrays in AFL

An array is simply a list (or row) of values. In some books it may be referred to as a vector. Each numbered row of values in the example represents an individual array. Amibroker has stored in its database 6 arrays for each symbol. One for opening price, one for the low price, one for the high price, one for the closing price and one for volume (see the rows labelled 1-5 below) and one for open interest. These can be referenced in AFL as open, low, high, close, volume, openint or o, l, h, c, v, oi.

All array indices in AFL are zero-based, i.e. counting bars starting from bar 0 (oldest). The latest (newest) bar has an index of (BarCount-1). The 10-element array will have BarCount = 10 and indices going from 0 to 9 as shown below

Exemple:

myema[ 0 ] = Close[ 0 ];
for( i = 1; i < BarCount; i++ )
{
    myema[ i ] = 0.1 * Close[ i ] + 0.9 * myema[ i - 1 ];
}
for( i = 0; i < BarCount; i = i + 3 ) // increment by 3 every iteration

Sources:

Good luck ;)

Upvotes: 1

GiselleMtnezS
GiselleMtnezS

Reputation: 105

This is quite simple, for it boils down to the basic structure of a for loop. Here is your error:

The code doesn't work in Amibroker because of this line for (i=1;i< num_events_in_range;i++) which violates Amibroker syntax. For loop does not accept array type. num_events_in_range is an array.

As your error suggests, this is the line with the problem:

for (i=1;i<num_events_in_range; i++)

   where, ^^^^^^^^^^^^^^^^^^^ this is the problem

In the structure of a for loop:

First you declare the index (i) as:

let i = [your starting point, usually 0 because is the first item in the array, in this case 1)

Then you must tell the for loop when you want the index to stop. To do so, you compare the index with a number type value. When i is equal to or greater than this number it will stop as instructed.

Your error arouses because: An array is not a number type.

Hence the index cannot be compared to an array.

You must compare index with a number, and Here is where .length comes into play if you want the for loop to run for as long as the given array lasts.

The best way to think about it is that the for loop will iterate per item on the given array.

To do so, we use the .length property of the array. It returns a number value of how many items are located into the array.

In this case:

num_events_in_range.length gives you a number, the number of items in the num_events_in_range array.

Last but not least, you must tell the for loop the factor of its iteration. Although i++ (index adding one to itself every time to run through every single item with no exceptions) is the most common use for this feature, you can change it to i+2 or i+3 and index will count in 2s and 3s.

For example: By 2s, (assuming starting point is 0): 0,2,4,6,8,10, 12,14, 16, 18... until index reaches the point where it is the same or higher than its comparison number.

Upvotes: 1

Shylajhaa
Shylajhaa

Reputation: 1688

The syntax of for loop is

for ( init-expression ; cond-expression ; loop-expression )

In your code i < num_events_in_range is an invalid condition, since i is an integer and num_events_in_range is an array.

In place of num_events_in_range, use the length of num_events_in_range

Upvotes: 4

Related Questions