Portfolio-level backtesting

IMPORTANT: Please read first Tutorial: Backtesting your trading ideas article

New backtester works on PORTFOLIO LEVEL, it means that there is single portfolio equity and position sizing refers to portfolio equity. Portfolio equity is equal to available cash plus sum of all simultaneously open positions at given time.

AmiBroker's portfolio backtester lets you combine trading signals and trade sizing strategies into simulations which exactly mimic the way you would trade in real time. A core feature is its ability to perform dynamic money management and risk control at the portfolio level. Position sizes are determined with full knowledge of what's going on at the portfolio level at the moment the sizing decision is made. Just like you do in reality.

HOW TO SET IT UP ?

There are only two things that need to be done to perform portfolio backtest

1. You need to have first the formula that generates buy / sell / short /cover signals as described in "Backtesting your trading ideas" article

2. You should define how many simultaneous trades you want to test and what position sizing algorithm you want to use.

SETTING UP MAXIMUM NUMBER OF SIMULTANEOUSLY OPEN TRADES

There are two ways to set the maximum number of simultaneously open trades:

1. Go to the Settings dialog, switch to Portfolio tab and enter the number to Max. Open Positions field

2. Define the maximum in the formula itself (this overrides any setting in the Settings window) using SetOption function:

SetOption("MaxOpenPositions", 5 ); // This sets maximum number of open positions to 5

SETTING UP POSITION SIZE

IMPORTANT: to enable more than one symbol to be traded you have to add PositionSize variable to your formula, so less than 100% of funds are invested in single security:

PositionSize = -25; // invest 25% of portfolio equity in single trade

or

PositionSize = 5000; // invest $5000 into single trade

There is a quite common way of setting both position size and maximum number of open positions so equity is spread equally among trades:

PosQty = 5; // You can define here how many open positions you want
SetOption("MaxOpenPositions", PosQty );
PositionSize = -100/PosQty; // invest 100% of portfolio equity divided by max. position count

You can also use more sophisticated position sizing methods. For example volatility-based position sizing (Van Tharp-style):

PositionSize = -2 * BuyPrice/(2*ATR(10));

That way you are investing investing 2% of PORTFOLIO equity in the trade adjusted by BuyPrice/2*ATR factor.

USING POSITION SCORE

You can use new PositionScore variable to decide which trades should be entered if there are more entry signals on different securities than maximum allowable number of open positions or available funds. In such case AmiBroker will use the absolute value of PositionScore variable to decide which trades are preferred. See the code below. It implements simple MA crossover system, but with additional flavour of preferring entering trades on symbols that have low RSI value. If more buy signals occur than available cash/max. positions then the stock with lower RSI will be preferred. You can watch selection process if you backtest with "Detailed log" report mode turned on.

The code below includes also the example how to find optimum number of simultaneously open positions using new Optimization in Porfolio mode.

/*****
** REGULAR PORTFOLIO mode
** This sample optimization
** finds what is optimum number of positions open simultaneously
**
****/

SetOption("InitialEquity", 20000 );
SetTradeDelays(1,1,1,1);
RoundLotSize = 1;

posqty = Optimize("PosQty", 4, 1, 20, 1 );
SetOption("MaxOpenPositions", posqty);

// desired position size is 100% portfolio equity
// divided by PosQty positions

PositionSize = -100/posqty;

// The system is very simple...
// MA parameters could be optimized too...
p1 = 10;
p2 = 22;
// simple MA crossover
Short=Cross( MA(C,p1) , MA(C,p2) );
Buy=Cross( MA(C,p2) , MA(C,p1) );
// always in the market
Sell=Short;
Cover=Buy;

// now additional score
// that is used to rank equities
// when there are more ENTRY signals that available
// positions/cash
PositionScore = 100-RSI(); // prefer stocks that have low RSI;

ROTATIONAL TRADING

Rotational trading (also known as fund-switching or scoring and ranking) is possible too. For more information see the description of EnableRotationalTrading function.

See Also:

Backtesting your trading ideas article.

Backtesting systems for futures contracts article.

Using AFL editor section of the guide.

Insider guide to backtester (newsletter 1/2002)