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

rad14733

Well-known member
VIP
@RickK Back when I had my open source CMS project I did a lot of Javascript coding but haven't done much in the past 10 - 13 years... Only a bit of maintenance coding to help fix things like WYSIWYG editor bugs and such, and tweaks to another now defunct CMS that was a fork of my code... I coded in it daily for several years but haven't done any serious web coding in a long time... I was going to try TDA's API about a week ago and that can use Javascript...
 

jorge50505

New member
VIP
@mashume thank you for creating this indicator i am using v4 with 21 feel its faster then the original since i am a scalper

i know i have alot on my screens but basically followed thru when it turned bright green on 1 minute and became ready to sell as soon as it turned orange and with balance bb i found on this forum as soon as histogram volume became lower i got out perfectly

curious what others have combined your indicator with here


 
Last edited:

El Profesor

New member
@mashume thank you so much for this study. I am curious if you or anyone else in the forum has recreated this in TradeStation.? I know this is Thinkscript for TOS, but curious if anyone has experience with EasyLanguage(seems Python based)?
 

mashume

Well-known member
VIP
@mashume thank you so much for this study. I am curious if you or anyone else in the forum has recreated this in TradeStation.? I know this is Thinkscript for TOS, but curious if anyone has experience with EasyLanguage(seems Python based)?
I've never worked going from ThinkScript to EasyLanguage, though I've gone the other direction a few times (and my day job is working as a python developer).

-mashume
 

El Profesor

New member
I've never worked going from ThinkScript to EasyLanguage, though I've gone the other direction a few times (and my day job is working as a python developer).

-mashume

Can you DM me? I think I may have accomplished it, and would love your feedback.
 

BBDPDC

New member
VIP
Ok here's a thought. Labels to show the polarity of this indicator from a higher timeframe (e.g. 2m position on a 1m chart). I use this for confirmation when entering i.e. if the positive turning point (Dark Green line) has fired on the higher timeframe i can enter with higher risk, if the Buy signal (Green line) has fired i can enter with low risk.

I'm going to attempt to code this now but hoping someone who actually knows what they are doing can help while i bumble about in the meantime ;-)
 

BBDPDC

New member
VIP
Ok here's a thought. Labels to show the polarity of this indicator from a higher timeframe (e.g. 2m position on a 1m chart). I use this for confirmation when entering i.e. if the positive turning point (Dark Green line) has fired on the higher timeframe i can enter with higher risk, if the Buy signal (Green line) has fired i can enter with low risk.

I'm going to attempt to code this now but hoping someone who actually knows what they are doing can help while i bumble about in the meantime ;-)
replying to my own question/request like the sad puppy i am. I think this covers it bu would be grateful if someone could check my code please.

https://tos.mx/m4Sv5GX
 

rad14733

Well-known member
VIP
@BBDPDC Can you post the code, using the </> icon, for review without the need to import into TOS please... Please make it a habit to always post the code, not just a shared link...
 

BBDPDC

New member
VIP
@BBDPDC Can you post the code, using the </> icon, for review without the need to import into TOS please... Please make it a habit to always post the code, not just a shared link...
@rad14733 apologies, I hadn't considered that folks might not want to import my potentially p!ss poor code into there TOS! Here's the code:

Code:
#Hull HigherAgg Label

declare upper;

input price = HL2;
input HMA_Length = 18;
input lookback = 1;
input agg =  { "1 min", default "2 min", "5 min", "10 min", "15 min", "30 min", "60 min", "4 hours"};

def nan = double.nan;

