February 10

12 comments

Testing A Euro Currency Futures Scalping Strategy, Part 3

By Jeff Swanson

February 10, 2014

Automated Trading Development, EasyLanguage, Euro Futures, scalping

In the previous article, “Testing A Euro Currency Futures Scalping Strategy, Part 2“, we discovered a time based filter that really improved the performance of the system. By eliminating the unproductive times to trade nearly all aspects of the system were improved with only the smallest cost of annual return. In this article I want to look at another filter which will really help to improve performance. So, let's try to improve this Euro Scalping Strategy.

Early in this series we tested the idea of implementing a bull or bear market regime filter. In the end, this did not help too much and the filter was abandoned. Another method I like to use to divide the market is volatility. Markets naturally cycle between low volatility and high volatility. Maybe our trading system performs better in high volatility markets. Or maybe it performs better in low volatility markets. Or perhaps it performs best away from volatility extremes. To test this idea I’m going to measure volatility based upon the price action on a daily bar chart and use TradeStation’s optimize feature to gauge our system's performance over different market volatility conditions.

The Volatility Filter

To accomplish our volatility test I first need to capture the volatility on the daily chart. Remember, we are trading on a 1-minute chart so how do we do this? Well, in TradeStation there are built-in EasyLanguage functions which can grab the daily price elements such as open, high, low and close from the daily timeframe. However, I’m going to show a technique that requires adding the daily price data into our existing 1-minute chart. I’m doing this because this is a valuable skill – inserting different timeframes into a single chart. Knowing how to do this allows you to build trading systems that can access various timeframes within a single chart. This will allow you to generate signals on a daily chart and trade on a 5-minute chart, for example. 

The following code is executed when the Euro session ends. It simply computes the closing day’s range and then computes the 12-day average of the daily ranges. This average value will be our volatility score which will determine if we take trades or not.

If ( Time = SessionEndTime(1,1) ) Then
Begin
    // Compute the daily range and average
   ocRange = ( HighD(0) – lowD(0) ) * PriceScale;
   ocRangeAvg = Average( ocRange, 12 );
   volFilter = ocRangeAvg < vol and ocRangeAvg > vol-10;
End;

We then set a boolean flag, volFilter, based upon a specific volatility range. That is, if the volatility is between a specific range of values, we set our flag indicating it’s OK (true) to take trades in the current market environment.

Using TradeStation’s optimization feature I’m going to execute the trading system over the historical data 20 times. For each iteration the volatility filter will be altered to produce a specific 10 “point” range where trades will be taken. The first iteration will test the volatility range between 10-20, the next between 20-30, and so on. This will give us an idea if volatility plays a part in the success of the system.

Please note, I’m applying the volatility filter to the baseline system – not the system with the time filter. I want to independently test the volatility filter to see how it alone affects the performance of the system. At this time, I don’t want to stack filters on top of each other. Below are the results of the volatility study. The x-axis contains the volatility range as measured by our calculation explained above. The x-axis contains the net profit in dollars.

This looks a bit sloppy. The point is to notice any region(s) where no profits occur, or regions were profits tend to occur. I clearly see a region near the low end of the values, below 60, where there are very few or no trades taking place. If you spend some time looking you will see the net profit tends to taper off when you get into the high values above 190. The two largest spikes occur at 110 and 170. There seems to be a cluster of more positive net profit bars around the middle, but it’s not overly clear. Overall, I think this suggests that our system may best perform when volatility is not at extreme lows or at extreme highs.

At this point I’m going to add the time filter to see if we can get a better picture of what’s going on. Here is the bar graph with the same optimization.

This is much clearer. You can better see that values between 50 and 240 produce the bulk of the net profits. In particular, values above 240 produce some very large losses. Let’s look at it another way. Below is a bar graph depicting the results in average net profits per trade.

We can see about the same picture. Clearly there is a lot of losses at the very high end of our volatility. Again, the bulk of our profitable trades seems to be between 60 and 240. To test how this will affect the performance of our system let’s adjust our volatility filter to only take trades when volatility is between 60 and 240. The results of this test vs. the baseline system are below.

EC Scalping System Independent Filters

Baseline

Quiet Hours

Vol Filter

Net Profit

$11,207

$9,748

$8,348

Profit Factor

1.38

2.01

1.43

Total Trades

456

233

328

%Winners

71%

70%

70%

