Rotational backtest with conditional exit

Hello, I'm finding some difficulties when coding a rotational portfolio. I've searched into the forum for some insight but I didn't find any useful solution (other topics like this: here and others). I hope you could help me.

The system is pretty simple: rotate 2 assets (that are part of a Norgate's watchlist). Position score based on the ROC values an a filter consisting on a SMA. Every rotation have to be done only on a particular day of week, but the system should cash out any asset also at any other day if the close price goes below the SMA.

So, to fix the idea, the rules have to be:

  1. buy next day on open if today is the right day for rotations AND if close is above SMA AND if ROC is the greatest or the second greatest.
  2. sell at the opening of the next day if close goes below SMA (only that particular stock, NOT all the stocks)
  3. doesn't rotate if close price is higher than SMA

My issue is that the exits don't respond correctly. The exits occur only at the same day of week setted for the entry. It ignores the condition C < SMA that could occur during the week

this is my code attempt:

// Rt_custEntryDay_condCashOut.afl

//	PARAMETERS
Positions = 2;
RotationDay = RtD = 1; //0=Sun... 6=Sat

//	BACKTESTER SETUP
SetBacktestMode(backtestRotational); 
SetOption("MaxOpenPositions",Positions); 
SetOption("WorstRankHeld",Positions); 
SetOption("InitialEquity", 100000);
SetPositionSize(100/Positions, spsPercentOfEquity);

//	INDICATORS AND CONDITIONS
SelInd = selectionIndicator = ROC(C,	5) + 1000;	
trendFilter = TF = MA(C, 5);
DOW = DayOfWeek();

//	ROTATION SELECTIONS
PositionScore = IIf(DOW == RtD , IIf( C > TF, SelInd, 0), IIf(C > TF, scoreNoRotate, 0));

To simulate the next day at open operations I've set the following options:
Schermata 2022-06-20 alle 18.43.48

This is an example of the error:
tradelist

chart

As per the documentation here: AFL Function Reference - ENABLEROTATIONALTRADING there is no way to exit individual symbols the way you've described when running in Rotational Mode.

Exits are generated automatically when security's rank drops below "worst rank held" . There is no real control over when exits happen except of setting low score to force exits. You can also set the score on any (at least one) security to value of scoreNoRotate to prevent rotation (so already open positions are kept). But this is global and does not give you individual control.

To achieve your goal, you have a couple of options:

  1. Rewrite your strategy as a non-rotational system using Buy and Sell rules.
  2. Allow AmiBroker to evaluate entries and exits every day (i.e. never use scoreNoRotate), but when the Close is above the MA use the score from the last rotation day. Code something like this should work:
    PositionScore = IIf(C < TF, 0, ValueWhen(DOW == RtD , SelInd));
  3. Use a CBT to control entries and exits yourself.

Note that Option 2 may not be exactly what you want, because it will allow new symbols to rotate in on non-rotation days on which another symbol exits because of the MA rule.

3 Likes

Thank you mradtke, understood. As you correctly pointed out the Option 2 doesn't work for me due to the new symbols that rotate in. So I'm going rewrite the system using a regular backtesting as you suggested in Option 1.

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.