#
# 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
#
# ----------------------
# Update Author: TheBewb
# Created a study based of Mahsume's Hull Concavity study that shows the concavity of different aggregations and length HMAs as a lower study. It is a lot of information and not sure how actionable since you get mixed signals a lot but if the market is trending good confirmation
declare lower;
input aggperiod = AggregationPeriod.FIVE_MIN;
input aggperiod2 = AggregationPeriod.FIFTEEN_MIN;
def price = open(period = aggperiod);
def price2 = open(period = aggperiod2);
input HMA_Length = 21;
input HMA_length2 = 34;
input HMA_length3 = 55;
input HMA_Length4 = 21;
input HMA_length5 = 34;
input HMA_length6 = 55;
input lookback = 2;
def 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;
def turning_point = if concavity[1] != concavity then HMA else Double.NaN;
def preBull = concavity[1] == 1 and HMA < HMA[1];
def Bull = concavity[1] == 1 and HMA > HMA[1];
def preBear = concavity[1] == -1 and HMA > HMA[1];
def Bear = concavity[1] == -1 and HMA < HMA [1];
def MA_Max = if HMA[-1] < HMA and HMA > HMA[1] then HMA else Double.NaN;
def MA_Min = if HMA[-1] > HMA and HMA < HMA[1] then HMA else Double.NaN;
def HMA2 = HullMovingAvg(price = price, length = HMA_length2);
def delta2 = HMA2[1] - HMA2[lookback + 1];
def delta_per_bar2 = delta2 / lookback;
def next_bar2 = HMA2[1] + delta_per_bar2;
def concavity2 = if HMA2 > next_bar2 then 1 else -1;
def turning_point2 = if concavity2[1] != concavity2 then HMA2 else Double.NaN;
def preBull2 = concavity2[1] == 1 and HMA2 < HMA2[1];
def Bull2 = concavity2[1] == 1 and HMA2 > HMA2[1];
def preBear2 = concavity2[1] == -1 and HMA2 > HMA2[1];
def Bear2 = concavity2[1] == -1 and HMA2 < HMA2[1];
def MA_Max2 = if HMA2[-1] < HMA2 and HMA2 > HMA2[1] then HMA2 else Double.NaN;
def MA_Min2 = if HMA2[-1] > HMA2 and HMA2 < HMA2[1] then HMA2 else Double.NaN;
def HMA3 = HullMovingAvg(price = price, length = HMA_length3);
def delta3 = HMA3[1] - HMA3[lookback + 1];
def delta_per_bar3 = delta3 / lookback;
def next_bar3 = HMA3[1] + delta_per_bar3;
def concavity3 = if HMA3 > next_bar3 then 1 else -1;
def turning_point3 = if concavity3[1] != concavity3 then HMA3 else Double.NaN;
def preBull3 = concavity3[1] == 1 and HMA3 < HMA3[1];
def Bull3 = concavity3[1] == 1 and HMA3 > HMA3[1];
def preBear3 = concavity3[1] == -1 and HMA3 > HMA3[1];
def Bear3 = concavity3[1] == -1 and HMA3 < HMA3[1];
def MA_Max3 = if HMA3[-1] < HMA3 and HMA3 > HMA3[1] then HMA3 else Double.NaN;
def MA_Min3 = if HMA3[-1] > HMA3 and HMA3 < HMA3[1] then HMA3 else Double.NaN;
def HMA4 = HullMovingAvg(price = price2, length = HMA_Length4);
def delta4 = HMA4[1] - HMA4[lookback + 1];
def delta_per_bar4 = delta4 / lookback;
def next_bar4 = HMA4[1] + delta_per_bar4;
def concavity4 = if HMA4 > next_bar4 then 1 else -1;
def turning_point4 = if concavity4[1] != concavity4 then HMA4 else Double.NaN;
def preBull4 = concavity4[1] == 1 and HMA4 < HMA4[1];
def Bull4 = concavity4[1] == 1 and HMA4 > HMA4[1];
def preBear4 = concavity4[1] == -1 and HMA4 > HMA4[1];
def Bear4 = concavity4[1] == -1 and HMA4 < HMA4[1];
def MA_Max4 = if HMA4[-1] < HMA4 and HMA4 > HMA4[1] then HMA4 else Double.NaN;
def MA_Min4 = if HMA4[-1] > HMA4 and HMA4 < HMA4[1] then HMA4 else Double.NaN;
def HMA5 = HullMovingAvg(price = price2, length = HMA_length5);
def delta5 = HMA5[1] - HMA5[lookback + 1];
def delta_per_bar5 = delta5 / lookback;
def next_bar5 = HMA5[1] + delta_per_bar5;
def concavity5 = if HMA5 > next_bar5 then 1 else -1;
def turning_point5 = if concavity5[1] != concavity5 then HMA5 else Double.NaN;
def preBull5 = concavity5[1] == 1 and HMA5 < HMA5[1];
def Bull5 = concavity5[1] == 1 and HMA5 > HMA5[1];
def preBear5 = concavity5[1] == -1 and HMA5 > HMA5[1];
def Bear5 = concavity5[1] == -1 and HMA5 < HMA5[1];
def MA_Max5 = if HMA5[-1] < HMA5 and HMA5 > HMA5[1] then HMA5 else Double.NaN;
def MA_Min5 = if HMA5[-1] > HMA5 and HMA5 < HMA5[1] then HMA5 else Double.NaN;
def HMA6 = HullMovingAvg(price = price2, length = HMA_length6);
def delta6 = HMA6[1] - HMA6[lookback + 1];
def delta_per_bar6 = delta6 / lookback;
def next_bar6 = HMA6[1] + delta_per_bar6;
def concavity6 = if HMA6 > next_bar6 then 1 else -1;
def turning_point6 = if concavity6[1] != concavity6 then HMA6 else Double.NaN;
def preBull6 = concavity6[1] == 1 and HMA6 < HMA6[1];
def Bull6 = concavity6[1] == 1 and HMA6 > HMA6[1];
def preBear6 = concavity6[1] == -1 and HMA6 > HMA6[1];
def Bear6 = concavity6[1] == -1 and HMA6 < HMA6[1];
def MA_Max6 = if HMA6[-1] < HMA6 and HMA6 > HMA6[1] then HMA6 else Double.NaN;
def MA_Min6 = if HMA6[-1] > HMA6 and HMA6 < HMA6[1] then HMA6 else Double.NaN;
plot Trend1 = If(IsNaN(Price[0]), Double.NaN, 6);
Trend1.AssignValueColor(if bull then color.green else if bear then color.red else if prebull then color.dark_green else if prebear then color.DARK_ORANGE else color.magenta);
Trend1.SetPaintingStrategy(PaintingStrategy.POINTS);
Trend1.SetLineWeight(3);
plot Trend2 = If(IsNaN(Price[0]), Double.NaN, 5);
Trend2.AssignValueColor(if bull2 then color.green else if bear2 then color.red else if prebull2 then color.dark_green else if prebear2 then color.DARK_ORANGE else color.magenta);
Trend2.SetPaintingStrategy(PaintingStrategy.POINTS);
Trend2.SetLineWeight(3);
plot Trend3 = If(IsNaN(Price[0]), Double.NaN, 4);
Trend3.AssignValueColor(if bull3 then color.green else if bear3 then color.red else if prebull3 then color.dark_green else if prebear3 then color.DARK_ORANGE else color.magenta);
Trend3.SetPaintingStrategy(PaintingStrategy.POINTS);
Trend3.SetLineWeight(3);
plot Trend4 = If(IsNaN(Price[0]), Double.NaN, 3);
Trend4.AssignValueColor(if bull4 then color.green else if bear4 then color.red else if prebull4 then color.dark_green else if prebear4 then color.DARK_ORANGE else color.magenta);
Trend4.SetPaintingStrategy(PaintingStrategy.POINTS);
Trend4.SetLineWeight(3);
plot Trend5 = If(IsNaN(Price[0]), Double.NaN, 2);
Trend5.AssignValueColor(if bull5 then color.green else if bear5 then color.red else if prebull5 then color.dark_green else if prebear5 then color.DARK_ORANGE else color.magenta);
Trend5.SetPaintingStrategy(PaintingStrategy.POINTS);
Trend5.SetLineWeight(3);
plot Trend6 = If(IsNaN(Price[0]), Double.NaN, 1);
Trend6.AssignValueColor(if bull6 then color.green else if bear6 then color.red else if prebull6 then color.dark_green else if prebear6 then color.DARK_ORANGE else color.magenta);
Trend6.SetPaintingStrategy(PaintingStrategy.POINTS);
Trend6.SetLineWeight(3);