Autoregressive Cloud
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//  /$$$$$$   /$$                                                         /$$                                            
// /$$__  $$ | $$                                                        | $$                                            
//| $$  \__//$$$$$$    /$$$$$$  /$$    /$$ /$$$$$$   /$$$$$$   /$$$$$$$ /$$$$$$    /$$$$$$  /$$    /$$ /$$$$$$   /$$$$$$$
//|  $$$$$$|_  $$_/   /$$__  $$|  $$  /$$//$$__  $$ /$$__  $$ /$$_____/|_  $$_/   /$$__  $$|  $$  /$$//$$__  $$ /$$_____/
// \____  $$ | $$    | $$$$$$$$ \  $$/$$/| $$$$$$$$| $$  \__/|  $$$$$$   | $$    | $$$$$$$$ \  $$/$$/| $$$$$$$$|  $$$$$$ 
// /$$  \ $$ | $$ /$$| $$_____/  \  $$$/ | $$_____/| $$       \____  $$  | $$ /$$| $$_____/  \  $$$/ | $$_____/ \____  $$
//|  $$$$$$/ |  $$$$/|  $$$$$$$   \  $/  |  $$$$$$$| $$       /$$$$$$$/  |  $$$$/|  $$$$$$$   \  $/  |  $$$$$$$ /$$$$$$$/
// \______/   \___/   \_______/    \_/    \_______/|__/      |_______/    \___/   \_______/    \_/    \_______/|_______/ 

//       ___________________
//      /                   \
//     /  _____        _____ \
//    /  /     \      /     \  \
// __/__/       \____/       \__\_____
//|           ___________           ____|
// \_________/           \_________/
//            \  /////// /
//             \/////////
// © Steversteves

//@version=5
indicator("Autoregressive Cloud", overlay=true)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            User Inputs                                                                              ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

smalen = input.int(3, "SMA Length", tooltip = "Smoothes the Autoregression Range. Reccomended value 3.") 
timeframe = input.timeframe("", "Timeframe Period", tooltip = "Sets the trading range for the desired timeframe.") 
len = input.int(50, "Lookback Length", tooltip = "Lookback length for the autoregressive function.")  
transp = input.int(85, "Transparency", tooltip = "Sets the transparency of the clouds.") 
showtable = input.bool(true, "Show Correlation Table", tooltip = "Show the Correlation Results Table.") 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            Arrays                                                                                   ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

cl_reg_array = array.new_float() 
cl_sq_array = array.new_float() 
cl_lag_array = array.new_float() 
cl_lag_sq_array = array.new_float() 
cl_cl_array = array.new_float() 

hi_reg_array = array.new_float() 
hi_sq_array = array.new_float() 
hi_lag_array = array.new_float() 
hi_lag_sq_array = array.new_float() 
hi_hi_array = array.new_float() 

lo_reg_array = array.new_float() 
lo_sq_array = array.new_float() 
lo_lag_array = array.new_float() 
lo_lag_sq_array = array.new_float() 
lo_lo_array = array.new_float() 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            Security Requests                                                                         ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

