Identifying Divergences

Identifying Divergences

Optuma’s scripting language allows you to create any number of scans and tests on any number of tools and values. But when we were asked if we could create a scan to identify divergences between price and a momentum indicator, such as the RSI, I wasn’t sure how this could be done.

Optuma’s scripting language allows you to create any number of scans and tests on any number of tools and values. But when we were asked if we could create a scan to identify divergences between price and a momentum indicator, such as the RSI, I wasn’t sure how this could be done. After a bit of noodling with charts and working out the logic (ok, and a bit of help from my smart colleagues in Australian HQ) we came up with a way to mathematically determine when a divergence occurs.

What’s the deal with divergences?

Let’s back up a bit: why are we interested in divergences? We’ve looked at them before in terms of an index and market breadth (see Mathew’s article here) and it’s the same situation we are looking for: when the price movement is not confirmed by a momentum indicator - such as the RSI. When this happens could be an indication that a change in trend is imminent. A bullish (or positive) divergence occurs when prices are in a downtrend and making lower lows, but the RSI indicator is making higher lows. Conversely, a bearish/negative divergence is when higher price highs occur with lower RSI highs, indicating momentum may be fading and prices may fall.

Positive and Negative Divergence Positive and Negative Divergence

We could physically scroll through hundreds of chart and try to identify when this happens, but we thought it would be easier to see if we could create a scripting formula to tell us when these events occur.

So how does it work?

By using Pivot Lables and the Pivot() function we can highlight any high or low of a price chart or indicator, with the higher the pivot value the more significant the pivot is. So in the example of a negative divergence we identify the last two highs of the RSI and take the corresponding price value when they occurred. If prices are making new highs but the RSI is making lower highs then negative divergence has been identified.

In this example, the Show Bar lines identify RSI pivots set to 15 bars, ie the high/low must be the most extreme value for 15 bars before and after:

RSI Pivots RSI Pivots

Once we’ve identified when the RSI pivots, we take the corresponding price value to work out if the divergence has occurred. Here’s the complete script for a negative divergence, with a condition that the RSI peak must 4% lower than the previous peak, and the price must be at least 4% higher (this is an arbitrary value - you can adjust this tolerance and the pivot values as required):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Negative RSI divergence
// Get the RSI value
RSI1 = RSI(BARS=14);
// Calculate 15 pivot RSI high
P1 = PIVOT(RSI1, MIN=15, TYPE=High);
// Get value of the RSI peak
V1 = VALUEWHEN(RSI1, P1 <> 0);
// Is RSI high 4% lower than previous?
Sig1 = V1 < V1[1]*0.96;
// get stock high value at RSI peak
V2 = VALUEWHEN(HIGH(), P1 <> 0);
// Is stock high 4% higher than at previous RSI peak?
Sig2 = V2 > V2[1]*1.04;
// Show when RSI has lower high & price higher low
Sig1 and Sig2

Let me explain what each of these lines are doing (remember lines beginning // are comments and are ignored by the formula):

Line 4: variable RSI1 calculates the 14-period RSI for each day
Line 6: variable P1 finds all the 15 day pivot highs for the RSI
Line 8: variable V1 gets the RSI value when each pivot occurs (ie when the pivot value is not equal to 0)
Line 10: compare the RSI peak value with the previous peak, and if it’s more than 4% lower (V1[1]0.96) then variable Sig1 is true. (To change the tolerance to eg 5% it would be 0.95.)
Line 12: variable V2 gets the high price of the stock on each day of the RSI peak
Line 14: compare the price high with the high at the previous RSI peak, and if it’s more than 4% (V2[1]
1.04) higher then variable Sig2 is true. (To change the tolerance to eg 5% it would be 1.05.)
Line 16: a divergence signal is triggered when both the RSI (Sig1) and price (Sig2) conditions are true on the same day

The concept is identical for positive divergences, but with pivot and price lows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Positive RSI divergence
// Get the RSI value
RSI1 = RSI(BARS=14);
// Calculate 15 pivot RSI low
P1 = PIVOT(RSI1, MIN=15, TYPE=Low);
// Get value of the RSI low
V1 = VALUEWHEN(RSI1, P1 <> 0);
// Is RSI high 4% higher than previous?
Sig1 = V1 > V1[1]*1.04;
// Get stock low value at RSI low
V2 = VALUEWHEN(LOW(), P1 <> 0);
// Is stock high 4% lower than at previous RSI low?
Sig2 = V2 < V2[1]*0.96;
// Show when RSI has higher low & price lower high
Sig1 and Sig2

Of course, divergences don’t just work with RSI. You could try it with other momentum indicators, such as On Balance Volume, or Money Flow Index : simply replace the RSI function in Line 4 with OBV(), for example.

Once applied to a Show Bar or scan then the divergences can be identified. Click the buttons below to save a workbook for ASX and US data showing the divergences on the charts:

RSI Pivots RSI Pivots