How to fetch the elements through array subscript

Hi All,

I am exploring some code snippet using array concept. I am trying to retrieve elements through array .


But C[0],C[1] not fetching the latest first and second element of the array.

The below is my understanding of array in AFL.
But somewhere my understanding is wrong please guide me. If it is with example then much appreciate.
Thanks in advance

Set Analysis Range to "All quotes" for your example code to get equal first value in "Close" column.
You have set to different range setting other than "All quotes".

Index zero refers to first element of entire array.
Selected analysis range being smaller than that is not outputting entire array.

If you want output of first element of any analysis range (setting) then use this, for example.

fbr = Status("firstbarinrange");// flag first bar of any analysis range
firstClose = LastValue(ValueWhen(fbr, Close));// firstClose - not an array but element of array
secondClose = LastValue(ValueWhen(Ref(fbr,-1), Close));// secondClose - not an array but element of array

Filter = 1;

AddColumn(C[0],"C[0] (entire array)",1.4);
AddColumn(C[1],"C[1] (entire arrray)",1.4);
AddColumn(firstClose,"1st Close of Range",1.4);
AddColumn(secondClose ,"2nd Close of Range",1.4);




Hi much thanks @fxshrat .Yes i was selected the range of "from date", "To date" .Now i understood.
If i want to get the latest values through subscript .I am using the below code .But obviously it is fetching the last value in the array.



But to get the Barcount value at each and every 5 minute frame i am trying to use the below code. Do not know what is the condition need to mention in the code. My intention is to fetch the close values of each and every bar through Barcount and array subscript.

i= ValueWhen(Condition,BarCount,1); 
CurrentBarClose = Close[i]; 

Filter = 1;
AddColumn(CurrentBarClose ,"CurrentBarClose ",1.4);

So both the above columns values should same.
Can you suggest me.
Thanks in advance.

It is obviously wrong because you did not read this:

Index [ 0 ] in AFL represents FIRST array element (the OLDEST), not the LAST (latest).

You are coming from other platform apparently (like Tradestation) that uses reverse logic (i.e. 0 index is "latest").

In AmiBroker close[ 0 ] is the OLDEST bar in the database. In AmiBroker Bar number, like time, INCREASES.
The most recent bar (latest) is close[ BarCount - 1 ]

The second most recent bar is close[ BarCount - 2]

Again, reading this is ESSENTIAL.

The second thing you mentioned, BarCount is a NUMBER (scalar), not array, it represents the number of bars in the array, not the bar index as you assumed.

If you want to display bar index, you should use BarIndex() (nomen omen) function

And you MUST really read this

The statement like this:

i= ValueWhen(Condition,BarCount,1);  // INCORRECT
CurrentBarClose = Close[i];  // INCORRECT

is incorrect on two levels. It uses BarCount instead of BarIndex in ValueWhen call. And it ignores the fact that ValueWhen is array function, returns ARRAY and as such can be used as index

You should be writing

CurrentBarClose = ValueWhen( Condition, Close, 1 );

(single line like this is doing everything you wanted to do in 3 lines)

The key thing to understand that pretty much all variables are ARRAYS, not scalars.
You work on arrays in parallel.
If you want to work with scalars sequentially (the "old" way like non-array languages work) you need to write a LOOP (like in "old" languages) that iterates thru array elements. So either you write array code and use array functions (like ValueWhen) and process arrays at once in single call or you do "old school" and write looping code (like in 'old' languages) and do things sequentially for each bar.

So either this (array code):

CloseWhenConditionIsMet = ValueWhen( Condition, Close );

or this (looping code with old school index-wise access)

for( i = 0; i < BarCount; i++ )
   if( Condition[ i ] )
      CloseWhenConditionIsMet [ i ] = Close[ i ];
    if( i > 0 )
       CloseWhenConditionIsMet [ i ] = CloseWhenConditionIsMet [ i - 1 ]; // keep previous

As you can see array code is whole lot shorter than old-school looping.


Thanks @Tomasz @fxshrat. I read the links and understood all the concepts.
My requirement is to count the number of consecutive green bars in the chart.
So i developed the below code.

for(i= presentCandleBarIndex ;Change[i]>0;i--) // How to find the presentCandleBarIndex . 
     Count = Count+1;
// Change is an array,which contains negative and positive values .If it is positive then it is a green candle

Can you modify the above code to get the correct output.

Thanks in advance.

Think via arrays not loops. You do not need looping for that.

Plot( C, "", colorDefault, styleCandle );

redBar = C < O;// or ROC(C,1) < 0; etc...

sumGreen = SumSince(redBar, 1);

//conseqGreen = sumGreen;
// or
conseqGreen = Max(0,sumGreen-1);//IIf(sumGreen > 1, sumGreen-1, 0);
// or ...

Plot( conseqGreen, "conseqGreen", colorGreen, styleHistogram | styleOwnScale );

or similar...



Thanks @fxshrat for your valuable inputs. In my case i need to use older version of amibroker for getting some compatibility of plugins . But "SumeSince" is available only with higher version. Can you guide me how to get same output using older version of amibroker of AFL?

Thanks in advance

Minimum supported forum version is AmiBroker 6.0. And as for plugin compatibility... that does not make much sense to me. ADK plugins should work with any new version.

Please look carefully here. It explains it already.

1 Like

SumSince is available in 6.10 and higher. For 6.00 and lower you can use BarsSince instead of SumSince.

sumGreen = BarsSince( redBar );

BarsSince function is available in any version

1 Like