Reverse Ehler Instantaneous Trendline - TraderHalai
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//
// This script uses a reverse function of the famous Ehler Instantaneous Trendline to calculate the source price required in order
// to change from Bullish to bearish
//
// From my analysis, the reverse price does appear to be rather choppy, though it is accurate. This is because Ehler's Instantaneous
// Trendline tends to remain trending for longer periods of time with above average hold periods.
//
// The main suitability for this would be higher level functions. However, I have found that SHA Trend is more accurate and provides better
// Risk adjusted return than using this function
//
// As I had spent a bit of time getting the reverse function mathematics to work, I decided to publish this as open source for the benefit, scrutiny and for further development by the TradingView community anyways.
//
// Enjoy!
// © TraderHalai
// @version=5

indicator(title = "Reverse Ehler Instantaneous Trendline - TraderHalai", shorttitle="Reverse Ehler Instant Trend - TraderHalai" , overlay = true)

//Inputs
src = input.source(close, "Source",                         group = "Calculation Parameters")
alpha = input.float(0.07, "Alpha",                          group = "Calculation Parameters")

i_showIT = input.bool(true, "Show Ehler Instantaneous Trendline", group = "Display Options")
i_infoBox = input.bool(true, "Show info box",               group = "Display Options")
i_showTriggerLine = input.bool(false, "Show trigger line",  group = "Display Options")
i_colorBars = input.bool(false, "Color bars",               group = "Display Options")
i_showReverseCloseLine = input.bool(false, "Show Reverse Function Calculation", group = "Display Options")

i_decimalP = input.int(2, "Number of decimal places",       group = "Infobox Options")
i_boxOffSet = input.int(0, "Info box offset",               group = "Infobox Options")

//Reverse Instantaneous Trendline Function
//
//Calculated using the following formula (sourced from Wolfram alpha)
//Reverse Src = (-4 (a^2 - 2 a + 2) k - 8 (a - 1) j + a (2 a t + 3 a u - 4 u))/((a - 4) a) and a^2 !=4 a
instant(float src, float alpha) =>
    itrend = 0.0
    itrend := bar_index < 7 ? (src + 2 * nz(src[1]) + nz(src[2])) / 4 : 
         (alpha - math.pow(alpha, 2) / 4) * src + 0.5 * math.pow(alpha, 2) * nz(src[1]) - (alpha - 0.75 * math.pow(alpha, 2)) * nz(src[2]) +  2 * (1 - alpha) * nz(itrend[1]) - math.pow(1 - alpha, 2) * nz(itrend[2])
    trigger = 2 * itrend - nz(itrend[2])
    reverseSrc = bar_index < 7 ? -4 * itrend[2] -(2 * src[1]) - src[2] + 8 * itrend : 
         (-4 * (math.pow(alpha, 2) - 2 * alpha + 2) * itrend[2] - 8 * (alpha - 1) * itrend[1] + alpha * (2 * alpha * src[1] + 3 * alpha * src[2] -4 * src[2])) / ((alpha - 4) * alpha)
    [trigger, itrend, reverseSrc]



//Calculations
[trig, sig, reverseSrc] = instant(src, alpha)
bull = trig > sig 
col = bull ? color.green : color.red


//Info box
haDirectionText = bull ? 'BULLISH Above: '  : 'BEARISH Below: '

f_truncdNum ( Val, DecPl ) => 
    Fact = math.pow (10, DecPl)
    int( Val * Fact) / Fact

var label  Infobox      = na

labelXLoc       = time_close + ( i_boxOffSet * ( time_close - time_close[1] ) )
infoBoxText     =  haDirectionText + str.tostring(f_truncdNum(reverseSrc, i_decimalP))

if i_infoBox
    Infobox := label.new ( labelXLoc, close, infoBoxText, xloc.bar_time, yloc.price, color.new(#00000f, 50), label.style_label_left, color.white )

label.delete ( Infobox[1] )


//Plots
plot(i_showIT ? trig : na, title="Instantaneous TrendLine", color=col, linewidth=2)
plot(i_showTriggerLine ? sig : na, color=color.gray, title= "Trigger Line")
barcolor(i_colorBars ? col : na)
plot(i_showReverseCloseLine ? reverseSrc : na, color=color.aqua)