This document presents most common mistakes and problems that users encounter when writing their custom formulas. Please read carefully to avoid making similar errors.
“=” (assignment) vs “==” (equality check)
There are two similar looking but completely different operators in AFL.
“=” is a variable assignment operator
“==” is an equality check operator
EXAMPLE
Incorrect code:
result = IIf(
Variable = 10 , High, Low ); //
WRONG
If you want to check if variable is equal to 10, you MUST use “==”
Correct code:
result = IIf(
Variable == 10 , High, Low ); //
CORRECT
Parentheses can be used to control the operation precedence (the order in which the operators are calculated). AmiBroker always does operations within the innermost parentheses first. To learn the the precedence of operations when parentheses are not used, visit: http://www.amibroker.com/guide/a_language.html
EXAMPLE:
“I would like to buy whenever either Close is higher that it’s 10-periods Moving Average or Close is at least 10% higher than yesterday’s close, but buy should only apply when Current Volume is higher than it’s 10-period Moving Average. However – I get Buy signals for the days when Volume is lower than MA(Volume,10). Why?”
Buy = Close > MA( Close, 10 ) OR Close == 1.1 * Ref( Close,
-1 ) AND Volume > MA( Volume, 10 );
The solution is to add parentheses, otherwise system buys whenever Close > MA(Close,10) condition is met ( or Close == 1.1*Ref(Close,-1) AND Volume > MA(Volume,10) are both met).
Buy = ( Close > MA( Close, 10 ) OR Close == 1.1 * Ref( Close,
-1 ) )
AND Volume > MA( Volume, 10 );
The IIf( ) function is used to create conditional assignments.
variable = IIf( EXPRESSION, TRUE_PART, FALSE_PART );
The above "IIf" statement means: For each bar EXPRESSION is true assign TRUE_PART to the variable, otherwise (when EXPRESSION is false) assign FALSE_PART.
EXAMPLE
Incorrect code
IIf( Close > 10,
result = 7, result
= 9 ); //
WRONG
Correct code:
result = IIf( Close > 10, 7, 9 ); //
CORRECT
IIf functions should be used to handle arrays, if you need conditional text function use WriteIf instead.
EXAMPLE
Incorrect code:
variable = IIf(Condition, "Text
1","Text 2" ); //
WRONG
IIf( ) function returns array, NOT STRING, so it’s impossible to assign text to variable with use of IIF. Use WriteIf( ) function instead:
Correct code:
variable = WriteIf(
condition, "Text 1", "Text
2" ); // CORRECT
Please note however that WriteIf function returns just single STRING, not arrays of strings, so only the selected value is used for evaluation.
if-else statement needs boolean (or single numeric expression), not array
The if keyword executes statement1 if expression is true (nonzero); if else is present and expression is false (zero), it executes statement2. After executing statement1 or statement2, control passes to the next statement. Expression must be boolean ( True/False) type (so it CANNOT be ARRAY because there would be no way do decide whether to execute statement1 or not, if for example array was: [True,True,False,.....,False,True] )
if( expression )
statement1
else
statement2
EXAMPLE
if( Close > Open ) //
WRONG
Color = colorGreen; //statement
1
else
Color = colorRed; //statement
2
Plot(Close,"Colored
Price",Color,styleCandle);
The above example is wrong, as both Open and Close are arrays and such expression as Close > Open is also an ARRAY. The solution depends on the statement. It’s either possible to implement it on bar-by-bar basis, with use of FOR loop:
for(
i = 0; i < BarCount;
i++ )
{
if( Close[
i ] > Open[ i
] ) // CORRECT
Color[ i ] = colorGreen;
else
Color[ i ] = colorRed;
}
Plot( Close, "Colored
Price", Color, styleCandle );
It is also possible in this case to use IIf( ) function:
Color = IIf( Close > Open, colorGreen, colorRed ); //
ALSO CORRECT - working directly on arrays
Plot( Close, "Colored
Price", Color, styleCandle );
There is a fundamental difference between BarCount and BarIndex(). BarCount is a numeric variable that holds just one number (the count of elements in array). On the other hand BarIndex() is a function that returns ARRAY representing consecutive index of each bar.
EXAMPLE
Incorrect code:
for (i
= 0;
i < BarIndex();i++
) // WRONG
{
// your formula
}
It’s not allowed to use ARRAY inside for loop, and Barindex() returns ARRAY. That is why it’s necessary to change the formula.
Correct code:
for (i
=0 ;
i < BarCount ;i++
) // CORRECT
{
//your formula
}
TimeFrameExpand( ) is required to match data with original time frame
The TimeFrameSet( ) replaces current price/volume arrays: open, high, low, close, volume, openint, avg with time-compressed bars of specified interval once you switched to a different time frame all calculations and built-in indicators operate on selected time frame. To get back to original interval call TimeFrameRestore( ) function. The TimeFrameExpand( ) is used to decompress array variables that were created in different time frame. Decompressing is required to properly display and use the array created in different time frame.
EXAMPLE
Incorrect code:
TimeFrameSet( inWeekly );
MA14_Weekly = MA( Close, 14 );
TimeFrameRestore();
Buy = Cross( Close,
MA14_Weekly ); //
WRONG - Close and MA15_Weekly use different time scales
The above formula is wrong, as MA14_Weekly variable should be EXPANDED to match original timeframe. The right contents should be:
Correct code:
TimeFrameSet( inWeekly );
MA14_Weekly = MA( Close, 14 );
TimeFrameRestore();
Buy = Cross( Close, TimeFrameExpand(
MA14_Weekly, inWeekly )
); // CORRECT, expanded weekly MA can be matched
against daily close
EXAMPLE 2:
Incorrect code:
TimeFrameSet( inWeekly );
MA14_Weekly = MA( Close, 14 );
TimeFrameRestore();
Buy = Cross( Close, TimeFrameExpand(
MA14_Weekly, inDaily ) ); // WRONG
It’s always necessary to indicate in TimeFrameExpand( ) function, which timeframe was variable calculated in. So if MA14_Weekly was calculated in out of weekly data, inWeekly should be the correct parameter of TimeFrameExpand( ) function.
Correct code:
TimeFrameSet( inWeekly );
MA14_Weekly = MA( Close, 14 );
TimeFrameRestore();
Buy = Cross( Close, TimeFrameExpand(
MA14_Weekly, inWeekly ) );//
CORRECT