# Triple Exhaustion Indicator
##
##
## CREDITS
## Requested by @Chence27 from criteria listed here https://usethinkscript.com/threads/triple-exhaustion-indicator.9001/
##
##
## Removing the header Credit credits and description is not permitted, any modification needs to be shared.
##
## V 1.0 : @cos251 - Initial release per request from www.usethinkscript.com forum thread:
## : https://usethinkscript.com/threads/triple-exhaustion-indicator.9001/
##
##
## adding MTF labels @irishgold 08/22/2022
declare upper;
input agperiod1 = { "1 min", default "2 min", "3 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "2 hours", "4 hours", "Day", "Week", "Month"};
input agperiod2 = {"1 min", "2 min", "3 min", default "5 min", "10 min", "15 min", "30 min", "1 hour", "2 hours", "4 hours", "Day", "Week", "Month"};
input agperiod3 = {"1 min", "2 min", "3 min", "5 min", default "10 min", "15 min", "30 min", "1 hour", "2 hours", "4 hours", "Day", "Week", "Month"};
input agperiod4 = {"1 min", "2 min", "3 min", "5 min", "10 min", default "15 min", "30 min", "1 hour", "2 hours", "4 hours", "Day", "Week", "Month"};
input DI_Length = 14;
# --- Inputs
input over_bought = 80;
input over_sold = 20;
input KPeriod = 10;
input DPeriod = 10;
def priceH1 = high(period = agperiod1);
def priceH2 = high(period = agperiod2);
def priceH3 = high(period = agperiod3);
def priceH4 = high(period = agperiod4);
def priceL1 = low(period = agperiod1);
def priceL2 = low(period = agperiod2);
def priceL3 = low(period = agperiod3);
def priceL4 = low(period = agperiod4);
def priceC1 = close(period = agperiod1);
def priceC2 = close(period = agperiod2);
def priceC3 = close(period = agperiod3);
def priceC4 = close(period = agperiod4);
input priceH = high;
input priceL = low;
input priceC = close;
input averageType = AverageType.SIMPLE;
input length = 400;
input paintBars = yes;
input showLabels = yes;
input percentGain = .005;
# --- Indicators - StochasticSlow / MACD / MACD StDev / DMI+/-
def SlowK = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH, priceL, priceC, 3, averageType).FullK;
def SlowK1 = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH1, priceL1, priceC1, 3, averageType).FullK;
def SlowK2 = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH2, priceL2, priceC2, 3, averageType).FullK;
def SlowK3 = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH3, priceL3, priceC3, 3, averageType).FullK;
def SlowK4 = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH4, priceL4, priceC4, 3, averageType).FullK;
def MACD = reference MACD()."Value";
# This section is for the aggregations term MACD
def MACD1 = (ExpAverage(priceC1[1], 12)) - (ExpAverage(priceC1[1], 26));
def MACD2 = (ExpAverage(priceC2[1], 12)) - (ExpAverage(priceC2[1], 26));
def MACD3 = (ExpAverage(priceC3[1], 12)) - (ExpAverage(priceC3[1], 26));
def MACD4 = (ExpAverage(priceC4[1], 12)) - (ExpAverage(priceC4[1], 26));
def priceMean1 = SimpleMovingAvg(MACD1, length);
def priceMean2 = SimpleMovingAvg(MACD2, length);
def priceMean3 = SimpleMovingAvg(MACD3, length);
def priceMean4 = SimpleMovingAvg(MACD4, length);
def MACD_stdev1 = (MACD1 - priceMean1) / StDev(MACD1, length);
def MACD_stdev2 = (MACD2 - priceMean2) / StDev(MACD2, length);
def MACD_stdev3 = (MACD3 - priceMean3) / StDev(MACD3, length);
def MACD_stdev4 = (MACD4 - priceMean4) / StDev(MACD4, length);
def priceMean = SimpleMovingAvg(MACD, length);
def MACD_stdev = (MACD - priceMean) / StDev(MACD, length);
def dPlus = reference DMI()."DI+";
def dMinus = reference DMI()."DI-";
# DMI computations
def hiDiff1 = priceH1 - priceH1[1];
def loDiff1 = priceL1[1] - priceL1;
def plusDM1 = if hiDiff1 > loDiff1 and hiDiff1 > 0 then hiDiff1 else 0;
def minusDM1 = if loDiff1 > hiDiff1 and loDiff1 > 0 then loDiff1 else 0;
def ATR1 = MovingAverage(averageType, TrueRange(priceH1, priceC1, priceL1), DI_Length);
def dPlus1 = 100 * MovingAverage(AverageType.WILDERS, plusDM1, DI_Length) / ATR1;
def dMinus1 = 100 * MovingAverage(AverageType.WILDERS, minusDM1, DI_Length) / ATR1;
def hiDiff2 = priceH2 - priceH2[1];
def loDiff2 = priceL2[1] - priceL2;
def plusDM2 = if hiDiff2 > loDiff2 and hiDiff2 > 0 then hiDiff2 else 0;
def minusDM2 = if loDiff2 > hiDiff2 and loDiff2 > 0 then loDiff2 else 0;
def ATR2 = MovingAverage(averageType, TrueRange(priceH2, priceC2, priceL2), DI_Length);
def dPlus2 = 100 * MovingAverage(AverageType.WILDERS, plusDM2, DI_Length) / ATR2;
def dMinus2 = 100 * MovingAverage(AverageType.WILDERS, minusDM2, DI_Length) / ATR2;
def hiDiff3 = priceH3 - priceH3[1];
def loDiff3 = priceL3[1] - priceL3;
def plusDM3 = if hiDiff3 > loDiff3 and hiDiff3 > 0 then hiDiff3 else 0;
def minusDM3 = if loDiff3 > hiDiff3 and loDiff3 > 0 then loDiff3 else 0;
def ATR3 = MovingAverage(averageType, TrueRange(priceH3, priceC3, priceL3), DI_Length);
def dPlus3 = 100 * MovingAverage(AverageType.WILDERS, plusDM3, DI_Length) / ATR3;
def dMinus3 = 100 * MovingAverage(AverageType.WILDERS, minusDM3, DI_Length) / ATR3;
def hiDiff4 = priceH4 - priceH4[1];
def loDiff4 = priceL4[1] - priceL4;
def plusDM4 = if hiDiff4 > loDiff4 and hiDiff4 > 0 then hiDiff4 else 0;
def minusDM4 = if loDiff4 > hiDiff4 and loDiff4 > 0 then loDiff4 else 0;
def ATR4 = MovingAverage(averageType, TrueRange(priceH4, priceC4, priceL4), DI_Length);
def dPlus4 = 100 * MovingAverage(AverageType.WILDERS, plusDM4, DI_Length) / ATR4;
def dMinus4 = 100 * MovingAverage(AverageType.WILDERS, minusDM4, DI_Length) / ATR4;
# --- End Indicators
# --- Conditions
def sellerRegular1 = SlowK1 < 20 and MACD_stdev1 < -1 and dPlus1 < 15;
def sellerRegular2 = SlowK2 < 20 and MACD_stdev2 < -1 and dPlus2 < 15;
def sellerRegular3 = SlowK3 < 20 and MACD_stdev3 < -1 and dPlus3 < 15;
def sellerRegular4 = SlowK4 < 20 and MACD_stdev4 < -1 and dPlus4 < 15;
def buyerRegular1 = SlowK1 > 80 and MACD_stdev1 > 1 and dMinus1 < 15;
def buyerRegular2 = SlowK2 > 80 and MACD_stdev2 > 1 and dMinus2 < 15;
def buyerRegular3 = SlowK3 > 80 and MACD_stdev3 > 1 and dMinus3 < 15;
def buyerRegular4 = SlowK4 > 80 and MACD_stdev4 > 1 and dMinus4 < 15;
def sellerRegular = SlowK < 20 and MACD_stdev < -1 and dPlus < 15;
def sellerExtreme = SlowK < 20 and MACD_stdev < -2 and dPlus < 15;
def buyerRegular = SlowK > 80 and MACD_stdev > 1 and dMinus < 15;
def buyerExtreme = SlowK > 80 and MACD_stdev > 2 and dMinus < 15;
def priceJump = if close[1] > (open[5] + open[5] * percentGain) then 1 else 0;
# --- End Conditions
# --- Arrows/Triggers
plot RegularBuy = if sellerRegular[1] and !sellerRegular then low else Double.NaN;
#plot ExtremeBuy = if sellerExtreme[1] and !sellerExtreme then low else Double.NaN;
RegularBuy.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
#ExtremeBuy.SetPaintingSTrategy(paintingSTrategy.Arrow_UP);
RegularBuy.SetDefaultColor(CreateColor(255, 126, 0));
RegularBuy.SetLineWeight(2);
#ExtremeBuy.SetDefaultColor(CreateColor(255,126,0));
#ExtremeBuy.SetLineWeight(2);
plot RegularSell = if buyerRegular[2] and !buyerRegular[1] then high else Double.NaN;
RegularSell.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
RegularSell.SetLineWeight(2);
RegularSell.SetDefaultColor(CreateColor(255, 126, 0));
def currentPeriod = GetAggregationPeriod();
AddLabel(yes, if buyerRegular[2] and !buyerRegular[1] then "TF: " + currentPeriod/60000 + " min Sell " else if sellerRegular[1] and !sellerRegular then "TF: " + currentPeriod/60000 + " min Buy " else "TF: " + currentPeriod/60000 + " min", if buyerRegular[2] and !buyerRegular[1] then Color.RED else if sellerRegular[2] and !sellerRegular[1] then Color.GREEN else Color.GRAY);
AddLabel(yes, if buyerRegular1[2] and !buyerRegular1[1] then "TF: " + agperiod1 + " Sell " else if sellerRegular1[1] and !sellerRegular1 then "TF: " + agperiod1 + " Buy " else "TF: " + agperiod1, if buyerRegular1[2] and !buyerRegular1[1] then Color.RED else if sellerRegular1[2] and !sellerRegular1[1] then Color.GREEN else Color.GRAY);
AddLabel(yes, if buyerRegular2[2] and !buyerRegular2[1] then "TF: " + agperiod2 + " Sell " else if sellerRegular2[1] and !sellerRegular2 then "TF: " + agperiod2 + " Buy " else "TF: " + agperiod2, if buyerRegular2[2] and !buyerRegular2[1] then Color.RED else if sellerRegular2[2] and !sellerRegular2[1] then Color.GREEN else Color.GRAY);
AddLabel(yes, if buyerRegular3[2] and !buyerRegular3[1] then "TF: " + agperiod3 + " Sell " else if sellerRegular3[1] and !sellerRegular3 then "TF: " + agperiod3 + " Buy " else "TF: " + agperiod3, if buyerRegular3[2] and !buyerRegular3[1] then Color.RED else if sellerRegular3[2] and !sellerRegular3[1] then Color.GREEN else Color.GRAY);
AddLabel(yes, if buyerRegular4[2] and !buyerRegular4[1] then "TF: " + agperiod4 + " Sell " else if sellerRegular4[1] and !sellerRegular4 then "TF: " + agperiod4 + " Buy " else "TF: " + agperiod4, if buyerRegular4[2] and !buyerRegular4[1] then Color.RED else if sellerRegular4[2] and !sellerRegular4[1] then Color.GREEN else Color.GRAY);