L_Beta
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © fourkhansolo

//@version=5

// @description TODO: add library description here
library("L_Beta")//, overlay=true)

// ****************************************  Importing Modules ****************************************
import fourkhansolo/L_Index_4khansolo/2 as index


// ****************************************  Beta Score More Systematic ****************************************
//x = close
//y = close
//std_of_x = ta.stdev(x, length)
//std_of_y = ta.stdev(y, length)
//correlation_of_x_and_y=ta.correlation(x,y,length)
//beta = (std_of_x*std_of_y)/correlation_of_x_and_y
//plot(beta)
// ****************************************  Beta Score More Systematic ****************************************
export beta_length(string resolution,int multiplier)=>
    // Use this instead for simplicity sake
    //beta_length = beta_length(period,multiplier); monthly set for period and multipier set to Monthly
    
    
    // This works as per year
    conversion = if resolution == "D"
        251//365//252 days in a year (open days)
    else if resolution == "W"
        52 // 52 weeks in a year
    else if resolution == "M"
        12 //12 months in a year
    else if resolution == "3M"
        4 // 3Months (4x) in a year
    else if resolution == "12M"
        1 // 1 year
    beta_length = conversion * multiplier
    // TO invole
    // anualized_period = length(intervals,multiplier)


// ****************************************  Beta Score More Systematic ****************************************

export beta_less_intuitive(series float price_x, series float price_y, series int length)=>
    // Beta implies slope {rise over run}
    // Berk, J. B., T., H. J. V., DeMarzo, P. M., Stangeland, D., &amp; Marosi András. (2020). Fundamentals of Corporate Finance. Pearson. 
    // (Berk et al., p. 406)
    // Beta. Wikipedia. Accessed on Aug 27, 2022. https://en.wikipedia.org/wiki/Beta_(finance)
    mean_x = ta.sma(price_x, length) // Intended for stock_returns
    mean_y = ta.sma(price_y, length) // Intended for index_returns
    //closer1=x+y*length
    mean_xy = 0.0
    mean_xx = 0.0
    mean_yy = 0.0
    for i=0 to length -1
        mean_xy := mean_xy+price_x[i]*price_y[i]
    mean_xy := mean_xy/length
    covariance_xy = mean_xy - (mean_x*mean_y)
    //[mean_x,mean_y,mean_xy, covariance_xy]
    // Variance for X and Y 
    for j=0 to length -1
        mean_xx := mean_xx+price_x[j]*price_x[j]
        mean_yy := mean_yy+price_y[j]*price_y[j]
    mean_xx:=mean_xx/length
    mean_yy:=mean_yy/length
    //[mean_xx,mean_yy,mean_xy,covariance_xy]
    // variances for X and y
    variance_for_x=mean_xx-(mean_x*mean_x)
    variance_for_y=mean_yy-(mean_y*mean_y)
    //[variance_for_x,variance_for_y,mean_xy,covariance_xy]
    // correlation score
    correlation=covariance_xy/math.sqrt(variance_for_x*variance_for_y)
    betaScore=covariance_xy/variance_for_y
    [variance_for_x,variance_for_y,mean_xy,correlation,betaScore]    


export beta(series float stock_returns, series float index_returns,int length)=>
    // To Replicate the beta values from other sources (like Yahoo Finace)...
    // ... The Parameter from the top must be selected to "M", and "M" on the indicator then 5 Years on the indicator
    // Berk, J. B., T., H. J. V., DeMarzo, P. M., Stangeland, D., &amp; Marosi András. (2020). Fundamentals of Corporate Finance. Pearson. 
    // (Berk et al., p. 406)
    correlation = ta.correlation(stock_returns, index_returns, length)
    return_index_std = ta.stdev(index_returns, length)
    return_stock_std = ta.stdev(stock_returns, length)
    beta_returns = return_stock_std* correlation/return_index_std

// ****************************************  Auto select if selected ****************************************
export index_auto_select(simple string index_select)=>
    index_selected = if index_select == "Auto"
        index.indexName()//indexName=
    else
        index_select
// ****************************************  Auto select TIMEFRAME ****************************************
export timeframe_auto_select(simple string intervals)=>
    // interval = input.session("Auto", "Day | Week | Month | Quarter | Year", options=["Auto","D", "W", "M","3M","12M"])
    result = if intervals == "Auto"
        timeframe.period
    else
        intervals
    // To invoke the function
    // intervals = timeframe_auto_select(interval)        
// ****************************************  Time-frame based checker ****************************************
export return_checker (string test)=>
    // Source:
    // Comparing timeframes. Trading View. Accessed on Aug 29, 2022. https://www.tradingview.com/pine-script-docs/en/v5/concepts/Timeframes.html#timeframe-string-specifications
    // This function prevents the codes in the comments below
    // you can also highlight by the way
    // oneYearInterval = timeframe.change("12M") // goes back 1year
    // oneQuarterInterval = timeframe.change("3M") // goes back 3 Months
    // oneMonthInterval = timeframe.change("1M") // goes back 1Month
    // oneWeekInterval = timeframe.change("1W") // goes back 1Month
    // oneDayInterval = timeframe.change("1D") // goes back 1Month
    result = if test == "12M"
        oneYearInterval = timeframe.change("12M")       // goes back 1year
    else if test == "3M"
        oneQuarterInterval = timeframe.change("3M")     // goes back 3 Months
    else if test == "M"
        oneMonthInterval = timeframe.change("1M")       // goes back 1Month
    else if test == "W"
        oneWeekInterval = timeframe.change("1W")        // goes back 1Month
    else if test == "D"
        oneDayInterval = timeframe.change("1D")         // goes back 1Month
    output = result

// ****************************************  Returns Calculation ****************************************
export returns(series float stock_price, series float index_price)=>
    // Pre-requisites 
    // 1) Index Price (request.security(index_name, period, close, lookahead=barmerge.lookahead_on))
    // 2) Stock Price (request.security(stock_name, period, close, lookahead=barmerge.lookahead_on))
    
    // This function will handout two variables with prices attached to them
    // The return values are calculated below
    stock_returns = (stock_price-stock_price[1])/stock_price[1] // ((Today Price)-(Yesterday Price))/-(Yesterday Price)
    index_returns = (index_price-index_price[1])/index_price[1]  // ((Today Price)-(Yesterday Price))/-(Yesterday Price)
    stock_returns_percentage = stock_returns * 100 // Converting to Percentages
    index_returns_percentage = index_returns * 100 // Converting to Percentages
    [stock_returns, index_returns, stock_returns_percentage, index_returns_percentage]
    // the following to invoke
    // [stock_returns,index_returns]=returns(stock_price,index_price)
    
// ****************************************  Real Work ****************************************
interval = input.session("Auto", "Intervals: Day Week Month", options=["Auto","D", "W", "M","3M","12M"])
intervals = timeframe_auto_select(interval)     
multiplier = input.int(5, title="Year Multiplier (For how Long?)", options=[1,2,3,4,5,10,15,20])
length = beta_length(intervals,multiplier)

stock_name = syminfo.tickerid
simple_stock_close = request.security(stock_name,"D",close)
current_stock_price=request.security(stock_name,intervals,simple_stock_close)
index_select = input.session("Auto", "Pick Your Index", options=["Auto","TSX", "SPX", "IXIC","W4500","Gold","Silver"])
index_name = index_auto_select(index_select)
simple_index_close = request.security(index_name,intervals,close, currency=syminfo.currency)
current_index_price = request.security(index_name,intervals,simple_index_close, currency=syminfo.currency)
//plot(current_index_price)//
// ****************************************  Frequency Check ****************************************
frequency_checker = return_checker(intervals)
bgcolor(frequency_checker ? color.new(color.blue,70) : na)



