Correlation Coefficient: Visible Range Dynamic Average R 
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//Correlation Coefficient with Dynamic Average R (shows R average for the visible chart only, changes as you zoom in or out)
//the Correlation Coefficient function for Pearson's R is taken directly from "BA🐷 CC" indicator by @balipour
//wrote this primarily to get a dynamic measure of Bond vs Stock (ZB1! vs ES1!) correlation for arbitrary start times; whether it be the last month, last year, last 5yrs etc

// © twingall

//@version=5
indicator("Correlation Coefficient Visible Average", 'CC Visible Avg', overlay =false, precision =2, max_bars_back = 5000)

src = input(close, "source")
length = input(100, "R lookback length") // I prefer 100 for daily chart; 20 for weekly chart
userSymbol = input.symbol("DXY", "Asset to compare")
userSymbolClose =request.security(userSymbol, "", src)

backtestMode = input.bool(true, "Backtest mode: both RHS and LHS cut-off", tooltip = "default on: shows the Average R for whatever is visible on the chart only")

manual = input.bool(false, "manual input #bars back", group = "manual (NOT visible-chart/not dynamic)")
inputBarsBack = input.int(100, "bars back (for manual mode only)", group = "manual (NOT visible-chart/not dynamic)")
//--//
// Correlation Coefficent function :-borrowed directly from "BA🐷 CC", @balipour
cc(x, y, len) => 
    lenMinusOne = len - 1
    meanx = 0.0, meany = 0.0
    for i=0.0 to lenMinusOne
        meanx := meanx + nz(x[i])
        meany := meany + nz(y[i])
    meanx := meanx / len
    meany := meany / len
    sumxy=0.0, sumx=0.0, sumy=0.0
    for i=0  to lenMinusOne
        sumxy := sumxy +    (nz(x[i]) - meanx) * (nz(y[i]) - meany)
        sumx  := sumx  + math.pow(nz(x[i]) - meanx, 2)
        sumy  := sumy  + math.pow(nz(y[i]) - meany, 2)
    sumxy / math.sqrt(sumy * sumx)
//--//

//plotting
R = cc(src, userSymbolClose, length) 
manualCond =bar_index> last_bar_index - inputBarsBack
plot(manual?(manualCond?R:na):R, title = "correlation coefficient")
hline(1.0, color= color.black)
hline(0.0, color= color.red)
hline(-1.0, color= color.black)

// ~~ dynamic average R ~~

VisibleBars = ta.barssince(time == chart.left_visible_bar_time)
AvCC(_R, _visBars)=>
    meancc =0.0
    for i=1.0 to (_visBars)
        meancc:=meancc +nz(_R[i])
    meancc:= meancc/_visBars

    // backtest version of this function (RHS cutoff as well as the default LHS cutoff)

_startVis = ta.barssince(time == chart.left_visible_bar_time)
_endVis = nz(ta.barssince(time == chart.right_visible_bar_time)) //add nz() function to fix error where NaN returns when white-space to RHS of last bar
startVis= manual?inputBarsBack:_startVis
endVis=manual?0:_endVis
VisibleBars_backtest = startVis-endVis
AvCC_backtest(_R, _rhs, _lhs, _visBars)=>
    meancc =0.0
    for i=_rhs to _lhs
        meancc:=meancc +nz(_R[i])
    meancc:= meancc/_visBars


_avg = AvCC(R,VisibleBars)
_avg_backtest = AvCC_backtest(R,endVis,startVis,VisibleBars_backtest)
backtestLabelPos =chart.left_visible_bar_time+ ((chart.right_visible_bar_time -chart.left_visible_bar_time)/2)
pos = str.pos(userSymbol, ":")  //get only the ticker part out of the string 
tkr= str.substring(userSymbol, pos+1) //get only the ticker part out of the string 
if barstate.islastconfirmedhistory and backtestMode and not manual
    label.new(backtestLabelPos, 1.2, text=tkr +"  Vis-Avg-R =  "+ str.tostring(_avg_backtest, '0.00'), color=color.new(color.white, 80), textcolor=color.red, size=size.large, style=label.style_label_left, xloc=xloc.bar_time, textalign=text.align_right)
if barstate.islastconfirmedhistory and not backtestMode and not manual
    label.new(bar_index, 1.2, text=tkr+ "  Vis-Avg-R =  "+ str.tostring(_avg, '0.00'), color=color.new(color.white, 100), textcolor=color.red, size=size.large, style=label.style_label_right, xloc=xloc.bar_index, textalign=text.align_right)
if barstate.islastconfirmedhistory and manual
    label.new(bar_index, 1.2, text=tkr +"  Vis-Avg-R =  "+ str.tostring(_avg_backtest, '0.00'), color=color.new(color.white, 80), textcolor=color.red, size=size.large, style=label.style_label_right, xloc=xloc.bar_index, textalign=text.align_right)