The realities of modern markets have had a profound effect on how we can trade. Global reach, electronic trade matching, vastly expanded trading hours and even changes in margining and data dissemination can affect the performance of trading system logic.
One simple set of logic at the heart of this storm is the opening range breakout. Opening range breakouts have been an old friend for many system traders, but now only stock index traders, where an active pit market remains, can rely on it. However, there are workarounds, and these solutions point the way for future study of modern markets.
There are several practical ways to approach the opening range breakout. Some are expedient, while others are more complicated.
The first fix is temporary, but relatively simple: Create simulated day-only session data from the 24-hour data. Depending on your software, when you import the data, you simply change the data universe, the parameters for the market, start time, end time, minimum move point value, etc. You can use intraday 24-hour data and set the start end session to the old pit times and create simulated day session data. We can use this data and test various opening range strategies.
Another solution is to develop a new reference point, such as the old open (day session open). The most obvious candidate for this is the closing price. The close does not test as well as the open, but in many cases it works fine. It also makes sense as a reference point to test the next open during the period when the pit still was being used. We also can see how it works with the electronic open, which happens only a few hours after the close.
Let’s test a range breakout with a trend filter system using several different reference points. The code is online at futuresmag.com/ruggierocodes.
This code provides a simple test rig for various reference points. We commented out a simple filter so we can easily switch it on or off. We start our testing without the filter and, because we’re looking for market bias and not developing a final system, without any deduction for slippage and commission. We test on a basket of markets using four reference points:
- Original open (uses NextOpen function)
- The close
- (High + low + close) / 3
- This code block:
If RePointNumber=2 Then
If High-Low<>0 Then
If HLRatio>.7 Then
If HLRatio<.3 Then
If HLRatio>.7 and HLRatio>.3 then
The idea with No. 4 is to change our point based on where we close. If we finish closer to the high, we assume we made the low first and accept that point. If we close near the low, the high happens first, so we need to add to the previous close. When we close near the center of the bar, we use the simple close.
We test this on a basket of markets using merged Pinnacle futures contracts. Here’s what we learn:
- In general, the close works well but needs a wider entry point. We find that 30% of the range is good when we used the original open, while 75% to 125% of the range works well when using the close as our reference point.
- During our long-term backtest, we saw that the open is still the best measure, but the performance has degraded over the past two years as electronic markets have proliferated.
- Simple measures such as (high + low + close) / 3 work fine but not as good as having a pit open.
- While developing a new reference point breakout methodology, we need to include the older period with the open because it allows us to make sure our methodology is as robust as it worked during this older period. It also can help us research the old open and see if we can create a statistical proxy.
- While the old pit opens were universal, these proxies are not. For example, in many real commodity markets, the close works well as a reference, but for 30-year Treasury bonds, the (high + low + close) / 3 works better.
Better walk forward
Walk-forward testing, covered in-depth in "Navigating the new financial landscape" (December 2010), is a critical component of a viable trading program. A modern approach automatically can find the most robust parameters and use smart algorithms to switch between selected sets.
To start, we create an N dimensional map of the optimization space and the performance of a given strategy. We use this to find the most robust set of parameters. We map this space and identify areas that show robustness. These criteria are then part of our selection methods.
One strategy identifies the most robust area and selects a set of parameters in the middle of it. Another problem is when two sets of parameters are close in performance and there are times when one is long and the other short. In general terms, this issue and the resulting erratic performance often can be dealt with using fuzzy logic.
Another strategy combines two different systems in a walk-forward way. One example uses intermarket bond trading systems. One of these systems uses a positively correlated market to trade T-bonds, such as the Utility Sector Index (UTY), while another uses a negatively correlated market, such as silver. We then use our algorithm to find the best parameters as we walk forward for both systems:
- If either is long, we buy
- If both are short, we sell.
This is done because of the upward bias for bonds. In other words:
- If both go short, we exit a long position
- If one goes long, we exit a short position.
The code will help better illustrate the concept and can be found at futuresmag.com/ruggierocodes. On the first bar, we create two system shells, as well as the range and steps for each parameter. One function, PercentNear, uses fuzzy logic. In effect, it instructs the system not to replace the current set of parameters from a given neighborhood unless the new one scores better.
The systems are a simple intermarket divergence of price vs. a moving average. System one uses a positively correlated intermarket, and system two uses a negatively correlated one. We record the position of each system and use that to trade the real system.
If (Mode1 = "Long") or(Mode2 = "Long") Then
Buy("", 1, 0, Market, Day)
If (Mode1 = "Short" ) and (Mode2 = "Short") Then
Sell("", 1, 0, Market, Day)
ExitShort("", "", 1, 0, Market, Day)
ExitLong("", "", 1, 0, Market, Day)
If either is long, then we buy. If both are short, then we sell. For this current logic, Exitlong is called and not Exitshort. However, Exitshort also is there to modify the script in case our changes cause this to be false. One example would be to make sure the best system is profitable in its training set. It’s possible that a slightly different set of rules would cause the exits. For example, we could check the performance of the best subsystem and only allow the buy or sell if it’s above a given measure. This technology allows us to study multiple sample windows and use them to modify our systems.