Triangular Momentum Oscillator & Real Time Divergences

Oscillators are widely used in technical analysis and can return a large amount of information to the trader depending on their design. It is common to use oscillators to detect divergences with the price, divergences occur when the tops/bottoms made by the oscillator and price are negatively correlated.

The following oscillator is based on the momentum of a triangular moving average, hence the name “triangular momentum” because of the very smooth property of the triangular moving average, we aimed at a real-time detection of divergences instead of using more common methods such as relying on pivot high/low detection which are suitable for more noisy oscillators.

The oscillator can also be colored based on a gradient derived from the correlation between its output and the price which can be useful to detect when the oscillator is out of phase (significantly lagging or leading the price).

The indicator is available here.

1. Settings

  • src: Input source of the indicator.
  • Show Lines : Show lines connecting the current top/bottom with the previous one made by the oscillator when a divergence is detected. True by default.
  • Color Based On Price/Oscillator Correlation: Allows the color of the oscillator to change based on its correlation with the price, with red colors suggesting a negative correlation.

2. Usage

The divergences detected by the oscillator are regular divergences, where the oscillator leads price variations.

Using higher values of length allows the oscillator to filter out longer-term variations thus being smoother as a result.

By using the color mode based on the price/oscillator correlation we can see where the oscillator leads or lag the price, and since divergences are based on the price and oscillator going in the opposite direction we can have information where price might reverse.

It is also possible to interpret the oscillator without relying on the divergence detection, with a decreasing value of the oscillator indicating a downtrend and an increasing value indicating an uptrend.

3. Code

// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//@version=4
study("Triangular Momentum Oscillator & Real Time Divergences","TMO")
length = input(14)
src = input(close)
show_lines = input(true,"Show Lines")
colcor = input(false,"Color Based On Price/Oscillator Correlation")
//----
var css = array.new_color(na)
if barstate.isfirst
array.push(css,#FF1100), array.push(css,#FF1200), array.push(css,#FF1400), array.push(css,#FF1500), array.push(css,#FF1700), array.push(css,#FF1800), array.push(css,#FF1A00), array.push(css,#FF1B00), array.push(css,#FF1D00), array.push(css,#FF1F00), array.push(css,#FF2000), array.push(css,#FF2200), array.push(css,#FF2300), array.push(css,#FF2500), array.push(css,#FF2600), array.push(css,#FF2800), array.push(css,#FF2900), array.push(css,#FF2B00), array.push(css,#FF2D00), array.push(css,#FF2E00), array.push(css,#FF3000), array.push(css,#FF3100), array.push(css,#FF3300), array.push(css,#FF3400), array.push(css,#FF3600), array.push(css,#FF3700), array.push(css,#FF3900), array.push(css,#FF3B00), array.push(css,#FF3C00), array.push(css,#FF3E00), array.push(css,#FF3F00), array.push(css,#FF4100), array.push(css,#FF4200), array.push(css,#FF4400), array.push(css,#FF4500), array.push(css,#FF4700), array.push(css,#FF4900), array.push(css,#FF4A00), array.push(css,#FF4C00), array.push(css,#FF4D00), array.push(css,#FF4F00), array.push(css,#FF5000), array.push(css,#FF5200), array.push(css,#FF5300), array.push(css,#FF5500), array.push(css,#FF5700), array.push(css,#FF5800), array.push(css,#FF5A00), array.push(css,#FF5B00), array.push(css,#FF5D00), array.push(css,#FF5E00), array.push(css,#FF6000), array.push(css,#FF6200), array.push(css,#FF6300), array.push(css,#FF6500), array.push(css,#FF6600), array.push(css,#FF6800), array.push(css,#FF6900), array.push(css,#FF6B00), array.push(css,#FF6C00), array.push(css,#FF6E00), array.push(css,#FF7000), array.push(css,#FF7100), array.push(css,#FF7300), array.push(css,#FF7400), array.push(css,#FF7600), array.push(css,#FF7700), array.push(css,#FF7900), array.push(css,#FF7A00), array.push(css,#FF7C00), array.push(css,#FF7E00), array.push(css,#FF7F00), array.push(css,#FF8100), array.push(css,#FF8200), array.push(css,#FF8400), array.push(css,#FF8500), array.push(css,#FF8700), array.push(css,#FF8800), array.push(css,#FF8A00), array.push(css,#FF8C00), array.push(css,#FF8D00), array.push(css,#FF8F00), array.push(css,#FF9000), array.push(css,#FF9200), array.push(css,#FF9300), array.push(css,#FF9500), array.push(css,#FF9600), array.push(css,#FF9800), array.push(css,#FF9A00), array.push(css,#FF9B00), array.push(css,#FF9D00), array.push(css,#FF9E00), array.push(css,#FFA000), array.push(css,#FFA100), array.push(css,#FFA300), array.push(css,#FFA400), array.push(css,#FFA600), array.push(css,#FFA800), array.push(css,#FFA900), array.push(css,#FFAB00), array.push(css,#FDAC00), array.push(css,#FBAD02), array.push(css,#F9AE03), array.push(css,#F7AE04), array.push(css,#F5AF06), array.push(css,#F3B007), array.push(css,#F1B108), array.push(css,#EFB20A), array.push(css,#EDB30B), array.push(css,#EBB30C), array.push(css,#E9B40E), array.push(css,#E7B50F), array.push(css,#E4B610), array.push(css,#E2B712), array.push(css,#E0B813), array.push(css,#DEB814), array.push(css,#DCB916), array.push(css,#DABA17), array.push(css,#D8BB18), array.push(css,#D6BC1A), array.push(css,#D4BD1B), array.push(css,#D2BD1C), array.push(css,#D0BE1E), array.push(css,#CEBF1F), array.push(css,#CCC020), array.push(css,#C9C122), array.push(css,#C7C223), array.push(css,#C5C224), array.push(css,#C3C326), array.push(css,#C1C427), array.push(css,#BFC528), array.push(css,#BDC62A), array.push(css,#BBC72B), array.push(css,#B9C72C), array.push(css,#B7C82E), array.push(css,#B5C92F), array.push(css,#B3CA30), array.push(css,#B0CB32), array.push(css,#AECC33), array.push(css,#ACCC34), array.push(css,#AACD36), array.push(css,#A8CE37), array.push(css,#A6CF38), array.push(css,#A4D03A), array.push(css,#A2D13B), array.push(css,#A0D13C), array.push(css,#9ED23E), array.push(css,#9CD33F), array.push(css,#9AD440), array.push(css,#98D542), array.push(css,#95D643), array.push(css,#93D644), array.push(css,#91D746), array.push(css,#8FD847), array.push(css,#8DD948), array.push(css,#8BDA4A), array.push(css,#89DB4B), array.push(css,#87DB4C), array.push(css,#85DC4E), array.push(css,#83DD4F), array.push(css,#81DE50), array.push(css,#7FDF52), array.push(css,#7CE053), array.push(css,#7AE054), array.push(css,#78E156), array.push(css,#76E257), array.push(css,#74E358), array.push(css,#72E45A), array.push(css,#70E55B), array.push(css,#6EE55C), array.push(css,#6CE65E), array.push(css,#6AE75F), array.push(css,#68E860), array.push(css,#66E962), array.push(css,#64EA63), array.push(css,#61EA64), array.push(css,#5FEB66), array.push(css,#5DEC67), array.push(css,#5BED68), array.push(css,#59EE6A), array.push(css,#57EF6B), array.push(css,#55EF6C), array.push(css,#53F06E), array.push(css,#51F16F), array.push(css,#4FF270), array.push(css,#4DF372), array.push(css,#4BF473), array.push(css,#48F474), array.push(css,#46F576), array.push(css,#44F677), array.push(css,#42F778), array.push(css,#40F87A), array.push(css,#3EF97B), array.push(css,#3CF97C), array.push(css,#3AFA7E), array.push(css,#38FB7F), array.push(css,#36FC80), array.push(css,#34FD82), array.push(css,#32FE83), array.push(css,#30FF85),
//----
up = highest(src,length)
dn = lowest(src,length)
osc = mom(sma(sma(src,length),length),length)
phosc = crossunder(change(osc),0)
plosc = crossover(change(osc),0)
bear = osc > 0 and phosc and valuewhen(phosc,osc,0) < valuewhen(phosc,osc,1)
and valuewhen(phosc,up,0) > valuewhen(phosc,up,1) ? 1 : 0
bull = osc < 0 and plosc and valuewhen(plosc,osc,0) > valuewhen(plosc,osc,1)
and valuewhen(plosc,dn,0) < valuewhen(plosc,dn,1) ? 1 : 0
//----
simple_css = osc > osc[1] and osc > 0 ? #00c42b : osc < osc[1] and osc > 0 ? #4ee567 :
osc < osc[1] and osc < 0 ? #ff441f : osc > osc[1] and osc < 0 ? #c03920 : na
cor_css = array.get(css,round((.5*correlation(osc,close,length)+.5)*199))
plot(osc,"Osc",colcor ? cor_css : simple_css,3,plot.style_histogram)
plotshape(iff(bull,osc,na),"Bullish Circle",shape.circle,location.absolute,#00c42b,0,size=size.tiny)
plotshape(iff(bear,osc,na),"Bearish Circle",shape.circle,location.absolute,#ff441f,0,size=size.tiny)
plotshape(iff(bull,osc,na),"Bullish Label",shape.labelup,location.absolute,#00c42b,0,text="Buy",textcolor=color.white,size=size.tiny)
plotshape(iff(bear,osc,na),"Bearish Label",shape.labeldown,location.absolute,#ff441f,0,text="Sell",textcolor=color.white,size=size.tiny)
//----
n = bar_index
bull_x1 = valuewhen(plosc,n,1),bull_y1 = valuewhen(plosc,osc,1)
bear_x1 = valuewhen(phosc,n,1),bear_y1 = valuewhen(phosc,osc,1)
var line bull_line = na,var line bear_line = na
if show_lines
if bull
bull_line := line.new(bull_x1,bull_y1,n,osc,color=#00c42b)
else if bear
bear_line := line.new(bear_x1,bear_y1,n,osc,color=#ff441f)

Lux Algo aims to provide traders with truly useful, unique, & reliable tools that can give them an edge over others in any market.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store