Portfolio Backtester Interface Reference Guide

(Updated February 20th, 2010 to cover enhancements and additions introduced in AmiBroker 5.30.0)

Basics

AmiBroker version 4.67.0 exposes a new object-oriented interface to the portfolio backtester, allowing control over the second phase of the backtest. This allows a multitude of applications, including but not limited to:

This document describes all objects, methods, and properties exposed by the portfolio interface.

Requirements

To use the new interface, the user needs AmiBroker 4.67.0 or higher and needs to have AFL coding skills, including understanding the terms: an object, method, and property.

Various approaches for various applications

The portfolio backtester interface supports various approaches to the customization of the backtest process that suit different applications.

Getting access to the interface

To access the new portfolio backtester interface, you need to:

Typing Conventions

Despite the fact that the interface handles integer data types such as long, short, bool, and two different floating-point types: float and double, AFL itself converts all those data types to float because AFL treats all numbers as floats (32-bit IEEE floating-point numbers).

Objects

The interface exposes the following objects:

The only object directly accessible from AFL is the Backtester object; all other objects are accessible by calling Backtester object methods, as shown in the picture below.


Backtester object

The Backtester object allows control over the backtest process (processing signals, entering/exiting/scaling trades) and provides access to the signal list, open position and trade list, and to the performance statistics object.

Methods:

Properties:

Signal object

A Signal object represents a trading signal (buy/sell/short/cover) or a ranking array element generated by AmiBroker during the first phase of backtest when your formula is executed on every symbol under test. During this first phase scan, AmiBroker collects data from buy/sell/short/cover signal, price, position size, and score arrays, performs sorting of signals, and puts top-ranked entry signals and all scale and exit signals into the list. A separate list of trading signals is maintained for every bar. The signal list is sorted so that first entry signals appear (top-ranked first), and after that, scaling and exit signals follow. To conserve memory, AmiBroker stores only (2*MaxOpenPositions) top-ranked entry signals per bar. It keeps, however, all exit and scaling signals. Once the first phase is completed and the backtester enters the second phase (real backtest), it iterates through bars and through all signals within a given bar and executes trades based on these signals.

To iterate through the signal list, you should use the GetFirstSignal() / GetNextSignal() methods of the Backtester object, as shown below:

// retrieve the interface to portfolio backtester
bo = GetBacktesterObject();

for( i = 0; i < BarCount; i++ )
{
    for( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) )
    {
       if( sig.IsEntry() )
       {
          // handle entry signal
         ....
       }�
    }
   
    bo.ProcessTradeSignals( i );
}

Methods:

Properties:

 
Trade object

A Trade object represents either a currently open position (open trade) or a closed trade. AmiBroker maintains two lists of trades: an open position list (accessible using the GetFirstOpenPos()/GetNextOpenPos() methods of the Backtester object) and closed trade lists (accessible using the GetFirstTrade()/GetNextTrade() methods of the Backtester objects). Once an open position is closed by the backtester, it is automatically moved from the open position list to the trade list. When the backtest is completed (after a PostProcess() call), AmiBroker closes out all open positions, so the trade list includes all trades. You can access both lists at any time during the backtest; you can also access the trade list after completion to generate trade-related statistics.

To iterate through the open position list, you should use the GetFirstOpenPos() / GetNextOpenPos() methods of the Backtester object, as shown below:

    // 'bo' variable holds Backtester object retrieved earlier
   
    for
( openpos = bo.GetFirstOpenPos(); openpos; openpos = bo.GetNextOpenPos() )
     {
          
// openpos variable now holds Trade object

     }

To iterate through the closed trade list, you should use the GetFirstTrade() / GetNextTrade() methods of the Backtester object, as shown below:

    for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
     {
          
// trade variable now holds Trade object

     }

Methods:

Properties:

 
Stats object

A Stats object provides access to built-in backtester statistics and metrics. Metrics are usually calculated once the backtest is completed, but it is also possible to calculate metrics during the backtest. To calculate current metrics and get access to them, simply call the GetPerformanceStats() method of the Backtester object. Please note that if you calculate statistics in the middle of the backtest, they will include only closed trades.

To calculate and access stats, use the following code:

// 'bo' variable holds Backtester object retrieved earlier

stats = bo.GetPerformanceStats(
0 );

Methods:

Properties:

-none-

MonteCarloSim object

The object allows access to Monte Carlo simulation results and has only one method.

Methods:

Further information

Examples and more documentation can be found in this Houston presentation covering the custom backtester interface (300 KB PDF format) and the Knowledge Base: http://www.amibroker.com/kb/category/afl/custom-backtest/