Search code examples
linear-regressionpine-scriptpearson-correlation

Calculate Pearson's R for Linear Regression PineScript


I have a pinescript strategy below in which I am trying to calculate the Pearsons R correlation value. I got the code from here and modified it a bit (https://www.tradingview.com/script/CD7yUWRV-Linear-Regression-Trend-Channel/).

His code does not include the Pearson's R correlation which is very important to the trading strategy I'm trying to use since it indicates the strength of the trend and it's direction (up or down). To see a working examle of the Pearson's R, add the default indicator linear regression and it will be the number to the bottom left. I'll attach a screenshot for an example.

enter image description here

How do I calculate the Pearson's R Value from the code I have so far?

I have looked for sample pine scripts that have the Pearson's R calculation for linear regression in pinescript and could not find anything.

strategy(title="Linear Regression Trend Channel Strategy", overlay=true,initial_capital=1000,commission_type=strategy.commission.percent,commission_value=0.26,default_qty_type=strategy.percent_of_equity,default_qty_value=100)
period     = input(     240, "Period"       , input.integer, minval=3)//288
deviations = input(    2.0, "Deviation(s)" , input.float  , minval=0.1, step=0.1)
extendType = input("Right", "Extend Method", input.string , options=["Right","None"])=="Right" ? extend.right : extend.none
periodMinusOne = period-1
Ex = 0.0, Ey = 0.0, Ex2 = 0.0, Exy = 0.0, for i=0 to periodMinusOne
    closeI = nz(close[i]), Ex := Ex + i, Ey := Ey + closeI, Ex2 := Ex2 + (i * i), Exy := Exy + (closeI * i)
ExEx = Ex * Ex, slope = Ex2==ExEx ? 0.0 : (period * Exy - Ex * Ey) / (period * Ex2 - ExEx)
linearRegression = (Ey - slope * Ex) / period
intercept = linearRegression + bar_index * slope
deviation = 0.0, for i=0 to periodMinusOne
    deviation := deviation + pow(nz(close[i]) - (intercept - slope * (bar_index[i])), 2.0)
deviation := deviations * sqrt(deviation / periodMinusOne)
startingPointY = linearRegression + slope * periodMinusOne
var line upperChannelLine = na  , var line medianChannelLine = na  , var line lowerChannelLine = na
line.delete(upperChannelLine[1]), line.delete(medianChannelLine[1]), line.delete(lowerChannelLine[1])
upperChannelLine  := line.new(bar_index - period + 1, startingPointY + deviation, bar_index, linearRegression + deviation, xloc.bar_index, extendType, color.new(#FF0000, 0), line.style_solid , 2)
medianChannelLine := line.new(bar_index - period + 1, startingPointY            , bar_index, linearRegression            , xloc.bar_index, extendType, color.new(#C0C000, 0), line.style_solid , 1)
lowerChannelLine  := line.new(bar_index - period + 1, startingPointY - deviation, bar_index, linearRegression - deviation, xloc.bar_index, extendType, color.new(#00FF00, 0), line.style_solid , 2)

if(crossunder(close,line.get_y2(lowerChannelLine)))
    strategy.entry("Long", strategy.long)

if(crossover(close,line.get_y2(upperChannelLine)))
    strategy.entry("Short", strategy.short)

Solution

  • // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
    // © x11joe
    // Credit given to @midtownsk8rguy for original source code.  I simply modified to add Pearson's R
    
    //@version=4
    study("Linear Regression Trend Channel With Pearson's R", "LRTCWPR", true, format.inherit)
    period     = input(     20, "Period"       , input.integer, minval=3)
    deviations = input(    2.0, "Deviation(s)" , input.float  , minval=0.1, step=0.1)
    extendType = input("Right", "Extend Method", input.string , options=["Right","None"])=="Right" ? extend.right : extend.none
    periodMinusOne = period-1
    Ex = 0.0, Ey = 0.0, Ex2 = 0.0,Ey2 =0.0, Exy = 0.0, for i=0 to periodMinusOne
        closeI = nz(close[i]), Ex := Ex + i, Ey := Ey + closeI, Ex2 := Ex2 + (i * i),Ey2 := Ey2 + (closeI * closeI), Exy := Exy + (closeI * i)
    ExT2 = pow(Ex,2.0) //Sum of X THEN Squared
    EyT2 = pow(Ey,2.0) //Sym of Y THEN Squared
    PearsonsR = (Exy - ((Ex*Ey)/period))/(sqrt(Ex2-(ExT2/period))*sqrt(Ey2-(EyT2/period)))
    ExEx = Ex * Ex, slope = Ex2==ExEx ? 0.0 : (period * Exy - Ex * Ey) / (period * Ex2 - ExEx)
    linearRegression = (Ey - slope * Ex) / period
    intercept = linearRegression + bar_index * slope
    deviation = 0.0, for i=0 to periodMinusOne
        deviation := deviation + pow(nz(close[i]) - (intercept - slope * (bar_index[i])), 2.0)
    deviation := deviations * sqrt(deviation / periodMinusOne)
    startingPointY = linearRegression + slope * periodMinusOne
    var label pearsonsRLabel = na
    label.delete(pearsonsRLabel[1])
    pearsonsRLabel := label.new(bar_index,startingPointY - deviation*2,text=tostring(PearsonsR), color=color.black,style=label.style_labeldown,textcolor=color.white,size=size.large)
    var line upperChannelLine = na  , var line medianChannelLine = na  , var line lowerChannelLine = na
    line.delete(upperChannelLine[1]), line.delete(medianChannelLine[1]), line.delete(lowerChannelLine[1])
    upperChannelLine  := line.new(bar_index - period + 1, startingPointY + deviation, bar_index, linearRegression + deviation, xloc.bar_index, extendType, color.new(#FF0000, 0), line.style_solid , 2)
    medianChannelLine := line.new(bar_index - period + 1, startingPointY            , bar_index, linearRegression            , xloc.bar_index, extendType, color.new(#C0C000, 0), line.style_solid , 1)
    lowerChannelLine  := line.new(bar_index - period + 1, startingPointY - deviation, bar_index, linearRegression - deviation, xloc.bar_index, extendType, color.new(#00FF00, 0), line.style_solid , 2)
    

    Okay so I posted my solution below. I got the idea thanks to a youtube video here, https://www.youtube.com/watch?v=2B_UW-RweSE

    This really helped me figure out the formula. Hope this helps someone else on tradingView that needed this!

    enter image description here