Novelty_ua

Help on Reddit

Jul 27th, 2025 (edited)
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.26 KB | None | 0 0
  1. //@version=6
  2. indicator(title="HTF Candles & Separators", shorttitle="HTF+Candles+Sep", overlay=true, max_boxes_count=500, max_lines_count=500, max_labels_count=500) // Increased labels count
  3. // --- HTF Settings ---
  4. timeframe1 = input.timeframe('D', 'Timeframe 1')
  5. timeframe2 = input.timeframe('W', 'Timeframe 2')
  6. timeframe3 = input.timeframe('M', 'Timeframe 3')
  7. numBoxes = input.int(3, 'Number of Boxes', minval=1, maxval=10)
  8. // Separator Timeframe Selection
  9. separatorTF = input.timeframe('D', 'Separator Timeframe')
  10. // Box Settings
  11. BoxShow = input.bool(true, 'Show HTF Boxes')
  12. BoxWidth = input.int(1, 'Box Border Width', minval=0)
  13. BoxLineStyle = input.bool(false, 'Box Border Dashed') ? line.style_dashed : line.style_solid
  14. // HTF mSpot Settings
  15. mSpotShow = input.bool(false, 'Show HTF mSpot')
  16. mSpotWidth = input.int(1, 'mSpot Line Width', minval=0)
  17. mSpotStyle = input.bool(true, 'mSpot Line Dashed') ? line.style_dashed : line.style_solid
  18. // HTF Open Line Settings
  19. OpenLineShow = input.bool(true, 'Show HTF Open Line')
  20. OpenLineWidth = input.int(1, 'Open Line Width', minval=0)
  21. OpenLineStyle = input.bool(false, 'Open Line Dashed') ? line.style_dashed : line.style_solid
  22. // --- Timeframe Label Settings ---
  23. showLabels = input.bool(true, "Show Timeframe Labels", group="Timeframe Labels")
  24. labelPosition = input.string("Top", "Label Position", options=["Top", "Middle", "Bottom"], group="Timeframe Labels")
  25. labelSize = input.string("small", "Label Size", options=["tiny", "small", "normal", "large"], group="Timeframe Labels")
  26. labelColor = input.color(color.white, "Label Color", group="Timeframe Labels")
  27. labelBgColor = input.color(color.new(color.black, 50), "Label Background Color", group="Timeframe Labels")
  28. // HTF Box Colors - Automated (no user selection)
  29. boxBullishColor = color.new(#66bb6a, 80) // Green for bullish
  30. boxBearishColor = color.new(#f7525f, 80) // Red for bearish
  31. boxBorderColor = color.new(#9598a1, 50) // Gray border
  32. mSpotColor = color.new(#9598a1, 50) // Gray mSpot
  33. openLineColor = color.new(#00ff00, 50) // Green open line
  34. // --- Period Separator Inputs ---
  35. showSeparators = input.bool(true, "Show Period Separators")
  36. sepColorInput = input.color(color.gray, "Separator Color", group="Period Separators")
  37. sepStyleInput = input.string("Dotted", "Separator Style", options=["Solid", "Dashed", "Dotted"], group="Period Separators")
  38. sepWidthInput = input.int(1, "Separator Width", minval=1, group="Period Separators")
  39. sepMode = input.string("Historical", options=["Historical", "Present"], title="Separator Mode", group="Period Separators")
  40. // --- HTF Variables Arrays ---
  41. var float[] htfHigh = array.new_float(3, na)
  42. var float[] htfLow = array.new_float(3, na)
  43. var float[] htfOpen = array.new_float(3, na)
  44. var float[] htfClose = array.new_float(3, na)
  45. var int[] htfBarIndex = array.new_int(3, na)
  46. var float[] prevmSpotValue = array.new_float(3, na)
  47. var float[] prevOpen = array.new_float(3, na)
  48. var box[] currentBoxes = array.new_box(3, na)
  49. var line[] currentLines = array.new_line(3, na)
  50. var line[] currentOpenLines = array.new_line(3, na)
  51. var label[] currentLabels = array.new_label(3, na) // Array to store current labels
  52. // Timeframes array
  53. timeframes = array.from(timeframe1, timeframe2, timeframe3)
  54. // --- Period Separator Variables ---
  55. var line[] separators = array.new_line()
  56. // Get line style function
  57. getLineStyle(string styleInput) =>
  58. switch styleInput
  59. "Solid" => line.style_solid
  60. "Dashed" => line.style_dashed
  61. "Dotted" => line.style_dotted
  62. => line.style_dotted
  63. // Pre-calculate HTF time changes outside the loop
  64. htfTime1 = request.security(syminfo.tickerid, timeframe1, time)
  65. htfTime2 = request.security(syminfo.tickerid, timeframe2, time)
  66. htfTime3 = request.security(syminfo.tickerid, timeframe3, time)
  67. changeHTF1 = ta.change(htfTime1) != 0
  68. changeHTF2 = ta.change(htfTime2) != 0
  69. changeHTF3 = ta.change(htfTime3) != 0
  70. // Pre-calculate separator time change
  71. separatorTime = request.security(syminfo.tickerid, separatorTF, time)
  72. changeSeparatorTF = ta.change(separatorTime) != 0
  73.  
  74. // Helper function to determine label Y position
  75. getLabelYPos(float top, float bottom, string position) =>
  76. switch position
  77. "Top" => top
  78. "Middle" => (top + bottom) / 2
  79. "Bottom" => bottom
  80. => (top + bottom) / 2 // Default to middle
  81.  
  82. // Main logic for each timeframe
  83. for i = 0 to numBoxes - 1
  84. if i < array.size(timeframes)
  85. tf = array.get(timeframes, i)
  86. // Get the pre-calculated change flag for this timeframe
  87. bool changeHTF = i == 0 ? changeHTF1 : i == 1 ? changeHTF2 : changeHTF3
  88. // Create security context for each timeframe
  89. htfOpenVal = request.security(syminfo.tickerid, tf, open)
  90. htfHighVal = request.security(syminfo.tickerid, tf, high)
  91. htfLowVal = request.security(syminfo.tickerid, tf, low)
  92. htfCloseVal = request.security(syminfo.tickerid, tf, close)
  93. barIndex = bar_index + 1
  94. if changeHTF
  95. // --- A new HTF bar has started ---
  96. highVal = array.get(htfHigh, i)
  97. lowVal = array.get(htfLow, i)
  98. openVal = array.get(htfOpen, i)
  99. closeVal = array.get(htfClose, i)
  100. barIdx = array.get(htfBarIndex, i) + 1
  101. prevMSpot = array.get(prevmSpotValue, i)
  102. prevOpn = array.get(prevOpen, i)
  103. if not na(highVal) and not na(lowVal)
  104. // Calculate current period's mSpot
  105. float currentmSpotValue = math.avg(highVal, lowVal)
  106. // Draw mSpot line using previous mSpot (shifted display)
  107. if not na(prevMSpot)
  108. if mSpotShow
  109. line.new(x1=barIdx, y1=prevMSpot, x2=barIndex, y2=prevMSpot, xloc=xloc.bar_index, color=mSpotColor, style=mSpotStyle, width=mSpotWidth)
  110. // Determine box color based on direction from previous open to previous mSpot
  111. bool boxBullish = false
  112. if not na(prevOpn) and not na(prevMSpot)
  113. boxBullish := prevOpn > prevMSpot // Upward = Bearish, Downward = Bullish
  114. BGColor = boxBullish ? boxBearishColor : boxBullishColor
  115. // Draw box using CURRENT open and PREVIOUS mSpot
  116. boxCreated = box(na)
  117. if BoxShow and not na(openVal) and not na(prevMSpot)
  118. boxCreated := box.new(left=barIdx, top=math.max(openVal, prevMSpot), right=barIndex, bottom=math.min(openVal, prevMSpot), border_width=BoxWidth, border_style=BoxLineStyle, border_color=boxBorderColor, bgcolor=BGColor)
  119. // --- Draw Timeframe Label for the *previous* HTF bar ---
  120. if showLabels and not na(boxCreated) and not na(tf)
  121. labelY = getLabelYPos(math.max(openVal, prevMSpot), math.min(openVal, prevMSpot), labelPosition)
  122. label.new(x=barIdx + (barIndex - barIdx) / 2, y=labelY, text=tf, xloc=xloc.bar_index, yloc=yloc.price, style=label.style_label_center, textcolor=labelColor, size=labelSize, color=labelBgColor)
  123. // Draw open line using current open
  124. if OpenLineShow and not na(openVal)
  125. line.new(x1=barIdx, y1=openVal, x2=barIndex , y2=openVal, xloc=xloc.bar_index, color=openLineColor, style=OpenLineStyle, width=OpenLineWidth)
  126. // Store current values for next period
  127. array.set(prevmSpotValue, i, currentmSpotValue)
  128. array.set(prevOpen, i, openVal)
  129. // Store data points for the *new* HTF bar
  130. array.set(htfOpen, i, htfOpenVal)
  131. array.set(htfClose, i, htfCloseVal)
  132. array.set(htfBarIndex, i, bar_index)
  133. array.set(htfHigh, i, htfHighVal)
  134. array.set(htfLow, i, htfLowVal)
  135. else if bar_index > 0
  136. // --- The current HTF bar continues ---
  137. highVal = array.get(htfHigh, i)
  138. lowVal = array.get(htfLow, i)
  139. closeVal = array.get(htfClose, i)
  140. htfHighCurrent = request.security(syminfo.tickerid, tf, high)
  141. htfLowCurrent = request.security(syminfo.tickerid, tf, low)
  142. htfCloseCurrent = request.security(syminfo.tickerid, tf, close)
  143. array.set(htfHigh, i, math.max(highVal, htfHighCurrent))
  144. array.set(htfLow, i, math.min(lowVal, htfLowCurrent))
  145. array.set(htfClose, i, htfCloseCurrent)
  146. // Handle last bar updates
  147. if barstate.islast and bar_index > 0
  148. // Clean up temporary "current" objects from previous iterations
  149. boxToDelete = array.get(currentBoxes, i)
  150. lineToDelete1 = array.get(currentLines, i)
  151. lineToDelete2 = array.get(currentOpenLines, i)
  152. labelToDelete = array.get(currentLabels, i) // Get label to delete
  153. if not na(boxToDelete)
  154. box.delete(boxToDelete)
  155. if not na(lineToDelete1)
  156. line.delete(lineToDelete1)
  157. if not na(lineToDelete2)
  158. line.delete(lineToDelete2)
  159. if not na(labelToDelete) // Delete label
  160. label.delete(labelToDelete)
  161. // Redraw final elements for the *current* HTF bar on the last chart bar
  162. highVal = array.get(htfHigh, i)
  163. lowVal = array.get(htfLow, i)
  164. openVal = array.get(htfOpen, i)
  165. closeVal = array.get(htfClose, i)
  166. barIdx = array.get(htfBarIndex, i)
  167. prevMSpot = array.get(prevmSpotValue, i)
  168. prevOpn = array.get(prevOpen, i)
  169. if not na(highVal) and not na(lowVal)
  170. float currentmSpotValue = math.avg(highVal, lowVal)
  171. // Draw mSpot line using previous mSpot (shifted display)
  172. if not na(prevMSpot)
  173. if mSpotShow
  174. newLine = line.new(x1=barIdx, y1=prevMSpot, x2=barIndex, y2=prevMSpot, xloc=xloc.bar_index, color=mSpotColor, style=mSpotStyle, width=mSpotWidth)
  175. array.set(currentLines, i, newLine)
  176. // Determine box color based on direction from previous open to previous mSpot
  177. bool boxBullish = false
  178. if not na(prevOpn) and not na(prevMSpot)
  179. boxBullish := prevOpn > prevMSpot // Upward = Bearish, Downward = Bullish
  180. BGColor = boxBullish ? boxBearishColor : boxBullishColor
  181. // Draw box using CURRENT open and PREVIOUS mSpot
  182. newBoxCreated = box(na)
  183. if BoxShow and not na(openVal) and not na(prevMSpot)
  184. newBoxCreated := box.new(left=barIdx, top=math.max(openVal, prevMSpot), right=barIndex, bottom=math.min(openVal, prevMSpot), border_width=BoxWidth, border_style=BoxLineStyle, border_color=boxBorderColor, bgcolor=BGColor)
  185. array.set(currentBoxes, i, newBoxCreated)
  186. // --- Draw Timeframe Label for the *current* HTF bar ---
  187. newLabelCreated = label(na)
  188. if showLabels and not na(newBoxCreated) and not na(tf)
  189. labelY = getLabelYPos(math.max(openVal, prevMSpot), math.min(openVal, prevMSpot), labelPosition)
  190. newLabelCreated := label.new(x=barIdx + (barIndex - barIdx) / 2, y=labelY, text=tf, xloc=xloc.bar_index, yloc=yloc.price, style=label.style_label_center, textcolor=labelColor, size=labelSize, color=labelBgColor)
  191. array.set(currentLabels, i, newLabelCreated) // Store the new label object
  192. // Draw open line using current open
  193. if OpenLineShow and not na(openVal)
  194. newOpenLine = line.new(x1=barIdx, y1=openVal, x2=barIndex, y2=openVal, xloc=xloc.bar_index, color=openLineColor, style=OpenLineStyle, width=OpenLineWidth)
  195. array.set(currentOpenLines, i, newOpenLine)
  196. // --- Period Separator Logic for Selected Timeframe ---
  197. if changeSeparatorTF and showSeparators
  198. new_separator = line.new(x1=bar_index, x2=bar_index, y1=high + syminfo.mintick, y2=low - syminfo.mintick, extend=extend.both, color=sepColorInput, style=getLineStyle(sepStyleInput), width=sepWidthInput)
  199. array.push(separators, new_separator)
  200. if sepMode == "Present" and array.size(separators) > 1
  201. line_to_delete = array.shift(separators)
  202. line.delete(line_to_delete)
Advertisement
Add Comment
Please, Sign In to add comment