def HMA = HullMovingAvg(HL2(period=agg), 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;

def turning_point = if concavity[1] != concavity then HMA else nan;

AddLabel(yes, "HULL",  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);
 
Thank you all for your comments and encouragement.

I have a laundry list of things in this post:
  1. Variations to scripts
  2. Scanner
  3. Testing

Script Variations

@chillc15, I'm intrigued by the Arnaud Legoux MA, and so here is a variant of the upper study that will allow you to choose between Hull, Simple, Exponential, Williams, and ALMA. I haven't gone through the various permutations, but bear in mind that the 'overshoot' and smoothing of the Hull is part of what makes the turning point signal so attractive.

@Miket Used your posted code for the ALMA. Hope you're good with this use. Thanks!

Code:
#
# Multiple Moving Average Concavity and Turning Points
#  or
# The Second Derivative of the A Moving Average
#
# via useThinkScript
# request from chillc15
# Added Arnaud Legoux MA and other Moving Averages
#
# Author: Seth Urion (Mahsume)
# Version: 2020-02-22 V2
#
# This code is licensed (as applicable) under the GPL v3
#
# ----------------------

declare upper;

input price = HL2;
input MA_Length = 21;
input lookback = 2;

input MovingAverage = {default "HMA", "EMA", "SMA", "WMA", "ALMA"};

script ALMA {
# Attributed to Miket
# https://tos.mx/9mznij
# https://usethinkscript.com/threads/alma-arnaud-legoux-ma-indicator-for-thinkorswim.174/
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;

def m = (Offset * (Window - 1));
def s = Window/Sigma;

def SumVectorData = fold y = 0 to Window with WS do WS + Exp(-(sqr(y-m))/(2*sqr(s))) * getvalue(Data, (Window-1)-y);
def SumVector = fold z = 0 to Window with CW do CW + Exp(-(sqr(z-m))/(2*sqr(s)));

plot ALMA = SumVectorData / SumVector;
}

plot MA;
switch (MovingAverage) {
case EMA:
    MA = MovAvgExponential(price, length = MA_Length);
case SMA:
    MA = simpleMovingAvg(price, length = MA_Length);
case WMA:
    MA = wma(price, length = MA_Length);
case ALMA:
    MA = ALMA(Data = price, window = MA_Length);
default:
    MA = HullMovingAvg(price = price, length = MA_Length);
}


def delta = MA[1] - MA[lookback + 1];
def delta_per_bar = delta / lookback;

def next_bar = MA[1] + delta_per_bar;

def concavity = if MA > next_bar then 1 else -1;

plot turning_point = if concavity[-1] != concavity then MA else double.nan;

MA.AssignValueColor(color = if concavity == -1 then
    if MA > MA[1] then color.dark_orange else color.red else
    if MA < MA[1] then color.dark_green else color.green);

MA.SetLineWeight(3);

turning_point.SetLineWeight(4);
turning_point.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
turning_point.SetDefaultColor(color.white);

plot MA_Max = if MA[-1] < MA and MA > MA[1] then MA else Double.NaN;
MA_Max.SetDefaultColor(Color.WHITE);
MA_Max.SetPaintingStrategy(PaintingStrategy.SQUARES);
MA_Max.SetLineWeight(3);

plot MA_Min = if MA[-1] > MA and MA < MA[1] then MA 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 = MA - 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);

SCANS

@mailbagman2000 , Scans, yes...
Scan 1 -- Buy signals.

This scan relies on the upper study being called "Concavity" and is entered on the scan page as a custom.
Code:
Concavity("hma length" = 55, price = CLOSE)."buy" is true within 2 bars

Scan 2 -- Stocks approaching possible Buy signals
I thought that, since the lower indicator crossovers can generate signals, that an 'early warning' scan might be of interest. We can scan for any HMA that has a negative convergence, and look for a decrease in the distance below zero. It may be a long way off, it may never get there, but we are alerted before the trade entry.

Code:
script ConcavityDivergence {
#
# Hull Moving Average Concavity Divergence
#  or
# The Second Derivative of the Hull Moving Average
#
# Author: Seth Urion (Mahsume)
# Version: 2020-02-21 Initial Public
#
# This code is licensed (as applicable) under the GPL v3
#
# ----------------------

declare lower;

input price = HL2;

input HMA_length = 34;
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 = displacer(-1, 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);

}

def signal = ConcavityDivergence("hma length" = 55)."concavity";
def HMA = ConcavityDivergence("hma length" = 55)."HMA";
def next = ConcavityDivergence("hma length" = 55)."next_bar";

plot buy = signal < 0 and (HMA - next) > (HMA[1] - next[1]);

TESTING

I used the built-in strategy feature of thinkorswim, with block sizes of 100. All tests were run on 1 year Daily charts, with an HMA length of 55 and set price to CLOSE

