Positionsize in backtesting results

I would need to see PositionSize as % of the available equity in the Backtest results.
I thought to add a custom metrics to get it from backtesting.
I guess there are two options:

  1. get PosSize
  2. get the position values and divide it by equity.
    In either case I don’t know how to do it. In the instructions I have found:
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( sig = bo.GetFirstSignal(); sig; sig = bo.GetNextSignal() ) 
        if( sig.IsEntry() ) 
          // handle entry signal 

But I don’t know what command would retrieve the “float PosSize”.
Any help would be highly appreciated.
I have also found Positionsizing from custom backtest procedure but this does not address what I’m looking for.


All of the AmiBroker objects, including methods and properties, are defined here: https://www.amibroker.com/guide/a_custombacktest.html. However, it might be worth taking a step back: how are you setting your position size in the first place?


I’d use something like:

for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() ) 
      {posPct = 100 * pos.GetPositionValue() / bo.Equity}

@stevo713 if you do that, then you will be calculating a potentially different position size for every bar that the trade is open. I suspect that @jbenfeld wants to capture the position size only when the trade opens, or perhaps when it closes. Both of those are very easy if you’re writing a low-level CBT, but that may be beyond @jbenfeld’s current comfort zone. That’s why I asked how the position size was being set in the first place. If he wants his position sizes to be a certain percentage of equity, then he should just specify that with SetPostionSize() and be done with it.

1 Like

I’m not sure I fully understand your goal, but if you only need to display that value in backtest results, you can check the following post as a starting point http://forum.amibroker.com/t/adding-percent-of-portfolio-on-entry-as-a-trade-metric/3062/5?u=pmxgs
(I’m assuming the position size itself is defined in first phase of backtest)

stevo713, mradtke, pmxgs Thanks for replying.

The Initial PosizionSize is set at percentage level : PositionSize= - some number; with minus in front;

I am trying to report that value next to the trade (at least when a position is opened) . The one set by " PositionSize= - some number;" so that when I run a backtesting I can see that value in the report.

“I suspect that @jbenfeld wants to capture the position size only when the trade opens”

I guess that is what I need.

If you set your position size in first phase, then you can use the cbt code provided ( http://forum.amibroker.com/t/adding-percent-of-portfolio-on-entry-as-a-trade-metric/3062/5?u=pmxgs ) as a starting point.
This code just adds the position size of each trade, to to backtest results.

Hi pmxgs and all,
thanks for your time and help provided so far. I have tested the following code and it “partially” works for me:

SetCustomBacktestProc(""); // Now custom-backtest procedure follows 
if( Status("action") == actionPortfolio )
{   bo = GetBacktesterObject();
    // run default backtest procedure without generating the trade list
st = bo.GetPerformanceStats(0); // get stats for all trades
   // iterate through closed trades first 
   for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() ) 
   {   Eq = Lookup( bo.EquityArray, trade.EntryDateTime );
       trade.AddCustomMetric("Entry", 100*trade.GetEntryValue/eq); 
   // iterate through eventually still open positions 
   for( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() ) 
   {  Eq = Lookup( bo.EquityArray, trade.EntryDateTime );
      trade.AddCustomMetric("Entry", 100*trade.GetEntryValue/eq);
    // generate trade list
    bo.ListTrades( );

Thought there are a coupe of points I wanted to improve/clarify:

  1. The PosSize reported is sligthly different that the one set by PositionSize in AFL.
    For example if i allocate a 16.67% now with this formula I get 16.35. I guess this is due to the fact that in the backtesting code we use : 100*trade.GetEntryValue/eq.

QUESTION: is there any way to get the original Value set in the AFL? I tried the code:

trade.AddCustomMetric("Entry", trade.PosSize);

But it does not work.Any guess?

  1. the code
    // generate trade list
    bo.ListTrades( );

list all buy signals including those that have 0 PosSize.
QUESTION: is there anyway to exclude them from the list?
I have tried the code:

    bo.ListTrades( );

but it does not work.

Any help would be higly appreciated.


the small difference might be due to the fact that we are dividing trade size by portfolio equity at the close of the bar, and backtester might use a different equity amount to determine trade size (example: closed trades funds are not yet available)

  1. This line: trade.AddCustomMetric("Entry", trade.PosSize); does not work because trade object does not have a position size property. You can check this part in the user manual to see which methods and properties are available : http://www.amibroker.com/guide/a_custombacktest.html

  2. You should call Backtest method with True option:

// generate trade list
  bo.Backtest( True );

like in the code example, if you want to add per trade custom metrics.
If you have signals with zero position size, those do not generate trades, so are excluded from the trade list (probably you made other changes to your system for that to happen ).
The code example provided before, just adds per trade metrics, it does not change anything in the trading system itself.


If you tell AB that you want your position size to be 10% of equity, then AB will purchase as many shares as possible without going over 10% of your equity. The purchase amount will also include commissions. Therefore, unless you have set your round lot size to zero (allow fractional shares) and also set your commissions to zero, your actual position size will almost always be slightly smaller than your target position size.

1 Like

@ pmxgs
I can live with that smal discrepancy and about (2) is working well. Thanks.

Again, thanks to all you for your time.