Limit exit trade size as % of exit bar volume

Hello,

I have been trying to find a way of limit sell size of a stock to the day trade volume to mimic real exit process.

I want the backtester to sell only what it can practically sell and not just assume it sold all the position then complete selling the next day and so on.

Is there anyway of doing this ?

Regards,

The technical term for this is Scale out or Scaling out.

Maybe you didn't search it that way, if you do, you will get many posts and threads discussing how to exit a position in parts based on some condition.

Also, on a lighter note, is your Quantity so huge that its more than daily Volume :slight_smile: or are these illiquid instruments? anyway, there are lots of discussion on scaling out.

Hello Travick,

I am aware of scale out and scale in where you 'change' position size manually.

What i am asking for is considering the daily volume when you are completely selling a position and only sell like 10% or whatever percentage that you can practically trade and continue the rest of the sell on the next day.

I deal with a fund that is difficult to trade positions directly and can have positions higher than available volume very easily.

Regards,

There's nothing to prevent you from using the Volume to determine your scale-out size...

I am using a custom backtester, i need to do the following:

On exit condition, i need to check the position size against the bar volume and :
1- sell all position if position size is less than 1/3 of bar volume.
2. scale out only 1/3 of the volume if position size is more and continue scaling out till the position is closed.

In short, i want to limit the sell to 1/3 of the volume at exit and keep scaling out.

What i tried is:

  1. assigning a sell signal when conditions occur then change it to scale out signal with new position size when position size is large, i found that sig.Type cannot be changed from 2 (sell) to 6 (scale out)

  2. assigning a scale out signal and change it to sell if amount left is less than 1/3 volume, it's not also changing signal type to a sell.

My problem would be solved if i can change the signal type from inside the signals loop of the custom backtestin

here is my custom backtesting code.

if ( Status( "action" ) == actionPortfolio ) 
{
    bo = GetBacktesterObject();
    bo.PreProcess();

    for ( bar = fvb; bar < BarCount; bar++ )
    {
		entries = bo.GetSignalQty(bar, 1); // get entries
		exits   = bo.GetSignalQty(bar, 2);
        opens   = bo.GetOpenPosQty();
		openPositions = (entries+opens)-exits;
		
		maxSizePosition=99/openPositions;
		maxSizePosition = IIf(maxSizePosition>15,15,maxSizePosition);
		// set the position size based on number of entries + open positions
			
		for ( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) )
		{
			
			if (sig.IsEntry())
			{
				sig.PosSize = - maxSizePosition/2;
				pos=bo.FindOpenPos(sig.Symbol);
				if(!IsNull(pos))
				{
					//sig.Type = 5;
					currentSize=pos.GetPositionValue()/bo.Equity();
					if(currentSize<sig.PosSize)
					{
						sig.Type = 5;
						sig.PosSize = - maxSizePosition/2;
						
					}
				}
				
				
			}
			
			else if(sig.Type==5) //scale in
			{	
				
				sig.PosSize = - maxSizePosition;
				
			}
			else if (sig.Type == 6) //scale out
			{
				statusB=StaticVarGet( "status" + sig.Symbol);
				if(statusB[bar]==-1)
				{
					pos=bo.FindOpenPos(sig.Symbol);
					if(!IsNull(pos))
					{
						BarVolume=Foreign(sig.Symbol, "V" );
						maxBarVolume=BarVolume[bar]/3;
						value=pos.Shares;
						currentSize=(pos.GetPositionValue()/bo.Equity())*100;
						
						if(value>maxBarVolume)
						{
							
							soldSize=(((value-maxBarVolume)*pos.GetPrice(bar,"C"))/bo.Equity() )*100;
							sig.PosSize = - (currentSize - soldSize);
							
							
							_TRACEF("type %g shares %g size %g soldsize %g newsize %g ",sig.Type,value,currentSize,soldSize,sig.PosSize); 
							
						}
						else
						{
							sig.Type=2;
							_TRACEF("type %g shares %g ",sig.Type,sig.PosSize); 
						}
					}
				}
				else
					sig.PosSize = - maxSizePosition/2;	
				
			}
			
			
		}
		
		bo.ProcessTradeSignals( bar );
	}
    bo.PostProcess();
}	

Please note that i did the same for the entry signals and it worked ( I am aware it already exists but the difference is i need it to continue buying and fulfilling the required position as long as the entry conditions occur).

Thanks in advance,

There are multiple ways that you could solve this problem. Two that come immediately to mind are:

  1. Generate the correct signal (either Sell or Scale-Out) in your Phase 1 AFL
  2. In your CBT, use the low-level methods bo.EnterTrade(), bo.ExitTrade() and bo.ScaleTrade(). That way, you could exit when you get a scale-out signal, for example.
1 Like

Thank you very much for your help.
I tried it and it worked.
I just have one more question for the same topic. How can i ignore the basic sell signal if i scaled it out ?

i mean if i done a manual scale out when i had a sell signal, how to tell the backtester to ignore this sell signal when i did the scale out ?

Thanks in advance

I can only guess what your latest code is doing, since you have not posted it. But it sounds like you're generating a Sell signal, and then on certain occasions you're trying to override it with a a scale-out instead. I would have done it the other way: always generate a Scale-Out signal, and if the scale-out is for 100% of the position then call bo.ExitTrade() instead of bo.ScaleTrade(). That way if you're allowing bo.ProcessTradeSignals() to do some processing as well, it won't matter if you allow the bo.ScaleTrade() to fall through because there will be no trade left to scale out of. Personally, I don't mix the mid-level and low-level CBT methods, but that's up to you.