Rotation with different code to enter vs code to hold

I'm trying to write code that uses a stronger condition for a position to be entered than held. If the close is above both moving averages, the security should be considered (using momentum) for rotational trading. But once the strategy already owns the position, I want a weaker condition to continue owning it -- the close needs to only be above one of the moving averages. I've read a number of posts on rotational systems and can't find an example of how to do this.

Any assistance would be greatly appreciated.

//MA rotation test



//Rotational trading inputs
NumPos = 6; 	//Number of allowed positions
SetPositionSize(100/NumPos,spsPercentOfEquity);
SetOption( "MaxOpenPositions", NumPos );
EnableRotationalTrading();
SetOption("WorstRankHeld",10);

// trade on next day open
SetTradeDelays( 1, 1, 1, 1 );
BuyPrice = Open;

//Calculate moving averages (weekly data assumed)
MA1 = MA(C,40);
MA2 = MA(C,30);

//Calculated average momentum across several periods
MOMO = ( ROC(C,6) + ROC(C,13) + ROC(C,26) + ROC(C,52) )/4;

//System should enter position if both close is above MA1 and MA2
PositionScore = IIf(C>MA1 AND C>MA2,MOMO,0);

Hi PropKid

Unfortunately I can't test now your code, but an idea to match this condition could be to use the ScoreNoRotate command:

//System should enter position if both close is above MA1 and MA2
PositionScore = IIf(C>MA1 AND C>MA2,MOMO, IIf(C>MA1 OR C>MA2, scoreNoRotate, 0));

2DD, thanks very much for your input.

My understanding is that scoreNoRotate will impact all symbols. If so, no other rotations or trades would take place for that bar if a single symbol initiated scoreNoRotate. I read through the Houston presentation by Tomasz from a number of years ago on the Custom Backtester (CBT) and I think that might be needed to accomplish what I'm trying to do but I haven't been able to find an example code yet that seems relevant. My understanding of the CBT is that it can interrupt the rotation function before a trade is placed.

Hopefully someone with CBT experience can offer some guidance.

When using EnableRotationalTrading, how can you reference the current symbol being evaluated to determine if the system is already long that security? Been doing lots of Googling this afternoon and can't find info on this. May be the key to be issue.

Thanks.

The answer is that you can't tell, and rotational trading has nothing to do with it. AmiBroker runs the backtest in two phases: phase one generates signals and other associated information for each symbol in your testing universe, and phase two processes those signals (or rankings, in the case of a rotational system) to determine when to enter and exit trades. So during phase one, you can't know what is going to happen in phase two.

As to your original question, possibly you could utilize Worst Rank Held to stay in a position even after the initial conditions are no longer true. For example, if the Close is greater than both MAs, you could use a position score of 2000 + MOMO, if the close is greater than just one MA use a score of 1000 + MOMO, and if the close is less than both MAs use a position score of 0 which should close the position if it's open. If Worst Rank Held is equal to the size of your universe, I think this might do what you want.

Another possibility is to write a rotational-style strategy without using AmiBroker's built-in Rotational Mode. Your Buy signal would require the Close to be above both MAs and your Sell signal would require the close to be below both MAs. You could continue to use MOMO for position score, although you should be using something like 1000 + MOMO because AmiBroker uses the absolute value of the position score, which means you could inadvertently prioritize a stock with very negative momentum.

Your most flexible solution will be to learn how the CBT works and implement something there. However, depending on your background, creating your own CBT might be quite daunting so this approach should only be pursued if you can't achieve your goals using the standard backtest.

3 Likes

Rotational trading uses only one rank and trades that are once entered are kept open unless they drop below "worstrankheld" setting.
For what you want to achieve you would need to have separate ranks for entering and separate for holding, but that is not what rotational trading mode is designed for.

So instead of rotational trading you should just use regular mode with position score as explained
https://www.amibroker.com/guide/h_portfolio.html

I don't really see any obstacle to use super simple code like this (regular mode, not rotational):

Buy = C > MA1 AND C > MA2; // enter when Close is above both MAs
Sell = C < MA1 AND C < MA2; // exit when Close dropped below both MAs

PositionScore = Max( MOMO, 0 ); // your score (momentum) - but only positive

Some seem to assume that PositionScore is for rotational mode only. That is false. PositionScore works in ANY backtest mode.

4 Likes

Tomasz, thanks so much for your help.

One quick follow-up. I added your code below with one final line.

//MA rotation test



//Rotational trading inputs
NumPos = 6; 	//Number of allowed positions
SetPositionSize(100/NumPos,spsPercentOfEquity);
SetOption( "MaxOpenPositions", NumPos );
EnableRotationalTrading();
SetOption("WorstRankHeld",10);

// trade on next day open
SetTradeDelays( 1, 1, 1, 1 );
BuyPrice = Open;

//Calculate moving averages (weekly data assumed)
MA1 = MA(C,40);
MA2 = MA(C,30);

//Calculated average momentum across several periods
MOMO = ( ROC(C,6) + ROC(C,13) + ROC(C,26) + ROC(C,52) )/4;

Buy = C > MA1 AND C > MA2; // enter when Close is above both MAs
Sell = C < MA1 AND C < MA2; // exit when Close dropped below both MAs

PositionScore = Max( MOMO, 0 ); // your score (momentum) - buy only positive
PositionScore = IIf(PositionScore>10,0,PositionScore);  //Exit any position that isn't in top 10 or rankings

One further question: since this would not be using rotational trading, will the last line I added be sufficient to exit stocks that drop out of the top 10 in terms of momentum ("MOMO" variable above) rankings? Acting like the WorstRankHeld option for rotational trading? My current inputs are to buy a max of 6 positions so should be buying the top 6 based on momentum and my hope is to use the last line above to exit a stock if its rank drops out of the top 10.

Thanks again to everyone for their input.

In Regular Backtest mode "WorstRankHeld" is not used for exits. The exit rule is defined in your Sell variable assignment. It would sell any symbols (if there are open positions on them) if close drops below both averages (because that is what Sell variable assignment says).