Avg. Trade Net Profit

$24.58

$41.83

$25.45

Annual Rate of Return

7.07%

6.04%

5.71%

Max Drawdown (Intraday)

$4,632

$3,018

$2,910

Expectancy

0.11

0.30

0.13

Expectancy Score

4.77

6.56

3.95

We can see this does improve the results vs. the baseline system ever so slightly. I’m looking primarily at the Profit Factor and Average Trade Net Profit. It certainly does not have nearly as much impact as the time-based filter. What would happen if we combine the two?

Combining The Two Filters

Now we can take the time-based filter and combine it with our newly created volatility filter. Doing that generates the following results:

EC Scalping System Filters

Baseline

Quiet Hours

Vol Filter

Quiet Hours & Vol Filter

Net Profit

$11,207

$9,748

$8,348

$9,305

Profit Factor

1.38

2.01

1.43

3.44

Total Trades

456

233

328

164

%Winners

71%

70%

70%

70%

Avg. Trade Net Profit

$24.58

$41.83

$25.45

$56.74

Annual Rate of Return

7.07%

6.04%

5.71%

6.19%

Max Drawdown (Intraday)

$4,632

$3,018

$2,910

$1,975

Expectancy

0.11

0.30

0.13

0.74

Expectancy Score

4.77

6.56

3.95

11.48

The combined system (far right column) does very well vs. the baseline system. Again, I’m looking at the Profit Factor and Average Trade Net Profit. Our average trade net profit has more than doubled and we significantly reduced the total trades taken. This tells me we have removed unproductive or losing trades. We are not making a comfortable amount per trade, unlike the baseline system which was a very small margin of $24.58 per trade. Combining the two filters reduces drawdown and that can clearly be seen in the equity graph below.

For a reminder this is what our baseline system equity curve looked like.

Conclusion

We are clearly moving forward nicely. So far, all our work has produced two changes to the original system.

  1. Only trade during the quiet market hours of 1100 – 2400 Central.
  2. Only trade when the market is absent of volatility extremes.

It’s a lot of work for only a few lines of code. In the next article we are going to explore adding a stop loss value and testing the system on our out-of-sample data.

Jeff Swanson

About the author

Jeff has built and traded automated trading systems for the futures markets since 2008. He is the creator of the online courses System Development Master Class and Alpha Compass. Jeff is also the founder of EasyLanguage Mastery - a website and mission to empower the EasyLanguage trader with the proper knowledge and tools to become a profitable trader.

  • Jeff, this is just a note of encouragement, your work is very much appreciated and I look forward to receiving your emails. Well done and thank you, great work as usual on this system.

  • I wonder what would happen if you broke down “volatility” (a vague concept at best) further, and considered “directional volatility” and “non-directional volatility”?

    Supposing that a market usually moves 10 ticks per day, and then suddenly it is moving 100 ticks per day. We’d say it has become much more volatile. But if the price change consists of a series of 100 tick consecutive up days, then that is a very different environment than if it consists of 100 tick up days that are each followed by a 100 tick down day.

    Interesting to see this strategy develop, and I look forward to the next installment!

  • Hi Jeff – as always, very nice article! Keep up the good work!

    Am a big fan of scalping strategies and I do run couple of them. However, one thing I learned about them is, that you simply must not run them during news releases. Because you trade 11-23 central, you eliminated most of them but not all of them! For example FED rate decisions are released at 1pm central. Simply check the date & time of the top 5 looser on forexfactory.com/calendar. They have data all the way back to 1jan2007. I would bet that at least 4 of them do coincide with some news releases.

    The next step would be to backtest the strategy with a news filter. If the average holding period is 5mins, simply avoid trading 15mins before & after the news to be on the safe side.

    Curious to hear you findings!

    Regards,

    Mike

  • The results definitely looks promising. My only concern would be that if I interpret the results correctly, that the latest version look to be generating about 170 trades over an almost 10 year period. That works out to be about 17 trades a year, which is about 1.5 trades a month. Can this still be called a scalping system then? 🙂

    • Sevensa, the word “scalping” is referring to the profit target which is only a few ticks – not the frequency of trading. This would be a low frequency scalping system. Thanks for writing!

      • It’s ok for low frequency scalping but 170 trades in my humble opinion are not a large enough database to do robust backtesting

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

    Learn To Code & Build Strategies
    Using EasyLanguage. 

    >