Hull Moving Average Turning Points and Concavity (2nd Derivatives)

G

greentonic

New member
Code:
# Love those painted candles.
# Hull Moving Average Concavity and Turning Points
# or
# The Second Derivative of the Hull Moving Average
#
# Author: Seth Urion (Mahsume)
# Version: 2020-05-01 V4 / Moded With painted candles
#
# Now with support for ToS Mobile
#
# This code is licensed (as applicable) under the GPL v3
# UseThinkScript.com
# https://usethinkscript.com/threads/...avity-2nd-derivatives.1803/page-14#post-23080
# ----------------------

# INSTRUCTIONS:
# SETTINGS TO SET UP ALERT NOTIFICATIONS - JAzcarate -
# BUY / SELL CHART ALERTS WITH EMAIL / TEXT
# STUDY NAME: HULL MOVING AVERAGE TURNING POINTS
# 2 MINUTE CHART SETTING 200 period HMA
# 5 MINUTE CHART SETTING 100 period HMA
# 10 MINUTE CHART SETTING 55 PERIOD HMA

# SELL FROM RESISTANCE - BUY FROM SUPPORT


declare upper;

input price = HL2;
input HMA_Length = 250;
input lookback = 2;

# I read somewhere that it's faster to define nan's and then use the def'd var rather than call double.nan every time.
def nan = double.nan;

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 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 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 Nan;
MA_Min.SetDefaultColor(Color.WHITE);
MA_Min.SetPaintingStrategy(PaintingStrategy.TRIANGLES);
MA_Min.SetLineWeight(3);

# NOTE: I PREFER TO TURN OFF UP ARROWS WHEN IN DOWN TREND. IF IN DOWNTRENDING SWINGARM, THE TURN ON ONLY DOWN SELL ARROWS. YOU CAN DO THIS USING THE INPUT SETTINGS SCREEN.

plot sell = if turning_point and concavity == -1 then high else 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 nan;
buy.SetDefaultColor(Color.CYAN);
buy.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
buy.SetLineWeight(3);

def divergence = HMA - next_bar;

addLabel(yes, concat("DIVERGENCE: " , divergence), color = if concavity < 0 then if divergence[1] > divergence then Color.RED else color.PINK else if divergence[1] < divergence then color.green else color.yellow);

###################
#
# 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);

###################
#
# 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 nan;
CCD_D.SetDefaultColor(Color.RED);
CCD_D.SetLineWeight(3);

plot CCD_I = if concavity == -1 and HMA >= HMA[1] then HMA else nan;
CCD_I.SetDefaultColor(Color.DARK_ORANGE);
CCD_I.SetLineWeight(3);

plot CCU_D = if concavity == 1 and HMA <= HMA[1] then HMA else nan;
CCU_D.SetDefaultColor(COLOR.DARK_GREEN);
CCU_D.SetLineWeight(3);

plot CCU_I = if concavity == 1 and HMA > HMA[1] then HMA else nan;
CCU_I.SetDefaultColor(COLOR.GREEN);
CCU_I.SetLineWeight(3);

AddChartBubble(MA_MAX == MA_MAX , MA_MAX , "SHORT DA FUCK OUT OF THAT SHIT" , Color.YELLOW,no);


AddChartBubble(MA_MIN == MA_MIN , MA_MIN , "BUY Confirmed" , Color.YELLOW, yes);



assignPriceColor(if concavity[1] == -1 then
if HMA > HMA[1] then color.dark_green else color.red else
if HMA < HMA[1] then color.red else color.green);
 
A

astro_phx

New member
@mashume Can you please look at this code and correct it for the alert. I have put the code you have given to me but the alert is not working into it. Am I doing something wrong?

Code:
#
# Hull Moving Average Concavity and Turning Points
#  or
# The Second Derivative of the Hull Moving Average
#
# Author: Seth Urion (Mahsume)
# 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 = close;
input HMA_Length = 55;
input lookback = 5;

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);
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 MA_Max and HMA[-1] then open[-1] else double.nan;
sell.SetDefaultColor(Color.DARK_ORANGE);
sell.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
sell.SetLineWeight(3);

plot buy = if MA_Min and HMA[-1] then open[-1] else double.nan;
buy.SetDefaultColor(Color.CYAN);
buy.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
buy.SetLineWeight(3);

def divergence = HMA - next_bar;

