May 19, 2008
Recently on the AmiBroker mailing list some users expressed wish to have access to some of portfolio backtest metrics available in “historical” form (i.e. as date series, as opposed to scalars), so they can be plotted as an indicator.
Implementing such functionality is actually easy with existing tools and does not require any OLE scripts. Everything you need is small custom-backtester procedure that just reads built-in stats every bar and puts them into composite ticker.
In the accompanying indicator code all you need to do is simply use Foreign() function to access the historical metrics data generated during backtest.
The code below shows the BACKTEST formula with custom backtester part:
// Replace lines below with YOUR TRADING SYSTEM
PositionScore = 1/RSI(14);
PositionSize = -25;
SetOption("WorstRankHeld", 7 );
SetOption("MaxOpenPositions", 4 );
// BELOW IS ACTUAL CUSTOM BACKTESTER PART
// that can read any built-in metric (in this example UlcerIndex)
// and store it into composite ticker for further
// retrieval as data series
SetOption("UseCustomBacktestProc", True );
if( Status("action") == actionPortfolio )
bo = GetBacktesterObject();
bo.PreProcess(); // Initialize backtester
// initialize with null
// you can have as many historical metrics as you want
// (just duplicate line below for many metrics you want)
MyHistStat1 = Null;
MyHistStat2 = Null; // add your own
for(bar=0; bar < BarCount; bar++)
bo.ProcessTradeSignals( bar );
// recalculate built-in stats on EACH BAR
stats = bo.GetPerformanceStats( 0 );
// the line below reads the metric and stores it as array element
// you can add many lines for each metric of your choice
MyHistStat1[ bar ] = stats.GetValue("UlcerIndex"); // get ulcer index value calculated this bar
MyHistStat2[ bar ] = stats.GetValue("WinnersPercent"); // add your own
bo.PostProcess(); // Finalize backtester
// now STORE the historical data series representing the metric of your choice
// duplicate the line below for as many metrics as you want
AddToComposite( MyHistStat1, "~~~UI_HISTORICAL", "X", atcFlagEnableInPortfolio | atcFlagDefaults );
// you can add your own as shown below
AddToComposite( MyHistStat2, "~~~WP_HISTORICAL", "X", atcFlagEnableInPortfolio | atcFlagDefaults );
In the code above, for illustration purposes, we are exporting UlcerIndex and Winners Percent metrics as data series. They are stored in composite tickers for easy retrieval from indicator level.
You can easily extend code to include ANY number of metrics you want.
Now in order to Plot metrics as indicators, use this simple formula:
PlotForeign("~~~UI_HISTORICAL", "UlcerIndex Historical", colorRed, styleLine );
PlotForeign("~~~WP_HISTORICAL", "Winners Percent", colorBlue, styleLine | styleOwnScale );
As you can see with one Foreign function call you can read the historical value of any metric generated by the backtester.
NOTE: when running backtest please setup a filter in AA that EXCLUDES composites (group 253) from backtest set.