I am new to AFL programming. I am writing a function to count a streak of closing prices s.t. each subsequent closing price is higher than the previous one. That is, we have C[k] > C[k+1]. This assumes C[0] is the lastest closing price, c[1] the day before and so on (to be clear, Is this correct?) Here is the code...
function StreakCountN( n )
{
k = C;
count = 0;
for( i = 0; i < n; i++ ) {
if ( C[ i ] > C[ i + 1 ] )
count++;
}
return count;
An array identifier followed by an expression in square brackets ([ ]) is a subscripted representation of an element of an array object.
arrayidentifier [ expression ]
It represents the value of expression-th element of array.
BarCount constant gives the number of bars in array (such as Close, High, Low, Open, Volume, etc).
Array elements are numbered from 0 (zero) to BarCount-1.
BarCount does NOT change as long as your formula continues execution, but it may change between executions when new bars are added, zoom factor is changed or symbol is changed.
To get the first bar you can use array[ 0 ], to get the last bar of array you can use array[ BarCount - 1 ];
For example:
Close[ 5 ];
Represents the sixth element (bar) of the close array.
Close[ 0 ];
Represents the very first available bar of the close array.
High[ BarCount - 1 ];
Represents the last bar of High array. ”
This means that each time you use a loop you should verify that you index is always >= 0 AND < BarCount.
Since you are new to AFL, I recommend studying this thread to better understand how to work with Amibroker Formula Language: you'll find that many times no loop is needed.
Ok - so I updated the code - One of the problems was that I did not know that C[BarCount-1] is the last closing price of the underlying. So here is the modified code and I am still getting an "Array Subscript out of Range Error" - I have no idea what is going on. When I debugged the code, the indexing seemed Ok (I am new so I must be missing something) - Thanks in advance...
function StreakCountN( n )
{
iters = 0;
count = 0;
for( i = BarCount - 1; i > BarCount - n - 1; i-- ) {
iters++;
if ( C[ i ] > C[ i - 1 ] )
count++;
}
return count;
}
@pmfiorini, as you are new to AmiBroker and AFL, this might help you get up to speed a bit quicker to understand the Array processing.
Think of it like Excel. You have a Row of Prices, and the Columns are the days.
So you have rows with Open, High, Low, Close, and Volume.
Now you want to do a calculation, you will need to write the code in a cell that ONLY references Rows above and Cells above and/or to the Left. For Example: Midpoint =(H + L)/2
Since your new Row - Midpoint is Below the H & L rows, you can reference them.
Similarly, a new Row - PriorClose = Close from one Column to the left of the current cell.
Thinking this way should help you get started.
Next step is to READ READ READ the Manual. After the Tutorial, check out the Function References. Specifically see if you can understand BarsSince and Ref from @portfoliobuilder's suggestion.
When i run the code in the editor it is working fine as expected. But the same code if i run through explorer getting the error as "Array subscript out of range.You must not access array elements outside o barcount-1 range. you attempt to access non existing of 7th element of array." Please let me know the issue. you can reproduce the issue just to run the program in explorer window.
Please find the attachment for more details.
you're new to AB, and having a go, that's a good thing, IMO.
providing code, and explanations & examples of the type of problem and where/ when being experienced, even better.
your use of "C[k] > C[k+1]" and "This assumes C[0] is the lastest closing price, c[1] the day before and so on", suggests that you didn't/ don't understand how AB indexes quotes, which is potentially a source of errors in your code. You probably do understand it by now.
I don't understand the purpose of the n argument to the function.
In regard to #3, I presume you mean that the closing price today is higher than yesterday's closing price.
When putting your original code, and @bobptz's into an AFL, I get horizontal lines, whose value "jumps" around a lot when scrolling backwards and forwards. Also, I don't understand what your function is doing - loops can be very useful, but they're always a headache, and need lots of time to think them through properly. Did I also mention that they're hard to debug.:
SetChartOptions(0,chartShowArrows|chartShowDates|chartWrapTitle);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("PriceColor", colorBlack ), ParamStyle("PriceStyle", styleCandle, maskPrice));
function StreakCountN1( n )
{
k = C;
count = 0;
for( i = 1; i < n; i++ ) {
if ( C[ i ] > C[ i - 1 ] )
count++;
}
return count;
}
function StreakCountN2( n )
{
n = Min(n, BarCount-1);
iters = 0;
count = 0;
for( i = BarCount - 1; i > BarCount - n - 1; i-- ) {
iters++;
if ( C[ i ] > C[ i - 1 ] )
count++;
}
return count;
}
selMaxStreak = Param("selMaxStreak", 2, 1, 100, 1, 1) ;
clcStreak1 = StreakCountN1(selMaxStreak) ;
clcStreak2 = StreakCountN2(selMaxStreak) ;
Plot(clcStreak1, "clcStreak1", ParamColor("Streak1", colorCycle), ParamStyle("Streak1 style", styleLine + styleOwnScale)) ;
Plot(clcStreak2, "clcStreak2", ParamColor("Streak2", colorCycle), ParamStyle("Streak2 style", styleLine + styleOwnScale)) ;
// Break the problem down into manageable chunks
function Streaker1(inpArray)
{
isHigher = inpArray > Ref(inpArray, -1) ;
return BarsSince(!isHigher) ;
}
// Now, optimise it for speed - remove any unnecessary/ intermediary steps.
function Streaker2(inpArray)
{
return BarsSince(!(inpArray > Ref(inpArray, -1))) ;
}
clcStreaker1 = Streaker1(Close) ;
clcStreaker2 = Streaker2(Close) ;
Plot(clcStreaker1, "clcStreaker1", ParamColor("Streaker1", colorCycle), ParamStyle("Streaker1 style", styleLine + styleOwnScale)) ;
Plot(clcStreaker2, "clcStreaker2", ParamColor("Streaker2", colorCycle), ParamStyle("Streaker2 style", styleLine + styleOwnScale)) ;
Towards the end, are a couple of new functions which use array processing, ie. no loops - my interpretation of what you're trying to achieve in the original question.