Completely wrong CBT usage. was: help with SetBarsRequired

I use this CBT code to set a maximum of 2 open positions when the Nasdaq index is below its 200 day moving average:

// parameters
per = 200;	
MaxOpenPos = 2;	

// load NDX data
ndx = Foreign( "$NDX", "C" );

// danger when NDX is below EMA	
ndx_ema = EMA( ndx, per );
danger = ndx < ndx_ema;

SetOption( "UseCustomBacktestProc", True );

if( Status( "action" ) == actionPortfolio )
{
	bo = GetBacktesterObject();
	bo.PreProcess();
	dt = DateTime();	
	
	// loop for all bars
	for( bar = 0; bar < BarCount; bar++ )
	{		
		// openpos at the beginning of this day
		openpos = bo.GetOpenPosQty();	
		
		_TRACE( "bar: " + bar + " ," + DateTimeToStr(dt[bar]) + " starting openpos: " + openpos[bar] + ", danger: " + danger[bar] );		
				
		Cnt = 0;
		for( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) )
		{			
			if (sig.IsEntry)
			{
				cnt++;	
				
				// cancel buy if danger and maxopenpositions
				if ( Openpos[bar] + cnt > MaxOpenPos AND danger[bar] )
				{			
					sig.Price = -1;
					_TRACE("cnt = " + cnt + ", buy cancelled in " + sig.Symbol);
				}
				else
					_TRACE("cnt = " + cnt + ", buy signal in " + sig.Symbol);
			}				
		}
		_TRACE(" date = " + DateTimeToStr(dt[bar]) + ", Cnt = " + Cnt);	
		bo.ProcessTradeSignals( bar );
	}
	bo.PostProcess();
}

This code needs to load 200 previous bars to work properly:

I added "SetBarsRequired" as per the documentation, but still I cannot make it work from the first bar in range. What am I doing wrong? Thank you

No. You are mistaken. You don't understand how portfolio backtest works in AmiBroker and what is the purpose of custom backtest.

Your formula DOES NOT need 200 bars in Custom Backtest. It only needs 200 bars in FIRST PHASE of backtest (that is NOT custom backtest).

Portfolio backtest runs in TWO phases. In first phase it is executed for every symbol in the "apply to" filter. Then it uses ALL BARS available for given symbol (unless you enabled padding then the number of bars is equal to reference symbol). In first phase ALL TRADING SIGNALS (buy/sell/short/cover) MUST BE GENERATED.

In second phase the signals ARE NOT generated at all. All your calculations are irrelevant. Second phase runs with ~~~EQUITY as current symbol and it has only AS MANY BARS as from-to date range covers. In CBT phase you just enter trades based on signals collected in first phase.
YOU DO NOT do anything else in CBT phase. Therefore all this "danger" variable display is nonsense as you do NOT use EMAs in CBT. Any moving avereages calculated anyway in CBT as in your code are totally ignored. They are not used, discarded.

If you for some reason need values of indicators in CBT phase you should use technique described (AS ALWAYS) in the documentation:

Please note the fact that the code for CBT presented in KB comes BEFORE the "normal part".

Your code contains completely USELESS CBT part that you should just remove. And SetBarsRequired is completely not needed and in fact ignored by CBT.

1 Like