addLabel(no, concat("DIVERGENCE: " , divergence), color = if concavity < 0 then if divergence[1] > divergence then Color.RED else color.PINK else if divergence[1] < divergence then color.green else color.yellow);

###################
#
# 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);

###################


AddOrder(OrderType.BUY_AUTO, MA_Min, tickcolor = Color.WHITE, arrowcolor = Color.WHITE, name = "LONG", tradeSize = 1, price = open[-1]);

AddOrder(OrderType.SELL_AUTO, MA_Max, tickcolor = Color.WHITE, arrowcolor = Color.WHITE, name = "SHORT", tradeSize = 1, price = open[-1]);
 
rad14733

rad14733

Well-known member
VIP
@astro_phx You need to use the same conditional logic for the Alert() as you would for your plot... Also, as long as your parameters are all passed, and in proper order, the parameter names can be omitted... I haven't tested the code so if earlier logic is incorrect then more edits may be required...

Ruby:
Alert(MA_Min and HMA[-1] , "Buy", Alert.BAR, Sound.Bell);

Alert(MA_Max and HMA[-1] , "Sell", Alert.BAR, Sound.Chimes);
 
A

astro_phx

New member
Thank you very much for your reply. @rad14733 But it still doesn't work.
 
Last edited:
rad14733

rad14733

Well-known member
VIP
Thank you very much for your reply. @rad14733 But it still doesn't work.
I'll "try" to look at the code again but I'm also trying to get a new trading system tweaked so I can post it, hopefully, by the end of the week... I seem to keep getting distracted and then have to work on the code while I'm trading, which isn't the best scenario...
 
A

astro_phx

New member
I'll "try" to look at the code again but I'm also trying to get a new trading system tweaked so I can post it, hopefully, by the end of the week... I seem to keep getting distracted and then have to work on the code while I'm trading, which isn't the best scenario...
Please take your time. Thank you very much again.
 
scott69

scott69

Member
Hi all, I just started using this code this morning. I have it on the /NQ on the 5 minute chart, with a setting of 5 (it starts with a setting of 21). Not using it for signals, just confirmation, although with further study, it could be interpreted for signals. My main overview chart is 15 minutes, setup in 5 minute chart (with this study), then trigger in 1 minute chart. I had to comment out the "alerts" in the original code because of error messages, but I didn't read through all the comments to see if that was covered. Probably not related, but I notice that for the last few days, Alerts are not working in TOS, and they said they are aware of the problem, whatever that means. Thanks to the developer and comments from others....
 
scott69

scott69

Member
Just to update my post, I tried the 5 setting on the "hma setting" on a 5 minute chart for confirmation of entry signals, and that turned out to be a little too "tight." I went to a 10 setting, and that seems to work much better for both trend indication (colored MA) and for price crosses of said line. I should add that in trading the /NQ, I am only in for minutes to hours. The short term moves lately can be $1000s of loss in minutes if not careful.
 
T

topmarx

New member
VIP
Hi all

The normal scan = Concavity("hma length" = 55, price = CLOSE)."buy" is true within 2 bars

Is there a way to scan for the confirmed buys, the alerts use this "MA_MIN == MA_MIN , MA_MIN , "BUY Confirmed" - is there a way to scan for this?
 
T

tem2005

Member
VIP
@mashume so version 4 calculates the buy and sell arrows based on last past candle and current candle? which means the arrows (if shown) won't disappear after closing of the current candle?
 
F

FOTM_8888

Member
VIP
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').
Arrows are provided as Buy and Sell and could perhaps be scanned against.

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

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
great job!! thank you some for share this awesome scripts.. please can you share with us the back testing strategy please. thank you once again
 
C

cpyleitz

New member
@mashume, thank your for this script and all the help you've provided. I would like to know if there's anyway to make this work in a tick setting. It seems possible but since the code is written to aggregate period, Tick chart is not supported.
 
D

designatedrhythm

New member
I really like this strategy. Would it be possible to code this into NinjaTrader to autotrade?
 
D

dhiltonnj

New member
wow, yeah, ever had that feeling rate of change is slowing and its time to get out of a long? great job making it visual... Ill be playing around with this in the am... Thanks!!
 
M

mashume

Well-known member
VIP
@mashume so version 4 calculates the buy and sell arrows based on last past candle and current candle? which means the arrows (if shown) won't disappear after closing of the current candle?
If you have it set to calculate on the CLOSE rather than HL2 or HLC3 or OHLC4 then yes. perhaps. ;-)
 
