Using backtestRegularRaw to duplicate results of backtestRotational

Hello everyone,

I have a backtestRotational strategy which works great using this code:

hmb=Param("HoldMinBars",1,1,89);
/*=====  Symbol Ranking =====*/
if (Status("stocknum")==0)
{
    StaticVarRemove("sum*");	StaticVarRemove("ret*");        
    StaticVarRemove("ri*");     StaticVarRemove("Rank*");
    for (i=0; (symbol=StrExtract(watchlist,i)) != ""; i++)
    {
        SetForeign (symbol);
	ri=EMA(ROC(Close,89),3);
        RestorePriceArrays();	
        StaticVarSet("ri"+symbol,ri);	
    }  	
 /*===== Generate Ranks =====*/
StaticVarGenerateRanks("Rank","ri",0,1224);
}
/*===== Get Static Variables =====*/
symbol=Name();
ri=StaticVarGet("ri"+symbol);	RankRi=StaticVarGet("RankRi"+symbol);;
/*===== Backtest Parameters =====*/
EnableRotationalTrading();
SetOption("MaxOpenPositions",2);
SetOption("WorstRankHeld",14);
SetOption("AllowPositionShrinking",True);
SetPositionSize(100/mop,spsPercentOfEquity);
SetTradeDelays(1,1,1,1);
SetOption("HoldMinBars",hmb);
SetOption("ExtraColumnsLocation",0);
//===== Buy/Sell Criteria ============
PositionScore=100+ri;

Since I would like to have an additional Sell criteria other than just that of WorstRankHeld, I have tried to accomplish this using backtestRegularRaw. This works fine and matches the backtestRotational results when HoldMinBars=1 using this modified code:

/*===== Backtest Parameters =====*/
SetBacktestMode(backtestRegularRaw);
SetOption("MaxOpenPositions",2);
SetOption("WorstRankHeld",14);
SetOption("AllowPositionShrinking",True);
SetPositionSize(100/mop,spsPercentOfEquity);
SetTradeDelays(1,1,1,1);
SetOption("HoldMinBars",hmb);
SetOption("ExtraColumnsLocation",0);
//===== Buy/Sell Criteria ==============
Buy=1;
Sell=RankRi>wrh;
PositionScore=100+ri;

The issue I am facing is that when I increase the HoldMinBars value to any number higher than 1, it seems to break the code and the results no longer match those of backtestRotational.

I have tried at least 10 variations of the BuySell criteria to make this work, including using BarsSince to get the code to recognize the number of bars since Buy, but without success. Would appreciate it if anyone has any ideas that might point me in the right direction.

Russell

You need to use CBT, check this example:

//  Rotation rules 
MaxPositions = 4;
SetOption("MaxOpenPositions", MaxPositions  );
SetOption("WorstRankHeld", MaxPositions + 2 );
SetPositionSize( 100 / MaxPositions, spsPercentOfEquity ); 

SetBacktestMode( backtestRotational );
PositionScore = 10000 - ROC( C, 252 ); 


// additional exit rule 
symbol = Name ();
exit =  mtRandomA() < .3;  // random exit replace with your exit rules
StaticVarSet ( symbol + "exit", exit ); 

SetCustomBacktestProc("");

if (Status("action") == actionPortfolio) 
{
    bo = GetBacktesterObject();	//  Get backtester object
    bo.PreProcess();	//  Do pre-processing (always required)

    for (i = 0; i < BarCount; i++)	//  Loop through all bars
    {
        for ( pos = bo.GetFirstOpenPos(); pos ; pos = bo.GetNextOpenPos())
        {
			symbol = pos.Symbol ; 
			price = pos.GetPrice( i , "C" );
			exit = StaticVarGet ( symbol + "exit" ); 
			
			if ( exit [i] )  {
			bo.ExitTrade ( i , symbol , price );
			}  
        }
        
        
        
        bo.ProcessTradeSignals( i );	//  Process trades at bar (always required)
   
    
    }  
      
    bo.PostProcess();	//  Do post-processing (always required)
}

aron,

Thanks for your response and the sample code. I have never used the CBT before but now is a good time to learn something new and see if I can use it to accommodate a second exit condition for my rotational backtest. Your CBT code gives me a good place to start.

Russell