safwan092

Untitled

Aug 31st, 2025
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.64 KB | None | 0 0
  1. //@version=5
  2. indicator("ICT S&D Profile + Range Filter [TFO]", "S&D Profile + Range Filter", true, max_boxes_count = 500, max_labels_count = 500)
  3.  
  4. // ================================== ICT SEEK & DESTROY PROFILE ==================================
  5. // -------------------------------------------------- Inputs --------------------------------------------------
  6. var g_KZS = "Killzones"
  7. as_am = input.session(title="Asia", defval="2000-0300", inline = "ASKZ", group = g_KZS)
  8. askz_color = input.color(color.new(color.blue, 80), "", inline = "ASKZ", group = g_KZS)
  9. lo_am = input.session(title="London", defval="0300-0830", inline = "LOKZ", group = g_KZS)
  10. ldkz_color = input.color(color.new(color.yellow, 80), "", inline = "LOKZ", group = g_KZS)
  11. ny_am = input.session(title="New York", defval="0830-1600", inline = "NYKZ", group = g_KZS)
  12. nykz_color = input.color(color.new(color.green, 80), "", inline = "NYKZ", group = g_KZS)
  13.  
  14. var g_CRT = "Success Criteria"
  15. crt_inside_day = input.bool(true, "NY Stays Within London Range", tooltip = "The New York range is contained within the London range", group = g_CRT)
  16. crt_outside_day = input.bool(true, "NY Exceeds London High & Low", tooltip = "The New York range exceeds both the high and low of the London range", group = g_CRT)
  17. crt_close_in_lo = input.bool(true, "NY Closes Within London Range", tooltip = "The New York range closes within the London range", group = g_CRT)
  18. crt_sd_limit = input.bool(true, "NY Range Too Small", tooltip = "The New York range will be compared to the standard deviation of its historical ranges, multiplied by this factor", inline = "SD", group = g_CRT)
  19. sd_limit = input.float(1.0, "", inline = "SD", group = g_CRT)
  20.  
  21. var g_SND = "Labels"
  22. show_snd_pre = input.bool(true, "Potential S&D Day", inline = "PRE", tooltip = "If London took both sides of the Asian range, this label will be generated", group = g_SND)
  23. snd_pre_color = input.color(title="", defval = #f23645, inline = "PRE", group = g_SND)
  24. show_snd_day = input.bool(true, "Successful S&D Day", inline = "POST", tooltip = "If New York met any of the selected success criteria, this label will populate", group = g_SND)
  25. snd_day_color = input.color(title="", defval = #089981, inline = "POST", group = g_SND)
  26.  
  27. var g_WRN = "Warning"
  28. show_wrn_table = input.bool(true, "Show Warning", tooltip = "Display the custom warning message when it is a potential S&D day (for the duration of the NY session)", group = g_WRN)
  29. wrn_msg = input.string("Potential S&D Day", "Warning Message", group = g_WRN)
  30. wrn_text = input.color(color.white, "Text Color", group = g_WRN)
  31. wrn_bg = input.color(#f23645, "Table Background", group = g_WRN)
  32.  
  33. var g_STY = "Statistics"
  34. show_stat_table = input.bool(true, "Show Statistics Table", group = g_STY)
  35. table_position = input.string('Top Right', "Table Position", options = ['Bottom Center', 'Bottom Left', 'Bottom Right', 'Middle Center', 'Middle Left', 'Middle Right', 'Top Center', 'Top Left', 'Top Right'], group = g_STY)
  36. table_size = input.string('Auto', "Text Size", options = ['Auto', 'Tiny', 'Small', 'Normal', 'Large', 'Huge'], group = g_STY)
  37. table_text = input.color(color.black, "Text", group = g_STY)
  38. table_bg = input.color(color.white, "Table Background", group = g_STY)
  39. table_frame = input.color(color.black, "Table Frame", group = g_STY)
  40. table_border = input.color(color.black, "Table Border", group = g_STY)
  41. table_border_width = input.int(1, "Table Border Width", group = g_STY)
  42. table_frame_width = input.int(2, "Table Frame Width", group = g_STY)
  43. // -------------------------------------------------- Inputs --------------------------------------------------
  44.  
  45.  
  46. // -------------------------------------------------- Constants & Variables --------------------------------------------------
  47. nykz = not na(time(timeframe.period, ny_am, "America/New_York"))
  48. lokz = not na(time(timeframe.period, lo_am, "America/New_York"))
  49. askz = not na(time(timeframe.period, as_am, "America/New_York"))
  50.  
  51. var int sessions = 0
  52.  
  53. var int last_snd_pre = 0
  54. var int last_snd_day = 0
  55.  
  56. var int total_snd_wrn = 0
  57. var int total_snd_day = 0
  58.  
  59. var box nykz_box = na
  60. var box lokz_box = na
  61. var box askz_box = na
  62.  
  63. var int last_new_ny = na
  64. var float last_ny_high = na
  65. var float last_ny_low = na
  66. var float last_ny_close = na
  67.  
  68. var int last_new_lo = na
  69. var float last_lo_high = na
  70. var float last_lo_low = na
  71. var float last_lo_close = na
  72.  
  73. var int last_new_as = na
  74. var float last_as_high = na
  75. var float last_as_low = na
  76. var float last_as_close = na
  77.  
  78. var ny_range = array.new_float()
  79. // -------------------------------------------------- Constants & Variables --------------------------------------------------
  80.  
  81.  
  82. // -------------------------------------------------- Functions --------------------------------------------------
  83. manual_stdev() =>
  84. mean = array.avg(ny_range)
  85. accum = 0.0
  86. size = array.size(ny_range)
  87. if size > 0
  88. for i = 0 to size - 1
  89. accum += math.pow((array.get(ny_range, i) - mean), 2)
  90. sd = math.sqrt(accum / size)
  91.  
  92. get_table_position(pos) =>
  93. result = switch pos
  94. "Bottom Center" => position.bottom_center
  95. "Bottom Left" => position.bottom_left
  96. "Bottom Right" => position.bottom_right
  97. "Middle Center" => position.middle_center
  98. "Middle Left" => position.middle_left
  99. "Middle Right" => position.middle_right
  100. "Top Center" => position.top_center
  101. "Top Left" => position.top_left
  102. "Top Right" => position.top_right
  103.  
  104. get_text_size(size) =>
  105. result = switch size
  106. 'Auto' => size.auto
  107. 'Tiny' => size.tiny
  108. 'Small' => size.small
  109. 'Normal' => size.normal
  110. 'Large' => size.large
  111. 'Huge' => size.huge
  112. // -------------------------------------------------- Functions --------------------------------------------------
  113.  
  114.  
  115. // -------------------------------------------------- Core Logic --------------------------------------------------
  116. if nykz
  117. if not nykz[1]
  118. nykz_box := box.new(bar_index, high, bar_index, low, text = "New York", text_color = nykz_color, bgcolor = nykz_color, border_color = nykz_color)
  119. sessions += 1
  120. else
  121. top = box.get_top(nykz_box)
  122. bot = box.get_bottom(nykz_box)
  123. if high > top
  124. top := high
  125. if low < bot
  126. bot := low
  127. box.set_rightbottom(nykz_box, bar_index, bot)
  128. box.set_top(nykz_box, top)
  129.  
  130. if lokz
  131. if not lokz[1]
  132. lokz_box := box.new(bar_index, high, bar_index, low, text = "London", text_color = ldkz_color, bgcolor = ldkz_color, border_color = ldkz_color)
  133. else
  134. top = box.get_top(lokz_box)
  135. bot = box.get_bottom(lokz_box)
  136. if high > top
  137. top := high
  138. if low < bot
  139. bot := low
  140. box.set_rightbottom(lokz_box, bar_index, bot)
  141. box.set_top(lokz_box, top)
  142.  
  143. if askz
  144. if not askz[1]
  145. askz_box := box.new(bar_index, high, bar_index, low, text = "Asia", text_color = askz_color, bgcolor = askz_color, border_color = askz_color)
  146. else
  147. top = box.get_top(askz_box)
  148. bot = box.get_bottom(askz_box)
  149. if high > top
  150. top := high
  151. if low < bot
  152. bot := low
  153. box.set_rightbottom(askz_box, bar_index, bot)
  154. box.set_top(askz_box, top)
  155.  
  156. if not nykz and nykz[1]
  157. last_ny_high := box.get_top(nykz_box)
  158. last_ny_low := box.get_bottom(nykz_box)
  159. last_ny_close := close[1]
  160. last_new_ny := bar_index
  161. array.push(ny_range, last_ny_high - last_ny_low)
  162.  
  163. if not lokz and lokz[1]
  164. last_lo_high := box.get_top(lokz_box)
  165. last_lo_low := box.get_bottom(lokz_box)
  166. last_lo_close := close[1]
  167. last_new_lo := bar_index
  168.  
  169. if not askz and askz[1]
  170. last_as_high := box.get_top(askz_box)
  171. last_as_low := box.get_bottom(askz_box)
  172. last_as_close := close[1]
  173. last_new_as := bar_index
  174.  
  175. snd_day_wrn = false
  176. if last_new_lo > last_new_as and last_lo_high > last_as_high and last_lo_low < last_as_low and last_snd_pre < last_new_lo
  177. snd_day_wrn := true
  178. last_snd_pre := bar_index
  179. total_snd_wrn += 1
  180.  
  181. snd_day_valid = false
  182. if last_new_ny > last_new_lo and last_snd_pre > last_new_as and last_snd_day < last_new_ny
  183. outside_day = crt_outside_day ? last_ny_high >= last_lo_high and last_ny_low <= last_lo_low : false
  184. inside_day = crt_inside_day ? last_ny_high < last_lo_high and last_ny_low > last_lo_low : false
  185. close_inside_lo = crt_close_in_lo ? last_ny_close < last_lo_high and last_ny_close > last_lo_low : false
  186. stdev = crt_sd_limit ? last_ny_high - last_ny_low <= manual_stdev() * sd_limit : false
  187.  
  188. if outside_day or inside_day or close_inside_lo or stdev
  189. snd_day_valid := true
  190. last_snd_day := bar_index
  191. total_snd_day += 1
  192.  
  193. if show_snd_pre and snd_day_wrn
  194. label.new(bar_index, last_lo_high, "Potential S&D Day", color = snd_pre_color, textcolor = wrn_text)
  195. if show_snd_day and snd_day_valid
  196. label.new(bar_index, last_ny_high, "Valid S&D Day", color = snd_day_color, textcolor = wrn_text)
  197. // -------------------------------------------------- Core Logic --------------------------------------------------
  198.  
  199.  
  200. // -------------------------------------------------- Table --------------------------------------------------
  201. var stats = table.new(get_table_position(table_position), 10, 10, bgcolor = table_bg, frame_color = table_frame, border_color = table_border, frame_width = table_frame_width, border_width = table_border_width)
  202. table_text_size = get_text_size(table_size)
  203.  
  204. if barstate.islast
  205. if show_stat_table
  206. table.cell(stats, 0, 1, "Seek & Destroy Profile", text_color = table_text, text_size = table_text_size)
  207. table.cell(stats, 0, 2, "Total Sessions", text_color = table_text, text_size = table_text_size)
  208. table.cell(stats, 1, 2, str.tostring(sessions), text_color = table_text, text_size = table_text_size)
  209. table.cell(stats, 0, 3, "Warnings Given", text_color = table_text, text_size = table_text_size)
  210. table.cell(stats, 1, 3, str.tostring(total_snd_wrn), text_color = table_text, text_size = table_text_size)
  211. table.cell(stats, 0, 4, "Warning Success", text_color = table_text, text_size = table_text_size)
  212. table.cell(stats, 1, 4, str.tostring(total_snd_day), text_color = table_text, text_size = table_text_size)
  213. table.cell(stats, 0, 5, "Warning Success Rate", text_color = table_text, text_size = table_text_size)
  214. success_rate = total_snd_wrn > 0 ? math.round(total_snd_day / total_snd_wrn * 100) : 0
  215. table.cell(stats, 1, 5, str.tostring(success_rate) + "%", text_color = table_text, text_size = table_text_size)
  216.  
  217. if show_wrn_table and snd_day_wrn
  218. table.cell(stats, 0, 1, wrn_msg, text_color = wrn_text, bgcolor = wrn_bg, text_size = table_text_size)
  219. // -------------------------------------------------- Table --------------------------------------------------
  220.  
  221.  
  222. // ================================== RANGE FILTER INDICATOR ==================================
  223. // Inputs for Range Filter
  224. var grp_RF = "Range Filter Settings"
  225. rf_src = input(defval=close, title="Source", group=grp_RF)
  226. rf_per = input.int(defval=100, minval=1, title="Sampling Period", group=grp_RF)
  227. rf_mult = input.float(defval=3.0, minval=0.1, title="Range Multiplier", group=grp_RF)
  228.  
  229. // Color variables for Range Filter
  230. rf_upColor = color.white
  231. rf_midColor = #90bff9
  232. rf_downColor = color.blue
  233.  
  234. // Range Filter Functions
  235. rf_smoothrng(x, t, m) =>
  236. wper = t * 2 - 1
  237. avrng = ta.ema(math.abs(x - x[1]), t)
  238. smoothrng = ta.ema(avrng, wper) * m
  239. smoothrng
  240.  
  241. rf_rngfilt(x, r) =>
  242. rngfilt = x
  243. rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r :
  244. x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
  245. rngfilt
  246.  
  247. // Range Filter Calculations
  248. rf_smrng = rf_smoothrng(rf_src, rf_per, rf_mult)
  249. rf_filt = rf_rngfilt(rf_src, rf_smrng)
  250.  
  251. // Filter Direction
  252. rf_upward = 0.0
  253. rf_upward := rf_filt > rf_filt[1] ? nz(rf_upward[1]) + 1 : rf_filt < rf_filt[1] ? 0 : nz(rf_upward[1])
  254. rf_downward = 0.0
  255. rf_downward := rf_filt < rf_filt[1] ? nz(rf_downward[1]) + 1 : rf_filt > rf_filt[1] ? 0 : nz(rf_downward[1])
  256.  
  257. // Target Bands
  258. rf_hband = rf_filt + rf_smrng
  259. rf_lband = rf_filt - rf_smrng
  260.  
  261. // Colors
  262. rf_filtcolor = rf_upward > 0 ? rf_upColor : rf_downward > 0 ? rf_downColor : rf_midColor
  263. rf_barcolor = rf_src > rf_filt and rf_src > rf_src[1] and rf_upward > 0 ? rf_upColor :
  264. rf_src > rf_filt and rf_src < rf_src[1] and rf_upward > 0 ? rf_upColor :
  265. rf_src < rf_filt and rf_src < rf_src[1] and rf_downward > 0 ? rf_downColor :
  266. rf_src < rf_filt and rf_src > rf_src[1] and rf_downward > 0 ? rf_downColor : rf_midColor
  267.  
  268. // Plots
  269. rf_filtplot = plot(rf_filt, color=rf_filtcolor, linewidth=2, title="Range Filter")
  270. rf_hbandplot = plot(rf_hband, color=color.new(rf_upColor, 70), title="High Target")
  271. rf_lbandplot = plot(rf_lband, color=color.new(rf_downColor, 70), title="Low Target")
  272.  
  273. // Fills
  274. fill(rf_hbandplot, rf_filtplot, color=color.new(rf_upColor, 90), title="High Target Range")
  275. fill(rf_lbandplot, rf_filtplot, color=color.new(rf_downColor, 90), title="Low Target Range")
  276.  
  277. // Bar Color (only if Range Filter bar coloring is enabled)
  278. barcolor(rf_barcolor)
  279.  
  280. // Break Outs
  281. rf_longCond = false
  282. rf_shortCond = false
  283. rf_longCond := rf_src > rf_filt and rf_src > rf_src[1] and rf_upward > 0 or
  284. rf_src > rf_filt and rf_src < rf_src[1] and rf_upward > 0
  285. rf_shortCond := rf_src < rf_filt and rf_src < rf_src[1] and rf_downward > 0 or
  286. rf_src < rf_filt and rf_src > rf_src[1] and rf_downward > 0
  287.  
  288. rf_CondIni = 0
  289. rf_CondIni := rf_longCond ? 1 : rf_shortCond ? -1 : rf_CondIni[1]
  290. rf_longCondition = rf_longCond and rf_CondIni[1] == -1
  291. rf_shortCondition = rf_shortCond and rf_CondIni[1] == 1
  292.  
  293. // Signals
  294. plotshape(rf_longCondition, title="Buy Signal", text="Buy", textcolor=color.white, style=shape.labelup, size=size.small, location=location.belowbar, color=color.new(#aaaaaa, 20))
  295. plotshape(rf_shortCondition, title="Sell Signal", text="Sell", textcolor=color.white, style=shape.labeldown, size=size.small, location=location.abovebar, color=color.new(rf_downColor, 20))
  296.  
  297. // Alerts
  298. alertcondition(rf_longCondition, title="Buy alert on Range Filter", message="Buy alert on Range Filter")
  299. alertcondition(rf_shortCondition, title="Sell alert on Range Filter", message="Sell alert on Range Filter")
  300. alertcondition(rf_longCondition or rf_shortCondition, title="Buy and Sell alert on Range Filter", message="Buy and Sell alert on Range Filter")
Advertisement
Add Comment
Please, Sign In to add comment