I recently watched the video, "Oscillator Trading Indicator!, a trading system for all assets!", on the StatOasis channel. It's a simple trading concept based upon an oscillator indicator. When I see videos like this, I'm very skeptical. Most of what you see on YouTube will not work. Thus, it's time to put this concept to the test!
This article will duplicate the recommended trading method on the S&P futures market. Then I'll expand the trading idea to different markets and modify the strategy. Please watch the video for a solid overview of the indicator and trading strategy.
Let's get going!
The Indicator
The baseline strategy is straightforward. First, you calculate two simple moving averages. The first is based upon the close. The second is based upon the open.
We are looking for a trending market based upon the simple moving average of the close being higher than the simple moving average of the open. Makes sense. A rising market will likely have a higher closing price than the open.
Adding A Trend Filter
The YouTube host then recommends a trend filter to only take trades in the direction of the trend. This was accomplished by using two simple moving averages.
average( close, 100 )[1] > average( close, 100 )[2] and
average( close, 100 )[2] > average( close, 100 )[3];
longTrend2 = average( close, 100 ) > average( close, 100 )[10];
You can see longTrend1 is bullish when the 100-period simple moving average has three consecutive higher values. The longTrend2 is bullish when the 100-period simple moving average is higher than itself 100 bars ago.
The Baseline Strategy
The baseline strategy code is below. You'll see that a profit target and stop-loss value are based upon the true average range. In this case, the 20-period moving average.
StopFactor(5),
ProfitFactor(10),
smaPeriod(9);
longTrend1(False),
longTrend2(False),
StopLoss$(0),
Target$(0),ATR(0),
openSMA(0),
closeSMA(0);
openSMA = average( Open, smaPeriod );
closeSMA = average( Close, smaPeriod );
BullishOscilator = closeSMA > openSMA;
longTrend1 = average( close, 100 ) > average( close, 100 )[1] and average( close, 100 )[1] > average( close, 100 )[2] and average( close, 100 )[2] > average( close, 100 )[3];
longTrend2 = average( close, 100 ) > average( close, 100 )[10];
if BullishOscilator and longTrend1 and longTrend2 then
StopLoss$ = round2fraction( ATR * Bigpointvalue * StopFactor );
Trading Environment
I will test the baseline code on the 60-minute E-mini S&P (@ES) market from 2007. Below are the assumptions used to generate the backtest:
- Starting account size of $50,000.
- Dates tested are from January 1, 2007 through January 29, 2021.
- Trading 1 Contract.
- $30 deducted for slippage and commissions per round trip.

Click on image to enlarge
Baseline Results
In the YouTube video, the results looked decent. That's not too unexpected, as we're building a long-only strategy for the S&P, with a considerable upside bias. In particular, the upside bias has been strong for the past 10 years or so. Within the actual results from QuantOasis, they only test this strategy from 2009. I went back further and got this:

I marked the year 2009 in the graph above to show you when QuantOasis started their backtest. You can see it was right at the low point. Since 2009 the equity graph has been moving up. So, the original historical period may be a little deceiving. But since 2009, this strategy is doing really well.
Average Profit Per Trade: $233 Net Profit vs Drawdown: 2.1 Annual Rate of Return: 7.57% Max Intraday Drawdown: $44,756.
Removing Profit Target
I also don't like that we have a profit target that is equal to the stop loss. That is, we're using 10 times the 20-period ATR. I want to let my profits run. I'm going to modify the code to exit a trade when one of the trend filters is no longer bullish.

Well, that did not help at all.
Buying On Pull-Back
In this test, I'm going to buy when the oscillator is bearish. I'll do this by taking trades when the closing SMA is less than the open SMA.

These simple modifications did not show any improvement. Not to say you can't improve this strategy on the S&P but, you'll have to dig deeper.
What About Other Stock Index Markets?
Let's go back to the original code and test it on Mini DOW (YM) and Mini Nasdaq (NQ) markets. Slippage and commissions are deducted.

@NQ

@YM
We can see the NQ only performs well (very well!) over the most recent years. However, most of the time, you see the equity curve is hovering around the zero line. The YM market looks rather similar to ES. Overall, the stock index markets that I trade look similar. That is, the strategy has worked well for the last few years.
What About Other Markets?
Let's take a quick look at several other futures markets to get a feel for how this baseline strategy may work. Slippage and commission are taken into account.

@US

@LH

@GC

@EC
Conclusion
With this simple test, we can't demonstrate that using this particular oscillator as the foundation of a strategy is not great. Sure, there is much more you could test, such as different timeframes, profit targets, stops, and other filters. But I like to see better performance without adding much to the basic idea. I don't see that in this case. The exception seems to be the stock index markets. Maybe. If you wanted to test this oscillator strategy idea, I would start with the stock index markets. Don't forget to try different intraday timeframes.
If you want to learn to code in EasyLanguage so you can test trading ideas, just like we did in this article, then join me in the Coder Edition of my System Development Master Class.
Good work. I like your thinking style.
Glad you liked it.
Hi Jeff, I tried copy/pasting this Oscillator code and TS10 won’t verify. Unknown identifier “MP”.
Are you going to be adding the verified ELD file into the code library section anytime soon?
Hi Erv. MP is a function for MarketPosition. Simply replace “MP” with “MarketPosition” and you should be fine.
👍