Advertisement
xmd79

Linear Regression Channel Ultimate

Oct 31st, 2024
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.75 KB | None | 0 0
  1. // @ Julien_Eche
  2.  
  3. //@version=5
  4. indicator("Linear Regression Channel Ultimate", shorttitle = 'LRC', overlay=true, max_bars_back=5000)
  5.  
  6. pI = input.int(500, "Periods", minval=2)
  7. uL = input.bool(true, "Log Scale")
  8. devMultiplier = input.float(2.0, "Deviation Multiplier", minval=0.1, step=0.1)
  9. nFills = input.int(23, "Number of Profile Fills", minval=2, maxval=23)
  10. activityMethod = input.string("Volume", "Activity calculation method", options=["Touches", "Volume"])
  11. numActivityLines= input.int(5, "Number of Most Active Levels to Display", minval=1, maxval=5)
  12. showProfile = input.bool(true, "Show Profile")
  13.  
  14. regColor = input.color(color.new(color.gray, 0), "Regression Channel", inline="reg_channel")
  15. regLineStyle = input.string("Solid", "", options=["Solid", "Dotted", "Dashed"], inline="reg_channel")
  16. regLineWidth = input.int(1, "", minval=1, maxval=4, inline="reg_channel")
  17. fillColor = input.color(color.new(#909497, 95), "Channel Fill", inline="channel_fill")
  18.  
  19. showRegLine = input.bool(false, "Show Regression Line", inline="reg_line")
  20. regLineColor = input.color(color.new(color.gray, 0), "", inline="reg_line")
  21. regLineStyleOpt = input.string("Dashed", "", options=["Solid", "Dotted", "Dashed"], inline="reg_line")
  22. regLineWidthOpt = input.int(1, "", minval=1, maxval=4, inline="reg_line")
  23.  
  24. useCustomColor = input.bool(false, "Use custom Most Active Levels color")
  25. customColor = input.color(color.new(#00BBFF, 50), "Custom Color", inline="act_line")
  26. actLineStyle = input.string("Solid", "", options=["Solid", "Dotted", "Dashed"], inline="act_line")
  27. actLineWidth = input.int(1, "", minval=1, maxval=5, inline="act_line")
  28.  
  29. loActColor = input.color(color.new(#00BBFF, 95), "Low Activity", inline="profile_color")
  30. hiActColor = input.color(color.new(#00BBFF, 25), "High Activity", inline="profile_color")
  31.  
  32. eS = extend.right
  33. lI = math.min(bar_index + 1, pI)
  34. f_adjust(p) => uL ? math.log(p) : p
  35. f_unadjust(p) => uL ? math.exp(p) : p
  36.  
  37. cS(len) =>
  38. if not barstate.islast or len <= 1
  39. [float(na), float(na), float(na)]
  40. else
  41. sX = 0.0, sY = 0.0, sXS = 0.0, sXY = 0.0
  42. for i = 0 to len - 1
  43. v = f_adjust(close[i])
  44. p = i + 1.0
  45. sX += p, sY += v, sXS += p * p, sXY += v * p
  46. sl = (len * sXY - sX * sY) / (len * sXS - sX * sX)
  47. av = sY / len
  48. ic = av - sl * sX / len + sl
  49. [sl, av, ic]
  50.  
  51. [s, a, i] = cS(lI)
  52. sP = f_unadjust(i + s * (lI - 1))
  53. eP = f_unadjust(i)
  54.  
  55. var float uSP = na
  56. var float uEP = na
  57. var float lSP = na
  58. var float lEP = na
  59.  
  60. var line bL = na
  61. if showRegLine
  62. if na(bL) and not na(sP)
  63. bL := line.new(bar_index - lI + 1, sP, bar_index, eP,
  64. width=regLineWidthOpt, extend=eS, color=regLineColor,
  65. style=regLineStyleOpt == "Solid" ? line.style_solid : regLineStyleOpt == "Dotted" ? line.style_dotted : line.style_dashed)
  66. else
  67. line.set_xy1(bL, bar_index - lI + 1, sP)
  68. line.set_xy2(bL, bar_index, eP)
  69. line.set_color(bL, regLineColor)
  70. line.set_style(bL, regLineStyleOpt == "Solid" ? line.style_solid : regLineStyleOpt == "Dotted" ? line.style_dotted : line.style_dashed)
  71. line.set_width(bL, regLineWidthOpt)
  72. else
  73. line.delete(bL)
  74.  
  75. cD(len, sl, av, ic) =>
  76. uD = 0.0, dD = 0.0, sDA = 0.0
  77. dxx = 0.0, dyy = 0.0, dxy = 0.0
  78. per = len - 1
  79. dY = ic + sl * per / 2
  80. v = ic
  81. for j = 0 to per
  82. pr = f_adjust(high[j]) - v
  83. if pr > uD
  84. uD := pr
  85. pr := v - f_adjust(low[j])
  86. if pr > dD
  87. dD := pr
  88. pr := f_adjust(close[j])
  89. dx = pr - av
  90. dy = v - dY
  91. pr -= v
  92. sDA += pr * pr
  93. dxx += dx * dx
  94. dyy += dy * dy
  95. dxy += dx * dy
  96. v += sl
  97. sD = math.sqrt(sDA / (per == 0 ? 1 : per))
  98. pR = dxx == 0 or dyy == 0 ? 0 : dxy / math.sqrt(dxx * dyy)
  99. [sD, pR, uD, dD]
  100.  
  101. [sD, pR, uD, dD] = cD(lI, s, a, i)
  102.  
  103. applyDeviation(baseValue, deviation) => f_unadjust(f_adjust(baseValue) + deviation)
  104. uSP := applyDeviation(sP, devMultiplier * sD)
  105. uEP := applyDeviation(eP, devMultiplier * sD)
  106. lSP := applyDeviation(sP, -devMultiplier * sD)
  107. lEP := applyDeviation(eP, -devMultiplier * sD)
  108.  
  109. var line u = na
  110. var line l = na
  111. if na(u) and not na(uSP)
  112. u := line.new(bar_index - lI + 1, uSP, bar_index, uEP, width=regLineWidth, extend=eS, color=regColor,
  113. style=regLineStyle == "Solid" ? line.style_solid : regLineStyle == "Dotted" ? line.style_dotted : line.style_dashed)
  114. else
  115. line.set_xy1(u, bar_index - lI + 1, uSP)
  116. line.set_xy2(u, bar_index, uEP)
  117. line.set_color(u, regColor)
  118. line.set_style(u, regLineStyle == "Solid" ? line.style_solid : regLineStyle == "Dotted" ? line.style_dotted : line.style_dashed)
  119. line.set_width(u, regLineWidth)
  120.  
  121. if na(l) and not na(lSP)
  122. l := line.new(bar_index - lI + 1, lSP, bar_index, lEP, width=regLineWidth, extend=eS, color=regColor,
  123. style=regLineStyle == "Solid" ? line.style_solid : regLineStyle == "Dotted" ? line.style_dotted : line.style_dashed)
  124. else
  125. line.set_xy1(l, bar_index - lI + 1, lSP)
  126. line.set_xy2(l, bar_index, lEP)
  127. line.set_color(l, regColor)
  128. line.set_style(l, regLineStyle == "Solid" ? line.style_solid : regLineStyle == "Dotted" ? line.style_dotted :line.style_dashed)
  129. line.set_width(l, regLineWidth)
  130.  
  131. linefill.new(u, showRegLine ? bL : l, color=fillColor)
  132. if showRegLine
  133. linefill.new(bL, l, color=fillColor)
  134.  
  135. var label pL = na
  136. label.delete(pL[1])
  137. if not na(pR)
  138. pL := label.new(bar_index - lI + 1, lSP, str.tostring(pR, "#.###"), color=color.new(color.white, 100), textcolor=color.gray, size=size.normal, style=label.style_label_up)
  139.  
  140. calcLineValue(startY, endY, currentBar, totalBars) =>
  141. f_unadjust(f_adjust(startY) + (f_adjust(endY) - f_adjust(startY)) * currentBar / totalBars)
  142.  
  143. color_from_gradient(percent, color1, color2) =>
  144. r = color.r(color1) + (color.r(color2) - color.r(color1)) * percent
  145. g = color.g(color1) + (color.g(color2) - color.g(color1)) * percent
  146. b = color.b(color1) + (color.b(color2) - color.b(color1)) * percent
  147. t = color.t(color1) + (color.t(color2) - color.t(color1)) * percent
  148. color.rgb(r, g, b, t)
  149.  
  150. var counts = array.new_float(nFills, 0.0)
  151. var activityLines = array.new_line(numActivityLines)
  152. var profileFills = array.new_linefill(nFills)
  153.  
  154. if barstate.islast
  155. array.clear(counts)
  156. for actLine in activityLines
  157. line.delete(actLine)
  158. array.clear(activityLines)
  159. for pf in profileFills
  160. linefill.delete(pf)
  161. array.clear(profileFills)
  162.  
  163. for idx1 = 0 to nFills - 1
  164. y1 = calcLineValue(lSP, uSP, idx1, nFills)
  165. y2 = calcLineValue(lEP, uEP, idx1, nFills)
  166. count = 0.0
  167. for j = 0 to lI - 1
  168. lineValue = calcLineValue(y1, y2, j, lI - 1)
  169. if activityMethod == "Touches"
  170. if low[lI - 1 - j] <= lineValue and high[lI - 1 - j] >= lineValue
  171. count += 1.0
  172. else
  173. if low[lI - 1 - j] <= lineValue and high[lI - 1 - j] >= lineValue
  174. count += volume[lI - 1 - j]
  175. array.push(counts, count)
  176.  
  177. maxCount = array.max(counts)
  178. sortedIndices = array.sort_indices(counts, order.descending)
  179. var float activitySlope = 0.0
  180. minActivityThreshold = maxCount * 0.1
  181. displayedActivityLines = 0
  182.  
  183. for idx2 = 0 to nFills - 1
  184. if displayedActivityLines >= numActivityLines
  185. break
  186. index = array.get(sortedIndices, idx2)
  187. count = array.get(counts, index)
  188. if count >= minActivityThreshold
  189. actY1 = calcLineValue(lSP, uSP, index + 0.5, nFills)
  190. actY2 = calcLineValue(lEP, uEP, index + 0.5, nFills)
  191. if idx2 == 0
  192. activitySlope := (f_adjust(actY2) - f_adjust(actY1)) / (bar_index - (bar_index - lI + 1))
  193.  
  194. percent = count / maxCount
  195. lineColor = useCustomColor ? customColor : color_from_gradient(percent, loActColor, hiActColor)
  196. lineStyle = actLineStyle == "Solid" ? line.style_solid : actLineStyle == "Dotted" ? line.style_dotted : line.style_dashed
  197.  
  198. startX = showProfile ? math.min(bar_index, bar_index - lI + 1 + math.round((count / maxCount) * math.round(lI / 5))) : bar_index - lI + 1
  199. startY = showProfile ? f_unadjust(f_adjust(actY1) + activitySlope * (startX - (bar_index - lI + 1))) : actY1
  200.  
  201. actLine = line.new(startX, startY, bar_index, actY2, color=lineColor, width=actLineWidth, style=lineStyle, extend=extend.right)
  202. array.push(activityLines, actLine)
  203. displayedActivityLines += 1
  204.  
  205. if showProfile
  206. profileLength = math.round(lI / 5)
  207. for idx3 = 0 to nFills - 1
  208. y1_top = calcLineValue(lSP, uSP, idx3, nFills)
  209. y1_bottom = calcLineValue(lSP, uSP, idx3 + 1, nFills)
  210. y2_top = calcLineValue(lEP, uEP, idx3, nFills)
  211. y2_bottom = calcLineValue(lEP, uEP, idx3 + 1, nFills)
  212. count = array.get(counts, idx3)
  213. percent = count / maxCount
  214. fillColor := color_from_gradient(percent, loActColor, hiActColor)
  215. lineLength = math.round((count / maxCount) * profileLength)
  216. x2 = math.min(bar_index, bar_index - lI + 1 + lineLength)
  217. topLine = line.new(bar_index - lI + 1, y1_top, x2, f_unadjust(f_adjust(y1_top) + activitySlope * lineLength), color=color.new(fillColor, 100))
  218. bottomLine = line.new(bar_index - lI + 1, y1_bottom, x2, f_unadjust(f_adjust(y1_bottom) + activitySlope * lineLength), color=color.new(fillColor, 100))
  219. profileFill = linefill.new(topLine, bottomLine, color=fillColor)
  220. array.push(profileFills, profileFill)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement