TP-Plus Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © nashuald

//@version=5
indicator("TP-Plus Indicator", shorttitle = "TPI+", overlay = true )


period = input(20, "Fast Period")
periodSlow = input(40, "Slow Period")
priceSrc = input.source(hlcc4, "Source")
// minTrendStrength = input(10, "Min Trend Strength")
// minTrendLength = input(12, "Min trend length")
emaPeriod = 18 // input(18, "EMA Period (Filter)")


mult = 1.5
rangePercent = 95

// Calculates slope
linearRegFunc(src, period) => 
    float sumX = 0
    float sumY = 0
    float sumXY = 0
    float sumXX = 0
    float sumYY = 0
    float yMax = ta.highest(src, period)
    float yMin = ta.lowest(src, period)
    float factor = 1.0 / (yMax[0] - yMin[0])
    float y = 0
    for i = 0 to period
        sumX += i
        y := (src[i] - yMin) * period * factor
        sumY += y
        sumXY += i * y
        sumXX += i * i

    float meanX = sumX / period
    float meanY = sumY / period
    float numerador = 0
    float denominador = 0
    for i = 0 to period
        y := (src[i] - yMin)  * period * factor
        numerador += (i - meanX) * (y - meanY)
        denominador += math.pow(period - meanX, 2)

    float slope = numerador / denominador
    // float intercept = meanY - slope * meanX

    slope

float[] vals = array.new_float()
for i = 0 to period
    array.push(vals, open[i])
    array.push(vals, high[i])
    array.push(vals, low[i])
    array.push(vals, close[i])
    

sma = vals.avg()
stdev = vals.stdev()

top = sma + mult * stdev
bottom = sma - mult * stdev
percent = (open > bottom and open < top ? 1 : 0) + (high > bottom and high < top ? 1 : 0) + (low > bottom and low < top ? 1 : 0) + (close > bottom and close < top ? 1 : 0)
percent := 100 * percent / 4


float slopePrice = linearRegFunc(priceSrc, period)

float rawAngle = -math.atan(slopePrice) * 180 / math.pi
float angle = ta.sma(rawAngle, 5)


float slopePriceSlow = linearRegFunc(priceSrc, periodSlow)

float rawAngleSlow = -math.atan(slopePriceSlow) * 180 / math.pi
float angleSlow = ta.sma(rawAngleSlow, 5)

string labelText = ""
int cont = 0
for i = 0 to period
    if angle[i] > angle[i+1]
        cont += 1
    else if angle[i] <= angle[i+1]
        cont -= 1


ema = ta.ema(close, emaPeriod) 

createLine = false
max = ta.highest(high, periodSlow)[0]
min = ta.lowest(low, periodSlow)[0]
float angleRange = 8
if math.abs(angleSlow[0] - angle[0]) < angleRange and angle[0] > -angleRange and angle[0] < angleRange and angleSlow[0] > -angleRange and angleSlow[0] < angleRange
    createLine := true

// it draws top and bottom levels if createLine is true 
if createLine[0] and createLine[0] != createLine[1]
    line.new(bar_index-periodSlow, max, bar_index + periodSlow, max, color=color.white) 
    line.new(bar_index-periodSlow, min, bar_index + periodSlow, min, color=color.white) 