cl = request.security(syminfo.ticker, timeframe, close, lookahead=barmerge.lookahead_on)
cl_lag = request.security(syminfo.ticker, timeframe, close[1], lookahead=barmerge.lookahead_on) 
hi = request.security(syminfo.ticker, timeframe, high, lookahead=barmerge.lookahead_on) 
hi_lag = request.security(syminfo.ticker, timeframe, high[1], lookahead=barmerge.lookahead_on) 
lo = request.security(syminfo.ticker, timeframe, low, lookahead=barmerge.lookahead_on) 
lo_lag = request.security(syminfo.ticker, timeframe, low[1], lookahead=barmerge.lookahead_on) 
op = request.security(syminfo.ticker, timeframe, open, lookahead=barmerge.lookahead_on) 


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            Loop security prices                                                                     ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
for i = 0 to len 
    array.push(cl_reg_array, cl[i])
    array.push(cl_sq_array, cl[i] * cl[i]) 
    array.push(cl_lag_array, cl_lag[i])
    array.push(cl_lag_sq_array, cl_lag[i] * cl_lag[i])
    array.push(cl_cl_array, cl[i] * cl_lag[i])  
    array.push(hi_reg_array, hi[i])
    array.push(hi_sq_array, hi[i] * hi[i]) 
    array.push(hi_lag_array, hi_lag[i])
    array.push(hi_lag_sq_array, hi_lag[i] * hi_lag[i])
    array.push(hi_hi_array, hi[i] * hi_lag[i])  
    array.push(lo_reg_array, lo[i])
    array.push(lo_sq_array, lo[i] * lo[i]) 
    array.push(lo_lag_array, lo_lag[i])
    array.push(lo_lag_sq_array, lo_lag[i] * lo_lag[i])
    array.push(lo_lo_array, lo[i] * lo_lag[i])  


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            Colours                                                                                  ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// White Base Scheme
whiteBaseColor1 = color.new(color.rgb(51 * 1.5, 255 * 0.6, 255 * 0.6), transp)
whiteBaseColor2 = color.new(color.rgb(51 * 1.8, 255 * 0.8, 255 * 0.8), transp) 
whiteBaseColor3 = color.new(color.rgb(51 * 2, 255 * 1, 255 * 1), transp) 

// Teal Base Scheme
tealBaseColor1 = color.new(color.rgb(51 * 2.2, 255 * 1.2, 255 * 1.2), transp) 
tealBaseColor2 = color.new(color.rgb(51 * 2.4, 255 * 1.4, 255 * 1.4), transp) 
tealBaseColor3 = color.new(color.rgb(51 * 2.6, 255 * 1.6, 255 * 1.6), transp) 

// Dark Navy Base Scheme
darkNavyBaseColor1 = color.new(color.rgb(51 * 2.8, 255 * 1.8, 255 * 1.8), transp) 
darkNavyBaseColor2 = color.new(color.rgb(51 * 3, 255 * 2, 255 * 2), transp)
darkNavyBaseColor3 = color.new(color.rgb(51 * 3.2, 255 * 2.2, 255 * 2.25), transp)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            Define Regression Variables                                                              ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var float y = 0.0 // intercept 
var float y2 = 0.0 
var float x = 0.0 // autoregressive dependent 
var float x2 = 0.0 
var float xy = 0.0 
var float b1 = 0.0 
var float bbb2 = 0.0 
var float abc = 0.0 
var float abc1 = 0.0 
var float se_add = 0.0 
var float r1 = 0.0 
var float r2 = 0.0 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            Autoregressive Functions                                                                ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Autoregresion for Close
y := array.sum(cl_reg_array)
y2 := array.sum(cl_sq_array) 

x := array.sum(cl_lag_array) 
x2 := array.sum(cl_lag_sq_array) 

xy := array.sum(cl_cl_array) 

b1 := xy - (x * y) / len 
bbb2 := x2 - (math.pow(x, 2) / len) 

cl_slope = (b1 / bbb2)

abc := y - (cl_slope * x) 
abc1 := abc / len 

pcl = (cl_lag * cl_slope) + abc1 

se_residuals = array.new_float() 

for i = 0 to len 
    array.push(se_residuals, (pcl[i] - cl[i]) * (pcl[i] - cl[i])) 

se_add := array.sum(se_residuals) 

r1 := se_add / (len - 2) 
r2 := math.sqrt(r1) 

a = plot(ta.sma(pcl, smalen), color=whiteBaseColor1) 
b = plot(ta.sma(pcl + r2, smalen), color=whiteBaseColor2) 
c = plot(ta.sma(pcl - r2, smalen), color=whiteBaseColor3) 
fill(a, b, color=whiteBaseColor1)
fill(a, c, color=whiteBaseColor3)

// Correlation for Close 
cl_cov = array.covariance(cl_reg_array, cl_lag_array)
cl_sd = array.stdev(cl_reg_array) 
cl_lag_sd = array.stdev(cl_lag_array)

cl_cor = cl_cov / (cl_sd * cl_lag_sd)

// Autoregresion for High

y := array.sum(hi_reg_array)
y2 := array.sum(hi_sq_array) 

x := array.sum(hi_lag_array) 
x2 := array.sum(hi_lag_sq_array) 

