SetPositionSize & sigScaleOut Causing wrong position sizing

Hi,

I've been having some trouble with sigScaleOut and SetPositionSizing.

I have a futures strategy that works as expected, however, when I attempt to add the code to scale out half positions

SetPositionSize( 50, spsPercentOfPosition * ( Buy == sigScaleOut ) );
SetPositionSize( 50, spsPercentOfPosition * ( Short == sigScaleOut ) );

I get the following warning and the trade does not take place, there is enough of an account balance and the currency is set correctly. It appears to be requesting -950 contracts

&NG not entered because of insufficient funds or wrong position size/value (reqEntryPrice: 1320, reqEntryPosSize: -950 shares (value = 0), reqLotSize: 1)

The strange thing is that this only occurs with Buy Signals and the sigScaleOut shouldnt have been triggered, shorts also work as expected, I also tried removing the SetPositionSize for the short and this didn't help.

My full exit code is

//////////////////Position size for initial entry/////////////////////////

SetPositionSize((Ref(num_contracts, -1)), spsShares);

/////////////////////// EXIT CONDITIONS ///////////////////////////////////

//Init variables
Buy_price = 0;
Sell_price = 0;
Target_price_2R = 0;
Target_price_3R = 0;
Target_price_4R = 0;
Target_price_1R = 0;
ISL = 0;
highsincebuy = 0;
lowsincebuy = 0;
breakeven = 0;
Entry_price = 0;
exit = 0;
bar=0;
test = 0;


for( i = 0; i < BarCount; i++ ) 
	{ 
	if(Buy_price == 0  AND Buy[i])
		{
		bar=i;
		Buy_price = Buy[i];
		Entry_price = High[i-1] + TickSize;
		ISL = Low[i-1] - TickSize;
		Target_price_1R = High[i-1] + (R[i-1]);
		Target_price_2R = High[i-1] + (R[i-1] * 2);
		Target_price_3R = High[i-1] + (R[i-1] * 3);
		Target_price_4R = High[i-1] + (R[i-1] * 5);
		breakeven = High[i-1] + (R[i-1] * 1.2);
		exit = 0;
		}
	
	// we are in a trade
	if(Buy_price > 0)
		{
		highsincebuy = Max( High[ i ], highsincebuy ); 
		// check that we haven't hit our stop
		
		//Breakeven stop
		if(exit == 0 AND High[i] > breakeven)
			{
			ISL = entry_price;
			price_action_plotter[i] = 1;
			}
			
		// if we hit our 2x R, sell half and place stop at 1R
		if(exit == 0 AND highsincebuy > Target_price_2R)
			{
			Buy[ i ] = sigScaleOut;
			ISL = Target_price_1R;
			exit = 2;
			exit_price[i] = Target_price_2R;
			//test=1;
			}
		
		//3R exit
		if(exit==2 AND highsincebuy > Target_price_3R)
		{
		//ISL = Target_price_2R;
		}
		
		//4R exit	
		if(exit==2 AND highsincebuy > Target_price_4R)
			{
			Sell[i] = 1;
			SellPrice = Target_price_4R;
			Buy_price = 0;
			exit=4;
			price_action_plotter[i] = 1;
			exit_price[i] = Target_price_4R;
			}
	
		// Execut stops
		if((exit == 0 OR exit==2) AND Low[i] < ISL)
			{
			Sell[i] = 1;
			SellPrice = ISL;
			Buy_price = 0;
			exit = 1;
			price_action_plotter[i] = 1;
			exit_price[i] = ISL;
			}
		}
		
	////////////////////SHORTS EXIT /////////////////////////
	
	if(Sell_price == 0 AND Short[i])
		{
		bar=i;
		h2 = High[i-1];
		l2 = Low[i-1];
		Sell_price = Short[i];
		entry_price = Low[i-1] - TickSize;
		ISL = High[i-1] + TickSize;
		Target_price_1R = Low[i-1] - (R[i-1]);
		Target_price_2R = Low[i-1] - (R[i-1] *2);
		Target_price_4R = Low[i-1] - (R[i-1] *4);
		breakeven = Low[i-1] - (R[i-1] * 1.2);
		lowsincebuy = Low[i];
		exit = 0;
		}
		// we are in a trade
	if(Sell_price > 0)
		{
		lowsincebuy = Min( low[ i ], lowsincebuy ); 
		// check that we haven't hit our stop
		
		//Breakeven stop
		if(exit == 0 AND Low[i] < breakeven)
			{
			ISL = entry_price;
			}
			
		// if we hit our 2x R, sell half and place stop at 1R
		if(exit == 0 AND lowsincebuy < Target_price_2R)
			{
			Short[ i ] = sigScaleOut;
			ISL = Target_price_1R;
			exit = 2;
			exit_price[i] = Target_price_2R;
			}
		
		//3R exit
		if(exit==2 AND lowsincebuy < Target_price_3R)
		{
		//ISL = Target_price_2R;
		}
			
		if(exit==2 AND lowsincebuy < Target_price_4R)
			{
			Cover[i] = 1;
			CoverPrice = Target_price_4R;
			Sell_price = 0;
			exit=4;
			exit_price[i] = Target_price_4R;
			}
	
		// Execute stops
		if((exit == 0 OR exit==2) AND High[i] > ISL)
			{
			Cover[i] = 1;
			CoverPrice = ISL;
			Sell_price = 0;
			exit = 1;
			}
		}
		
	}


// Scale out position

SetPositionSize((Ref(num_contracts, -1)), spsShares);

SetPositionSize( 50, spsPercentOfPosition * ( Buy == sigScaleOut ) );
SetPositionSize( 50, spsPercentOfPosition * ( Short == sigScaleOut ) );

Buy = ExRem(Buy, Sell);
Short = ExRem(Short, Cover);

Apologies for the long post, i know i'm going wrong somewhere but can't seem to figure it out

Thanks in advanced for any thoughts and ideas.

Cheers

@gwil perhaps try using the Special value spsNoChange (=0) means don't change previously set size for given bar .

SetPositionSize((Ref(num_contracts, -1)), spsShares);
SetPositionSize( 50, IIf( Short == sigScaleOut OR Buy == sigScaleOut, spsPercentOfPosition, spsNoChange ) );

Another possibility is to try using spsShares, for example

//trade two contracts with every entry signal
SetPositionSize(2, spsShares); 
//scale out one contract at a time
SetPositionSize( 1, IIf( Short == sigScaleOut OR Buy == sigScaleOut, spsShares, spsNoChange ) );

I don't have futures data to test this on, but it seems to work on stock data.

And you wrote that the warning was that there was not enough of an account balance so this following option may help.

SetOption("AllowPositionShrinking", True );
2 Likes

Hi @portfoliobuilder ,

Thanks for the help.

Using the below seems to fix the issue, it was still having the same problem with the spsPercentOfPosition version. The only thing I could think that would be causing this is using spsPercentOfPosition and spsShares in the same strategy

SetPositionSize( 1, IIf( Short == sigScaleOut OR Buy == sigScaleOut, spsShares, spsNoChange ) );

Thanks again!