This thread is still available for reading. If looking for specific information in this thread, here is a⚠This thread has exhausted its substantive discussion of this indicator so it has been locked⚠great hack for searching many-paged threads.

Future Questions & Answers can be posted here: https://usethinkscript.com/threads/hull-turning-points-concavity-questions.7847/

As I was looking at the Hull Moving Average, it occurred to me that taking the local minimums and maximums might not be the most effective use of it's smooth nature. Nor did it seem that a moving average cross over would provide timely signals.

And then I remembered that I used to teach physics and calculus and decided to look at rates of change and that lead me to...

CONCAVITY

which is nothing but the second derivative of the function (if you remember or not) and so this indicator was born.

It is in two parts -- the upper which is the Hull Moving Average with the addition of colored segments representing concavity and turning points: maxima, minima and inflection. The last of these are of the greatest interest. The second part is a plot of the calculation used in finding the turning points (which is roughly the second derivative of the HMA function, where zero crosses are the inflection points.

### UPPER INDICATOR

Upper HMA colors:- Green: Concave Up but HMA decreasing. The 'mood' has changed and the declining trend of the HMA is slowing. Long trades were entered at the turning point
- Light Green: Concave up and HMA increasing. Price is increasing, and since the curve is still concave up, it is accelerating upward.
- Orange: Concavity is now downward, and though price is still increasing, the rate has slowed, perhaps the mood has become less enthusiastic. We EXIT the trade (long) when this phase starts. Very little additional upward price movement is likely.
- Red: Concave down and HMA decreasing. Not good for long trades, but get ready for a turning point to enter long on again.

Upper Label Colors:

these are useful for getting ready to enter a trade, or exit a trade and serve as warnings that a turning point may be reached soon

- Green: Concave up and divergence (the distance from the expected HMA value to the actual HMA value is increasing). That is, we're moving away from a 2nd derivative zero crossover.
- Yellow: Concave up but the divergence is decreasing (heading toward a 2nd derivative zero crossover); it may soon be time to exit the trade.
- Red: Concave down and the absolute value of the divergence is increasing (moving away from crossover)
- Pink: Concave down but approaching a zero crossover from below (remember that that is the entry signal, so pink means 'get ready').

### LOWER INDICATOR

For those who prefer less cluttered uppers, I offer the plot of the divergence from expected HMA values; analogous to the second derivative in that the zero crossovers are of interest, as is the slope of the line. The further from zero, the stronger the curve of the concavity, and the more likely to reach a local minima or maxima in short order.### Miscelaneous

If you find that there are too many buy and sell signals, you can change the length of the HMA (I find 34 a happy medium, though 55 and sometimes 89 can be appropriate). You can also play with the value of the lookback, though that will slow down signals.This works well on Daily timeframes as well as intraday candles.

I set it up with

**High + Low / 2**as the default so that it shouldn't wait for close prices. That may not be appropriate to how you wish to trade.

Comments welcome. Let me know how you use it, how it works for your trades, and whether it made your head hurt trying to remember your calculus.

Happy Trading,

Mashume

UPPER:

https://tos.mx/cgKFdmm

LOWER:

https://tos.mx/p0k7ims

### UPPER CODE V4

Code:

```
#
# Hull Moving Average Concavity and Turning Points
# or
# The Second Derivative of the Hull Moving Average
#
# Author: Seth Urion (Mashume)
# Version: 2020-05-01 V4
#
# Now with support for ToS Mobile
#
# Faster, but not necessarily mathematically as good as the first
#
# This code is licensed (as applicable) under the GPL v3
#
# ----------------------
declare upper;
input price = HL2;
input HMA_Length = 55;
input lookback = 2;
input stddev_len = 21;
plot HMA = HullMovingAvg(price = price, length = HMA_Length);
def delta = HMA[1] - HMA[lookback + 1];
def delta_per_bar = delta / lookback;
def next_bar = HMA[1] + delta_per_bar;
def concavity = if HMA > next_bar then 1 else -1;
plot turning_point = if concavity[1] != concavity then HMA else double.nan;
HMA.AssignValueColor(color = if concavity[1] == -1 then
if HMA > HMA[1] then color.dark_orange else color.red else
if HMA < HMA[1] then color.dark_green else color.green);
HMA.SetLineWeight(3);
turning_point.SetLineWeight(4);
turning_point.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
turning_point.SetDefaultColor(color.white);
plot MA_Max = if HMA[-1] < HMA and HMA > HMA[1] then HMA else Double.NaN;
MA_Max.SetDefaultColor(Color.WHITE);
MA_Max.SetPaintingStrategy(PaintingStrategy.SQUARES);
MA_Max.SetLineWeight(3);
plot MA_Min = if HMA[-1] > HMA and HMA < HMA[1] then HMA else Double.Nan;
MA_Min.SetDefaultColor(Color.WHITE);
MA_Min.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
MA_Min.SetLineWeight(3);
plot sell = if turning_point and concavity == -1 then high else double.nan;
sell.SetDefaultColor(Color.DARK_ORANGE);
sell.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
sell.SetLineWeight(3);
plot buy = if turning_point and concavity == 1 then low else double.nan;
buy.SetDefaultColor(Color.CYAN);
buy.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
buy.SetLineWeight(3);
def divergence = HMA - next_bar;
addLabel(yes, concat("DIVERGENCE: " , divergence * 10000), color = if concavity < 0 then if divergence[1] > divergence then Color.dark_RED else color.PINK else if divergence[1] < divergence then color.dark_green else color.dark_orange);
def divergence_stddev = StandardDeviation(price = divergence, length = stddev_len);
addLabel(yes, concat("STDDEV: " , divergence_stddev * 10000), color = if absValue(divergence) > absValue(divergence_stddev) then color.blue else color.dark_gray);
###################
#
# ALERTS
#
###################
Alert(condition = buy, text = "Buy", "alert type" = Alert.BAR, sound = Sound.Bell);
Alert(condition = sell, text = "Sell", "alert type" = Alert.BAR, sound = Sound.Chimes);
Alert(condition = MA_Max, text = "MA Maximum", "alert type" = Alert.BAR, sound = Sound.Ding);
Alert(condition = MA_Min, text = "MA Minumum", "alert type" = Alert.BAR, sound = Sound.Ding);
###################
#
# 2020-05-01
#
# MOBILE TOS SUPPORT
#
# Each color of the HMA needs to be a separate plot as ToS Mobile
# lacks the ability to assign colors the way ToS Desktop does.
# I recommend a plain colored HMA behind the line
# Set the line color of the HMA above to gray or some neutral
#
# CCD_D -> ConCave Down and Decreasing
# CCD_I -> ConCave Down and Increasing
# CCU_D -> ConCave Up and Decreasing
# CCU_I -> ConCave Up and Increasing
#
###################
plot CCD_D = if concavity == -1 and HMA < HMA[1] then HMA else double.nan;
CCD_D.SetDefaultColor(Color.RED);
CCD_D.SetLineWeight(3);
plot CCD_I = if concavity == -1 and HMA >= HMA[1] then HMA else double.nan;
CCD_I.SetDefaultColor(Color.DARK_ORANGE);
CCD_I.SetLineWeight(3);
plot CCU_D = if concavity == 1 and HMA <= HMA[1] then HMA else double.nan;
CCU_D.SetDefaultColor(COLOR.DARK_GREEN);
CCU_D.SetLineWeight(3);
plot CCU_I = if concavity == 1 and HMA > HMA[1] then HMA else double.nan;
CCU_I.SetDefaultColor(COLOR.GREEN);
CCU_I.SetLineWeight(3);
#zscore @codydog
input zlength = 13;
input vlevel = 0.00;
def min = lowest(divergence, zlength);
def max = highest(divergence, zlength);
def Zscore = (divergence - Average(divergence, zlength)) / StDev(divergence, zlength);
# addlabel(1,"Zscore Div= " + round(zscore,2), if zscore > vlevel and zscore < 3 then color.blue else if zscore > 3 then color.red else if zscore < -vlevel and zscore > -3 then color.red else if zscore < -3 then color.blue else color.black);
```

### UPPER CODE

Code:

```
#
# Hull Moving Average Concavity and Turning Points
# or
# The Second Derivative of the Hull Moving Average
#
# Author: Seth Urion (Mashume)
# Version: 2020-02-23 V3
# Faster, but not necessarily mathematically as good as the first
#
# This code is licensed (as applicable) under the GPL v3
#
# ----------------------
declare upper;
input price = HL2;
input HMA_Length = 21;
input lookback = 2;
plot HMA = HullMovingAvg(price = price, length = HMA_Length);
# def delta_per_bar =
# (fold n = 0 to lookback with s do s + getValue(HMA, n, lookback - 1)) / lookback;
def delta = HMA[1] - HMA[lookback + 1];
def delta_per_bar = delta / lookback;
def next_bar = HMA[1] + delta_per_bar;
def concavity = if HMA > next_bar then 1 else -1;
plot turning_point = if concavity[1] != concavity then HMA else double.nan;
HMA.AssignValueColor(color = if concavity[1] == -1 then
if HMA > HMA[1] then color.dark_orange else color.red else
if HMA < HMA[1] then color.dark_green else color.green);
HMA.SetLineWeight(3);
turning_point.SetLineWeight(4);
turning_point.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
turning_point.SetDefaultColor(color.white);
plot MA_Max = if HMA[-1] < HMA and HMA > HMA[1] then HMA else Double.NaN;
MA_Max.SetDefaultColor(Color.WHITE);
MA_Max.SetPaintingStrategy(PaintingStrategy.SQUARES);
#####
# Added Alerts 2020-02-23
Alert(condition = buy, text = "Buy", "alert type" = Alert.BAR, sound = Sound.Chimes);
Alert(condition = sell, text = "Sell", "alert type" = Alert.BAR, sound = Sound.Chimes);
```

### LOWER CODE

Code:

```
#
# Hull Moving Average Concavity Divergence
# or
# The Second Derivative of the Hull Moving Average
#
# Author: Seth Urion (Mashume)
# Version: 2020-02-23 V3
#
# This code is licensed (as applicable) under the GPL v3
#
# ----------------------
declare lower;
input price = OPEN;
input HMA_length = 55;
input lookback = 2;
def HMA = HullMovingAvg(length = HMA_length, price = price);
def delta = HMA[1] - HMA[lookback + 1];
def delta_per_bar = delta / lookback;
def next_bar = HMA[1] + delta_per_bar;
def concavity = if HMA > next_bar then 1 else -1;
plot zero = 0;
zero.setdefaultcolor(color.gray);
zero.setpaintingstrategy(PaintingStrategy.DASHES);
plot divergence = HMA - next_bar;
divergence.setDefaultColor(Color.LIME);
divergence.SetLineweight(2);
plot cx_up = if divergence crosses above zero then 0 else double.nan;
cx_up.SetPaintingStrategy(PaintingStrategy.POINTS);
cx_up.SetDefaultColor(Color.LIGHT_GREEN);
cx_up.SetLineWeight(4);
plot cx_down = if divergence crosses below zero then 0 else double.nan;
cx_down.SetPaintingStrategy(PaintingStrategy.POINTS);
cx_down.SetDefaultColor(Color.RED);
cx_down.SetLineWeight(4);
```

### NEW VERSION 4

**Now with Mobile!**

https://tos.mx/NXqbYE9

Last edited by a moderator: