safwan092

XAUUSD Bollinger Breakout + Strong Moves - NY Session

Dec 27th, 2025
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.34 KB | None | 0 0
  1. //@version=5
  2. indicator("XAUUSD Bollinger Breakout + Strong Moves - NY Session", overlay=true, max_labels_count=100)
  3.  
  4. // --- New York Session Settings ---
  5. var string TZ = "America/New_York"
  6. var string SESSION = "0930-1900"
  7. bool inSession = not na(time(timeframe.period, SESSION, TZ))
  8. bool sessionStart = inSession and not inSession[1]
  9.  
  10. // --- Bollinger Bands Input Parameters ---
  11. int bb_length = input.int(20, "Bollinger Length", minval=2)
  12. float bb_stddev = input.float(2.0, "Standard Deviation", minval=0.5, maxval=5.0, step=0.1)
  13. float breakout_threshold = input.float(10.0, "Breakout Threshold (USD)", minval=1.0, step=0.5)
  14. color bullish_color = input.color(color.green, "Bullish Color")
  15. color bearish_color = input.color(color.red, "Bearish Color")
  16. bool show_markers = input.bool(true, "Show Price Markers")
  17. bool show_extreme = input.bool(true, "Highlight Largest")
  18.  
  19. // --- Strong Move Detection Parameters ---
  20. float min_move_percent = input.float(0.5, "Minimum Move %", minval=0.1, maxval=5.0, step=0.1)
  21. int lookback_bars = input.int(3, "Lookback Bars", minval=1, maxval=10)
  22. color strong_bullish_color = input.color(color.lime, "Strong Bullish Color")
  23. color strong_bearish_color = input.color(color.maroon, "Strong Bearish Color")
  24. bool show_strong_moves = input.bool(true, "Show Strong Moves")
  25.  
  26. // --- Bollinger Bands Calculation ---
  27. float basis = ta.sma(close, bb_length)
  28. float dev = ta.stdev(close, bb_length)
  29. float upper_band = basis + bb_stddev * dev
  30. float lower_band = basis - bb_stddev * dev
  31.  
  32. // Calculate distance from bands using HIGH and LOW
  33. float high_distance_from_upper = high - upper_band
  34. float low_distance_from_lower = lower_band - low
  35.  
  36. // Breakout conditions - ONLY DURING NY SESSION
  37. bool bullish_breakout = high_distance_from_upper >= breakout_threshold and inSession
  38. bool bearish_breakout = low_distance_from_lower >= breakout_threshold and inSession
  39.  
  40. // Track if breakout has occurred on current bar
  41. var bool current_bullish_breakout = false
  42. var bool current_bearish_breakout = false
  43. var float current_bullish_distance = 0.0
  44. var float current_bearish_distance = 0.0
  45.  
  46. // Track largest breakout in the NY session
  47. var float largest_bullish = 0.0
  48. var float largest_bearish = 0.0
  49. var int largest_bullish_bar = 0
  50. var int largest_bearish_bar = 0
  51.  
  52. // Update breakout status (real-time)
  53. if bullish_breakout
  54. current_bullish_breakout := true
  55. current_bullish_distance := high_distance_from_upper
  56.  
  57. if bearish_breakout
  58. current_bearish_breakout := true
  59. current_bearish_distance := low_distance_from_lower
  60.  
  61. // Update largest breakouts during NY session
  62. if bullish_breakout and high_distance_from_upper > largest_bullish
  63. largest_bullish := high_distance_from_upper
  64. largest_bullish_bar := bar_index
  65.  
  66. if bearish_breakout and low_distance_from_lower > largest_bearish
  67. largest_bearish := low_distance_from_lower
  68. largest_bearish_bar := bar_index
  69.  
  70. // Reset on new bar OR when session ends
  71. if barstate.isnew or (not inSession and inSession[1])
  72. current_bullish_breakout := false
  73. current_bearish_breakout := false
  74. current_bullish_distance := 0.0
  75. current_bearish_distance := 0.0
  76.  
  77. // Reset largest breakouts when session ends
  78. if not inSession and inSession[1]
  79. largest_bullish := 0.0
  80. largest_bearish := 0.0
  81. largest_bullish_bar := 0
  82. largest_bearish_bar := 0
  83.  
  84. // --- NY Session High/Low Reference Lines ---
  85. // Reference values for 9:30am candle
  86. var float refHigh = na
  87. var float refLow = na
  88.  
  89. // Lines and shaded box
  90. var line hiLine = na
  91. var line loLine = na
  92. var box rngBox = na
  93.  
  94. // When session starts (first bar >= 09:30 NY)
  95. if sessionStart
  96. refHigh := high
  97. refLow := low
  98.  
  99. // Create lines for that range
  100. hiLine := line.new(bar_index, refHigh, bar_index, refHigh, extend=extend.none, width=2, color=color.new(color.teal, 0))
  101. loLine := line.new(bar_index, refLow, bar_index, refLow, extend=extend.none, width=2, color=color.new(color.orange, 0))
  102.  
  103. // Shaded area between them
  104. rngBox := box.new(left=bar_index, top=refHigh, right=bar_index, bottom=refLow, border_color=color.new(color.gray, 80), bgcolor=color.new(color.gray, 90))
  105.  
  106. // While we're still within the NY session, extend everything to the current bar
  107. if inSession
  108. if not na(hiLine)
  109. line.set_x2(hiLine, bar_index)
  110. line.set_y2(hiLine, refHigh)
  111. if not na(loLine)
  112. line.set_x2(loLine, bar_index)
  113. line.set_y2(loLine, refLow)
  114. if not na(rngBox)
  115. box.set_right(rngBox, bar_index)
  116. box.set_top(rngBox, refHigh)
  117. box.set_bottom(rngBox, refLow)
  118.  
  119. // --- Strong Move Detection ---
  120. // Calculate move over the last N bars
  121. float highest_high = ta.highest(high, lookback_bars)
  122. float lowest_low = ta.lowest(low, lookback_bars)
  123. float move_size = highest_high - lowest_low
  124. float move_percent = (move_size / close) * 100
  125.  
  126. // Strong move conditions
  127. bool strong_bullish_move = move_percent >= min_move_percent and close > open and inSession
  128. bool strong_bearish_move = move_percent >= min_move_percent and close < open and inSession
  129.  
  130. // Track strong moves to avoid duplicate detection
  131. var int last_strong_move_bar = 0
  132. bool is_new_strong_move = bar_index > last_strong_move_bar + lookback_bars
  133.  
  134. // Detect new strong moves
  135. if (strong_bullish_move or strong_bearish_move) and is_new_strong_move and barstate.isconfirmed and show_strong_moves
  136. last_strong_move_bar := bar_index
  137.  
  138. // Draw lines for the move range
  139. line.new(bar_index - lookback_bars + 1, highest_high, bar_index, highest_high,
  140. color=strong_bullish_move ? strong_bullish_color : strong_bearish_color,
  141. width=2, style=line.style_solid)
  142. line.new(bar_index - lookback_bars + 1, lowest_low, bar_index, lowest_low,
  143. color=strong_bullish_move ? strong_bullish_color : strong_bearish_color,
  144. width=2, style=line.style_solid)
  145.  
  146. // Connect the lines at the ends (create a rectangle)
  147. line.new(bar_index - lookback_bars + 1, highest_high, bar_index - lookback_bars + 1, lowest_low,
  148. color=strong_bullish_move ? strong_bullish_color : strong_bearish_color,
  149. width=1, style=line.style_dotted)
  150. line.new(bar_index, highest_high, bar_index, lowest_low,
  151. color=strong_bullish_move ? strong_bullish_color : strong_bearish_color,
  152. width=1, style=line.style_dotted)
  153.  
  154. // Label with dollar amount
  155. string move_text = str.tostring(math.round(move_size * 100) / 100, "#.##") + "$"
  156. string percent_text = str.tostring(math.round(move_percent * 100) / 100, "#.##") + "%"
  157. string label_text = move_text + "\n" + percent_text
  158.  
  159. // Position label in the middle of the move
  160. float label_y = lowest_low + (move_size / 2)
  161.  
  162. if strong_bullish_move
  163. label.new(bar_index - math.round(lookback_bars / 2), label_y, label_text,
  164. color=strong_bullish_color, style=label.style_label_center,
  165. textcolor=color.white, size=size.normal,
  166. textalign=text.align_center)
  167. else
  168. label.new(bar_index - math.round(lookback_bars / 2), label_y, label_text,
  169. color=strong_bearish_color, style=label.style_label_center,
  170. textcolor=color.white, size=size.normal,
  171. textalign=text.align_center)
  172.  
  173. // --- Bollinger Bands Visualization ---
  174. // Plot Bollinger Bands
  175. plot(basis, "Basis", color=color.orange, linewidth=1)
  176. p1 = plot(upper_band, "Upper Band", color=color.blue, linewidth=1)
  177. p2 = plot(lower_band, "Lower Band", color=color.blue, linewidth=1)
  178. fill(p1, p2, color=color.new(color.blue, 90))
  179.  
  180. // --- Plot REAL-TIME breakout markers (ONLY DURING NY SESSION) ---
  181. if current_bullish_breakout and inSession
  182. // Marker on the price where breakout occurred
  183. if show_markers
  184. line.new(bar_index - 1, high, bar_index, high, color=bullish_color, width=2, style=line.style_solid)
  185.  
  186. // Label with distance
  187. label_y = high + (high * 0.0005) // Small offset above price
  188.  
  189. if bar_index == largest_bullish_bar and show_extreme
  190. label.new(bar_index, label_y, "▲ " + str.tostring(math.round(current_bullish_distance * 100) / 100, "#.##") + "$", color=bullish_color, style=label.style_label_down, textcolor=color.white, size=size.large)
  191. else
  192. label.new(bar_index, label_y, str.tostring(math.round(current_bullish_distance * 100) / 100, "#.##") + "$", color=bullish_color, style=label.style_label_down, textcolor=color.white, size=size.normal)
  193.  
  194. if current_bearish_breakout and inSession
  195. // Marker on the price where breakout occurred
  196. if show_markers
  197. line.new(bar_index - 1, low, bar_index, low, color=bearish_color, width=2, style=line.style_solid)
  198.  
  199. // Label with distance
  200. label_y = low - (low * 0.0005) // Small offset below price
  201.  
  202. if bar_index == largest_bearish_bar and show_extreme
  203. label.new(bar_index, label_y, "▼ " + str.tostring(math.round(current_bearish_distance * 100) / 100, "#.##") + "$", color=bearish_color, style=label.style_label_up, textcolor=color.white, size=size.large)
  204. else
  205. label.new(bar_index, label_y, str.tostring(math.round(current_bearish_distance * 100) / 100, "#.##") + "$", color=bearish_color, style=label.style_label_up, textcolor=color.white, size=size.normal)
  206.  
  207. // Plot historical breakouts (after bar closes) - ONLY DURING NY SESSION
  208. if barstate.isconfirmed and inSession[1]
  209. // Bullish breakout that occurred
  210. if high[1] - upper_band[1] >= breakout_threshold
  211. label.new(bar_index - 1, high[1], "✓", color=color.new(bullish_color, 30), style=label.style_label_down, textcolor=bullish_color, size=size.small)
  212.  
  213. // Bearish breakout that occurred
  214. if lower_band[1] - low[1] >= breakout_threshold
  215. label.new(bar_index - 1, low[1], "✓", color=color.new(bearish_color, 30), style=label.style_label_up, textcolor=bearish_color, size=size.small)
  216.  
  217. // --- Plot breakout threshold lines ---
  218. plot(upper_band + breakout_threshold, "Upper Threshold", color=color.new(color.green, 50), style=plot.style_circles, linewidth=1)
  219. plot(lower_band - breakout_threshold, "Lower Threshold", color=color.new(color.red, 50), style=plot.style_circles, linewidth=1)
  220.  
  221. // --- Background color for NY Session ---
  222. bgcolor(inSession ? color.new(color.blue, 90) : na, title="NY Session Background")
  223.  
  224. // --- Info table ---
  225. var table info_table = table.new(position.top_right, 1, 8, border_width=1)
  226. if barstate.islast
  227. table.cell(info_table, 0, 0, "XAUUSD Bollinger + Strong Moves", text_color=color.white, bgcolor=color.blue)
  228. table.cell(info_table, 0, 1, "NY Session: 9:30-19:00", text_color=color.white, bgcolor=color.gray)
  229. table.cell(info_table, 0, 2, "Threshold: " + str.tostring(breakout_threshold) + " USD", text_color=color.white, bgcolor=color.gray)
  230. table.cell(info_table, 0, 3, "Strong Move: ≥" + str.tostring(min_move_percent) + "%", text_color=color.white, bgcolor=color.gray)
  231. table.cell(info_table, 0, 4, "Timeframe: " + timeframe.period, text_color=color.white, bgcolor=color.gray)
  232. table.cell(info_table, 0, 5, "▲▼ = Largest in Session", text_color=color.white, bgcolor=color.gray)
  233. table.cell(info_table, 0, 6, "✓ = Confirmed", text_color=color.white, bgcolor=color.gray)
  234. table.cell(info_table, 0, 7, "Real-Time Detection", text_color=color.white, bgcolor=color.gray)
  235.  
  236. // --- Alerts for breakouts (ONLY DURING NY SESSION) ---
  237. alertcondition(bullish_breakout, "Bullish Breakout NY", "Price moved above upper band by ${breakout_threshold} during NY session")
  238. alertcondition(bearish_breakout, "Bearish Breakout NY", "Price moved below lower band by ${breakout_threshold} during NY session")
  239.  
  240. // --- NY Session High/Low Breakout Alerts ---
  241. bool breakHigh = inSession and ta.crossover(close, refHigh)
  242. bool breakLow = inSession and ta.crossunder(close, refLow)
  243. alertcondition(breakHigh, title="Break Above 9:30 High", message="Price broke above the 9:30am High (NY).")
  244. alertcondition(breakLow, title="Break Below 9:30 Low", message="Price broke below the 9:30am Low (NY).")
  245.  
  246. // --- Strong Move Alerts ---
  247. alertcondition(strong_bullish_move and barstate.isconfirmed, "Strong Bullish Move", "Strong bullish move detected: ${move_percent}% over ${lookback_bars} bars")
  248. alertcondition(strong_bearish_move and barstate.isconfirmed, "Strong Bearish Move", "Strong bearish move detected: ${move_percent}% over ${lookback_bars} bars")
Advertisement
Add Comment
Please, Sign In to add comment