I received several questions based upon a recent article by Curtis White called, A Better Regime Filter To Boost Returns. Readers were looking for a complete strategy to download and for more explanation on how the classifier works. I think Curtis did a great job in his explanation so this article is just a rehash of his work. I took Curtis's example and fleshed it out as a TradeStation strategy which you can download below.
Getting Started With a Basic Trading Model
Lets start out with a simple trading model. In this case, we'll be using what Curtis used in his orginal post, Larry Connors 2-period RSI applied to the S&P futures market. The trading rules are below.
- Price must be above its 200-day moving average.
- Buy next bar at market when RSI(2) crosses below 5.
- Sell next bar when RSI(2) crosses above 50.
Note, these may not be the identical rules Curtis used, but it's close. These simple rules will allow us to easily demonstrate what a regime classifier can do. Also, note there are no stops used in this demo strategy nor is slippage and commissions deducted. The basic trading model produces the following results.
Basic Strategy | |
---|---|
Net Profit | $13,612 |
Profit Factor | 1.44 |
Total Trades | 73 |
%Winners | 74% |
Avg.Trade Net Profit | 186.47 |
Return on Capital | 13.6% |
Max Drawdown | $13,350 |
The important thing to note about this strategy is the buy and sell signals are static. In this case, the buy condition is when the 2-period RSI crosses below five and the sell condition occurs when the 2-period RSI crosses above 50. These threshold values never change. Even if the market changes over the months or years the buy/sell threshold doesn't change. Let's write code to make those values dynamic so our strategy changes based upon the conditions of the market. We'll do that by creating a classifier that will divide the market into different regimes.
Creating A Regime Classifier
The idea of a regime classifier is to change the behavior of your trading model based upon the different conditions of the overall market you're trading. In this case, we are going to change the buy and sell thresholds based upon the bullishness or bearishness of the S&P futures.
Curtis used a longer period RSI calculation to act as a regime filter. Curtis noticed that a 14-period RSI in the overbought zone often indicates the market is in a strong bull mode. When the 14-period RSI is in the oversold region the market is in a much more bearish mode. Based on this we wish to adapt on buy and sell signals accordingly.
Please see the original article for more information on this classifier.
Strong Bull Markets: When the market is strongly bullish based upon our regime classifier, we want to make it easier to enter a long trade which makes sense. During strong up-trends pullbacks tend to be more shallow. Thus we loosen the threshold of our buy condition. We also want to hold our trade longer during these strongly bullish times. Thus, we change our exit condition threshold as well by making it more difficult to reach.
You can see in the code below we are changing our Buy Threshold based upon what our classifier is reporting. The stronger the market, the higher the buy threshold is raised thus making it easier to enter new trades. In short, we are buying into shallower and shallower pullbacks.
BullMarket = Close > Average( Close, 200 );
RsiClassifier = RSI( Close, 14 );
BuyThresholdV = 30;
BuyThresholdV = IFF( RsiClassifier >= -10, 10, BuyThresholdV);
BuyThresholdV = IFF( RsiClassifier >= 30, 20, BuyThresholdV);
BuyThresholdV = IFF( RsiClassifier >= 50, 30, BuyThresholdV);
BuyCondition = RSI( Close, 2 ) < BuyThresholdV;
SellCondition = RSI( Close, 2 ) > SellThresholdV;
Again, our buy threshold rises from 10 to 20 and then to 30 as our 14-period RSI (our classifier) rises. What this means is, as the market becomes more bullish we make it easier to open new long trades.
Weak Bull Markets: When the market is weakly bullish or even bearish, we want to make it more difficult to enter a long trade and make it easier to exit any open trades. This makes sense as well.
BullMarket = Close > Average( Close, 200 );
RsiClassifier = RSI( Close, 14 );
SellThresholdV = 70;
SellThresholdV = IFF( RsiClassifier >= -10, 60, SellThresholdV);
SellThresholdV = IFF( RsiClassifier >= 30, 70, SellThresholdV);
SellThresholdV = IFF( RsiClassifier >= 50, 80, SellThresholdV);
BuyCondition = RSI( Close, 2 ) < BuyThresholdV;
SellCondition = RSI( Close, 2 ) > SellThresholdV;
Results With RSI Classifier
Basic Strategy | Classifier Strategy | |
---|---|---|
Net Profit | $13,612 | $75,900 |
Profit Factor | 1.44 | 1.76 |
Total Trades | 73 | 269 |
%Winners | 74% | 73% |
Avg.Trade Net Profit | 186.47 | $282.16 |
Return on Capital | 13.6% | 75.9% |
Max Drawdown | $13,350 | $17,425 |
In this case, we can see a dramatic difference between our Basic Strategy and the Classifier Strategy. We make over three times as many trades and each trade generates more net profit on average. This seems to be a very positive improvement. On the other hand, our drawdown did not improve. We're taking more trade thus our market exposure has also increased. This is not unexpected since our returns are so much better. More risk, more reward. However, I don't think our risk is unreasonable especially when you consider we don't have any stops.
I did not opimize the classifier settings which one could do rather easily. You could also use a different indicator as the regime classifier. Overall this simple example is a great demonstration on the concept of a multi-state regime classification being used to change buy/sell thresholds. Now it's up to you to test how this concept can be used in your trading.
The code for this strategy is available to download for all EasyLanguage Mastery subscribers. The strategy code has one input which allows you to switch between the Basic Strategy and the Classifier Strategy.
Brilliant explanation, thank you so much, Jeff…
It was obviously well described also by Curtis in his article, but I am “a bit slow thinker” so I needed the extra hint from you to grasp it. Apart from a gifted programmer you are obviously a good teacher 🙂
Glad you found it helpful!
Many thanks for the explanation!
But what does the ‘-10’ mean in ‘RsiClassifier >= -10’? The RSI will never have the minus value, right?
You’re welcome. It’s true the RSI will never reach that value. You could use a zero instead of a -10. I’m not sure why a -10 was chosen in the original article.
Can you please add a .txt file of the code? I am more comfortable with Python, so it will be useful.
The conditions for a strong bull market and weak bull market appear identical. Should the weak bull market test have a “”?
Thanks for the comment. I’m not sure I see what you’re looking at. Can you highlight the code you’re looking at.
hello my name ist Dani,
After I imported the tws by calculating the strategie,
an event is showen: “tried to reference back more bars than allowed by the current MaxBarsBack Setting”. Can anyone help me?
You need to update your max bars back setting on your chart.