Porfolio 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 new object-oriented interface to porfolio backtester allowing to control 2nd phase of the backtest. This allows multitude of applications including, but not limited to:

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

Requirements

To use 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 porfolio backtester interface supports various approaches to customization of backtest process that suit different applications.

Getting access to the interface

To access new portfolio backtester interface you need to:

Typing Conventions

Despite the fact that interface handles integer data type such as long, short, bool and two different floating point types: float and double, the 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 Backtester object, all other objects are accessible by calling Backtester object methods as shown in the picture below.


Backtester object

Backtester object allows to control backtest process (process signals, enter/exit/scale trades) and get access to signal list, open position and trade list and to performance statistics object.

Methods:

Properties:

Signal object

Signal object represents trading signal (buy/sell/short/cover) or ranking array element generated by AmiBroker during 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 put top-ranked entry signals and all scale and exit signals into the list. Separate list of trading signals is maintaned for every bar. Signal list is sorted so first entry signals appear (top ranked first) and after that scaling and exit signals follow. To conserve memory AmiBroker stores only (2*MaxOpenPositons) top-ranked entry signals per bar. It keeps however all exit and scaling signals. Once first phase is completed and backtester enters 2nd phase (real backtest) it iterates through bars and through all signals within given bar and executes trades based on this signals.

To iterate through signal list you should use GetFirstSignal() / GetNextSignal() methods of 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

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

To iterate through open position list you should use GetFirstOpenPos() / GetNextOpenPos() methods of 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 closed trade list you should use GetFirstTrade() / GetNextTrade() methods of Backtester object, as shown below:

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

     }

Methods:

Properties:

 
Stats object

Stats object provides the access to built-in backtester statistics and metrics. Metrics are usually calculated once backtest is completed but it is also possible to calculate metrics during backtest. To calculate current metrics and get the access to them simply call GetPerformanceStats method of 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 to access MonteCarlo simulation results and has only one method

Methods:

Further information

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