Monthly rebalance for open positions in rotational strategies

Hi everyone,

I am trying to code a rotational stock trading system which buys 3 stocks based on an ROC ranking. It holds the 3 stocks for the following month and selects the top 3 again at month end.

Following are the rules:

Rules:

  • At the end of each month Buy top 3 stocks with equal position size based on ROC 60 day ranking.
  • Sell at the end of next month and buy top 3 again.
  • If open position exists for any top 3 stock, then rebalance to 33.33% total equity.

After searching this forum and making a google search, I was able to come up with the following:

SetBacktestMode(backtestRotational);

SetOption("InitialEquity", 100000);

totalPositions = 3;

SetOption("WorstRankHeld", totalPositions);

SetOption("MaxOpenPositions", totalPositions);

SetOption("AllowPositionShrinking", True );

SetPositionSize(100 / totalPositions, spsPercentOfEquity);

lastDayOfMonth = Month() != Ref(Month(), 1);

score = ROC(Close, 60);

PositionScore = 1000 + score;

PositionScore = IIf(lastDayOfMonth , PositionScore , scoreNoRotate);

The only issue with this code (for my purpose) is that it does not keep the position size 33.33% for an existing position. I understand that this could be easily accomplished by CBT which I haven't learnt yet. Before I start learning CBT, I want to check if there is a non CBT solution to this.

Any help here would be much appreciated. Thank you.

The simplest solution would be to not use Rotational Mode, and instead just buy and sell at the end of each month. Make sure to set Allow Same Bar Exit to false either in the Settings window or by using SetOption, so that your exits will take place before new entries are processed. With this solution you won't be able to use WorstRankHeld, but since you have it set to totalPositions anyway that shouldn't be a concern.

1 Like

@mradtke Thank you so much for your response.

I am trying the following based on my understanding of what you suggested.

SetOption("InitialEquity", 100000);

totalPositions = 3;

SetOption("MaxOpenPositions", totalPositions);

SetOption("AllowPositionShrinking", True );

SetPositionSize(100 / totalPositions, spsPercentOfEquity);

SetOption("AllowSameBarExit", False );


lastDayOfMonth = Month() != Ref(Month(), 1);

score = ROC(Close, 60);

PositionScore = 1000 + score;

Sell = lastDayOfMonth;
Buy = lastDayOfMonth;

However, this is making entries for first month only and only exits in the second month - screenshots below:

image

image

Please let me know what I might be doing wrong.

Sorry, I steered you in the wrong direction with AllowSameBarExit = False. Try this instead:

SetOption("AllowSameBarExit", true);
SetOption("HoldMinBars", 1 );

See also this page: http://www.amibroker.com/guide/h_portfolio.html

2 Likes

@mradtke This is working perfectly according to the requirement. Thank you so much!

Posting the full code below for other people's benefit:

/*
At the end of each month Buy top 3 stocks with equal position size based on ROC 60 day ranking.
Sell at the end of next month and buy top 3 again.
If open position exists for any top 3 stock, then rebalance to 33.33% total equity.
*/


SetOption("InitialEquity", 100000);

totalPositions = 3;

SetOption("MaxOpenPositions", totalPositions);

SetOption("AllowPositionShrinking", True );

SetPositionSize(100 / totalPositions, spsPercentOfEquity);

SetOption("AllowSameBarExit", True );

SetOption("HoldMinBars", 1);


lastDayOfMonth = Month() != Ref(Month(), 1);


score = ROC(Close, 60);

PositionScore = 1000 + score;

Sell = lastDayOfMonth;
Buy = lastDayOfMonth;
5 Likes