High level CBT returning -1 for sig.Price on long scale-ins

Long only system. When I scale-out of a position, I want to exit the same amount of shares as my last buy entry or buy scale-in. I am trying to use the the high level CBT to adjust the scale-out shares to appropriate quantity, so first I am capturing the last entry quantity into a static var to be retrieved later and used on the scale-out. A snipit of my attempt is below.

for (sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i))
			{   
				tmpPrc = sig.Price;
				if (doTrace) { _TRACE(dn_tn_i + " tmpPrc: " + NumToStr(tmpPrc, 1.2)); }
				
				//Long only system.
				if (sig.IsLong() AND NOT sig.Type == 2 AND NOT sig.Type == 6 )    // if this is a buy or scale-in, and not a sell and not a scale-out
				{
					psize = sig.PosSize;    	
					if (psize < 0)   
						psize = (-psize/100) * bo.Equity; 
					
					LastEntryShares = psize / tmpPrc;
					StaticVarSet ( "LastEntryShares" +  sig.Symbol, LastEntryShares);
					if (doTrace) { _TRACE(dn_tn_i + " En ---LastEntryShares: " + NumToStr(LastEntryShares, 1.4) + "  psize: " + NumToStr(psize, 1.2) + "  sig.Price: " + NumToStr(sig.Price, 1.2) + "  sig.Type: " + NumToStr(sig.Type, 1.0) ); }
				}
			
			
				if (sig.Type == 6)    //  If this signal is a scale-out exit
				{
					LastEntryShares = StaticVarGet ( "LastEntryShares" +  sig.Symbol);
					if (doTrace) { _TRACE(dn_tn_i + " Ex ---LastEntryShares: " + NumToStr(LastEntryShares, 1.4)); }
					sig.PosSize = LastEntryShares * tmpPrc;   
				}
}

The problem is for the scale-ins, the CBT is returning a -1 for price. When I use a detailed report, I can see the correct scale-price, so why would the CBT give me a -1 here? According to the manual it is supposed to be able to return price for scales.

image

How did you set your BuyPrice in your Phase1 AFL?

if (  BuyCond )
		{
			Buy[i] = 1;
			Buy[i] = sigScaleIn[i]  ;
			BuyPrice[i] = BuyPrc;
}

in a low level loop with the above statement

@vjsworld I did a short test with your code (adding the standard CBT required lines) and using some fake rules to Buy/Sell like this:

sigB = ((C > MA(C, 5)) OR (RSI() < 5));
sigS = ((C < MA(C, 5)) OR (RSI() > 85));
Buy = IIf(sigB, sigScaleIn, 0);
Sell = SigS;

immagine

The Price for ScaleIn trades is correctly printed, so IMO the main suspect, as hinted by @mradtke, is the loop where you set the signals.

thank you for investigating @beppe. From what you see in my code above concerning the sigScaleIn, can you see anything wrong?

@vjsworld, sigScalein is a special constant so I do not understand why you are using it as an array.

I will probably do it this way:

if( BuyCond )
{
    Buy[i] = sigScaleIn ;
    BuyPrice[i] = BuyPrc;
}

And obviously, you need to have BuyPrc already defined (_TRACE the loop to log the values or use an exploration to see what values you are actually assigning).

In my previous example when I get a buy signal I set Buy directly to SigScalIn because AB treats the first sigScaleIn as buy anyway (see Example 2 of Pyramiding (scaling in/out).

1 Like
if( BuyCond )
{
    Buy[i] = sigScaleIn ;
    BuyPrice[i] = BuyPrc;
}

I did it exactly like this now and I am still getting -1 for sig.Price on just the sig.Type 5 (scale-in). I know the scale-in entry prices are correct because I draw arrows on the chart, and also study the detailed backtest report.

Any other suggestions?

You need to show entire code, not part of it. Likely you are printing values after processing signals. ProcessTradeSignals may modify values and -1 price usually means that signal was already processed and/or should be skipped.

3 Likes

That was it @Tomasz! I had to move :

bo.ProcessTradeSignals( i );

to below this part of the CBT loop. Thank you!