A couple of weeks ago I sent my subscribers an email to a free eBook called “Understanding Gaps” by Scott Andrews. I’m going to assume that you know what a gap trade is. If not, please take a look at this article.
I’ve never had much success with trading gaps but the topic interests me. After reviewing the eBook I thought it would be a good idea to begin building a strategy tool to help analyze gaps. The tool will be written in EasyLanguage and I envision it being loaded into a chart where it will provide various statistical based results on gaps. Information such as…
These are just a few ideas off the top of my head. It’s a tall order to build such a testing tool so, we’ll start out very simple for this first article. In future articles we’ll build upon the original concept. Hopeful the final strategy tool will be helpful to many readers. Let’s get started.
The first metric analyzed in Scott’s eBook is the probability of a successful gap trade taking place based upon the size of a gap. Since Scott picked this as the first metric I’m going to start with gap size as well.
In the end we want to know how often a gap closes based upon its size. Do larger gaps fill less often than smaller gaps? To figure this out we’ll need the following information:
Before we can do anything, we first need to correctly compute the gap size.
The most obvious way to measure the size of a gap is to use the number of points or ticks from today’s open from yesterday’s close. That is:
Gap Size = Today’s Opening Price – Yesterday’s Closing Price
This will give us what we want but gap sizes will likely change based upon the instrument you’re trading. For example, let’s say we determine that a 10-point gap in the S&P eMini futures closes most of the time. Then we must ask, what happens when we move to a stock or other future contract? A 10-point gap in one instrument may mean something completely different in another instrument. This would not be a big deal if I was simply creating a testing tool for the eMini. However, I want this tool to work on a variety of instruments.
Furthermore, consider how gap sizes may change when you take into account changing market volatility. Over the years volatility in any given market will change. A 25-point gap today on the eMini may not be the same as a 25-point gap in five years. Put another way, gap sizes will likely expand during a more volatile periods and shrink during more quiet times. Using static values to categorize gap size may not be the best idea.
Scott proposed a way to normalize gap sizes based upon the average true range of the market. He does this by using the average true range over the past five days. Scott simply measures the gap size in points (or ticks) and divides this value by the 5-day average true range. Below is the formula.
Gap Size = ( Today’s Opening Price – Yesterday’s Closing Price ) / 5-Day Average True Range
Now we know how to compute a meaningful gap size let’s move on.
On the first bar of a new day the gap size will be computed and categorized into one of six different groups. It will also be important for us to track the total number of all gaps. This is done by simply incrementing a counter each time we have a valid gap. What is valid gap? Well, at this time that would be a gap size that is at least 4 ticks (a minimum price move is one tick). If a gap is smaller than this size, it will be ignored.
Following Scott’s lead, I’m also going to create six buckets or groups to describe the size of gaps. Each group represents a percentage of their 5-day ATR.
Once we know which group a particular gap belongs to I also increase a counter for that group. This way, we’ll have a tally for each of the different types of gaps. Here is the code for determining the gap size, categorizing the different gap groups and increasing the appropriate group counter.
GapSize = absvalue( PrevClosed - TodaysOpen );
Percent = GapSize / FiveDayATR;
if ( GapSize > minGapSize ) Then
GapCount = GapCount + 1;
If ( Percent < .20 ) then
CurrentGapType = 1;
Group1 = Group1 + 1;
Else if ( Percent < .40 ) Then
CurrentGapType = 2;
Group2 = Group2 + 1;
Else If ( Percent < .60 ) Then
CurrentGapType = 3;
Group3 = Group3 + 1;
Else If ( Percent < .80 ) Then
CurrentGapType = 4;
Group4 = Group4 + 1;
Else If ( Percent < 1.0 ) Then
CurrentGapType = 5;
Group5 = Group5 + 1;
CurrentGapType = 6;
Group6 = Group6 + 1;
What is success? When a gap is closed. I’m going to look for this by using the MP function. The code below detects when a trade was closed on the previous bar. If this happens we increment a “success” counter for the particular gap size we were trading.
If ( MP = 0 ) and ( MP <> 0 ) Then
If ( CurrentGapType = 1 ) then Group1Closed = Group1Closed + 1
Else if ( CurrentGapType = 2 ) Then Group2Closed = Group2Closed + 1
Else if ( CurrentGapType = 3 ) Then Group3Closed = Group3Closed + 1
Else If ( CurrentGapType = 4 ) Then Group4Closed = Group4Closed + 1
Else If ( CurrentGapType = 5 ) Then Group5Closed = Group5Closed + 1
Else If ( CurrentGapType = 6 ) Then Group6Closed = Group6Closed + 1;
Now we’ll have everything we need to compute the percentage of gap fills that occur based upon the size of the gap.
When we have run through the entire price history we’ll want to print our results. The most direct way to do this in TradeStation is to use the “Print” command to send text to the Print Log window. Since we know the number of total successful gap fills that took place and the total number of gaps that occurred based upon the gap group, it’s a simple step to compute the percentage of gaps which filled by dividing the group total by the total gaps counted. Below is the code which handles this.
If ( LastBarOnChart ) Then
Print( "Number of Gaps...: ", round(GapCount,0) );
Print( "Group 1..........: ", round(Group1,0), " (", Group1Closed / GapCount, ")" );
Print( "Group 2..........: ", round(Group2,0), " (", Group2Closed / GapCount, ")" );
Print( "Group 3..........: ", round(Group3,0), " (", Group3Closed / GapCount, ")" );
Print( "Group 4..........: ", round(Group4,0), " (", Group4Closed / GapCount, ")" );
Print( "Group 5..........: ", round(Group5,0), " (", Group5Closed / GapCount, ")" );
Print( "Group 6..........: ", round(Group6,0), " (", Group6Closed / GapCount, ")" );
I’m now going to execute this over the eMini (ES) from 2006-2015. To do this, all I need to do is load the strategy tool into the chart. Below is an image of the strategy tool running on a 5-minute chart.
The results are then printed within the Print Log window once the analysis is complete.
What we see in the Print Log is 2381 gaps were counted. Each Gap Group lists the number of gaps along with the percentage of gap fills in parenthesis. Thus, Group 1 sees 35% of the gaps completely fill within some time during the day while Group 6 only sees 2% of the gaps fill.
When you first compare these results to what Scott has in his eBook you’ll likely see a big difference. This confused me at first until I realized that Scott defined a “successful trade” as one that made money. In the strategy code I built, I defined a “successful trade” as closing the gap. I did this because it was the most straightforward event to code at this time.
Which method is better? I’m leaning towards a more nuanced definition. I do like the idea of a successful trade not necessarily meaning a gap close but instead, just being profitable. I can imagine one could build systems that don’t rely on a gap closing every time. Many points could be harvested from a market without the need for a gap to close. So, I think my first step in modifying this code will be to incorporate some other methods of measuring success.
This is the first step in building our gap analyzer and it’s very basic. However, we must start somewhere. As pointed out in the above paragraph, the definition of success will likely be modified in the next article. Scott also recorded profit factor for each of the different gap groups. Thinking about it at this very minute I kind of like the idea of recording potential profit vs drawdown. That is each trade will have a theoretical maximum profit (a gap close) and a theoretical maximum drawdown (how much heat you must take before reaching a gap close).
Future articles will expand upon this idea adding more analysis and in the end, we’ll hopefully have something useful when exploring possible gap trading opportunities.