Rotational System Help

Hi Amibroker Code Helpers!
In a sentence, my issue is that in a Rotational System, a Position with a higher score is not replacing position with a lower score.
Im trying to start super simple so I have this:

BuyPrice = SellPrice = ShortPrice = CoverPrice = Close;
SetTradeDelays( 1, 1, 1, 1);

Totalpositions = 10;
SetOption("WorstRankHeld", 1);
SetOption("MaxOpenPositions", Totalpositions );
PositionSize = -100 / Totalpositions ;

LastDayOfMonth = IIf( (Month() == Ref( Month(), 1) AND (Month() != Ref( Month(), 2)) ), 1, 0);
TradeDay = LastDayOfMonth;

Score = ROC(Close, 180);
PositionScore = IIf(Score < 0, 0, Score ); // Long only
PositionScore = IIf(TradeDay , PositionScore, scoreNoRotate);

This seems to work, as in it seems to rotate some positions every month, however on closer inspection, there was an open trade that as of 31/10/18 it had a NEGATIVE score (the ROC was -8.22). If i run the backtester now, its still saying that it still has that postion open, however if I run the exploration as of the 31/10/18 (last day of month when i thought it should have rotated) there are plenty of positions with a higher ROC/Score.

Can anyone see from the code why it didnt rotate into a better or higher ranked position?
Do you need any more info? Thanks soo much in advance!

@DaleCam I was unable to reproduce your problem of getting entries with negative scores but it may be due to other problems with your code. You wrote this is to be a "Rotational" system and yet I don't see how it will work without either

SetBacktestMode( backtestRotational );
// or use the older syntax

Also your variable for identifying the last trading day of the month is "wrong" (sort of). If you debug your code you will find that is finding the second last trading day of the month.

LastDayOfMonth = IIf( (Month() == Ref( Month(), 1) AND (Month() != Ref( Month(), 2)) ), 1, 0);

But you have compensated for that by using a trade delay of 1, so you actually do trade on the last bar of the month as you intended.

SetTradeDelays( 1, 1, 1, 1);

Incidentally that too can be changed (though its probably not necessary) but as written in the user guide in bold,
** The rotational trading mode uses "buy price" and "buy delay" from the Settings | Trade page as trade price and delay for both entries and exits (long and short)**

Which implies to me that this will work as well,

SetTradeDelays( 1, 0, 0, 0);

And lastly I don't understand your use of

SetOption("WorstRankHeld", 1);

Exits are generated automatically when security's rank drops below "worst rank held", and you have that set to 1. So you want to exit any security not holding the rank of number 1? But you want to hold 10 positions, so don't you at least want to hold the top 10 ranked securities?

Perhaps after incorporating some of those changes you could try again. Other options for your research would be to experiment with your calculations for "Score" and "PositionScore".

Best of luck!


Hi @portfoliobuilder, thank you so much for your detailed answer. I am sorry - I had missed including the line in my sample in the forum:

SetBacktestMode( backtestRotational );

It was the first line of my code and i missed it in the copy. Thanks for that observation!
I also understand the combo of looking at the second last day of the month and then delaying the entry by one. Im cant remember why it was written like that but i got it from some where with the explanation, and it worked so i kept it.
Finally with the WorstRankHeld = 1, I assumed that a score of anything under 1 would then be replaced by the positions with higher rankings. Thay way I could assign stocks zero in my criteria and it will never enter them.
An example of this is these line which i havent included yet because I want to make sure my base system works as expected before adding to it:

Filter = C > MA(C,200);
Score = ROC(Close, 120);
PositionScore = IIf(Score < 0, 0, Score ); // Long only
PositionScore = IIf(Filter, PositionScore,0); //Stocks that dont meet filter are assigned 0

Also, regarding your comment ALWAYS holding the top 10, I wanted to make this a bit of a hybrid roatational system, so that if there were NO stocks at the end of the month with a positive ROC, they would all be assiged a position score of 0, and therefore be exited at the end of the month, and no new ones added. So thats the explanation of why my code is the way it is. Well thats what im hoping to acheive! Now im just at the stage of trying to figure out why it isnt rotating in to the stocks with a higher position score!

Ok I seemed to have found the problem, the same issue and subsequent solution is in this thread:

The issue is when this is ticked in the settings:
Having it UNTICKED solves the problem.
Although I cant see how that should effect the backtest the way that it does!
Does anyone know how to untick that via code so that i dont forget to remove it on another occasion?
Thank you!