Advertisement
xmd79

Linear Regression Channel

Jan 23rd, 2024
261
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.57 KB | None | 1 0
  1. //@version=5
  2. indicator("Linear Regression Channel", shorttitle="LinReg", overlay=true,max_bars_back=1000,max_lines_count = 500)
  3.  
  4. lengthInput = input.int(200, title="Length", minval = 1, maxval = 5000)
  5. sourceInput = input.source(close, title="Source")
  6.  
  7. group1 = "Channel Settings"
  8. useUpperDevInput = input.bool(true, title="Upper Deviation", inline = "Upper Deviation", group = group1)
  9. upperMultInput = input.float(2.0, title="", inline = "Upper Deviation", group = group1)
  10. useLowerDevInput = input.bool(true, title="Lower Deviation", inline = "Lower Deviation", group = group1)
  11. lowerMultInput = input.float(2.0, title="", inline = "Lower Deviation", group = group1)
  12.  
  13. group2 = "Display Settings"
  14. extendLeftInput = input.bool(false, "Extend Lines Left", group = group2)
  15. extendRightInput = input.bool(true, "Extend Lines Right", group = group2)
  16. extendStyle = switch
  17. extendLeftInput and extendRightInput => extend.both
  18. extendLeftInput => extend.left
  19. extendRightInput => extend.right
  20. => extend.none
  21.  
  22. // group3 = "Color Settings"
  23. // colorUpper = input.color(color.new(color.blue, 85), "", inline = group3, group = group3)
  24. // colorLower = input.color(color.new(color.red, 85), "", inline = group3, group = group3)
  25.  
  26. //*************[ Variables ]***************
  27. // lengthBank = math.round(lengthInput*0.05 + 0.5) // roundup 5% of length to represent Bank move direction
  28. // lengthBankMid = math.round(lengthBank/4 + 0.5) // mid term
  29. // lengthBankShort = math.round(lengthBankMid/4 + 0.5) // mid term
  30.  
  31. calcSlope(source, length) =>
  32. max_bars_back(source, 5000)
  33. // if not barstate.islast or length <= 1
  34. // [float(na), float(na), float(na)]
  35. // else
  36. sumX = 0.0
  37. sumY = 0.0
  38. sumXSqr = 0.0
  39. sumXY = 0.0
  40. for i = 0 to length - 1 by 1
  41. val = source[i]
  42. per = i + 1.0
  43. sumX += per
  44. sumY += val
  45. sumXSqr += per * per
  46. sumXY += val * per
  47. slope = (length * sumXY - sumX * sumY) / (length * sumXSqr - sumX * sumX)
  48. average = sumY / length
  49. intercept = average - slope * sumX / length + slope
  50. [slope, average, intercept]
  51.  
  52. //###################[ Long term Slope ]############################
  53. // [s, a, i] = calcSlope(sourceInput[lengthBank], lengthInput)
  54. [s, a, i] = calcSlope(sourceInput, lengthInput)
  55. startPrice = i + s * (lengthInput - 1)
  56. endPrice = i
  57. var line baseLine = na
  58. if na(baseLine) and not na(startPrice)
  59. baseLine := line.new(bar_index - lengthInput + 1, startPrice, bar_index, endPrice, width=1, extend=extendStyle, color=color.new(color.gray, 100))
  60. else
  61. line.set_xy1(baseLine, bar_index - lengthInput + 1, startPrice)
  62. line.set_xy2(baseLine, bar_index, endPrice)
  63. na
  64.  
  65. //###################[ Mid term Slope ]############################
  66. lengthInputMid = math.round(lengthInput/4 + 0.5)
  67. [sMid, aMid, iMid] = calcSlope(sourceInput, lengthInputMid)
  68. // [sMid, aMid, iMid] = calcSlope(sourceInput[lengthBankMid], lengthInputMid)
  69. startPriceMid = iMid + sMid * (lengthInputMid - 1)
  70. endPriceMid = iMid
  71. var line baseLineMid = na
  72. if na(baseLineMid) and not na(startPriceMid)
  73. baseLineMid := line.new(bar_index - lengthInputMid + 1, startPriceMid, bar_index, endPriceMid, width=1, extend=extendStyle, color=color.new(color.gray, 100))
  74. else
  75. line.set_xy1(baseLineMid, bar_index - lengthInputMid + 1, startPriceMid)
  76. line.set_xy2(baseLineMid, bar_index, endPriceMid)
  77. na
  78.  
  79. //###################[ Short term Slope ]############################
  80. lengthInputShort = math.round(lengthInputMid/4 + 0.5)
  81. [sShort, aShort, iShort] = calcSlope(sourceInput, lengthInputShort)
  82. // [sShort, aShort, iShort] = calcSlope(sourceInput[lengthBankShort], lengthInputShort)
  83. startPriceShort = iShort + sShort * (lengthInputShort - 1)
  84. endPriceShort = iShort
  85. var line baseLineShort = na
  86. if na(baseLineShort) and not na(startPriceShort)
  87. baseLineShort := line.new(bar_index - lengthInputShort + 1, startPriceShort, bar_index, endPriceShort, width=1, extend=extendStyle, color=color.new(color.gray, 100))
  88. else
  89. line.set_xy1(baseLineShort, bar_index - lengthInputShort + 1, startPriceShort)
  90. line.set_xy2(baseLineShort, bar_index, endPriceShort)
  91. na
  92.  
  93. calcDev(source, length, slope, average, intercept) =>
  94. upDev = 0.0
  95. dnDev = 0.0
  96. stdDevAcc = 0.0
  97. dsxx = 0.0
  98. dsyy = 0.0
  99. dsxy = 0.0
  100. periods = length - 1
  101. daY = intercept + slope * periods / 2
  102. val = intercept
  103. for j = 0 to periods by 1
  104. price = high[j] - val
  105. if price > upDev
  106. upDev := price
  107. price := val - low[j]
  108. if price > dnDev
  109. dnDev := price
  110. price := source[j]
  111. dxt = price - average
  112. dyt = val - daY
  113. price -= val
  114. stdDevAcc += price * price
  115. dsxx += dxt * dxt
  116. dsyy += dyt * dyt
  117. dsxy += dxt * dyt
  118. val += slope
  119. stdDev = math.sqrt(stdDevAcc / (periods == 0 ? 1 : periods))
  120. pearsonR = dsxx == 0 or dsyy == 0 ? 0 : dsxy / math.sqrt(dsxx * dsyy)
  121. [stdDev, pearsonR, upDev, dnDev]
  122. // [stdDev, pearsonR, upDev, dnDev]
  123.  
  124. //###################[ Long term Standard Deviation ]############################
  125. // [stdDev, pearsonR, upDev, dnDev] = calcDev(sourceInput[lengthBank], lengthInput, s, a, i)
  126. [stdDev, pearsonR, upDev, dnDev] = calcDev(sourceInput, lengthInput, s, a, i)
  127. upperStartPrice = startPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
  128. upperEndPrice = endPrice + (useUpperDevInput ? upperMultInput * stdDev : upDev)
  129. var line upper = na
  130. lowerStartPrice = startPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -dnDev)
  131. lowerEndPrice = endPrice + (useLowerDevInput ? -lowerMultInput * stdDev : -dnDev)
  132. var line lower = na
  133. if na(upper) and not na(upperStartPrice)
  134. upper := line.new(bar_index - lengthInput + 1, upperStartPrice, bar_index, upperEndPrice, width=1, extend=extendStyle, color=color.new(color.green, 100))
  135. else
  136. line.set_xy1(upper, bar_index - lengthInput + 1, upperStartPrice)
  137. line.set_xy2(upper, bar_index, upperEndPrice)
  138. na
  139. if na(lower) and not na(lowerStartPrice)
  140. lower := line.new(bar_index - lengthInput + 1, lowerStartPrice, bar_index, lowerEndPrice, width=1, extend=extendStyle, color=color.new(color.green, 100))
  141. else
  142. line.set_xy1(lower, bar_index - lengthInput + 1, lowerStartPrice)
  143. line.set_xy2(lower, bar_index, lowerEndPrice)
  144. na
  145. linefill.new(upper, baseLine, color = s>0? color.new(color.red,90):color.new(color.green,80) )
  146. linefill.new(baseLine, lower, color = s>0? color.new(color.red,80):color.new(color.green,90) )
  147.  
  148. //###################[ Mid term Standard Deviation ]############################
  149. // [stdDevMid, pearsonRMid, upDevMid, dnDevMid] = calcDev(sourceInput[lengthBankMid], lengthInputMid, sMid, aMid, iMid)
  150. [stdDevMid, pearsonRMid, upDevMid, dnDevMid] = calcDev(sourceInput, lengthInputMid, sMid, aMid, iMid)
  151. upperStartPriceMid = startPriceMid + (useUpperDevInput ? upperMultInput * stdDevMid : upDevMid)
  152. upperEndPriceMid = endPriceMid + (useUpperDevInput ? upperMultInput * stdDevMid : upDevMid)
  153. var line upperMid = na
  154. lowerStartPriceMid = startPriceMid + (useLowerDevInput ? -lowerMultInput * stdDevMid : -dnDevMid)
  155. lowerEndPriceMid = endPriceMid + (useLowerDevInput ? -lowerMultInput * stdDevMid : -dnDevMid)
  156. var line lowerMid = na
  157. if na(upperMid) and not na(upperStartPriceMid)
  158. upperMid := line.new(bar_index - lengthInputMid + 1, upperStartPriceMid, bar_index, upperEndPriceMid, width=1, extend=extendStyle, color=color.silver)
  159. else
  160. line.set_xy1(upperMid, bar_index - lengthInputMid + 1, upperStartPriceMid)
  161. line.set_xy2(upperMid, bar_index, upperEndPriceMid)
  162. na
  163. if na(lowerMid) and not na(lowerStartPriceMid)
  164. lowerMid := line.new(bar_index - lengthInputMid + 1, lowerStartPriceMid, bar_index, lowerEndPriceMid, width=1, extend=extendStyle, color=color.silver)
  165. else
  166. line.set_xy1(lowerMid, bar_index - lengthInputMid + 1, lowerStartPriceMid)
  167. line.set_xy2(lowerMid, bar_index, lowerEndPriceMid)
  168. na
  169. // linefill.new(upperMid, baseLineMid, color = colorUpper)
  170. // linefill.new(baseLineMid, lowerMid, color = colorLower)
  171.  
  172. //###################[ Short term Standard Deviation ]############################
  173. // [stdDevShort, pearsonRShort, upDevShort, dnDevShort] = calcDev(sourceInput[lengthBankShort], lengthInputShort, sShort, aShort, iShort)
  174. [stdDevShort, pearsonRShort, upDevShort, dnDevShort] = calcDev(sourceInput, lengthInputShort, sShort, aShort, iShort)
  175. upperStartPriceShort = startPriceShort + (useUpperDevInput ? upperMultInput * stdDevShort : upDevShort)
  176. upperEndPriceShort = endPriceShort + (useUpperDevInput ? upperMultInput * stdDevShort : upDevShort)
  177. var line upperShort = na
  178. lowerStartPriceShort = startPriceShort + (useLowerDevInput ? -lowerMultInput * stdDevShort : -dnDevShort)
  179. lowerEndPriceShort = endPriceShort + (useLowerDevInput ? -lowerMultInput * stdDevShort : -dnDevShort)
  180. var line lowerShort = na
  181. if na(upperShort) and not na(upperStartPriceShort)
  182. upperShort := line.new(bar_index - lengthInputShort + 1, upperStartPriceShort, bar_index, upperEndPriceShort, width=1, extend=extendStyle, color=color.gray)
  183. else
  184. line.set_xy1(upperShort, bar_index - lengthInputShort + 1, upperStartPriceShort)
  185. line.set_xy2(upperShort, bar_index, upperEndPriceShort)
  186. na
  187. if na(lowerShort) and not na(lowerStartPriceShort)
  188. lowerShort := line.new(bar_index - lengthInputShort + 1, lowerStartPriceShort, bar_index, lowerEndPriceShort, width=1, extend=extendStyle, color=color.gray)
  189. else
  190. line.set_xy1(lowerShort, bar_index - lengthInputShort + 1, lowerStartPriceShort)
  191. line.set_xy2(lowerShort, bar_index, lowerEndPriceShort)
  192. na
  193. // linefill.new(upperShort, baseLineShort, color = colorUpper)
  194. // linefill.new(baseLineShort, lowerShort, color = colorLower)
  195.  
  196. //########################[ Plot DC ]###############################
  197. // upDC = ta.highest(high,lengthInput)
  198. // lowDC = ta.lowest(low,lengthInput)
  199. // midDC = (upDC+lowDC)/2
  200. // plot(upDC,style=plot.style_linebr,linewidth = 1,color=color.aqua)
  201. // plot(midDC,style=plot.style_linebr,linewidth = 1,color=color.yellow)
  202. // plot(lowDC,style=plot.style_linebr,linewidth = 1,color=color.orange)
  203.  
  204. //########################[ Plot Median ]###############################
  205. // aClose = array.new_float(0)
  206. // for j = 0 to lengthInput
  207. // array.push(aClose, close[j])
  208. // _median = array.median(aClose)
  209. // _stdev = array.stdev(aClose)
  210. // plot(_median,style=plot.style_linebr,linewidth = 1,color=color.yellow)
  211. // plot(_median + _stdev*2,style=plot.style_linebr,linewidth = 1,color=color.white)
  212. // plot(_median - _stdev*2,style=plot.style_linebr,linewidth = 1,color=color.orange)
  213.  
  214. // //########################[ Plot Bollinger Band ]###############################
  215. // [_middle, _upper, _lower] = ta.bb(close, lengthInput, 2)
  216. // plot(_middle,style=plot.style_linebr,linewidth = 1,color=color.yellow)
  217. // plot(_upper,style=plot.style_linebr,linewidth = 1,color=color.white)
  218. // plot(_lower,style=plot.style_linebr,linewidth = 1,color=color.orange)
  219.  
  220.  
  221. //########################[ Identify Trend ]###############################
  222. // _atr = ta.atr(lengthInputShort)
  223. var line sLine = na // support longterm
  224. var line rLine = na // resistance longterm
  225. // var box midBox = na // mid term box
  226. var box l0Box = na // long term current box #0
  227. var box l1Box = na // long term previous box #1
  228. var box l2Box = na // long term previous box #2
  229. var box l3Box = na // long term previous box #3
  230. // retest, turnaround and run !
  231. // isBreakUpMidBox = (ta.crossover(close,box.get_top(midBox)) or ta.crossover(close,box.get_bottom(midBox)) ) and close>open
  232. // isBreakDownMidBox = (ta.crossunder(close,box.get_top(midBox)) or ta.crossunder(close,box.get_bottom(midBox)) ) and close<open
  233. isStrongBuyZone = s<=0 and close>box.get_top(l0Box) and ( close>box.get_top(l1Box) or bar_index > nz(box.get_right(l1Box)) ) and ( close>box.get_top(l2Box) or bar_index > nz(box.get_right(l2Box)) ) and ( close>box.get_top(l3Box) or bar_index > nz(box.get_right(l3Box)) ) // close > top all active boxes
  234. isStrongSellZone = s>0 and close<box.get_bottom(l0Box) and ( close<box.get_bottom(l1Box) or bar_index > nz(box.get_right(l1Box)) ) and ( close<box.get_bottom(l2Box) or bar_index > nz(box.get_right(l2Box)) ) and ( close<box.get_bottom(l3Box) or bar_index > nz(box.get_right(l3Box)) ) // close < bottom all active boxes
  235. // plot(isStrongBuy? low-_atr:na, title='BUY',style=plot.style_circles,linewidth=1,color=color.white)
  236. // plot(isStrongSell? high+_atr:na, title='SELL',style=plot.style_circles,linewidth=1,color=color.orange)
  237. // plot(isBreakUpMidBox? low-_atr:na, title='Take Profit Short',style=plot.style_circles,linewidth=1,color=color.white)
  238. // plot(isBreakDownMidBox? high+_atr:na, title='Take Profit Long',style=plot.style_circles,linewidth=1,color=color.orange)
  239.  
  240. if (s>0 and s[1]<=0) or (s<0 and s[1]>=0) // identify long term trend change from sideway
  241. l3Box := l2Box
  242. l2Box := l1Box
  243. l1Box := l0Box
  244. l0Box := box.new(left=bar_index-lengthInput,top=upperEndPrice,right=bar_index+lengthInput*2,bottom=lowerEndPrice,border_width = 0,bgcolor = color.new(color.gray,90))
  245. line.set_color(rLine,color.new(color.orange,70))
  246. line.set_color(sLine,color.new(color.orange,70))
  247. rLine := line.new(x1=bar_index-lengthInput,y1=upperEndPrice,x2=bar_index+lengthInput*2,y2=upperEndPrice,color = color.orange)
  248. sLine := line.new(x1=bar_index-lengthInput,y1=lowerEndPrice,x2=bar_index+lengthInput*2,y2=lowerEndPrice,color = color.orange)
  249. // if (sMid>0 and sMid[1]<=0) or (sMid<0 and sMid[1]>=0) // identify mid term trend change from sideway
  250. // midBox := box.new(left=bar_index-lengthInputMid,top=upperEndPriceMid,right=bar_index+lengthInputMid,bottom=lowerEndPriceMid,border_width = 0,bgcolor = color.new(color.gray,90))
  251.  
  252.  
  253. // if s<0 and (sMid>0 and sMid[1]<=0) // identify long term uptrend but short trend change to down trend -> take profit
  254. // line.new(x1=bar_index-lengthInputMid,y1=upperEndPriceMid,x2=bar_index+lengthInputMid*2,y2=upperEndPriceMid,color = color.orange)
  255. // line.new(x1=bar_index-lengthInputMid,y1=lowerEndPriceMid,x2=bar_index+lengthInputMid*2,y2=lowerEndPriceMid,color = color.orange)
  256. // if s<0 and sMid<0 and (sShort>0 and sShort[1]<=0) // identify long term uptrend but short trend change to down trend -> take profit
  257. // line.new(x1=bar_index-lengthInputShort,y1=upperEndPriceShort,x2=bar_index+lengthInputShort*2,y2=upperEndPriceShort,color = color.gray)
  258. // line.new(x1=bar_index-lengthInputShort,y1=lowerEndPriceShort,x2=bar_index+lengthInputShort*2,y2=lowerEndPriceShort,color = color.gray)
  259.  
  260.  
  261. // highBody = close>open ? close : open //get high from body, no wick
  262. // lowBody = close<open ? close : open //get low from body, no wick
  263. // dcBodyHigh = ta.highest(highBody,lengthInputMid)
  264. // dcBodyLow = ta.lowest(lowBody,lengthInputMid)
  265. // dcBodyBase = (dcBodyHigh+dcBodyLow)/2
  266. // plot(dcBodyHigh,color=color.white,style=plot.style_linebr,linewidth = 1)
  267. // plot(dcBodyLow,color=color.white,style=plot.style_linebr,linewidth = 1)
  268. // plot(dcBodyBase,color=color.white,style=plot.style_linebr,linewidth = 1)
  269.  
  270. // _roc = ta.roc(3)
  271. // [middleC, upperC, lowerC] = ta.bb(close, lengthInput, 1)
  272. // plot(endPrice,color=color.yellow)
  273. // plot(upperEndPrice,color=color.red,linewidth = 2)
  274. // plot(lowerEndPrice,color=color.red,linewidth = 2)
  275. // plot(upperEndPriceMid,color=color.orange)
  276. // plot(lowerEndPriceMid,color=color.orange)
  277. // plot(upperEndPriceShort,color=color.yellow)
  278. // plot(lowerEndPriceShort,color=color.yellow)
  279.  
  280. // plot(middleC,color=color.orange)
  281. // plot(upperC,color=color.orange)
  282. // plot(lowerC,color=color.orange)
  283.  
  284. // isBreakUp(_lengthBank) =>
  285. // int counter = 0
  286. // isBankMove = close>upperEndPrice and _atr>upperAtr
  287. // for j=0 to _lengthBank
  288. // if close[j] > upperEndPrice[j]
  289. // counter += 1
  290. // else
  291. // break
  292. // isBankMove or counter >= _lengthBank ? true : false
  293. // isBreakDown(_lengthBank) =>
  294. // int counter = 0
  295. // isBankMove = close<lowerEndPrice and _atr>upperAtr
  296. // for j=0 to _lengthBank
  297. // if close[j] < lowerEndPrice[j]
  298. // counter += 1
  299. // else
  300. // break
  301. // isBankMove or counter >= _lengthBank ? true : false
  302.  
  303. // plot(isBreakUp(lengthBank)? upperEndPrice : na ,style=plot.style_linebr,linewidth = 3,color=color.green)
  304. // plot(isBreakDown(lengthBank)? lowerEndPrice : na ,style=plot.style_linebr,linewidth = 3,color=color.red)
  305.  
  306.  
  307. float trend = math.sign(startPrice - endPrice)
  308. alertcondition(sourceInput > line.get_price(upper, bar_index) or sourceInput < line.get_price(lower, bar_index), title='Regression Channel Exited', message="The price movement has exited Regression Channel's bounds")
  309. alertcondition(trend[1] >= 0 and trend < 0, title='Switched to Uptrend', message='The Regression Channel trend switched from Downtrend to Uptrend')
  310. alertcondition(trend[1] <= 0 and trend > 0, title='Switched to Downtrend', message='The Regression Channel trend switched from Uptrend to Downtrend')
  311.  
  312. //########################[ Identify Trend ]###############################
  313. var table ratings = table.new(position.top_right, 8, 2, frame_color = #000000)
  314. // if barstate.islastconfirmedhistory
  315. // table.cell(ratings, 0, 0, "bar_index", bgcolor = color.black, text_color = color.white)
  316. // table.cell(ratings, 1, 0, "L1 right", bgcolor = color.black, text_color = color.white)
  317. // table.cell(ratings, 2, 0, "L2 right", bgcolor = color.black, text_color = color.white)
  318. // table.cell(ratings, 3, 0, "Support price", bgcolor = color.black, text_color = color.white)
  319. // table.cell(ratings, 4, 0, "Resistance price", bgcolor = color.black, text_color = color.white)
  320. table.cell(ratings, 5, 0, "Buy bias?", bgcolor = color.black, text_color = color.green)
  321. table.cell(ratings, 6, 0, "Sell bias?", bgcolor = color.black, text_color = color.red)
  322.  
  323. // table.cell(ratings, 0, 1, str.tostring(bar_index), bgcolor = color.black, text_color = color.white)
  324. // table.cell(ratings, 1, 1, str.tostring(box.get_right(l1Box)), bgcolor = color.black, text_color = color.white)
  325. // table.cell(ratings, 2, 1, str.tostring(box.get_right(l2Box)), bgcolor = color.black, text_color = color.white)
  326. // table.cell(ratings, 3, 1, str.tostring(line.get_price(sLine,bar_index),format.mintick ), bgcolor = color.black, text_color = color.white)
  327. // table.cell(ratings, 4, 1, str.tostring(line.get_price(rLine,bar_index),format.mintick ), bgcolor = color.black, text_color = color.white)
  328. table.cell(ratings, 5, 1, isStrongBuyZone?'Yes':'No', bgcolor = color.black, text_color = color.white)
  329. table.cell(ratings, 6, 1, isStrongSellZone?'Yes':'No', bgcolor = color.black, text_color = color.white)
  330.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement