## October 5, 2014

### What are constants in AFL and how they work

The AFL language contains many pre-defined words like: shapeUpArrow, stopTypeTrailing, colorRed, styleThick, inDaily and many more. These are examples of constants. As written in AFL language specification (http://www.amibroker.com/guide/a_language.html): *Constants are tokens representing fixed numeric or character values*.

To better explain what this means, let us consider example of PI constant, which equals 3.14159265358979….. PI is the name of constant we use this name in mathematical equations, because it is easier and more practical to use than using the numerical value each time. Constants in AFL serve the same purpose, each of these words represents certain value properly interpreted by the program in the context they are used.

That is why using the following statement in backtesting code:

`ApplyStop( stopTypeTrailing, stopModePercent, 10 );`

is much better to use than cryptic statement like:

`ApplyStop( 2, 1, 10 );`

Both commands are equivalent, because value of stopTypeTrailing constant equals 2 and value of stopModePercent constant equals 1, yet the first version is much more understandable.

There is also another reason to use pre-defined constants rather than hard-coded numbers in the code. If for any reason the internal value of given constant changes due to development needs – all formulas using constants will continue to work properly (because new version would interpret them properly), while hard-coded numbers may change the code execution. For example – inWeekly and inMonthly constants have changed with introduction of N*inDaily timeframes, however if we always used:

TimeFrameSet( in Weekly ); in the code, then such internal change does not really affect our formulas at all.

There is one more example worth discussing – in the documentation of PlotShapes function we can find:

`Plot( Close, "Price", colorBlack, styleCandle );`

//

Buy = Cross( MACD(), Signal() );

Sell = Cross( Signal(), MACD() );

//

shape = Buy * shapeUpArrow + Sell * shapeDownArrow;

//

PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) );

So – what does the multiplication mean in the above context? If we remember that constants are in fact just numbers, and boolean **True** in AFL has numeric value of 1, while boolean **False** has numeric value of 0, then:

– if **Buy** is **True** (equals 1) and **Sell** is **False** (equals 0), then the result of such calculation will be

`shape = 1 * shapeUpArrow + 0 * shapeDownArrow = shapeUpArrow`

– if **Buy** is **False** (equals 0) and **Sell** is **True** (equals 1), then the result of such calculation will be:

`shape = 0 * shapeUpArrow + 1 * shapeDownArrow = shapeDownArrow`

The above approach is kind of shortcut that saves using conditional statements. It would work correctly only if **Buy** and **Sell** signals never occur on the same bar and only if we assign just 0 or 1 (**False** / **True**) to **Buy** and **Sell** arrays. Otherwise the result of calculations would be different. The internal value of **shapeUpArrow** is 1 and **ShapeDownArrow** is 2, so in situation, where both **Buy** and **Sell** signals were true, we would get

`shape = 1 * shapeUpArrow + 1 * shapeDownArrow = shapeUpArrow + shapeDownArrow = 1 + 2 = 3`

So – we would then pass number 3 to PlotShapes function and this is neither **shapeUpArrow** nor **ShapeDownArrow**, but a different shape. That is why in general case it is better to use conditional function IIf, like shown below:

`shape = IIf( Buy, shapeUpArrow, IIf( Sell, shapeDownArrow, shapeNone ) ); `

This way we are always sure that returned value will be **shapeUpArrow** or **shapeDownArrow** or **shapeNone**.

Filed by Tomasz Janeczko at 5:59 pm under AFL

No Comments