Rotational Strategy that Switches Time Frames

I'm hoping to make a rotational strategy that can switch time frames. What I want to do, is when the trend is bullish, I want the rotation to occur monthly, when it is bearish I would like the rotation to occur weekly. Below here is a code, that buys a basket of stocks when the trend is bullish and when the trend is bearish, it will buy a single inverse ETF. I can get the code to switch between strategies, but as I've written it, I can't get it to switch time frames. Any ideas or suggestions would be appreciated:

MaxPositions =5;//Optimize("MaxPositions", 14, 1, 25, 1); 
//SetOption("MaxOpenPositions", MaxPositions); 
PosPercent =100/MaxPositions;

SetTradeDelays( 1, 1, 1, 1 ); //use settings, set to 0 for close or 1 for open next day
//BuyPrice = Open; //has no effect in rotational mode, use settings  

NumberExtra =4;//Optimize("Number",4,0,20,1);
SetOption("WorstRankHeld", MaxPositions + NumberExtra); 
SetBacktestMode( backtestRotational );
IndexTicker = "$SPX";

//Index market filter
SetForeign(IndexTicker);  
TrendEMAPeriod = 200;//Optimize("TrendEMAPeriod1",200,30,300,5); 
Bullish = C > EMA(C,TrendEMAPeriod); 
RestorePriceArrays();

ScoreROCPeriod= 50;//Optimize("ScoreROCPeriod",2,5,200,5);
Score = 1000+ROC(Close,ScoreROCPeriod);

if (Name() == "SDS")// switches all available equity to this ETF when trend is bearish
{
MaxPositions = 1; 
 
//EntryTrig. Enter after a pullback when the price drops below then closes above the lower bollinger band 
EntryBBPeriod = 10;//Optimize("EntryBBPeriod",20,2,30,1); 
EntryBBWidth = 2;//Optimize("EntryBBWidth",2,0.5,5,0.1); 
EntryTrig = Cross(Close, bbandbot( Close, EntryBBPeriod, EntryBBWidth )) == 1; 

//ExitTrig. Exit if price spikes up above the upper Bollinger Band and then drops below the Upper Band 
ExitBBPeriod = 10;//Optimize("ExitBBPeriod",20,10,50,5); 
ExitBBWidth = 2;//Optimize("ExitBBWidth",2,0.2,3,0.2); 
ExitTrig = Cross(bbandtop( C, ExitBBPeriod, ExitBBWidth ),C) == 1;  

EnterBearTrade = EntryTrig;
ExitBearTrade = ExitTrig;
 
InPosition = Flip( EnterBearTrade, ExitBearTrade );

Score = IIF( !Bullish AND InPosition, 2000, 0 ); 
 
PosPercent = 100/MaxPositions;  
}

SetOption("MaxOpenPositions", MaxPositions  );
SetPositionSize( PosPercent , spsPercentOfEquity); 
PositionScore=Score;

Weekly = DayofWeek() == 5 ;	
Monthly = Month() != Ref(Month(), 1);
Rotation = IIf(Bullish,Monthly,Weekly);//Want to have a monthly rotation when the index trend is bullish and a weekly rotation when it is bearish

PositionScore = IIf(Rotation, Score, scoreNoRotate );
1 Like

@Marcel, I haven't had time to go through your code in detail or test it myself, but I'm wondering if you've used an Exploration to check whether your PositionScore is getting set at the appropriate times?

Also, you might want to change this:

Weekly = DayofWeek() == 5 ;	

to this:

Weekly = TimeFrameExpand(1, inWeekly, expandPoint);

So that you don't miss rotations on weeks where Friday is a market holiday.

3 Likes

Thank you so much for your suggestion Matt. I ran an exploration and I could see that I was still getting stock trades when the trend was bearish. I changed the line:

Score = 1000+ROC(Close,ScoreROCPeriod);

to:

Score = IIf(Bullish,1000+ROC(Close,ScoreROCPeriod),0);

Now the only weekly trades that I see are for SDS when the trend is bearish. I also used your example of TimeFrameExpand to switch to monthly rotation and that seems to work. My latest code is as follows:

MaxPositions =5;//Optimize("MaxPositions", 14, 1, 25, 1); 
//SetOption("MaxOpenPositions", MaxPositions); 
PosPercent =100/MaxPositions;

SetTradeDelays( 1, 1, 1, 1 ); //use settings, set to 0 for close or 1 for open next day
//BuyPrice = Open; //has no effect in rotational mode, use settings  

NumberExtra =4;//Optimize("Number",4,0,20,1);
SetOption("WorstRankHeld", MaxPositions + NumberExtra); 
SetBacktestMode( backtestRotational );
IndexTicker = "$SPX";

//Index market filter
SetForeign(IndexTicker);  
TrendEMAPeriod = 200;//Optimize("TrendEMAPeriod1",200,30,300,5); 
Bullish = C > EMA(C,TrendEMAPeriod); 
RestorePriceArrays();

ScoreROCPeriod= 50;//Optimize("ScoreROCPeriod",2,5,200,5);
Score = IIf(Bullish,1000+ROC(Close,ScoreROCPeriod),0);

if (Name() == "SDS")// switches all available equity to this ETF when trend is bearish
{
MaxPositions = 1; 
 
//EntryTrig. Enter after a pullback when the price drops below then closes above the lower bollinger band 
EntryBBPeriod = 10;//Optimize("EntryBBPeriod",20,2,30,1); 
EntryBBWidth = 2;//Optimize("EntryBBWidth",2,0.5,5,0.1); 
EntryTrig = Cross(Close, bbandbot( Close, EntryBBPeriod, EntryBBWidth )) == 1; 

//ExitTrig. Exit if price spikes up above the upper Bollinger Band and then drops below the Upper Band 
ExitBBPeriod = 10;//Optimize("ExitBBPeriod",20,10,50,5); 
ExitBBWidth = 2;//Optimize("ExitBBWidth",2,0.2,3,0.2); 
ExitTrig = Cross(bbandtop( C, ExitBBPeriod, ExitBBWidth ),C) == 1;  

EnterBearTrade = EntryTrig;
ExitBearTrade = ExitTrig;
 
InPosition = Flip( EnterBearTrade, ExitBearTrade );

Score = IIF( !Bullish AND InPosition, 2000, 0 ); 
 
PosPercent = 100/MaxPositions;  
}

SetOption("MaxOpenPositions", MaxPositions  );
SetPositionSize( PosPercent , spsPercentOfEquity); 
PositionScore=Score;

//Weekly = DayofWeek() == 5 ;	
Weekly = TimeFrameExpand(1, inWeekly, expandPoint);
//Monthly = Month() != Ref(Month(), 1);	
Monthly = TimeFrameExpand(1, inMonthly, expandPoint);	

Rotation = IIf(Bullish,Monthly,Weekly);//Want to have a monthly rotation when the index trend is bullish and a weekly rotation when it is bearish

PositionScore = IIf(Rotation, Score, scoreNoRotate );

Filter = Rotation;
AddColumn(PositionScore,"PositionScore",1.0,colorDefault,colorDefault,50); 
AddColumn(BuyPrice,"BuyPrice");
AddColumn(SellPrice,"SellPrice");
AddColumn(Bullish,"Bullish"); 
5 Likes