I'd like to plot a very simple indicator with the number of open and closed 
positions for every bar for a portfolio backtest.

It seems like this must be done through the Custom Backtester Interface 
therefore I tried to put together the articles:
-Historical Portfolio Backtest Metrics
http://www.amibroker.com/kb/2008/05/19/historical-portfolio-backtest-metrics/
-Advanced Portfolio Backtest Metrics
http://www.amibroker.com/guide/a_custombacktest.html
-Adding Custom Bactester Metrics
http://www.amibroker.com/guide/a_custommetrics.html

but it seems like charting user-created metrics is not that easy since GetValue 
method for Stats object doesn't allow to get user-created metrics values.

I came out with the below code which works fine but I'm quite sure there must 
be an easier and quicker way of doing it. Any hints?

Regards,

Paolo



///////////////////////////////////////////////////////////////////

SetOption("UseCustomBacktestProc", True ); 

if( Status("action") == actionPortfolio )
{
   

bo = GetBacktesterObject();
 
  bo.PreProcess(); // Initialize backtester
 
  // initialize with null 
  ClosedPos = Null; 
  OpenPos = Null;
  TotalPos = Null;

  for(bar=0; bar < BarCount; bar++)
  {
   bo.ProcessTradeSignals( bar );
  
   // recalculate built-in stats on EACH BAR
   //is it necessary???
   stats = bo.GetPerformanceStats( 0 );

   ClosedPositions = 0; 
   OpenPositions = 0; 
   TotalPositions = 0; 

   // iterate through closed trades first 
   for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade()) 
   { 
       ClosedPositions++;
   } 

   // iterate through eventually still open positions 
   for( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos()) 
   { 
       OpenPositions++; 
   } 

   //TotalPositions = ClosedPositions + OpenPositions;

 
   // the line below reads the metric and stores it as array element
   // you can add many lines for each metric of your choice
   ClosedPos[bar] = ClosedPositions; 
   OpenPos[bar] = OpenPositions;
   //TotalPos[bar] = TotalPositions;

  }

  bo.PostProcess(); // Finalize backtester

  AddToComposite( ClosedPos - Ref(ClosedPos, -1), "~~~ClosedPos", "X", 
atcFlagEnableInPortfolio | atcFlagDefaults );

  // you can add your own as shown below
  AddToComposite( OpenPos, "~~~OpenPos", "X", atcFlagEnableInPortfolio | 
atcFlagDefaults ); 
  //AddToComposite( TotalPos, "~~~TotalPos", "X", atcFlagEnableInPortfolio | 
atcFlagDefaults ); 
}

// Your system codes starts here
Sell = Cross(MACD(), Signal());
Buy = Cross(Signal(), MACD());
SetPositionSize(10 ,spsPercentOfEquity);

////////////////////////////////////////////////////////////////////

and the relative indicator:

//Positions Counter.afl
PlotForeign("~~~ClosedPos", "Closed Positions Historical", colorLightBlue, 
styleHistogram );
PlotForeign("~~~OpenPos", "Open Positions Historical", colorRed, 
styleHistogram);
TotalPos = Foreign("~~~ClosedPos", "C") + Foreign("~~~OpenPos", "C");
Plot(TotalPos, "Total Positions Historical", colorWhite, styleHistogram);

Reply via email to