/ This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // Credit given to @midtownsk8rguy for some original source code parts (I was given permission to do so). I simply modified to add Pearson's R and the ability to always draw lines matching a certain Pearson's R. // Credit also given to TradeBoneDogs for ideas for identifying and creating alerts for sideways, bull and bear markets. // © x11joe //@version=4 study("Linear Regression - Auto Adjust To Ideal Pearson's R (Min & Max)",overlay=true) deviations = input(    2.0, "Deviation(s)" , input.float  , minval=0.1, step=0.1) extendType = input("None", "Extend Method", input.string , options=["Right","None"])=="Right" ? extend.right : extend.none var int tempPeriod = na minPeriod = input(48,"Min Period",input.integer)//24 would be 48 hours (2 days) on the 2 hour. stepBy    = input(12,"Step By (Speeds Up Calculation, MUST be multiple of min and max)",input.integer) maxPeriod = input(360,"Max Period",input.integer)//168 would be 2 weeks or 14 days on the 2 hour. pearsonsIdealPositive = input(0.85,"Pearson's Ideal Value +",input.float) pearsonsIdealNegative = input(-0.85,"Pearson's Ideal Value -",input.float) pearsonsRBullish = input(-0.25," <= Short Pearson's R Bullish Zone",input.float) pearsonsRBearish = input(0.25," >= Short Pearson's R Bearish Zone",input.float) pearsonsRLongBullish = input(-0.25," <= Long Pearson's R Bullish Zone",input.float) pearsonsRLongBearish = input(0.25," >= Long Pearson's R Bearish Zone",input.float) showPearsonsRShortBox = input(true,"Show Pearsons R Short Info Box",input.bool) showPearsonsRLongBox = input(true,"Show Pearsons R Long Info Box",input.bool) showTrendShortBox = input(true,"Show Short Trend Info Box",input.bool) showTrendLongBox = input(true,"Show Long Trend Info Box",input.bool) //Sideways Trading would be anything that doesn't fit the above values. //Initially Define the variables var int periodMinusOne = na var float Ex = na var float Ey = na var float Ex2 = na var float Ey2 = na var float Exy = na var float ExT2 = na //Sum of X THEN Squared var float EyT2 = na //Sum of Y THEN Squared var float PearsonsR = na var float ExEx = na var float slope = na var float linearRegression = na var float intercept = na var float deviation = na var float startingPointY = na //Loop through the max period back to find situations in which the Pearson's is either -8.0 or 8.0 var int perfectPeriod = na var float maxPearsons = na var float maxStartingPointY = na var float maxLinearRegression = na var float maxDeviation = na for k=maxPeriod to minPeriod by stepBy     periodMinusOne := k-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)/k))/(sqrt(Ex2-(ExT2/k))*sqrt(Ey2-(EyT2/k)))     ExEx := Ex * Ex, slope = Ex2==ExEx ? 0.0 : (k * Exy - Ex * Ey) / (k * Ex2 - ExEx)     linearRegression := (Ey - slope * Ex) / k     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     perfectPeriod:=k     if(k==maxPeriod)         maxPearsons:=PearsonsR         maxStartingPointY:=startingPointY         maxLinearRegression:=linearRegression         maxDeviation := deviation     if(PearsonsR>=pearsonsIdealPositive or PearsonsR<=pearsonsIdealNegative)         break//exit the loop early and a line is chosen. var line upperChannelLine = na  , var line medianChannelLine = na  , var line lowerChannelLine = na, var line upperTradeLine = na, var line lowerTradeLine = na, var line maxTradeLine = na, var line maxUpperChannelLine = na, var line maxLowerChannelLine = na upperChannelLine  := line.new(bar_index - perfectPeriod + 1, startingPointY + deviation, bar_index, linearRegression + deviation, xloc.bar_index, extendType, color.new(#FF0000, 0), line.style_solid , 2) medianChannelLine := line.new(bar_index - perfectPeriod + 1, startingPointY            , bar_index, linearRegression            , xloc.bar_index, extendType, color.new(#C0C000, 0), line.style_solid , 1) lowerChannelLine  := line.new(bar_index - perfectPeriod + 1, startingPointY - deviation, bar_index, linearRegression - deviation, xloc.bar_index, extendType, color.new(#00FF00, 0), line.style_solid , 2) upperTradeLine    := line.new(bar_index - perfectPeriod + 1, startingPointY + (deviation*2), bar_index, linearRegression + (deviation*2), xloc.bar_index, extendType, color.new(#FF0000, 0), line.style_dashed , 2) lowerTradeLine    := line.new(bar_index - perfectPeriod + 1, startingPointY - (deviation*2), bar_index, linearRegression - (deviation*2), xloc.bar_index, extendType, color.new(#00FF00, 0), line.style_dashed , 2) maxTradeLine         := line.new(bar_index - maxPeriod + 1, maxStartingPointY , bar_index, maxLinearRegression , xloc.bar_index, extendType, color.new(#C0C000, 50), line.style_dotted , 2) maxUpperChannelLine  := line.new(bar_index - maxPeriod + 1, maxStartingPointY + maxDeviation, bar_index, maxLinearRegression + maxDeviation, xloc.bar_index, extendType, color.new(#FF0000, 50), line.style_dotted , 3) maxLowerChannelLine  := line.new(bar_index - maxPeriod + 1, maxStartingPointY - maxDeviation, bar_index, maxLinearRegression - maxDeviation, xloc.bar_index, extendType, color.new(#FF0000, 50), line.style_dotted , 3) alertcondition(crossover(close,line.get_y2(upperChannelLine)), title='Upper Boundry Crossed', message='The upper boundry has been crossed') alertcondition(crossunder(close,line.get_y2(lowerChannelLine)), title='Lower Boundry Crossed', message='The lower boundry has been crossed') alertcondition(crossover(close,line.get_y2(upperTradeLine)), title='Max Upper Boundry Crossed', message='The max upper boundry has been crossed') alertcondition(crossunder(close,line.get_y2(lowerTradeLine)), title='Max Lower Boundry Crossed', message='The max lower boundry has been crossed') // NOTE:: I tried calculating angles but that is not possible since price is in one direction and bars the other, not to mention the angle changes with zoom levels! var bool bullTrend = na var bool bearTrend = na var bool sidewaysTrend = na var bool longBullTrend = na var bool longBearTrend = na var bool longSidewaysTrend = na //By default assume it's sideways bullTrend := false bearTrend := false sidewaysTrend := true if(PearsonsR>=pearsonsRBearish)     bullTrend := false     bearTrend := true     sidewaysTrend := false if(PearsonsR<=pearsonsRBullish)     bullTrend := true     bearTrend := false     sidewaysTrend := false     // ----- longBullTrend := false longBearTrend := false longSidewaysTrend := false if(maxPearsons>=pearsonsRLongBearish)     longBullTrend := false     longBearTrend := true     longSidewaysTrend := false if(maxPearsons<=pearsonsRLongBullish)     longBullTrend := true     longBearTrend := false     longSidewaysTrend := false alertcondition((bullTrend==true and bullTrend[1]==false), title='Short Bull Trend Detected', message='A bullish short term trend has started') alertcondition((bearTrend==true and bearTrend[1]==false), title='Short Bear Trend Detected', message='A bearish short term trend has started') alertcondition((bearTrend==false and bullTrend==false and (bullTrend[1]==true or bearTrend[1]==true)), title='Short Sideways Trend Detected', message='A sideways short term trend has started') alertcondition((longBullTrend==true and longBullTrend[1]==false), title='Long Bull Trend Detected', message='A bullish long term trend has started') alertcondition((longBearTrend==true and longBearTrend[1]==false), title='Long Bear Trend Detected', message='A bearish long term trend has started') alertcondition((longBearTrend==false and longBullTrend==false and (longBullTrend[1]==true or longBearTrend[1]==true)), title='Long Sideways Trend Detected', message='A sideways long term trend has started') //This Drawing function was originally designed by RicardoSantos.  Me, @x11joe have edited his original code to fit my needs, but wanted to give this developer credit for his initial help! f_draw_infopanel(_x, _y, _color, _line, _text)=>     _rep_text = ""     for _l = 0 to _line         _rep_text := _rep_text + "\n"     _rep_text := _rep_text + _text     var label _la = na     label.delete(_la)     _la := label.new(x=_x, y=_y, text=_rep_text, xloc=xloc.bar_index, yloc=yloc.price,      color=#222222, style=label.style_labelup, textcolor=_color, size=size.large) var int lapos_x = na var float lapos_y = na lapos_x := bar_index lapos_y := lowest(close, 50) var int yPos = 0 yPos := -2 //reset it everytime //Calculate max height of info box first based on options selected if(showTrendLongBox)     yPos := yPos + 2 if(showTrendShortBox)     yPos := yPos + 2 if(showPearsonsRShortBox)     yPos := yPos + 2 if(showPearsonsRLongBox)     yPos := yPos + 2 if(showTrendLongBox)     f_draw_infopanel(lapos_x, lapos_y, color.new(color.purple, 20),   yPos, "Current Long Trend: "+ (longBullTrend ? "Bull" : longBearTrend ? "Bear" : "Sideways"))     yPos := yPos - 2 if(showTrendShortBox)     f_draw_infopanel(lapos_x, lapos_y, color.new(color.blue, 20),   yPos, "Current Short Trend: "+ (bullTrend ? "Bull" : bearTrend ? "Bear" : "Sideways"))     yPos := yPos - 2 if(showPearsonsRShortBox)     f_draw_infopanel(lapos_x, lapos_y, color.new(color.lime, 20),   yPos, "R=("+tostring(PearsonsR)+") , Period=("+tostring(perfectPeriod)+") - Short Trend")     yPos := yPos - 2 if(showPearsonsRLongBox)     f_draw_infopanel(lapos_x, lapos_y, color.new(color.red, 20),   yPos, "R=("+tostring(maxPearsons)+") , Period=("+tostring(maxPeriod)+") - Long Trend")     yPos := yPos - 2 //Clear the old lines line.delete(upperChannelLine[1]), line.delete(medianChannelLine[1]), line.delete(lowerChannelLine[1]), line.delete(upperTradeLine[1]), line.delete(lowerTradeLine[1]), line.delete(maxTradeLine[1]),line.delete(maxUpperChannelLine[1]),line.delete(maxLowerChannelLine[1])