M

mashume

Well-known member
VIP
@mashume, thank your for this script and all the help you've provided. I would like to know if there's anyway to make this work in a tick setting. It seems possible but since the code is written to aggregate period, Tick chart is not supported.
I haven't really looked into that. Perhaps some day when I have an abundance of time on my hands. Which hasn't been recently
 
S

Summies88

New member
So I did some backtesting on this with different Fibonacci lengths, timeframes, and including MACD as another entry/exit timing signal, and here are some early results. I was looking for Win Rates that were 65% or better, I am still looking for other confirmation indicators to make better entries. Any suggestions would be appreciated and I can provide more backtesting results… in due time.

TLDR:
Intraday Setup: My chosen setup is Setup #2 on the 5 min chart with the Original code and with the MACD (8,21,5) as entry confirmation. The Extended Hours are shown but only trade between 0930-1500 EST.
Swing Setup: My chosen setup is Setup #3 on the Daily chart with the Original code and with the MACD (8,21,5) as entry confirmation.


5 Day / 5 Min: My Chosen Intraday Setup is Setup #2
Setup #1: I have Extended Hours plotted but only took trades from 0930-1500 EST. I decided to end trading at 1500 so as not to have a position open that goes into the aftermarket hours. With this setup, I would go with the 34 HMA returning the best P/L and Win Rate.



Setup #2 (Chosen Intraday Setup): I had Extended Hours plotted but only took trades from 0930-1500 EST. I decided to end trading at 1500 so as not to have a position open that goes into the aftermarket hours. With this setup, I also used MACD (8, 21, 5, Exponential, no) to help confirm my entries but used the regular exit points provided by the original script. The entry criteria for this is the “buy” signal from the original code along with the MACD “Value” > “Avg”. The 21 HMA provides the best P/L and Win Rate with the 55 HMA providing the lowest P/L but the 2nd best Win Rate.




5 Year / 1 Day: My Chosen Swing Setup is either Setup #3 or #4
Setup #1: This setup is the original code with no changes. All of the different lengths are close in Win Rate. Nothing really stands out differently other than the 34 HMA and greater ones have almost 0.5% higher average gain. I don’t think this indicator alone is very good for Swing Trading.



Setup #2: This setup is the original code with a take profit at 5% gain. All of the different lengths are close in Win Rate. I plan on going back and putting in a stop loss at 5% to remove some of those losses in the 21 and 34 HMAs but I don’t think this indicator alone is very good for Swing Trading.



Setup #3: This setup is just like the 5 Day / 5 Min using the MACD as a confirmation to the entry point. As you can see the 21 HMA has the 2nd lowest P/L but the greatest Win Rate at 77% with only an average of 4 trades per year. Not the greatest P/L but that’s a decent Win Rate. An interesting thing to note is that the 89 and 144 HMAs provide almost 6x the profits with a 64% win rate with an average of 6.5 trades per year.



Setup #4: This setup is just like the 5 Day / 5 Min using the MACD as a confirmation to the entry point with a take profit at 5%. As you can see the 21 HMA has the 2nd lowest P/L but the greatest Win Rate at 77% with only an average of 4 trades per year. Not the greatest P/L but that’s a decent Win Rate. An interesting thing to note is that the 89 and 144 HMAs provide almost 4-5x the profits with a 64% win rate with an average of 6.5 trades per year.




360 Day / 1 Hour: My Chosen Swing Setup is ???
Setup #1: This setup is the original code with no changes. I didn’t exclude Pre-Market/Post-Market hours trading in this data set. All of the different lengths are close in Win Rate aside from the 144 HMA. I don’t think this indicator alone is very good for Swing Trading.



Setup #2: This setup is the original code with a take profit at 5% gain. I didn’t exclude Pre-Market/Post-Market hours trading in this data set. All of the different lengths are close in Win Rate aside from the 144 HMA. I don’t think this indicator alone is very good for Swing Trading.



Setup #3: This setup is just like the 5 Day / 5 Min using the MACD as a confirmation to the entry point. The 21 and 34 HMAs tie on Win Rate with 71% but the 21 HMA has a better Total P/L.

 
C

cpyleitz

New member
I haven't really looked into that. Perhaps some day when I have an abundance of time on my hands. Which hasn't been recently
Thanks Mashume, please keep that on the backburner, I know you have other priorities.
 

Similar threads

Top