This code shows how to rebalance open positions using low level CBT:
It uses getpositionvalue() which is calculated with closing prices to determine the number of shares to scale at the open. Therefore it has a future leak.
Instead of using getPositionValue() you should use yesterday's close multiplied by the number of shares; or even today's open:
price = pos.GetPrice( bar, "O" );
posval = pos.Shares*price;
To calculate position value at open, once you know the open.
I attach the TRACE in case you want to check
/*
Here is an example that shows how to code rotational trading system with rebalancing.
The system buys top 3 securities according to absolute value of positionscore
(user definable – in this example we used 20 day rate-of-change)
– each at 5% of equity then each day it rebalances existing positions to 5%
if only the difference between current position value and “ideal” value is greater
than 0.5% and bigger than one share.
*/
EnableRotationalTrading();
dt = DateTime();
EachPosPercent = 5;
PositionScore = 1000 + ROC( C, 20 );
PositionSize = -EachPosPercent;
SetOption("WorstRankHeld", 40 );
SetOption("MaxOpenPositions", 3 );
SetOption("UseCustomBacktestProc", True );
if( Status("action") == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess(); // Initialize backtester
for(bar=0; bar < BarCount; bar++)
{
bo.ProcessTradeSignals( bar );
CurEquity = bo.Equity;
_TRACE("Date: " + DateTimeToStr(dt[bar], 1)
+ "; CurEquity = " + NumToStr(CurEquity,1.2) );
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
posval = pos.GetPositionValue();
_TRACE( pos.Symbol + "; Pos value = "+ NumToStr(posval,1.2)
+ "; Shares = " + NumToStr(pos.Shares,1.0)
+ "; Open = " + NumToStr(pos.GetPrice( bar, "O"),1.2)
+ "; Close = " + NumToStr(pos.GetPrice( bar, "C"),1.2)
);
diff = posval - 0.01 * EachPosPercent * CurEquity;
price = pos.GetPrice( bar, "O" );
// rebalance only if difference between desired and
// current position value is greater than 0.5% of equity
// and greater than price of single share
if( diff != 0 AND
abs( diff ) > 0.005 * CurEquity AND
abs( diff ) > price )
{
bo.ScaleTrade( bar, pos.Symbol, diff < 0, price, abs( diff ) );
_TRACE( "*** Escalado "+ pos.Symbol + NumToStr(pos.shares,1) + " Shares");
}
}
_TRACE("......................................");
}
bo.PostProcess(); // Finalize backtester
}
Thank you