How to write your own chart commentary

One of the interesting aspects of using AmiBroker Formula Language is writing automatic chart commentaries. The idea behind this technique is as follows:

  1. You write the commentary formula that consists of two basic elements: static texts and AFL expressions
  2. AmiBroker evaluates expressions using currently selected symbol data and generates dynamic content
  3. The mixture of static text and evaluated formulas is displayed in commentary output window
  4. Additionally, buy/sell arrows are plotted on the chart

Commentaries are available from Analysis->Commentary menu. When you open commentary window you will see two tabs: Commentary and Formula. In the Formula tab, you can type the AFL statements, which will be evaluated by AmiBroker, resulting in dynamic commentary that appears in the Commentary tab. The following sections will guide you through the steps needed to write your very own commentary formulas.

Writing static texts

Static text elements written in the formula should be enclosed in the quotation marks and terminated by a semicolon as shown below:

"This is sample static text statement";

You can write several statements and each statement will be placed in a new line in the commentary output window:

"This is first line of text";
"This is second line of text";

Please type these examples into the edit field in the Formula tab and switch to Commentary tab. You will see the texts displayed in the output area but without any quotation marks or semicolons. This is because AmiBroker has evaluated these simple text statements into strings and displayed the strings in the output window.

Instead of just typing the text, it is advised that any new code use printf function instead.

printf( "This is sample static text statement" );

To write several lines of text you can use a couple of statements as shown above or you can do this using a single statement and line break sequence ('\n'):

printf( "This is first line of text\nThis is second line of text\nThis is third line of text" );

You can also concatenate the string constants which will result in a single line of text:

printf( "This" +
" is" +
" single"+
" line" + " of text" );

Colors and styles

Since version 5.90, commentary and interpretation windows support colors and bold/italic styles. To specify the beginning and end of a bold section, use <b> and </b> tags. To specify the beginning and end of an italic section, use <i> and </i> tags. To change text color use EncodeColor as shown in the example below:

printf("<b>Bold text</b>\n");
printf("<i>Italic text</i>\n");
printf("Now " + EncodeColor( colorRed ) + "red text\n");
printf("and finally " + EncodeColor( colorGreen ) + "green <b>AND bold <i>AND italic</i></b>\n");
printf(EncodeColor( colorBlack ) + "going back to black");

Dynamic content

I guess that you are quite bored with these simple examples; let's start with some dynamic content.

To enable dynamic commentaries, AFL has a couple of special functions available, but two of them are the most important: NumToStr() and WriteIF(). The WriteIF() function is used for conditional text display and will be described later in this article. Now, let us see what we can do using the NumToStr() function.

The AFL reference manual says:

SYNTAX NumToStr( NUMBER );
NumToStr( ARRAY );
RETURNS STRING
FUNCTION This function can only be used within a Guru commentary. It is used to display the numeric value of NUMBER or ARRAY.

So, if you want to display a value of a number or the currently selected bar of the array, you should use NumToStr() function. But... wait a minute - what does it mean "currently selected bar of the array"? Let me explain this using a simple formula (please type it in the Formula tab):

printf( NumToStr( close ) );

When you switch to Commentary tab, you will see the value of closing price (the same one which is displayed at the top of the main price chart). But when you click on the chart in another place, selecting a different date and then you click "Refresh" button, you will see a different value - the closing price at the day you have selected. So NumToStr( close ) function displays the value of the currently selected bar of the close array. And it works in exactly the same way with other arrays. If you write

printf( NumToStr( macd() ) );

you will see the exact value of the MACD indicator for the day you have selected in the main chart. With our current know-how, we are able to write some statistics:

printf( "Closing price = " + NumToStr( close ) + "\n" );
printf( "Change since yesterday = " + NumToStr( close - ref( close, -1 ) ) + "\n" );
printf( "Percent chg. since yesterday = " + NumToStr( roc( close, 1 ) ) + " %%\n" );
printf( "MACD =" + NumToStr( macd() ) + " , Signal line =" + NumToStr( signal() ) + "\n" );

When you switch to Commentary tab, you will see output similar to this one:

Closing price = 17.940
Change since yesterday = -0.180
Percent chg. since yesterday = -0.993 %
MACD = -0.001 , Signal line = 0.063

Quite nice, isn't it? You can also write the current symbol ticker and selected date using name() and date() functions as shown below:

printf( "Statistics of " + name() + " as of " + date() );

 

Instead of using NumToStr to convert a number to a string, we can format numbers directly using printf's flexible % format specifiers. For example, using %.2f means writing a number with 2 decimal places, %.3f will mean writing a number with 3 decimal places, %g will mean writing a number with the minimum required number of digits (auto-format). So we could write our previous example as follows:

printf( "Closing price = %.3f\n", close );
printf( "Change since yesterday = %.3f\n", close - ref( close, -1 ) );
printf( "Percent chg. since yesterday = %.2f%%\n", roc( close, 1 ) );
printf( "MACD = %.4f, Signal line = %.4f\n", macd(), signal() );

As we can see, this code is shorter and clearer. The first argument of printf function is a string (strictly speaking, a so-called formatting string that contains text and number placeholders/format specifiers marked with %). Subsequent arguments of the printf function are actual values (numbers) we want to write (without the need to convert to a string anymore). As you may have noted, if we want to specify just a percent sign, not a formatting sequence, we need to write %% (two percent signs).

But what we're missing here is the ability to write something if some condition is met and to write something different otherwise...

Conditional text output

AFL is equipped with a very nice function called WriteIF() that can output different texts depending on an expression. Let us look at what the documentation says:

SYNTAX writeif( EXPRESSION, "TRUE TEXT", "FALSE TEXT" )
RETURNS STRING
FUNCTION This function can only be used within a Guru commentary. If EXPRESSION evaluates to "true", then the TRUE TEXT string is displayed within the commentary. If EXPRESSION evaluates to "false", then the FALSE TEXT string is displayed.

So we can easily output different text depending on an expression, for example:

writeif( macd() > signal(), "The MACD is bullish because it is above its signal line", "The MACD is bearish because it is below its signal line" );

You can also combine several WriteIf() function calls in order to handle more possibilities:

"The current market condition for "+ name() + " is: ";

avgcond1 = ( c > ema( close, 200) ) + 0.1 * ( close > ema( close, 90) ) + 0.1 * ( close > ema( close , 30 ) );
avgcond2 = -( c < ema( close, 200) ) - 0.1 * ( close < ema( close, 90) ) - 0.1 * ( close < ema( close , 30 ) );

WriteIf( avgcond1 == 1.2,
"Very Bullish",
WriteIf( avgcond1 == 1.1,
"Bullish",
WriteIf( avgcond1 == 1.0,
"Mildly Bullish", "") ) ) +

WriteIf( avgcond2 == -1.2,
"Very Bearish",
WriteIf( avgcond2 == -1.1,
"Bearish",
WriteIf( avgcond2 == -1.0,
"Mildly Bearish", "") ) );

The formula above will return the text "The current market condition for {your ticker here} is: Very Bullish" if the close price is above the 30-day average, and the close is above the 90-day average, and the close is above the 200-day average. In other cases, the formula will give you Bullish, Mildly Bullish, Mildly Bearish, Bearish, or Very Bearish ratings.

For more examples on AFL commentaries, please check AFL formula library, especially the MACD commentary formula, which demonstrates all techniques presented here.

Now you are ready to start with your own commentaries... Good luck!