If strategy loses too much in this month, stop and go next month

I would like to create a code that, when applied to a strategy, reads the portfolio equity.
If at the beginning of the month, it has fallen over 5%, closes positions, and waits for the following month.
The logic must be based on the equity of the portfolio.

I searched the forum and read many threads but I did not find an example to adapt.
Reading in the forum I understood, that there are various types of equity.

//Equity of the single symbol
PortEquity = Foreign("~~~EQUITY", "C" );
//Cash of the single symbol
Port__Cash = Foreign("~~~EQUITY", "L" );

For the portfolio, however, it is necessary to interrogate the object with a CBT

bo.Equity;

I have read the examples
http://www.amibroker.com/kb/2006/03/06/re-balancing-open-positions/
and the guide
http://www.amibroker.com/guide/h_portfolio.html

I wrote this code but I can not complete it because I can not set a method to exit forcefully.

F_Month    = Month();
F_DateNum  = DateNum();
MonthlyStop[0] = True;
MonthlyStop    = IIf(F_Month != Ref(F_Month,-1), True, Ref(MonthlyStop,-1) );


Buy  = Cross( MACD(), Signal() ); 
Sell = Cross( Signal(), MACD() ); 

PosQty = 3;
InitialEquity = 100000;
SetOption("InitialEquity", InitialEquity);
SetPositionSize(InitialEquity/3, spsValue);
SetOption("WorstRankHeld", 40 );
SetOption("MaxOpenPositions", 20 ); 
RoundLotSize = 1;										//amount minimum of stock
TradeDelay = 1;											//set it to 0 for no delays
SetTradeDelays( TradeDelay, TradeDelay, TradeDelay, TradeDelay );

SetBacktestMode(backtestRegular);		

PositionScore = ROC( Close, 20 ); 

SetCustomBacktestProc("");
if( Status("action") == actionPortfolio )	{
	bo = GetBacktesterObject();
	bo.PreProcess();
	
	CMonth_End[0] = 0;
	for(bar=1; bar < BarCount; bar++)  {
		bo.ProcessTradeSignals( bar );
		CurEquity = bo.Equity;
		
		if (F_Month[bar] != F_Month[bar-1])
			CMonth_End[bar] = CurEquity[bar-1];
		else 
			CMonth_End[bar] = CMonth_End[bar-1];
		
		if (CMonth_End[bar] != 0)
			CMonth_Prf[bar] = 100 * (CurEquity[bar] - CMonth_End[bar])/CMonth_End[bar];
		else
			CMonth_Prf[bar] = 0;
			
		_TRACEF("Bar: %g, Date: %f, Month: %g, CurEquity: %g, EquityLastM: %g, %%Month: %g, ", bar, F_DateNum[bar], F_Month[bar], CurEquity[bar], CMonth_End[bar], CMonth_Prf[bar] );
		
		for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )  {
			if (CMonth_Prf[bar] <= -5){
				bo.ScaleTrade( bar, pos.Symbol, True, pos.GetPrice( bar, "O" ), pos.GetPositionValue() );
				MonthlyStop[bar] = False;
			}
		}
	}
	bo.PostProcess();
}

Any help, even just orientation is very welcome
Thanks from now to those who will answer me

If it doesn't have to be month on month, have a look at Howard Bandy's equity curve feedback code.

I have tried it with a few systems and it doesn't improve stats at all. I think Howard is of the same opinion.

When you try to trade the equity curve, you're applying a MA to capture profits on a squiggly line. But a MA applied to the price never works, so why would it work when you apply it to an equity curve?

Using bo.Equity, if you stop trading the equity will not update - you need to reduce position size and at the beginning of the next month calculate the conditions ( 5% fall ) rescaling the equity to full sized positions.

A simpler way is to

  • run the backtest ,
  • rename "~~~Equity"
  • re-run the backtest and apply your filter to the signals accessing the renamed equity form the previous backtest
2 Likes