xy := array.sum(hi_hi_array) 

b1 := xy - (x * y) / len 
bbb2 := x2 - (math.pow(x, 2) / len) 

hi_slope = (b1 / bbb2)

abc := y - (hi_slope * x) 
abc1 := abc / len 

phi = (hi_lag * hi_slope) + abc1 

se_residuals_high = array.new_float() 

for i = 0 to len 
    array.push(se_residuals_high, (phi[i] - hi[i]) * (phi[i] - hi[i])) 

se_add_high = array.sum(se_residuals_high) 

r1 := se_add_high / (len - 2) 
r2 := math.sqrt(r1) 

aa = plot(ta.sma(phi, smalen), color=tealBaseColor1) 
bb = plot(ta.sma(phi + r2, smalen), color=tealBaseColor2) 
cc = plot(ta.sma(phi - r2, smalen), color=tealBaseColor3) 
fill(aa, bb, color=tealBaseColor1)
fill(aa, cc, color=tealBaseColor3)

// Correlation for High 
hi_cov = array.covariance(hi_reg_array, hi_lag_array)
hi_sd = array.stdev(hi_reg_array)
hi_lag_sd = array.stdev(hi_lag_array)

hi_cor = hi_cov / (hi_sd * hi_lag_sd) 

// Autoregresion for Low

y := array.sum(lo_reg_array)
y2 := array.sum(lo_sq_array) 

x := array.sum(lo_lag_array) 
x2 := array.sum(lo_lag_sq_array) 

xy := array.sum(lo_lo_array) 

b1 := xy - (x * y) / len 
bbb2 := x2 - (math.pow(x, 2) / len) 

lo_slope = (b1 / bbb2)

abc := y - (lo_slope * x) 
abc1 := abc / len 

plo = (lo_lag * lo_slope) + abc1 

se_residuals_low = array.new_float() 

for i = 0 to len 
    array.push(se_residuals_low, (plo[i] - lo[i]) * (plo[i] - lo[i])) 

se_add := array.sum(se_residuals_low) 

r1 := se_add / (len - 2) 
r2 := math.sqrt(r1) 

aaa = plot(ta.sma(plo, smalen), color=darkNavyBaseColor1) 
bbb = plot(ta.sma(plo + r2, smalen), color=darkNavyBaseColor2) 
ccc = plot(ta.sma(plo - r2, smalen), color=darkNavyBaseColor3) 

fill(aaa, bbb, color=darkNavyBaseColor1)
fill(aaa, ccc, color=darkNavyBaseColor3)

lo_cov = array.covariance(lo_reg_array, lo_lag_array)
lo_sd = array.stdev(lo_reg_array)
lo_lag_sd = array.stdev(lo_lag_array)

lo_cor = lo_cov / (lo_sd * lo_lag_sd)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                                                            Data Table                                                                               ///
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

tablePosInput = input.string(title="Position", defval="Top Right", options=["Bottom Left", "Bottom Right", "Top Left", "Top Right"], tooltip="Select where you want the table to draw.")

var tablePos  = tablePosInput == "Bottom Left" ? position.bottom_left : tablePosInput == "Bottom Right" ? position.bottom_right : tablePosInput == "Top Left" ? position.top_left : tablePosInput == "Top Right" ? position.top_right : na

var cor_table = table.new(tablePos, columns = 3, rows = 5, border_color = whiteBaseColor1, border_width = 2)

if showtable
    table.cell(cor_table, 1, 1, text = "Correlation table", bgcolor = whiteBaseColor1, text_color = color.white)
    table.cell(cor_table, 1, 2, text = "Close Lag Correlation: " + str.tostring(math.round(cl_cor, 2)), bgcolor = whiteBaseColor1, text_color = color.white)
    table.cell(cor_table, 1, 3, text = "High Lag Correlation: " + str.tostring(math.round(hi_cor, 2)), bgcolor = whiteBaseColor2, text_color = color.white)
    table.cell(cor_table, 1, 4, text = "Low Lag Correlation: " + str.tostring(math.round(lo_cor, 2)), bgcolor = whiteBaseColor3, text_color = color.white)