Regression Curve with Normalized Angle
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © cmthoman

//@version=5
indicator(title="Regression Curve with Trend Correlation")
period = input.int(title="Lookback Period", group="Settings", defval=34)
src = input.source(title="Source", group="Settings", defval=hlc3, tooltip="Input source for the calculation")
high_cor_threshold = input.int(title="Trend Strength Threshold", group="Settings", defval=38, minval=35, maxval=45, tooltip="Defines at what value the correlation angle is considered to reflect a strong trend.\n\nPossible values range from 35 to 45 degrees.\nDefault Value is 38 degrees.")
trend_curve_threshold = input.int(title="Trend Direction Threshold", group="Settings", defval=10, minval=1, maxval=35, tooltip="Defines at what value the regression curve reflects a trend direction.\n\nPossible values range from 1 to 35 degrees.\nDefault value is 10 degrees.")

curve_color = input.color(title="Regression Curve Color", group="Output Colors", defval=color.new(color.gray, 40))
pearson_bull_color = input.color(title="Bullish Correlation Line Color", group="Output Colors", defval=color.new(color.green, 0))
pearson_bear_color = input.color(title="Bearish Correlation Line Color", group="Output Colors", defval=color.new(color.red, 40))

curve_fill_color = input.color(title="Trend Direction Fill Color", group="Threshold Colors", defval=color.new(color.gray, 90))
bull_threshold_color = input.color(title="Bullish Threshold Color", group="Threshold Colors", defval=color.new(color.green, 65))
bear_threshold_color = input.color(title="Bearish Threshold Color", group="Threshold Colors", defval=color.new(color.red, 65))
bull_fill_color = input.color(title="Bullish Fill Color", group="Threshold Colors", defval=color.new(color.green, 90))
bear_fill_color = input.color(title="Bearish Fill Color", group="Threshold Colors", defval=color.new(color.red, 90))

LinearRegression(period,src) =>

    float sumX = 0
    float sumY = 0
    float sumXSQ = 0
    float sumXY = 0
    float sumYSQ = 0
    float avgX = 0
    float avgY = 0

    for i = 0 to period - 1
        sumX := sumX + bar_index[i]
        sumY := sumY + src[i]
        sumXSQ := sumXSQ + math.pow(bar_index[i],2)
        sumYSQ := sumYSQ + math.pow(src[i],2)
        sumXY := sumXY + (bar_index[i] * src[i])
    
    avgX := sumX / period
    avgY := sumY / period
    
    pearson_r = ((period * sumXY ) - sumX * sumY) / math.sqrt( ((period * sumXSQ) - (sumX * sumX)) * ((period * sumYSQ) - (sumY * sumY)))
    regression_slope = ((period * sumXY - (sumX * sumY)) / (period * sumXSQ - (sumX * sumX)))
    
    [regression_slope, pearson_r]
    
[regression_slope, pearson_r] = LinearRegression(period,src)

pearson_r_degrees = math.round(math.todegrees(math.atan(pearson_r)))
regression_slope_degrees = math.round(math.todegrees(math.atan(regression_slope)))

h1 = hline(trend_curve_threshold, title="Long Trend Regression Curve Threshold", color=bull_threshold_color, editable=false)
h2 = hline(-1 * trend_curve_threshold, title="Short Trend Regression Curve Threshold", color=bear_threshold_color, editable=false)

h3 = hline(-1 * high_cor_threshold, title="Down Trend High Correlation Zone Top", color=bear_threshold_color, editable=false)
h4 = hline(-48, title="Down Trend High Correlation Zone Bottom", color=bear_threshold_color, editable=false)

h5 = hline(48, title="Up Trend High Correlation Zone Top", color=bull_threshold_color, editable=false)
h6 = hline(high_cor_threshold, title="Up Trend High Correlation Zone Bottom", color=bull_threshold_color, editable=false)

var color newColor = pearson_bull_color

if pearson_r_degrees[1] < high_cor_threshold and pearson_r_degrees[0] >= high_cor_threshold
    newColor := pearson_bear_color
if pearson_r_degrees[1] > -1 * high_cor_threshold and pearson_r_degrees[0] <= -1 * high_cor_threshold
    newColor := pearson_bull_color
    
p1 = plot(regression_slope_degrees, title="Regression Angle", color=curve_color, linewidth=2, style=plot.style_histogram, editable=true)
p2 = plot(pearson_r_degrees, title="Pearson R Angle", color=
  pearson_r_degrees[1] < high_cor_threshold and pearson_r_degrees[0] >= high_cor_threshold ? pearson_bull_color : 
  pearson_r_degrees[1] >= high_cor_threshold and pearson_r_degrees[0] >= high_cor_threshold ? pearson_bull_color : 
  pearson_r_degrees[1] >= high_cor_threshold and pearson_r_degrees[0] < high_cor_threshold ? pearson_bear_color :
  pearson_r_degrees[1] > -1 * high_cor_threshold and pearson_r_degrees[0] <= -1 * high_cor_threshold ? pearson_bear_color : 
  pearson_r_degrees[1] <= -1 * high_cor_threshold and pearson_r_degrees[0] <= -1 * high_cor_threshold ? pearson_bear_color : 
  pearson_r_degrees[1] <= -1 * high_cor_threshold and pearson_r_degrees[0] > -1 * high_cor_threshold ? pearson_bull_color : newColor,
  linewidth=2,
  editable=true
  )

fill(title="Trend Deadzone", hline1=h1, hline2=h2, color=curve_fill_color, editable=false)
fill(title="Strong Short Correlation Zone", hline1=h3, hline2=h4, color=bear_fill_color, editable=false)
fill(title="Strong Long Correlation Zone", hline1=h5, hline2=h6, color=bull_fill_color, editable=false)