First SPX
Buy and Hold: $55,600
Strategy: $77,372
Delta + $21772
qdaQ0uz.png



Next ADI
Buy and Hold: $1718
Strategy: $5202
Delta: + $3483
mcNVfVy.png


Last BA
Buy and Hold: ($9322)
Strategy: $14393
Delta: + $23715
XCL6Sdh.png


SHORT TIME FRAMES
I did not take time today to test shorter timeframes, though I imagine the results would be good. If there is interest, I'll try to post up some another time.

If you've read this far, thank you.
Happy trading and good luck.
This indicator is awesome! Is there a way to scan for MA_Min alert and MA_Max alert? I changed it to VWAP 30, 2 and love it on the 15mn and the 30mn. Buy on the Min and sell on the Max. Also how could I make this a buy script? All based on the upper script I have a 6yo in online Kindergarten so it's hard to watch charts now.
 
Last edited:

caspara2

New member
VIP
@mashume Thank you for sharing this very helpful indicator. I use the upper one daily with my standard day scan of up-trending stocks, along with volume and price movement, and the Schaff Trend Cycle. At one point, I had tried (without success) to create an indicator similar to yours, so I can appreciate the effort and math skills that were involved. Creating a nice scan with your indicator on multiple occasions has really found me some nice early upward-arcing trends.

I am up three out of four days in a row (one just barely down), even in a rocky market. After six plus months of learning (a lot of it on this site), I am finally not fearing the opening bell anymore, and can comfortably react to what I am seeing on multiple timeframe charts. Sorting by a Rate of Change (ROC) column aggregated at 5 minutes in my watchlists has definitely helped me recognize the start of any strong negative price movements, allowing me to sell all but one share and then repurchase the lot when the cycle switches back.

FYI, when I do find the perfect stock charts, I use Stock Fetcher to find other stocks with almost identical price patterns. Sometimes by doing this, I can find similar stocks that have not broken out yet. I'm not affiliated with them, just like the free service (that I didn't find elsewhere).
 
Last edited:

mashume

Well-known member
VIP
@mashume Thank you for sharing this very helpful indicator. I use the upper one daily with my standard day scan of up-trending stocks, along with volume and price movement, and the Schaff Trend Cycle. At one point, I had tried (without success) to create an indicator similar to yours, so I can appreciate the effort and math skills that were involved. Creating a nice scan with your indicator on multiple occasions has really found me some nice early upward-arcing trends.

I am up three out of four days in a row (one just barely down), even in a rocky market. After six plus months of learning (a lot of it on this site), I am finally not fearing the opening bell anymore, and can comfortably react to what I am seeing on multiple timeframe charts. Sorting by a Rate of Change (ROC) column aggregated at 5 minutes in my watchlists has definitely helped me recognize the start of any strong negative price movements, allowing me to sell all but one share and then repurchase the lot when the cycle switches back.

FYI, when I do find the perfect stock charts, I use Stock Fetcher to find other stocks with almost identical price patterns. Sometimes by doing this, I can find similar stocks that have not broken out yet. I'm not affiliated with them, just like the free service (that I didn't find elsewhere).
@caspara2 ,

Thank you for the kind words. They are sincerely appreciated. I'm also glad you're discovering some trading plans and strategies that work for you. Keep it up! And always remember, trading is fun!

Happy Trading,
-mashume
 

machdragon

New member
@mashume Thank you for creating this amazing indicator! I have been using this indicator on ThinkorSwim along with the QQE indicator for the last year and have found some success with my trading. Recently I have been using Tradingview to chart crypto, but the implementations of Hull on Tradingview felt somewhat lacking. I missed having this Hull indicator I loved so much, so I rewrote it for Tradingview one weekend haha. I have credited you in the source as the author of the original code along with some edits made by myself and a mentor.
Here is the script converted for Tradingview:
https://www.tradingview.com/script/6Fpb0VvK-MashumeHullTV/

Cheers, and thanks again!
-machdragon
 
Last edited:
I have the upper study named as "Concavity" and put in the scanner but I received "no such variable at 1:45 at least one plot should be defined at 1:1 and Expected double at 1:51 .... help?
 

Similar threads

Top