// ****************************************  Real Work ****************************************
[stock_returns, index_returns, stock_returns_percentage, index_returns_percentage]=returns(current_stock_price,current_index_price)
x = stock_returns_percentage
y = index_returns_percentage


correlations = ta.correlation(x,y,length)
[variance_for_x,variance_for_y,mean_xy,correlation,betaScore]=beta_less_intuitive(x,y,length) 
plot(betaScore,color=color.teal)

beta = ta.stdev(x,length)*correlations/ta.stdev(y,length)
plot(beta, "Manually Derived Beta",  color=color.red)

beta_beta=beta(stock_returns,index_returns,length)
plot(beta_beta,"Formula_Based_Function", color=color.yellow)
// The scores are the same compared to yahoo finance or investing.com. With "M" selected for parameter, and 5Y period.
// AAPL. Yahoo Finance. Accessed as of Aug 31, 2022. https://finance.yahoo.com/quote/AAPL?p=AAPL&.tsrc=fin-srch
// AAPL. Investing.com. Accessed as of Aug 31, 2022. https://ca.investing.com/equities/apple-computer-inc

export positron(series float number)=>
// This will basically change color based on positivity :)
// This is also available under the index library
    if number >= 0
        color.new(color.green,1)
    else
        color.new(color.red,1)
// ****************************************  Table ****************************************

tableNotification = table.new(position = position.middle_right, rows = 6, columns = 2, bgcolor = color.new(color.yellow,70), border_width=0)
table.cell(tableNotification, row = 0, column = 0, text = "Legend", text_color = color.yellow)
table.cell(tableNotification, row = 0, column = 1, text = "", text_color = color.yellow)
table.cell_set_tooltip(tableNotification, row = 0, column = 0, tooltip = "Legend")
//Source: https://www.tradingview.com/pine-script-reference/v5/#fun_str{dot}tonumber

// Beta
beta_string =str.tostring(math.round(beta_beta,2))
table.cell(tableNotification, row = 1, column = 0, text = "Beta", text_color = color.white, bgcolor=color.new(color.black,50))               
table.cell(tableNotification, row = 1, column = 1, text = beta_string, text_color = color.white, bgcolor=color.new(color.black,50))                    // Adding the datum into the table

// Correlations
correlations_string =str.tostring(math.round(correlations,2))
table.cell(tableNotification, row = 2, column = 0, text = "Correlations", text_color = color.white)               
table.cell(tableNotification, row = 2, column = 1, text = correlations_string, text_color = color.white)                    // Adding the datum into the table

// Correlations
year_string =str.tostring(math.round(multiplier,2))
table.cell(tableNotification, row = 3, column = 0, text = "For This Year Long (Y) ", text_color = color.white, bgcolor=color.new(color.black,50))               
table.cell(tableNotification, row = 3, column = 1, text = year_string, text_color = color.white, bgcolor=color.new(color.black,50))                    // Adding the datum into the table

// Length
length_string =str.tostring(math.round(length,2))
table.cell(tableNotification, row = 4, column = 0, text = "Frequency: " +intervals, text_color = color.white)               
table.cell(tableNotification, row = 4, column = 1, text = length_string, text_color = color.white)                    // Adding the datum into the table
table.cell_set_tooltip(tableNotification, row = 4, column = 0, tooltip = "Day = 251, W = 52, M = 12, 12M, = 1Year")
table.cell_set_tooltip(tableNotification, row = 4, column = 1, tooltip = "Day = 251, W = 52, M = 12, 12M, = 1Year")

// Index
index_string =str.tostring(math.round(current_index_price,2))
table.cell(tableNotification, row = 5, column = 0, text = index_name +" , "+ syminfo.currency, text_color = color.white, bgcolor=color.new(color.black,50))               
table.cell(tableNotification, row = 5, column = 1, text = index_string, text_color = color.white, bgcolor=color.new(color.black,50))                    // Adding the datum into the table
