Trade size based on the cash available at previous EOD

I am trying to back test a portfolio of stocks for an intraday strategy. I want to enter a trade with the size based on the cash available at EOD the previous day.

For example:

My risk per trade is 1%.

Day 1:

  • BOD Cash: 100,000
  • Risk:1000 per trade
  • Trades today: 10
  • Total Profit: 1000
  • EOD Cash 101,000

Day 2:

  • BOD Cash: 101,000
  • Risk:1010 per trade
  • Trades today: 5
  • Total Profit: -500
  • EOD Cash 100,500

Day 3:

  • BOD Cash: 100,500
  • Risk:1005 per trade
  • Trades today: 15
  • Total Profit: 5000
  • EOD Cash 105,500

How to accomplish this? By default, Amibroker sizes the trade based on the Portfolio Equity when entering the trade. I understand that this needs to be done using CBT. But I am not an expert in CBT and could not find anything so far that is close to my requirement to use it and build upon. Can someone point me to the right direction?

dn = DateNum();
newday = dn != Ref( dn, -1);
eod = dn != Ref(dn,1);

Buy = Cross(C, MA(C,20));
Sell = Cross(MA(C, 20), C);

pcnt = 10;

SetCustomBacktestProc("", 1);
/// @link https://forum.amibroker.com/t/trade-size-based-on-the-cash-available-at-previous-eod/20878/2
if ( Status( "action" ) == actionPortfolio ) {
	bo = GetBacktesterObject();
	initial_cash = bo.Cash;
	for ( i = 0; i < BarCount; i++ ) {          
		for ( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) )  {            
			if ( sig.IsLong() ) { 		
				if ( sig.IsEntry() )   
					sig.PosSize = pcnt/100*Nz(StaticVarGet("newDay_Cash"), initial_cash);	
			}   
		}       
		bo.ProcessTradeSignals( i );

		// Update cash after trades (EOD)
		if ( eod[i] ) StaticVarSet("newDay_Cash", bo.Cash);
	}
	bo.PostProcess();
}
4 Likes

This one should work also.

dn = DateNum();
newday = dn != Ref( dn, -1);
eod = dn != Ref(dn,1);

Buy = Cross(C, MA(C,20));
Sell = Cross(MA(C, 20), C);

pcnt = 10;

SetCustomBacktestProc("", 1);
/// @link https://forum.amibroker.com/t/trade-size-based-on-the-cash-available-at-previous-eod/20878/3
if ( Status( "action" ) == actionPortfolio ) {
	bo = GetBacktesterObject();
	nd_cash = bo.Cash;
	for ( i = 0; i < BarCount; i++ ) {          
		for ( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) )  {            
			if ( sig.IsLong() ) { 		
				if ( sig.IsEntry() )   
					sig.PosSize = pcnt/100*nd_cash;	
			}   
		}       
		bo.ProcessTradeSignals( i );

		// Update cash after trades (EOD)
		if ( eod[i] ) nd_cash = bo.Cash;
	}

	bo.PostProcess();
}
5 Likes

Thank you @fxshrat. I will try these two suggestions.

Works fantastic. Thanks a ton @fxshrat. Since my postion size is based on risk% and my stop loss, I have used number of shares in sig.PosSize as mentioned here.

These are good, both work nicely for single tickers. Is there any way to extend for portfolio backtests? Thanks.