ajiim

🎁

Aug 20th, 2026
5,084
2
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 110.67 KB | None | 2 0
  1. //@version=5
  2. indicator("Unicorn Model", shorttitle="Unicorn", overlay=true, max_boxes_count=500, max_lines_count=500, max_labels_count=500, max_bars_back=500)
  3.  
  4. type UnicornSetup
  5. bool isBull
  6. bool isUnicorn
  7. string sweepLabel
  8. float zoneTop
  9. float zoneBot
  10. float[] fvgTops
  11. float[] fvgBots
  12. float sweepLevel
  13. int sweepBar
  14. int activationBar
  15. float invalidLevel
  16. bool useSwingInval
  17. float entryPrice
  18. float riskSize
  19. float mainTarget
  20. float[] extraTargets
  21. int state
  22. bool alertedPotential
  23. bool alertedActivation
  24. bool alertedTarget
  25. bool alertedInvalWarn
  26. bool alertedInvalHit
  27. bool alertedBE
  28. bool isBEActive
  29. box zoneBox
  30. box[] fvgBoxes
  31. line sweepLine
  32. label sweepLbl
  33. label zoneLbl
  34. line[] targetLines
  35. label[] targetLabels
  36. line bb50Line
  37. line[] fvgCeLines
  38. line beTriggerLine
  39. label beTriggerLabel
  40.  
  41. type HtfFVG
  42. box fvgBox
  43. line midline
  44. label fvgLabel
  45. float top
  46. float bottom
  47. bool isBullish
  48. int startTime
  49. bool mitigated
  50. int mitigationTime
  51.  
  52. type SMT
  53. string smtType
  54. string smtPair
  55. float prevChartHigh
  56. float currChartHigh
  57. int prevChartHighTime
  58. int currChartHighTime
  59. float prevChartLow
  60. float currChartLow
  61. int prevChartLowTime
  62. int currChartLowTime
  63. bool confirmed
  64. int creationBar
  65. line smtLine
  66. label smtLabel
  67.  
  68. type Candle
  69. float o
  70. float c
  71. float h
  72. float l
  73. int o_idx
  74. int c_idx
  75. int h_idx
  76. int l_idx
  77. box body
  78. line wick_up
  79. line wick_down
  80. line line_o
  81. line line_h
  82. line line_l
  83. line line_c
  84. label lbl_o
  85. label lbl_h
  86. label lbl_l
  87. label lbl_c
  88.  
  89. type CandleSettings
  90. bool show
  91. string htf
  92. int max_display
  93.  
  94. type SettingsCandle
  95. color bull_body
  96. color bull_border
  97. color bull_wick
  98. color bear_body
  99. color bear_border
  100. color bear_wick
  101. int offset
  102. int buffer
  103. int width
  104. color line_color
  105.  
  106. type CandleSet
  107. Candle[] candles
  108. CandleSettings settings
  109. label infoLabel
  110. int htf_start_bar
  111. float htf_open_price
  112. float htf_high_trace
  113. float htf_low_trace
  114.  
  115. var GRP_GEN = "General Settings"
  116. i_history = input.int (50, "Max History", minval=1, maxval=50, group=GRP_GEN, tooltip="Max number of setups displayed simultaneously.")
  117. i_biasMode = input.string("Neutral", "Bias Mode", options=["Neutral","Bullish","Bearish","Auto"], group=GRP_GEN)
  118. i_modelMode = input.string("Unicorn", "Model Mode", options=["Breaker", "Unicorn", "Breaker + Unicorn"], group=GRP_GEN)
  119. i_showPotential = input.bool (true, "Show Potential Model", group=GRP_GEN)
  120. i_swingInval = input.bool (false, "Use Swing for Invalidation", group=GRP_GEN, tooltip="Stop loss placed at manipulation extreme.")
  121. i_discardInval = input.bool (false, "Discard Invalidated", group=GRP_GEN)
  122.  
  123. var G_TF = "HTF Candles Settings"
  124. htf_mode_candle = input.string("Auto", "Mode", options=["Auto", "Custom"], inline="htf1", group=G_TF)
  125. custom_htf_candle = input.string("1 week", "Custom TF", options=["30 minutes", "45 minutes", "90 minutes", "1 hour", "2 hours", "3 hours", "4 hours", "6 hours", "7 hours", "9 hours", "1 day", "1 week", "1 month", "3 months", "6 months", "12 months"], inline="htf1", group=G_TF)
  126. max_display_inp_candle = input.int(4, "Max Displayed", minval=1, maxval=50, group=G_TF)
  127.  
  128. show_htf_info = input.bool(true, "Show Info & Timer", inline="info1", group=G_TF)
  129. info_size = input.string(size.normal, "Size", options=[size.tiny, size.small, size.normal, size.large], inline="info1", group=G_TF)
  130. info_col = input.color(color.rgb(8, 8, 8), "Color", inline="info1", group=G_TF)
  131.  
  132. show_sweeps = input.bool(true, "Show Sweep Lines", inline="swp1", group=G_TF)
  133. line_color_candle = input.color(color.rgb(0, 0, 0), "Color", inline="swp1", group=G_TF)
  134.  
  135. var G_APP_CANDLE = "HTF Candle Appearance & Projections"
  136. bull_body_col_candle = input.color(color.new(#83b785, 0), "Bull Body / Border", inline="b1", group=G_APP_CANDLE)
  137. bull_bord_col_candle = input.color(color.new(#5f5f5f, 0), "", inline="b1", group=G_APP_CANDLE)
  138. bear_body_col_candle = input.color(color.new(#5f5f5f, 0), "Bear Body / Border", inline="b2", group=G_APP_CANDLE)
  139. bear_bord_col_candle = input.color(color.new(#5f5f5f, 0), "", inline="b2", group=G_APP_CANDLE)
  140. bull_wick_col_candle = input.color(color.new(#5f5f5f, 0), "Wick Bull / Bear", inline="w1", group=G_APP_CANDLE)
  141. bear_wick_col_candle = input.color(color.new(#5f5f5f, 0), "", inline="w1", group=G_APP_CANDLE)
  142.  
  143. chart_offset_candle = input.int(10, "Padding Offset", minval = 1, inline="dim1", group=G_APP_CANDLE)
  144. candle_buffer_candle = input.int(1, "Spacing", minval = 1, maxval = 4, inline="dim1", group=G_APP_CANDLE)
  145. candle_width_candle = input.int(1, "Width", minval = 1, maxval = 4, inline="dim1", group=G_APP_CANDLE) * 2
  146.  
  147. proj_o_enabled = input.bool(false, "Open Line", inline="po", group=G_APP_CANDLE)
  148. proj_o_col = input.color(color.new(#000000, 10), "", inline="po", group=G_APP_CANDLE)
  149. proj_o_style = input.string("Dotted", "", options=["Solid", "Dotted", "Dashed"], inline="po", group=G_APP_CANDLE)
  150. proj_o_width = input.int(1, "", minval=1, inline="po", group=G_APP_CANDLE)
  151.  
  152. proj_hl_enabled = input.bool(false, "High/Low Lines", inline="phl", group=G_APP_CANDLE)
  153. proj_hl_col = input.color(color.new(#000000, 10), "", inline="phl", group=G_APP_CANDLE)
  154. proj_hl_style = input.string("Dotted", "", options=["Solid", "Dotted", "Dashed"], inline="phl", group=G_APP_CANDLE)
  155. proj_hl_width = input.int(1, "", minval=1, inline="phl", group=G_APP_CANDLE)
  156.  
  157. proj_c_enabled = input.bool(false, "Close Line", inline="pc", group=G_APP_CANDLE)
  158. proj_c_col = input.color(color.new(#000000, 10), "", inline="pc", group=G_APP_CANDLE)
  159. proj_c_style = input.string("Dotted", "", options=["Solid", "Dotted", "Dashed"], inline="pc", group=G_APP_CANDLE)
  160. proj_c_width = input.int(1, "", minval=1, inline="pc", group=G_APP_CANDLE)
  161.  
  162. proj_lbl_enabled = input.bool(false, "Price Labels", inline="plbl", group=G_APP_CANDLE)
  163. proj_lbl_col = input.color(color.rgb(0, 0, 0), "", inline="plbl", group=G_APP_CANDLE)
  164. proj_lbl_size = input.string(size.small, "", options=[size.tiny, size.small, size.normal, size.large], inline="plbl", group=G_APP_CANDLE)
  165.  
  166. var GRP_SRC = "Liquidity Sources"
  167. i_srcMode = input.string("Multiple", "Source Mode", options=["Single","Multiple"], inline="sm1", group=GRP_SRC)
  168. i_srcAuto = input.string("Automatic","Mapping", options=["Automatic","Manual"], inline="sm1", group=GRP_SRC)
  169. i_srcAType = input.string("OHLC + Swing","Auto Type", options=["OHLC + Swing","OHLC Only","Swing Only"], group=GRP_SRC)
  170.  
  171. i_srcAEnable = input.bool (true, "Source A", inline="srcA", group=GRP_SRC)
  172. i_srcATF = input.timeframe("60", "TF", inline="srcA", group=GRP_SRC)
  173. i_srcALiq = input.string("OHLC + Swing","Liq", inline="srcA", options=["OHLC + Swing","OHLC Only","Swing Only"], group=GRP_SRC)
  174.  
  175. i_srcBEnable = input.bool (true, "Source B", inline="srcB", group=GRP_SRC)
  176. i_srcBTF = input.timeframe("240","TF", inline="srcB", group=GRP_SRC)
  177. i_srcBLiq = input.string("OHLC + Swing","Liq", inline="srcB", options=["OHLC + Swing","OHLC Only","Swing Only"], group=GRP_SRC)
  178.  
  179. i_srcCEnable = input.bool (true, "Source C", inline="srcC", group=GRP_SRC)
  180. i_srcCTF = input.timeframe("D", "TF", inline="srcC", group=GRP_SRC)
  181. i_srcCLiq = input.string("OHLC + Swing","Liq", inline="srcC", options=["OHLC + Swing","OHLC Only","Swing Only"], group=GRP_SRC)
  182.  
  183. var GRP_SESS_LIQ = "Session Liquidity Levels"
  184. i_useSessLiq = input.bool(true, "Enable Session Liquidity", group=GRP_SESS_LIQ)
  185. i_sessL1Name = input.string("Asia", "Session 1", inline="sl1", group=GRP_SESS_LIQ)
  186. i_sessL1Time = input.session("2000-0000", "", inline="sl1", group=GRP_SESS_LIQ)
  187. i_sessL2Name = input.string("London", "Session 2", inline="sl2", group=GRP_SESS_LIQ)
  188. i_sessL2Time = input.session("0200-0500", "", inline="sl2", group=GRP_SESS_LIQ)
  189. i_sessL3Name = input.string("New York AM", "Session 3", inline="sl3", group=GRP_SESS_LIQ)
  190. i_sessL3Time = input.session("0930-1200", "", inline="sl3", group=GRP_SESS_LIQ)
  191. i_sessL4Name = input.string("New York PM", "Session 4", inline="sl4", group=GRP_SESS_LIQ)
  192. i_sessL4Time = input.session("1330-1600", "", inline="sl4", group=GRP_SESS_LIQ)
  193.  
  194. var GRP_PROJ = "Target Projections & R:R"
  195. i_showRR = input.bool (true, "Show Main R:R Target", inline="r1", group=GRP_PROJ)
  196. i_rrMain = input.float (2.0, "Multiplier", minval=0.1, step=0.5, inline="r1", group=GRP_PROJ)
  197. i_projCalc = input.string("Confirmation Close", "Calculation Anchor", options=["Breaker Range", "Confirmation Close"], group=GRP_PROJ)
  198. i_showExtra = input.bool (false, "Show Extra Targets", inline="r2", group=GRP_PROJ)
  199. i_extraStr = input.string("1,3.5","Multipliers", inline="r2", group=GRP_PROJ, tooltip="Comma-separated R multiples, e.g. 1,1.5,3")
  200.  
  201. var GRP_BE = "Break-Even Protection (50%)"
  202. i_useBE = input.bool (true, "Enable Auto Break-Even", group=GRP_BE)
  203. i_showBELine = input.bool (true, "Show BE Trigger Line", inline="bel1", group=GRP_BE)
  204. i_beLineWidth = input.int (1, "Width", minval=1, maxval=4, inline="bel1", group=GRP_BE)
  205. i_beLineStyle = input.string("dotted", "Style", options=["solid","dashed","dotted"], inline="bel2", group=GRP_BE)
  206. i_beLineColor = input.color (color.new(#2962ff, 0), "Color", inline="bel2", group=GRP_BE)
  207.  
  208. var GRP_LIMIT = "Daily Risk Limiter"
  209. i_useDailyLimit = input.bool(true, "Enable Daily Trade Limits", group=GRP_LIMIT)
  210. i_maxDailyWins = input.int(1, "Max Wins", minval=1, inline="dl1", group=GRP_LIMIT)
  211. i_maxDailyLosses = input.int(2, "Max Losses", minval=1, inline="dl1", group=GRP_LIMIT)
  212.  
  213. var int[] dailyStats = array.new_int(3, 0)
  214.  
  215. var int[] stat_years = array.new_int(0)
  216. var int[] stat_months = array.new_int(0)
  217. var int[] stat_outcomes = array.new_int(0)
  218.  
  219. var GRP_STY = "Visuals & Zone Styling"
  220. i_lblSize = input.string("small", "Label Size", options=["tiny","small","normal","large","huge"], group=GRP_STY)
  221.  
  222. i_bullColor = input.color(color.new(#2962ff, 89), "Bull Breaker / Retested", inline="bc1", group=GRP_STY)
  223. i_bullRetColor = input.color(color.new(#2962ff, 85), "", inline="bc1", group=GRP_STY)
  224. i_bullFvgColor = input.color(color.new(#ff9800, 70), "Bull FVG Color", group=GRP_STY)
  225.  
  226. i_bearColor = input.color(color.new(#2962ff, 89), "Bear Breaker / Retested", inline="br1", group=GRP_STY)
  227. i_bearRetColor = input.color(color.new(#2962ff, 85), "", inline="br1", group=GRP_STY)
  228. i_bearFvgColor = input.color(color.new(#ff9800, 70), "Bear FVG Color", group=GRP_STY)
  229.  
  230. i_invalColor = input.color(color.new(#b0bec5, 92), "Invalidated Ghost Color", group=GRP_STY)
  231.  
  232. i_showCEBull = input.bool(false, "Show CE (Bull FVG)", inline="ceb", group=GRP_STY)
  233. i_extendFVGBull = input.bool(false, "Extend", inline="ceb", group=GRP_STY)
  234. i_showCEBear = input.bool(false, "Show CE (Bear FVG)", inline="cebe", group=GRP_STY)
  235. i_extendFVGBear = input.bool(false, "Extend", inline="cebe", group=GRP_STY)
  236.  
  237. i_showBB50Bull = input.bool(false, "Show Bull BB 50%", inline="bb5b", group=GRP_STY)
  238. i_extendBB50Bull = input.bool(false, "Extend", inline="bb5b", group=GRP_STY)
  239. i_showBB50Bear = input.bool(false, "Show Bear BB 50%", inline="bb5be", group=GRP_STY)
  240. i_extendBB50Bear = input.bool(false, "Extend", inline="bb5be", group=GRP_STY)
  241. i_bb50Color = input.color(color.new(#000000, 30), "BB 50% Color", group=GRP_STY)
  242.  
  243. i_sweepLineColor = input.color(color.new(#000000, 0), "Sweep Line Color/Style/Width", inline="swl1", group=GRP_STY)
  244. i_sweepLineStyle = input.string("solid","", options=["solid","dashed","dotted"], inline="swl1", group=GRP_STY)
  245. i_sweepLineWidth = input.int (1, "", minval=1, maxval=4, inline="swl1", group=GRP_STY)
  246.  
  247. i_sweepLblColor = input.color(color.new(#000000, 20), "Sweep Label Color & Size", inline="swlb1", group=GRP_STY)
  248. i_sweepLblSize = input.string("small", "", options=["tiny","small","normal","large","huge"], inline="swlb1", group=GRP_STY)
  249.  
  250. i_projLineColor = input.color(color.new(#000000, 0), "Projection Line Color/Style/Width", inline="prl1", group=GRP_STY)
  251. i_projLineStyle = input.string("dotted","", options=["solid","dashed","dotted"], inline="prl1", group=GRP_STY)
  252. i_projLineWidth = input.int (1, "", minval=1, maxval=4, inline="prl1", group=GRP_STY)
  253.  
  254. var GRP_SZF = "Breaker Size Filter"
  255. i_sizeFilter = input.string("All", "Filter Mode", options=["All","Small+Med+Large","Med+Large","Large","Custom"], group=GRP_SZF)
  256. i_customSizeMode = input.string("Points", "Custom Unit", options=["Points","Pips"], inline="cs1", group=GRP_SZF)
  257. i_customMin = input.float (0.0, "Min", minval=0, step=1, inline="cs2", group=GRP_SZF)
  258. i_customMax = input.float (0.0, "Max", minval=0, step=1, inline="cs2", group=GRP_SZF)
  259.  
  260. var GRP_TF = "Time & Session Filter"
  261. i_useTimeFilter = input.bool (true, "Enable Time Filter", inline="tf0", group=GRP_TF)
  262. i_tz = input.string("exchange", "Timezone", inline="tf0", group=GRP_TF)
  263. effectiveTz = i_tz == "exchange" ? syminfo.timezone : i_tz
  264.  
  265. i_sess1Enable = input.bool (true, "Session 1", inline="s1", group=GRP_TF)
  266. i_sess1Name = input.string("London","Name", inline="s1", group=GRP_TF)
  267. i_sess1 = input.session("0300-0500","", inline="s1", group=GRP_TF)
  268.  
  269. i_sess2Enable = input.bool (true, "Session 2", inline="s2", group=GRP_TF)
  270. i_sess2Name = input.string("New York","Name", inline="s2", group=GRP_TF)
  271. i_sess2 = input.session("0830-1130","", inline="s2", group=GRP_TF)
  272.  
  273. i_sess3Enable = input.bool (false, "Session 3", inline="s3", group=GRP_TF)
  274. i_sess3Name = input.string("NY PM","Name", inline="s3", group=GRP_TF)
  275. i_sess3 = input.session("1300-1600","", inline="s3", group=GRP_TF)
  276.  
  277. var G_FVG_TF = "Standalone FVG Settings"
  278. fvg_autoMode = input.bool(true, 'Auto HTF Mode', inline="fvga", group = G_FVG_TF)
  279. fvg_manualHTF = input.timeframe('D', 'Manual HTF', inline="fvga", group = G_FVG_TF)
  280. fvg_showBullish = input.bool(true, 'Bullish FVGs', inline="fvgb", group = G_FVG_TF)
  281. fvg_showBearish = input.bool(true, 'Bearish FVGs', inline="fvgb", group = G_FVG_TF)
  282. fvg_showBoxes = input.bool(true, 'Show Boxes', inline="fvgc", group = G_FVG_TF)
  283. fvg_showLabels = input.bool(true, 'Show Labels', inline="fvgc", group = G_FVG_TF)
  284. fvg_showMidlines = input.bool(false, 'Show Midlines', inline="fvgc", group = G_FVG_TF)
  285. fvg_bullishColor = input.color(color.new(#4a4a4a, 90), 'Colors (Bull / Bear)', inline="fvgd", group = G_FVG_TF)
  286. fvg_bearishColor = input.color(color.new(#4a4a4a, 90), '', inline="fvgd", group = G_FVG_TF)
  287. fvg_midlineColor = input.color(color.new(color.gray, 50), 'Midline Color', group = G_FVG_TF)
  288. fvg_labelTextColor = input.color(color.gray, 'Label Color', group = G_FVG_TF)
  289. fvg_maxFVGs = input.int(4, 'Max Mitigated FVGs to Keep', minval = 1, maxval = 100, group = G_FVG_TF)
  290.  
  291. var G_SMT_TF = "SMT Divergence Settings"
  292. smt_autoMode = input.bool(true, 'Auto HTF Mode', inline="smta", group = G_SMT_TF)
  293. smt_manualHTF = input.timeframe('D', 'Manual HTF', inline="smta", group = G_SMT_TF)
  294. smt_AutoMode_Pair = input.bool(true, 'Auto Pair Mapping', inline="smtp", group = G_SMT_TF)
  295. smt_ManualPair = input.symbol('', 'Manual Pair', inline="smtp", group = G_SMT_TF)
  296. smt_KeepOnlyLatest = input.bool(true, 'Keep Only Latest SMTs', group = G_SMT_TF)
  297. smt_ShowLabels = input.bool(true, 'Show Labels', inline="smtl", group = G_SMT_TF)
  298. smt_LineWidth = input.int(1, 'Line Width', minval = 1, inline="smtl", group = G_SMT_TF)
  299. smt_BullColor = input.color(color.rgb(0, 0, 0), "Colors (Bull / Bear)", inline="smtc", group = G_SMT_TF)
  300. smt_BearColor = input.color(color.rgb(0, 0, 0), "", inline="smtc", group = G_SMT_TF)
  301.  
  302. var GRP_ALT = "Alert Notifications"
  303. i_alertEnable = input.bool (false, "Enable All Alerts", group=GRP_ALT)
  304. i_alertPotential = input.bool (true, "Potential Breaker", inline="al1", group=GRP_ALT)
  305. i_alertActiv = input.bool (true, "Activation", inline="al1", group=GRP_ALT)
  306. i_alertTarget = input.bool (true, "Target Reached", inline="al2", group=GRP_ALT)
  307. i_alertWarn = input.bool (true, "Invalidation Warning", inline="al2", group=GRP_ALT)
  308. i_alertHit = input.bool (true, "Invalidation Hit", group=GRP_ALT)
  309.  
  310. var GRP_TBL = "HUD Dashboard Tables"
  311. i_showTable = input.bool (true, "Show Info Table", inline="tb1", group=GRP_TBL)
  312. i_tableMode = input.string("Simple","Mode", options=["Simple","Detailed"], inline="tb1", group=GRP_TBL)
  313. i_tablePos = input.string("Bottom Right","Position", inline="tb1", group=GRP_TBL)
  314.  
  315. i_showStats = input.bool(true, "Show Stats Table", inline="st1", group=GRP_TBL)
  316. i_statsPos = input.string("Top Right", "Position", inline="st1", group=GRP_TBL)
  317.  
  318. getHTFName(string htf) =>
  319. seconds = timeframe.in_seconds(htf)
  320. if seconds >= 2592000
  321. "1M"
  322. else if seconds == 604800
  323. "1W"
  324. else if seconds >= 86400
  325. str.tostring(math.round(seconds / 86400)) + "D"
  326. else if seconds == 5400
  327. "90M"
  328. else if seconds >= 3600
  329. str.tostring(math.round(seconds / 3600)) + "H"
  330. else if seconds >= 60
  331. str.tostring(math.round(seconds / 60)) + "M"
  332. else
  333. str.tostring(seconds) + "S"
  334.  
  335. getRemainingTimeHTF(string htf) =>
  336. var string r = ""
  337. if barstate.isrealtime
  338. timeRemaining = (time_close(htf) - timenow) / 1000
  339. if timeRemaining > 0
  340. hours = math.floor(timeRemaining / 3600)
  341. minutes = math.floor((timeRemaining % 3600) / 60)
  342. seconds = math.floor(timeRemaining % 60)
  343. r := (hours > 0 ? str.tostring(hours, "00") + ":" : "") +
  344. str.tostring(minutes, "00") + ":" +
  345. str.tostring(seconds, "00")
  346. else
  347. r := "00:00:00"
  348. else
  349. r := "N/A"
  350. r
  351.  
  352. get_dynamic_time(string htf) =>
  353. tf_secs = timeframe.in_seconds(htf)
  354. res = ""
  355. if tf_secs >= 2592000
  356. res := str.format("{0,date,MMM}", time)
  357. else if tf_secs >= 604800
  358. res := str.upper(str.format("{0,date,dd MMM}", time))
  359. else if tf_secs >= 86400
  360. res := str.format("{0,date,EEE}", time)
  361. else
  362. res := str.format("{0,number,00}:{1,number,00}", hour(time), minute(time))
  363. res
  364.  
  365. get_tf_string(string text_val) =>
  366. switch text_val
  367. "30 minutes" => "30"
  368. "45 minutes" => "45"
  369. "90 minutes" => "90"
  370. "1 hour" => "60"
  371. "2 hours" => "120"
  372. "3 hours" => "180"
  373. "4 hours" => "240"
  374. "6 hours" => "360"
  375. "7 hours" => "420"
  376. "9 hours" => "540"
  377. "1 day" => "1D"
  378. "1 week" => "1W"
  379. "1 month" => "1M"
  380. "3 months" => "3M"
  381. "6 months" => "6M"
  382. "12 months" => "12M"
  383. => text_val
  384.  
  385. getProjLineStyle(string style) =>
  386. switch style
  387. 'Solid' => line.style_solid
  388. 'Dotted' => line.style_dotted
  389. 'Dashed' => line.style_dashed
  390. => line.style_dotted
  391.  
  392. getProjLabelSize(string sz) =>
  393. switch sz
  394. 'Tiny' => size.tiny
  395. 'Small' => size.small
  396. 'Normal' => size.normal
  397. 'Large' => size.large
  398. => size.small
  399.  
  400. f_lineStyle(s) =>
  401. s == "dashed" ? line.style_dashed : s == "dotted" ? line.style_dotted : line.style_solid
  402.  
  403. method deleteProjections(Candle candle) =>
  404. if not na(candle.line_o)
  405. line.delete(candle.line_o)
  406. candle.line_o := na
  407. if not na(candle.line_h)
  408. line.delete(candle.line_h)
  409. candle.line_h := na
  410. if not na(candle.line_l)
  411. line.delete(candle.line_l)
  412. candle.line_l := na
  413. if not na(candle.line_c)
  414. line.delete(candle.line_c)
  415. candle.line_c := na
  416. if not na(candle.lbl_o)
  417. label.delete(candle.lbl_o)
  418. candle.lbl_o := na
  419. if not na(candle.lbl_h)
  420. label.delete(candle.lbl_h)
  421. candle.lbl_h := na
  422. if not na(candle.lbl_l)
  423. label.delete(candle.lbl_l)
  424. candle.lbl_l := na
  425. if not na(candle.lbl_c)
  426. label.delete(candle.lbl_c)
  427. candle.lbl_c := na
  428.  
  429. var SettingsCandle settingsCandle = SettingsCandle.new(
  430. bull_body_col_candle, bull_bord_col_candle, bull_wick_col_candle,
  431. bear_body_col_candle, bear_bord_col_candle, bear_wick_col_candle,
  432. chart_offset_candle, candle_buffer_candle, candle_width_candle, line_color_candle
  433. )
  434.  
  435. var CandleSet htf1 = CandleSet.new(array.new<Candle>(0), CandleSettings.new(true, "1W", max_display_inp_candle), na, bar_index, open, high, low)
  436.  
  437. var line[] sweep_lines = array.new_line(0)
  438.  
  439. tf_secs_candle = timeframe.in_seconds(timeframe.period)
  440. auto_tf_candle = tf_secs_candle <= timeframe.in_seconds("1") ? "15" :
  441. tf_secs_candle <= timeframe.in_seconds("3") ? "30" :
  442. tf_secs_candle <= timeframe.in_seconds("5") ? "60" :
  443. tf_secs_candle <= timeframe.in_seconds("15") ? "240" :
  444. tf_secs_candle <= timeframe.in_seconds("60") ? "1D" :
  445. tf_secs_candle <= timeframe.in_seconds("480") ? "1W" :
  446. tf_secs_candle <= timeframe.in_seconds("1440") ? "1M" : "1W"
  447.  
  448. htf1.settings.htf := htf_mode_candle == "Auto" ? auto_tf_candle : get_tf_string(custom_htf_candle)
  449.  
  450. isValidTimeframe(string HTF) =>
  451. n1 = timeframe.in_seconds(), n2 = timeframe.in_seconds(HTF)
  452. (n2 >= timeframe.in_seconds("1D") and n2 > n1) or (n1 < n2 and math.round(n2/n1) == n2/n1)
  453.  
  454. method Reorder(CandleSet candleSet, int offset) =>
  455. for l in sweep_lines
  456. line.delete(l)
  457. array.clear(sweep_lines)
  458.  
  459. size = candleSet.candles.size()
  460. float highest_point = 0.0
  461.  
  462. if size > 0
  463. for i = size-1 to 0
  464. Candle candle = candleSet.candles.get(i)
  465. t_buffer = offset + ((settingsCandle.width + settingsCandle.buffer) * (size - i - 1))
  466. posX = bar_index + t_buffer
  467. midX = posX + (settingsCandle.width / 2)
  468. r_pos = posX + settingsCandle.width
  469.  
  470. highest_point := math.max(highest_point, candle.h)
  471.  
  472. box.set_left(candle.body, posX)
  473. box.set_right(candle.body, posX + settingsCandle.width)
  474. line.set_x1(candle.wick_up, midX), line.set_x2(candle.wick_up, midX)
  475. line.set_x1(candle.wick_down, midX), line.set_x2(candle.wick_down, midX)
  476.  
  477. if i == 0
  478. candle.deleteProjections()
  479.  
  480. if proj_o_enabled
  481. candle.line_o := line.new(candle.o_idx, candle.o, midX, candle.o, style=getProjLineStyle(proj_o_style), color=proj_o_col, width=proj_o_width)
  482. if proj_lbl_enabled
  483. candle.lbl_o := label.new(r_pos, candle.o, str.tostring(candle.o, format.mintick), style=label.style_label_left, color=color.new(color.black, 100), textcolor=proj_lbl_col, size=getProjLabelSize(proj_lbl_size))
  484.  
  485. if proj_hl_enabled
  486. candle.line_h := line.new(candle.h_idx, candle.h, midX, candle.h, style=getProjLineStyle(proj_hl_style), color=proj_hl_col, width=proj_hl_width)
  487. candle.line_l := line.new(candle.l_idx, candle.l, midX, candle.l, style=getProjLineStyle(proj_hl_style), color=proj_hl_col, width=proj_hl_width)
  488. if proj_lbl_enabled
  489. candle.lbl_h := label.new(r_pos, candle.h, str.tostring(candle.h, format.mintick), style=label.style_label_left, color=color.new(color.black, 100), textcolor=proj_lbl_col, size=getProjLabelSize(proj_lbl_size))
  490. candle.lbl_l := label.new(r_pos, candle.l, str.tostring(candle.l, format.mintick), style=label.style_label_left, color=color.new(color.black, 100), textcolor=proj_lbl_col, size=getProjLabelSize(proj_lbl_size))
  491.  
  492. if proj_c_enabled
  493. candle.line_c := line.new(bar_index, candle.c, midX, candle.c, style=getProjLineStyle(proj_c_style), color=proj_c_col, width=proj_c_width)
  494. if proj_lbl_enabled
  495. candle.lbl_c := label.new(r_pos, candle.c, str.tostring(candle.c, format.mintick), style=label.style_label_left, color=color.new(color.white, 100), textcolor=proj_lbl_col, size=getProjLabelSize(proj_lbl_size))
  496. else
  497. candle.deleteProjections()
  498.  
  499. if i < size - 1
  500. Candle prev = candleSet.candles.get(i+1)
  501. prevPosX = offset + ((settingsCandle.width + settingsCandle.buffer) * (size - (i+1) - 1))
  502. prevMidX = bar_index + prevPosX + (settingsCandle.width / 2)
  503.  
  504. if show_sweeps
  505. if candle.h > prev.h and candle.c < prev.h
  506. sweep_lines.push(line.new(prevMidX, prev.h, posX + settingsCandle.width, prev.h, color=settingsCandle.line_color))
  507. if candle.l < prev.l and candle.c > prev.l
  508. sweep_lines.push(line.new(prevMidX, prev.l, posX + settingsCandle.width, prev.l, color=settingsCandle.line_color))
  509.  
  510. if show_htf_info
  511. label.delete(candleSet.infoLabel)
  512. string labelTxt = getHTFName(candleSet.settings.htf) + "\n(" + getRemainingTimeHTF(candleSet.settings.htf) + ")"
  513. labelX = bar_index + offset + ((settingsCandle.width + settingsCandle.buffer) * (size - 1) / 2)
  514.  
  515. candleSet.infoLabel := label.new(labelX, highest_point, labelTxt,
  516. color=color.new(color.white, 100),
  517. textcolor=info_col,
  518. style=label.style_label_down,
  519. size=info_size,
  520. text_font_family=font.family_monospace)
  521.  
  522. method Monitor(CandleSet candleSet) =>
  523. isNew = ta.change(time(candleSet.settings.htf)) != 0
  524.  
  525. if not isNew
  526. candleSet.htf_high_trace := math.max(high, candleSet.htf_high_trace)
  527. candleSet.htf_low_trace := math.min(low, candleSet.htf_low_trace)
  528.  
  529. if isNew
  530. candleSet.htf_start_bar := bar_index
  531. candleSet.htf_open_price := open
  532. candleSet.htf_high_trace := high
  533. candleSet.htf_low_trace := low
  534.  
  535. Candle candle = Candle.new(open, close, high, low, bar_index, bar_index, bar_index, bar_index)
  536. bull = candle.c > candle.o
  537. candle.body := box.new(bar_index, math.max(candle.o, candle.c), bar_index + 2, math.min(candle.o, candle.c),
  538. bull ? settingsCandle.bull_border : settingsCandle.bear_border, 1, bgcolor = bull ? settingsCandle.bull_body : settingsCandle.bear_body)
  539. candle.wick_up := line.new(bar_index, candle.h, bar_index, math.max(candle.o, candle.c), color=bull ? settingsCandle.bull_wick : settingsCandle.bear_wick)
  540. candle.wick_down := line.new(bar_index, math.min(candle.o, candle.c), bar_index, candle.l, color=bull ? settingsCandle.bull_wick : settingsCandle.bear_wick)
  541. candleSet.candles.unshift(candle)
  542. if candleSet.candles.size() > candleSet.settings.max_display
  543. Candle del = candleSet.candles.pop()
  544. box.delete(del.body), line.delete(del.wick_up), line.delete(del.wick_down)
  545. del.deleteProjections()
  546. candleSet
  547.  
  548. method Update(CandleSet candleSet, int offset) =>
  549. if candleSet.candles.size() > 0
  550. Candle candle = candleSet.candles.get(0)
  551.  
  552. if high > candle.h
  553. candle.h := high
  554. candle.h_idx := bar_index
  555. if low < candle.l
  556. candle.l := low
  557. candle.l_idx := bar_index
  558.  
  559. candle.c := close
  560. candle.c_idx := bar_index
  561.  
  562. bull = candle.c > candle.o
  563. box.set_top(candle.body, math.max(candle.o, candle.c)), box.set_bottom(candle.body, math.min(candle.o, candle.c))
  564. box.set_bgcolor(candle.body, bull ? settingsCandle.bull_body : settingsCandle.bear_body)
  565. line.set_y1(candle.wick_up, candle.h), line.set_y2(candle.wick_up, math.max(candle.o, candle.c))
  566. line.set_y1(candle.wick_down, candle.l), line.set_y2(candle.wick_down, math.min(candle.o, candle.c))
  567.  
  568. candleSet.Reorder(offset)
  569. candleSet
  570.  
  571. f_lblSize(s) =>
  572. s == "tiny" ? size.tiny : s == "small" ? size.small : s == "large" ? size.large : s == "huge" ? size.huge : size.normal
  573.  
  574. f_parseExtras(str) =>
  575. parts = str.split(str, ",")
  576. arr = array.new_float(0)
  577. for p in parts
  578. v = str.tonumber(str.trim(p))
  579. if not na(v)
  580. array.push(arr, v)
  581. arr
  582.  
  583. f_tfLabel(tf) =>
  584. switch tf
  585. "1" => "1m"
  586. "3" => "3m"
  587. "5" => "5m"
  588. "15" => "15m"
  589. "30" => "30m"
  590. "60" => "1H"
  591. "120" => "2H"
  592. "180" => "3H"
  593. "240" => "4H"
  594. "D" => "1D"
  595. "W" => "1W"
  596. "M" => "1M"
  597. => tf
  598.  
  599. f_findLevelOrigin(isBull, lvl) =>
  600. int offset = 0
  601. for j = 1 to 400
  602. match = isBull ? (math.abs(low[j] - lvl) < syminfo.mintick) : (math.abs(high[j] - lvl) < syminfo.mintick)
  603. if match
  604. offset := j
  605. break
  606. offset
  607.  
  608. f_findOHLCOrigin(isBull, lvl, tf) =>
  609. htf_curr_start = ta.valuewhen(ta.change(time(tf)), bar_index, 0)
  610. htf_prev_start = ta.valuewhen(ta.change(time(tf)), bar_index, 1)
  611. htf_prev_end = htf_curr_start - 1
  612. offset = 0
  613. if not na(htf_prev_start) and not na(htf_prev_end)
  614. start_j = bar_index - htf_prev_end
  615. end_j = bar_index - htf_prev_start
  616. for j = math.max(1, start_j) to math.min(490, end_j)
  617. match = isBull ? (math.abs(low[j] - lvl) < syminfo.mintick) : (math.abs(high[j] - lvl) < syminfo.mintick)
  618. if match
  619. offset := j
  620. break
  621. offset
  622.  
  623. f_alreadyTouched(isLowLevel, lvl, tf) =>
  624. int barsSinceStart = ta.barssince(ta.change(time(tf)))
  625. bool touched = false
  626. if not na(barsSinceStart) and barsSinceStart > 0
  627. int limit = math.min(barsSinceStart, 300)
  628. for i = 1 to limit
  629. if isLowLevel
  630. if low[i] <= lvl
  631. touched := true
  632. break
  633. else
  634. if high[i] >= lvl
  635. touched := true
  636. break
  637. touched
  638.  
  639. f_autoTFPair() =>
  640. ctf = timeframe.period
  641. aTF = switch ctf
  642. "1" => "15"
  643. "2" => "15"
  644. "3" => "15"
  645. "5" => "60"
  646. "10" => "60"
  647. "15" => "240"
  648. "30" => "240"
  649. "60" => "D"
  650. "240" => "W"
  651. => "W"
  652.  
  653. bTF = switch ctf
  654. "1" => "60"
  655. "3" => "60"
  656. "5" => "240"
  657. "15" => "D"
  658. "60" => "W"
  659. => "W"
  660.  
  661. cTF = switch ctf
  662. "1" => "240"
  663. "5" => "D"
  664. "15" => "W"
  665. => "W"
  666.  
  667. [aTF, bTF, cTF]
  668.  
  669. f_inSession() =>
  670. if not i_useTimeFilter
  671. true
  672. else
  673. inS1 = i_sess1Enable and not na(time(timeframe.period, i_sess1, effectiveTz))
  674. inS2 = i_sess2Enable and not na(time(timeframe.period, i_sess2, effectiveTz))
  675. inS3 = i_sess3Enable and not na(time(timeframe.period, i_sess3, effectiveTz))
  676. inS1 or inS2 or inS3
  677.  
  678. f_sessString() =>
  679. s = ""
  680. if i_useTimeFilter
  681. if i_sess1Enable
  682. s += i_sess1Name + ": " + i_sess1 + " "
  683. if i_sess2Enable
  684. s += i_sess2Name + ": " + i_sess2 + " "
  685. if i_sess3Enable
  686. s += i_sess3Name + ": " + i_sess3
  687. s
  688.  
  689. var float[] _bkSizeHistory = array.new_float(0)
  690.  
  691. f_sizeOk(bkSize) =>
  692. pip = syminfo.mintick * (syminfo.type == "forex" ? 10.0 : 1.0)
  693. sz = i_customSizeMode == "Pips" ? bkSize / pip : bkSize
  694.  
  695. if i_sizeFilter == "All"
  696. true
  697. else if i_sizeFilter == "Custom"
  698. minOk = i_customMin == 0.0 or sz >= i_customMin
  699. maxOk = i_customMax == 0.0 or sz <= i_customMax
  700. minOk and maxOk
  701. else
  702. array.push(_bkSizeHistory, sz)
  703. if array.size(_bkSizeHistory) > 100
  704. array.shift(_bkSizeHistory)
  705. n = array.size(_bkSizeHistory)
  706. if n < 3
  707. true
  708. else
  709. sorted = array.copy(_bkSizeHistory)
  710. array.sort(sorted)
  711. p33 = array.get(sorted, math.round(n * 0.33))
  712. p66 = array.get(sorted, math.round(n * 0.66))
  713. isSmall = sz < p33
  714. isMed = sz >= p33 and sz < p66
  715. isLarge = sz >= p66
  716. i_sizeFilter == "Small+Med+Large" ? true :
  717. i_sizeFilter == "Med+Large" ? (isMed or isLarge) :
  718. i_sizeFilter == "Large" ? isLarge : true
  719.  
  720. emaFast = ta.ema(close, 50)
  721. emaSlow = ta.ema(close, 200)
  722. autoBull = emaFast > emaSlow
  723.  
  724. f_biasOk(isBull) =>
  725. if i_biasMode == "Neutral"
  726. true
  727. else if i_biasMode == "Bullish"
  728. isBull
  729. else if i_biasMode == "Bearish"
  730. not isBull
  731. else
  732. isBull == autoBull
  733.  
  734. getFvgHTFPeriod() =>
  735. int tfSeconds = timeframe.in_seconds()
  736. string result = "D"
  737. if tfSeconds <= 15
  738. result := "5"
  739. else if tfSeconds <= 60
  740. result := "15"
  741. else if tfSeconds <= 180
  742. result := "30"
  743. else if tfSeconds <= 300
  744. result := "60"
  745. else if tfSeconds <= 600
  746. result := "150"
  747. else if tfSeconds <= 900
  748. result := "240"
  749. else if tfSeconds <= 1800
  750. result := "1D"
  751. else if tfSeconds <= 2700
  752. result := "720"
  753. else if tfSeconds <= 3600
  754. result := "1D"
  755. else if tfSeconds <= 7200
  756. result := "2D"
  757. else if tfSeconds <= 14400
  758. result := "1W"
  759. else if tfSeconds <= 21600
  760. result := "4D"
  761. else if tfSeconds <= 43200
  762. result := "1W"
  763. else if tfSeconds <= 86400
  764. result := "15D"
  765. else if tfSeconds <= 259200
  766. result := "45D"
  767. else if tfSeconds <= 604800
  768. result := "15W"
  769. else if tfSeconds <= 2592000
  770. result := "15M"
  771. else
  772. result := "45M"
  773. result
  774.  
  775. detectStandaloneFVG() =>
  776. var bool hasBearishFVG = false
  777. var bool hasBullishFVG = false
  778. var float bearishBottom = na
  779. var float bearishTop = na
  780. var float bullishBottom = na
  781. var float bullishTop = na
  782. var int htfTimeVal = na
  783. var int htfTime2Val = na
  784.  
  785. if barstate.isconfirmed
  786. float htfHigh0 = high[0]
  787. float htfLow0 = low[0]
  788. float htfHigh2 = high[2]
  789. float htfLow2 = low[2]
  790. int htfTime0 = time[0]
  791.  
  792. if not na(htfLow2) and htfHigh0 < htfLow2
  793. hasBearishFVG := true
  794. bearishBottom := htfHigh0
  795. bearishTop := htfLow2
  796. htfTimeVal := htfTime0
  797. htfTime2Val := time[2]
  798. else
  799. hasBearishFVG := false
  800.  
  801. if not na(htfHigh2) and htfLow0 > htfHigh2
  802. hasBullishFVG := true
  803. bullishBottom := htfHigh2
  804. bullishTop := htfLow0
  805. htfTimeVal := htfTime0
  806. htfTime2Val := time[2]
  807. else
  808. hasBullishFVG := false
  809.  
  810. [hasBearishFVG, hasBullishFVG, bearishBottom, bearishTop, bullishBottom, bullishTop, htfTimeVal, htfTime2Val]
  811.  
  812. formatTimeframe(string tf) =>
  813. seconds = timeframe.in_seconds(tf)
  814. if seconds < 60
  815. str.tostring(seconds) + "S"
  816. else if (seconds / 60) < 60
  817. str.tostring(math.round(seconds/60)) + "M"
  818. else if (seconds/60/60) < 24
  819. str.tostring(math.round(seconds/60/60)) + "H"
  820. else if (seconds/60/60/24) < 7
  821. str.tostring(math.round(seconds/60/60/24)) + "D"
  822. else if (seconds/60/60/24/7) < 4
  823. str.tostring(math.round(seconds/60/60/24/7)) + "W"
  824. else if (seconds/60/60/24/30) < 12
  825. str.tostring(math.round(seconds/60/60/24/30)) + "M"
  826. else
  827. str.tostring(math.round(seconds/60/60/24/365)) + "Y"
  828.  
  829. fvg_selectedHTF = fvg_autoMode ? getFvgHTFPeriod() : fvg_manualHTF
  830. fvg_newPeriod = ta.change(time(fvg_selectedHTF)) != 0
  831.  
  832. var HtfFVG[] activeHtfFVGs = array.new<HtfFVG>()
  833.  
  834. [fvg_htfHasBear, fvg_htfHasBull, fvg_htfBearBot, fvg_htfBearTop, fvg_htfBullBot, fvg_htfBullTop, fvg_htfT1, fvg_htfT2] = request.security(syminfo.tickerid, fvg_selectedHTF, detectStandaloneFVG(), lookahead = barmerge.lookahead_off)
  835. fvg_htfCloseVal = request.security(syminfo.tickerid, fvg_selectedHTF, close, lookahead = barmerge.lookahead_off)
  836.  
  837. getSmtHTFPeriod() =>
  838. int tfSeconds = timeframe.in_seconds()
  839. string result = "D"
  840. if tfSeconds <= 15
  841. result := "5"
  842. else if tfSeconds <= 60
  843. result := "15"
  844. else if tfSeconds <= 180
  845. result := "30"
  846. else if tfSeconds <= 300
  847. result := "60"
  848. else if tfSeconds <= 600
  849. result := "150"
  850. else if tfSeconds <= 900
  851. result := "240"
  852. else if tfSeconds <= 1800
  853. result := "1D"
  854. else if tfSeconds <= 2700
  855. result := "720"
  856. else if tfSeconds <= 3600
  857. result := "1D"
  858. else if tfSeconds <= 7200
  859. result := "2D"
  860. else if tfSeconds <= 14400
  861. result := "1W"
  862. else if tfSeconds <= 21600
  863. result := "4D"
  864. else if tfSeconds <= 43200
  865. result := "1W"
  866. else if tfSeconds <= 86400
  867. result := "15D"
  868. else if tfSeconds <= 259200
  869. result := "45D"
  870. else if tfSeconds <= 604800
  871. result := "15W"
  872. else if tfSeconds <= 2592000
  873. result := "15M"
  874. else
  875. result := "45M"
  876. result
  877.  
  878. getSmtPair() =>
  879. string ticker = syminfo.ticker
  880. string res = ""
  881. if str.contains(ticker, "MNQ1!")
  882. res := "CME_MINI:MES1!"
  883. else if str.contains(ticker, "MES1!")
  884. res := "CME_MINI:MNQ1!"
  885. else if str.contains(ticker, "MYM1!")
  886. res := "CME_MINI:MNQ1!"
  887. else if str.contains(ticker, "NQ1!") or str.contains(ticker, "NDX") or str.contains(ticker, "QQQ") or ticker == "NQ"
  888. res := "CME_MINI:ES1!"
  889. else if str.contains(ticker, "ES1!") or str.contains(ticker, "SPX") or str.contains(ticker, "SPY") or ticker == "ES"
  890. res := "CME_MINI:NQ1!"
  891. else if str.contains(ticker, "YM1!")
  892. res := "CME_MINI:NQ1!"
  893. else if str.contains(ticker, "RTY1!")
  894. res := "CBOT:YM1!"
  895. else if str.contains(ticker, "NAS100")
  896. res := "SPX500"
  897. else if str.contains(ticker, "SPX500")
  898. res := "NAS100"
  899. else if str.contains(ticker, "US30")
  900. res := "NAS100"
  901. else if str.contains(ticker, "EURUSD")
  902. res := "GBPUSD"
  903. else if str.contains(ticker, "GBPUSD")
  904. res := "EURUSD"
  905. else if str.contains(ticker, "EURCAD")
  906. res := "GBPCAD"
  907. else if str.contains(ticker, "GBPCAD")
  908. res := "EURCAD"
  909. else if str.contains(ticker, "AUDUSD")
  910. res := "NZDUSD"
  911. else if str.contains(ticker, "NZDUSD")
  912. res := "AUDUSD"
  913. else if str.contains(ticker, "EURAUD")
  914. res := "GBPAUD"
  915. else if str.contains(ticker, "GBPAUD")
  916. res := "EURAUD"
  917. else if str.contains(ticker, "AUDCAD")
  918. res := "NZDCAD"
  919. else if str.contains(ticker, "NZDCAD")
  920. res := "AUDCAD"
  921. else if str.contains(ticker, "EURJPY")
  922. res := "GBPJPY"
  923. else if str.contains(ticker, "GBPJPY")
  924. res := "EURJPY"
  925. else if str.contains(ticker, "AUDJPY")
  926. res := "NZDJPY"
  927. else if str.contains(ticker, "NZDJPY")
  928. res := "AUDJPY"
  929. else if str.contains(ticker, "EURNZD")
  930. res := "GBPNZD"
  931. else if str.contains(ticker, "GBPNZD")
  932. res := "EURNZD"
  933. else if str.contains(ticker, "CADJPY")
  934. res := "CHFJPY"
  935. else if str.contains(ticker, "CHFJPY")
  936. res := "CADJPY"
  937. else if str.contains(ticker, "USDJPY")
  938. res := "EURJPY"
  939. else if str.contains(ticker, "USDCAD")
  940. res := "EURCAD"
  941. else if str.contains(ticker, "USDCHF")
  942. res := "EURCHF"
  943. else if str.contains(ticker, "XAUUSD")
  944. res := "XAGUSD"
  945. else if str.contains(ticker, "XAGUSD")
  946. res := "XAUUSD"
  947. else if str.contains(ticker, "XAUEUR")
  948. res := "XAUUSD"
  949. else if str.contains(ticker, "XAUGBP")
  950. res := "COMEX:GC1!"
  951. else if str.contains(ticker, "GC1!")
  952. res := "XAGUSD"
  953. else if str.contains(ticker, "XAGEUR")
  954. res := "COMEX:SI1!"
  955. else if str.contains(ticker, "XAGGBP")
  956. res := "COMEX:SI1!"
  957. else if str.contains(ticker, "SIL1!") or str.contains(ticker, "SI1!")
  958. res := "XAGEUR"
  959. else if str.contains(ticker, "BTCUSDT") or str.contains(ticker, "BTC")
  960. res := "ETHUSDT"
  961. else if str.contains(ticker, "ETHUSDT") or str.contains(ticker, "ETH")
  962. res := "BTCUSDT"
  963. else
  964. res := "CME_MINI:ES1!"
  965. res
  966.  
  967. smt_selectedHTF = smt_autoMode ? getSmtHTFPeriod() : smt_manualHTF
  968. smt_newPeriod = ta.change(time(smt_selectedHTF)) != 0
  969.  
  970. var smtArray = array.new<SMT>()
  971. var smtLabels = array.new<label>()
  972.  
  973. var float smt_currCH = na, var int smt_currCHT = na
  974. var float smt_currCL = na, var int smt_currCLT = na
  975. var float smt_prevCH = na, var int smt_prevCHT = na
  976. var float smt_prevCL = na, var int smt_prevCLT = na
  977.  
  978. var float smt_chartPivotHigh = na, var int smt_chartPivotHighTime = na
  979. var float smt_prevChartPivotHigh = na, var int smt_prevChartPivotHighTime = na
  980. var float smt_smtPivotHigh = na, var float smt_prevSmtPivotHigh = na
  981.  
  982. var float smt_chartPivotLow = na, var int smt_chartPivotLowTime = na
  983. var float smt_prevChartPivotLow = na, var int smt_prevChartPivotLowTime = na
  984. var float smt_smtPivotLow = na, var float smt_prevSmtPivotLow = na
  985.  
  986. var line smt_liveBearLine = na
  987. var line smt_liveBullLine = na
  988.  
  989. smt_sPair = smt_AutoMode_Pair ? getSmtPair() : str.tostring(smt_ManualPair)
  990.  
  991. [smt_htfHigh, smt_htfLow, smt_htfHigh1, smt_htfLow1] = request.security(syminfo.tickerid, smt_selectedHTF, [high, low, high[1], low[1]], lookahead = barmerge.lookahead_off)
  992. [smt_htfOpen, smt_htfClose] = request.security(syminfo.tickerid, smt_selectedHTF, [open, close], lookahead = barmerge.lookahead_off)
  993.  
  994. [smt_sH_htf, smt_sL_htf, smt_sH1_htf, smt_sL1_htf] = request.security(smt_sPair != "" ? smt_sPair : syminfo.tickerid, smt_selectedHTF, [high, low, high[1], low[1]], lookahead = barmerge.lookahead_off)
  995. [smt_sH_piv, smt_sL_piv] = request.security(smt_sPair != "" ? smt_sPair : syminfo.tickerid, timeframe.period, [high[3], low[3]], lookahead = barmerge.lookahead_off)
  996.  
  997. [autoA, autoB, autoC] = f_autoTFPair()
  998. effTFA = i_srcAuto == "Automatic" ? autoA : i_srcATF
  999. effTFB = i_srcAuto == "Automatic" ? autoB : i_srcBTF
  1000. effTFC = i_srcAuto == "Automatic" ? autoC : i_srcCTF
  1001.  
  1002. [htfA_o, htfA_h, htfA_l, htfA_c, htfA_ph, htfA_pl] = request.security(syminfo.tickerid, effTFA,
  1003. [open, high, low, close, high[1], low[1]], lookahead=barmerge.lookahead_off)
  1004.  
  1005. [htfB_o, htfB_h, htfB_l, htfB_c, htfB_ph, htfB_pl] = request.security(syminfo.tickerid, effTFB,
  1006. [open, high, low, close, high[1], low[1]], lookahead=barmerge.lookahead_off)
  1007.  
  1008. [htfC_o, htfC_h, htfC_l, htfC_c, htfC_ph, htfC_pl] = request.security(syminfo.tickerid, effTFC,
  1009. [open, high, low, close, high[1], low[1]], lookahead=barmerge.lookahead_off)
  1010.  
  1011. [htfA_swH, htfA_swL] = request.security(syminfo.tickerid, effTFA,
  1012. [ta.pivothigh(high, 1, 1), ta.pivotlow(low, 1, 1)], lookahead=barmerge.lookahead_off)
  1013. [htfB_swH, htfB_swL] = request.security(syminfo.tickerid, effTFB,
  1014. [ta.pivothigh(high, 1, 1), ta.pivotlow(low, 1, 1)], lookahead=barmerge.lookahead_off)
  1015. [htfC_swH, htfC_swL] = request.security(syminfo.tickerid, effTFC,
  1016. [ta.pivothigh(high, 1, 1), ta.pivotlow(low, 1, 1)], lookahead=barmerge.lookahead_off)
  1017.  
  1018. f_ohlcHighSwept(htfPrevH) =>
  1019. high >= htfPrevH and low[1] < htfPrevH or (high[1] < htfPrevH and high >= htfPrevH)
  1020.  
  1021. f_ohlcLowSwept(htfPrevL) =>
  1022. low <= htfPrevL and high[1] > htfPrevL or (low[1] > htfPrevL and low <= htfPrevL)
  1023.  
  1024. var float swHigh_A = na, var int swHigh_A_age = 0
  1025. var float swLow_A = na, var int swLow_A_age = 0
  1026. var float swHigh_B = na, var int swHigh_B_age = 0
  1027. var float swLow_B = na, var int swLow_B_age = 0
  1028. var float swHigh_C = na, var int swHigh_C_age = 0
  1029. var float swLow_C = na, var int swLow_C_age = 0
  1030.  
  1031. isNewBarA = ta.change(time(effTFA))
  1032. isNewBarB = ta.change(time(effTFB))
  1033. isNewBarC = ta.change(time(effTFC))
  1034.  
  1035. inSessL1 = not na(time(timeframe.period, i_sessL1Time, "America/New_York"))
  1036. inSessL2 = not na(time(timeframe.period, i_sessL2Time, "America/New_York"))
  1037. inSessL3 = not na(time(timeframe.period, i_sessL3Time, "America/New_York"))
  1038. inSessL4 = not na(time(timeframe.period, i_sessL4Time, "America/New_York"))
  1039.  
  1040. var float sess1H = na, var float sess1L = na
  1041. var float sess2H = na, var float sess2L = na
  1042. var float sess3H = na, var float sess3L = na
  1043. var float sess4H = na, var float sess4L = na
  1044.  
  1045. if inSessL1
  1046. sess1H := not inSessL1[1] ? high : math.max(sess1H, high)
  1047. sess1L := not inSessL1[1] ? low : math.min(sess1L, low)
  1048. if inSessL2
  1049. sess2H := not inSessL2[1] ? high : math.max(sess2H, high)
  1050. sess2L := not inSessL2[1] ? low : math.min(sess2L, low)
  1051. if inSessL3
  1052. sess3H := not inSessL3[1] ? high : math.max(sess3H, high)
  1053. sess3L := not inSessL3[1] ? low : math.min(sess3L, low)
  1054. if inSessL4
  1055. sess4H := not inSessL4[1] ? high : math.max(sess4H, high)
  1056. sess4L := not inSessL4[1] ? low : math.min(sess4L, low)
  1057.  
  1058. sess1_sweptBull = i_useSessLiq and not inSessL1 and not na(sess1L) and low <= sess1L and low[1] > sess1L
  1059. sess1_sweptBear = i_useSessLiq and not inSessL1 and not na(sess1H) and high >= sess1H and high[1] < sess1H
  1060.  
  1061. sess2_sweptBull = i_useSessLiq and not inSessL2 and not na(sess2L) and low <= sess2L and low[1] > sess2L
  1062. sess2_sweptBear = i_useSessLiq and not inSessL2 and not na(sess2H) and high >= sess2H and high[1] < sess2H
  1063.  
  1064. sess3_sweptBull = i_useSessLiq and not inSessL3 and not na(sess3L) and low <= sess3L and low[1] > sess3L
  1065. sess3_sweptBear = i_useSessLiq and not inSessL3 and not na(sess3H) and high >= sess3H and high[1] < sess3H
  1066.  
  1067. sess4_sweptBull = i_useSessLiq and not inSessL4 and not na(sess4L) and low <= sess4L and low[1] > sess4L
  1068. sess4_sweptBear = i_useSessLiq and not inSessL4 and not na(sess4H) and high >= sess4H and high[1] < sess4H
  1069.  
  1070. sess_bull = sess1_sweptBull or sess2_sweptBull or sess3_sweptBull or sess4_sweptBull
  1071. sess_bear = sess1_sweptBear or sess2_sweptBear or sess3_sweptBear or sess4_sweptBear
  1072.  
  1073. sess_lvl = sess1_sweptBull ? sess1L : sess1_sweptBear ? sess1H :
  1074. sess2_sweptBull ? sess2L : sess2_sweptBear ? sess2H :
  1075. sess3_sweptBull ? sess3L : sess3_sweptBear ? sess3H :
  1076. sess4_sweptBull ? sess4L : sess4_sweptBear ? sess4H : float(na)
  1077.  
  1078. sess_lbl = sess1_sweptBull ? i_sessL1Name + " Low" : sess1_sweptBear ? i_sessL1Name + " High" :
  1079. sess2_sweptBull ? i_sessL2Name + " Low" : sess2_sweptBear ? i_sessL2Name + " High" :
  1080. sess3_sweptBull ? i_sessL3Name + " Low" : sess3_sweptBear ? i_sessL3Name + " High" :
  1081. sess4_sweptBull ? i_sessL4Name + " Low" : sess4_sweptBear ? i_sessL4Name + " High" : ""
  1082.  
  1083. if sess1_sweptBull
  1084. sess1L := na
  1085. if sess1_sweptBear
  1086. sess1H := na
  1087.  
  1088. if sess2_sweptBull
  1089. sess2L := na
  1090. if sess2_sweptBear
  1091. sess2H := na
  1092.  
  1093. if sess3_sweptBull
  1094. sess3L := na
  1095. if sess3_sweptBear
  1096. sess3H := na
  1097.  
  1098. if sess4_sweptBull
  1099. sess4L := na
  1100. if sess4_sweptBear
  1101. sess4H := na
  1102.  
  1103. if not na(htfA_swH)
  1104. swHigh_A := htfA_swH
  1105. swHigh_A_age := 0
  1106. else if isNewBarA and not na(swHigh_A)
  1107. swHigh_A_age := swHigh_A_age + 1
  1108. if swHigh_A_age > 5
  1109. swHigh_A := na
  1110.  
  1111. if not na(htfA_swL)
  1112. swLow_A := htfA_swL
  1113. swLow_A_age := 0
  1114. else if isNewBarA and not na(swLow_A)
  1115. swLow_A_age := swLow_A_age + 1
  1116. if swLow_A_age > 5
  1117. swLow_A := na
  1118.  
  1119. if not na(htfB_swH)
  1120. swHigh_B := htfB_swH
  1121. swHigh_B_age := 0
  1122. else if isNewBarB and not na(swHigh_B)
  1123. swHigh_B_age := swHigh_B_age + 1
  1124. if swHigh_B_age > 5
  1125. swHigh_B := na
  1126.  
  1127. if not na(htfB_swL)
  1128. swLow_B := htfB_swL
  1129. swLow_B_age := 0
  1130. else if isNewBarB and not na(swLow_B)
  1131. swLow_B_age := swLow_B_age + 1
  1132. if swLow_B_age > 5
  1133. swLow_B := na
  1134.  
  1135. if not na(htfC_swH)
  1136. swHigh_C := htfC_swH
  1137. swHigh_C_age := 0
  1138. else if isNewBarC and not na(swHigh_C)
  1139. swHigh_C_age := swHigh_C_age + 1
  1140. if swHigh_C_age > 5
  1141. swHigh_C := na
  1142.  
  1143. if not na(htfC_swL)
  1144. swLow_C := htfC_swL
  1145. swLow_C_age := 0
  1146. else if isNewBarC and not na(swLow_C)
  1147. swLow_C_age := swLow_C_age + 1
  1148. if swLow_C_age > 5
  1149. swLow_C := na
  1150.  
  1151. PIVOT_LEN = 3
  1152. swHi = ta.pivothigh(high, PIVOT_LEN, PIVOT_LEN)
  1153. swLo = ta.pivotlow (low, PIVOT_LEN, PIVOT_LEN)
  1154.  
  1155. var float lastSwHi = na, var int lastSwHiBar = na
  1156. var float lastSwLo = na, var int lastSwLoBar = na
  1157. if not na(swHi)
  1158. lastSwHi := swHi
  1159. lastSwHiBar := bar_index - PIVOT_LEN
  1160. if not na(swLo)
  1161. lastSwLo := swLo
  1162. lastSwLoBar := bar_index - PIVOT_LEN
  1163.  
  1164. bullFvgTop = low > high[2] ? low : na
  1165. bullFvgBot = low > high[2] ? high[2]: na
  1166. bearFvgTop = high < low[2] ? low[2] : na
  1167. bearFvgBot = high < low[2] ? high : na
  1168.  
  1169. var float bld_bull_sweepLevel = na
  1170. var int bld_bull_sweepBar = na
  1171. var int bld_bull_sweepOffset = na
  1172. var int bld_bull_htfPrevStart = na
  1173. var float bld_bull_swingHi = na
  1174. var float bld_bull_bbTop = na
  1175. var float bld_bull_bbBot = na
  1176. var int bld_bull_pivotBar = na
  1177. var int bld_bull_bbLen = na
  1178. var bool bld_bull_hasFvg = false
  1179. var float bld_bull_fvgTop = na
  1180. var float bld_bull_fvgBot = na
  1181. var int bld_bull_fvgIdx = na
  1182. var string bld_bull_liqLabel = ""
  1183. var float bld_bull_manipLow = na
  1184.  
  1185. var float bld_bear_sweepLevel = na
  1186. var int bld_bear_sweepBar = na
  1187. var int bld_bear_sweepOffset = na
  1188. var int bld_bear_htfPrevStart = na
  1189. var float bld_bear_swingLo = na
  1190. var float bld_bear_bbTop = na
  1191. var float bld_bear_bbBot = na
  1192. var int bld_bear_pivotBar = na
  1193. var int bld_bear_bbLen = na
  1194. var bool bld_bear_hasFvg = false
  1195. var float bld_bear_fvgTop = na
  1196. var float bld_bear_fvgBot = na
  1197. var int bld_bear_fvgIdx = na
  1198. var string bld_bear_liqLabel = ""
  1199. var float bld_bear_manipHigh = na
  1200.  
  1201. var UnicornSetup[] setups = array.new<UnicornSetup>(0)
  1202.  
  1203. srcAactive = i_srcMode == "Multiple" ? i_srcAEnable : true
  1204. srcBactive = i_srcMode == "Multiple" ? i_srcBEnable : false
  1205. srcCactive = i_srcMode == "Multiple" ? i_srcCEnable : false
  1206.  
  1207. liqTypeA = i_srcAuto == "Automatic" ? i_srcAType : i_srcALiq
  1208. liqTypeB = i_srcAuto == "Automatic" ? i_srcAType : i_srcBLiq
  1209. liqTypeC = i_srcAuto == "Automatic" ? i_srcAType : i_srcCLiq
  1210.  
  1211. f_checkSweep(srcEnable, htfPH, htfPL, swH, swL, liqType, tfLbl, tf) =>
  1212. sweptBull = false
  1213. sweptBear = false
  1214. sweptLvl = float(na)
  1215. lbl = ""
  1216. if srcEnable
  1217. useOhlc = liqType == "OHLC + Swing" or liqType == "OHLC Only"
  1218. useSwing = liqType == "OHLC + Swing" or liqType == "Swing Only"
  1219.  
  1220. ohlcLowAlreadyTouched = f_alreadyTouched(true, htfPL, tf)
  1221. ohlcHighAlreadyTouched = f_alreadyTouched(false, htfPH, tf)
  1222. swingLowAlreadyTouched = f_alreadyTouched(true, swL, tf)
  1223. swingHighAlreadyTouched = f_alreadyTouched(false, swH, tf)
  1224.  
  1225. htf_curr_start = ta.valuewhen(ta.change(time(tf)), bar_index, 0)
  1226. htf_prev_start = ta.valuewhen(ta.change(time(tf)), bar_index, 1)
  1227. htf_prev_end = htf_curr_start - 1
  1228.  
  1229. sw_low_offset = f_findLevelOrigin(true, swL)
  1230. swing_low_already_swept = false
  1231. if not na(sw_low_offset) and sw_low_offset > 1
  1232. for i = 1 to sw_low_offset - 1
  1233. if low[i] <= swL
  1234. swing_low_already_swept := true
  1235. break
  1236.  
  1237. sw_high_offset = f_findLevelOrigin(false, swH)
  1238. swing_high_already_swept = false
  1239. if not na(sw_high_offset) and sw_high_offset > 1
  1240. for i = 1 to sw_high_offset - 1
  1241. if high[i] >= swH
  1242. swing_high_already_swept := true
  1243. break
  1244.  
  1245. if useOhlc and not na(htfPL) and not ohlcLowAlreadyTouched and low <= htfPL
  1246. sweptBull := true
  1247. sweptLvl := htfPL
  1248. lbl := tfLbl + " OHLC"
  1249.  
  1250. if useSwing and not na(swL) and not sweptBull and not swingLowAlreadyTouched and not swing_low_already_swept and low <= swL
  1251. sweptBull := true
  1252. sweptLvl := swL
  1253. lbl := tfLbl + " Swing"
  1254.  
  1255. if useOhlc and not na(htfPH) and not ohlcHighAlreadyTouched and high >= htfPH
  1256. sweptBear := true
  1257. sweptLvl := htfPH
  1258. lbl := tfLbl + " OHLC"
  1259.  
  1260. if useSwing and not na(swH) and not sweptBear and not swingHighAlreadyTouched and not swing_high_already_swept and high >= swH
  1261. sweptBear := true
  1262. sweptLvl := swH
  1263. lbl := tfLbl + " Swing"
  1264.  
  1265. [sweptBull, sweptBear, sweptLvl, lbl]
  1266.  
  1267. [swA_bull, swA_bear, swA_lvl, swA_lbl] = f_checkSweep(srcAactive, htfA_h, htfA_l, swHigh_A, swLow_A, liqTypeA, f_tfLabel(effTFA), effTFA)
  1268. [swB_bull, swB_bear, swB_lvl, swB_lbl] = f_checkSweep(srcBactive, htfB_h, htfB_l, swHigh_B, swLow_B, liqTypeB, f_tfLabel(effTFB), effTFB)
  1269. [swC_bull, swC_bear, swC_lvl, swC_lbl] = f_checkSweep(srcCactive, htfC_h, htfC_l, swHigh_C, swLow_C, liqTypeC, f_tfLabel(effTFC), effTFC)
  1270.  
  1271. anyBullSweep = swA_bull or swB_bull or swC_bull or sess_bull
  1272. anyBearSweep = swA_bear or swB_bear or swC_bear or sess_bear
  1273.  
  1274. bullSweepLevel = swA_bull ? swA_lvl : swB_bull ? swB_lvl : swC_bull ? swC_lvl : sess_bull ? sess_lvl : float(na)
  1275. bullSweepLabel = swA_bull ? swA_lbl : swB_bull ? swB_lbl : swC_bull ? swC_lbl : sess_bull ? sess_lbl : ""
  1276. bullSweepTF = swA_bull ? effTFA : swB_bull ? effTFB : swC_bull ? effTFC : timeframe.period
  1277.  
  1278. bearSweepLevel = swA_bear ? swA_lvl : swB_bear ? swB_lvl : swC_bear ? swC_lvl : sess_bear ? sess_lvl : float(na)
  1279. bearSweepLabel = swA_bear ? swA_lbl : swB_bear ? swB_lbl : swC_bear ? swC_lbl : sess_bear ? sess_lbl : ""
  1280. bearSweepTF = swA_bear ? effTFA : swB_bear ? effTFB : swC_bear ? effTFC : timeframe.period
  1281.  
  1282. f_findBullBB(pivotOffset) =>
  1283. bbTop = float(na)
  1284. bbBot = float(na)
  1285. bbLen = 0
  1286. startIdx = na(pivotOffset) ? 1 : pivotOffset
  1287. for i = startIdx to startIdx + 8
  1288. if close[i] > open[i]
  1289. bbTop := na(bbTop) ? high[i] : math.max(bbTop, high[i])
  1290. bbBot := na(bbBot) ? low[i] : math.min(bbBot, low[i])
  1291. bbLen := (i - startIdx) + 1
  1292. else
  1293. if not na(bbTop)
  1294. break
  1295. if na(bbTop) and not na(pivotOffset)
  1296. bbTop := high[pivotOffset]
  1297. bbBot := low[pivotOffset]
  1298. bbLen := 1
  1299. [bbTop, bbBot, bbLen]
  1300.  
  1301. f_findBearBB(pivotOffset) =>
  1302. bbTop = float(na)
  1303. bbBot = float(na)
  1304. bbLen = 0
  1305. startIdx = na(pivotOffset) ? 1 : pivotOffset
  1306. for i = startIdx to startIdx + 8
  1307. if close[i] < open[i]
  1308. bbTop := na(bbTop) ? high[i] : math.max(bbTop, high[i])
  1309. bbBot := na(bbBot) ? low[i] : math.min(bbBot, low[i])
  1310. bbLen := (i - startIdx) + 1
  1311. else
  1312. if not na(bbTop)
  1313. break
  1314. if na(bbTop) and not na(pivotOffset)
  1315. bbTop := high[pivotOffset]
  1316. bbBot := low[pivotOffset]
  1317. bbLen := 1
  1318. [bbTop, bbBot, bbLen]
  1319.  
  1320. f_findBullFvg(bbTop, bbBot, sweepBarIndex) =>
  1321. tops = array.new_float(0)
  1322. bots = array.new_float(0)
  1323. idxs = array.new_int(0)
  1324. limit = math.min(25, bar_index - sweepBarIndex)
  1325. if limit >= 2
  1326. for i = 0 to limit - 2
  1327. if low[i] > high[i+2]
  1328. gt = low[i]
  1329. gb = high[i+2]
  1330. if gt >= bbBot and gb <= bbTop
  1331. array.push(tops, gt)
  1332. array.push(bots, gb)
  1333. array.push(idxs, i)
  1334. [array.size(tops) > 0, tops, bots, idxs]
  1335.  
  1336. f_findBearFvg(bbTop, bbBot, sweepBarIndex) =>
  1337. tops = array.new_float(0)
  1338. bots = array.new_float(0)
  1339. idxs = array.new_int(0)
  1340. limit = math.min(25, bar_index - sweepBarIndex)
  1341. if limit >= 2
  1342. for i = 0 to limit - 2
  1343. if high[i] < low[i+2]
  1344. gt = low[i+2]
  1345. gb = high[i]
  1346. if gt >= bbBot and gb <= bbTop
  1347. array.push(tops, gt)
  1348. array.push(bots, gb)
  1349. array.push(idxs, i)
  1350. [array.size(tops) > 0, tops, bots, idxs]
  1351.  
  1352. if anyBullSweep and f_inSession() and (na(bld_bull_bbTop) or bullSweepLevel <= bld_bull_sweepLevel)
  1353. pivotOffset = bar_index - lastSwHiBar
  1354. [bbt, bbb, bblen] = f_findBullBB(pivotOffset)
  1355. if not na(bbt) and not na(bbb)
  1356. isOhlc = str.contains(bullSweepLabel, "OHLC")
  1357. sweepOffset = isOhlc ? f_findOHLCOrigin(true, bullSweepLevel, bullSweepTF) : f_findLevelOrigin(true, bullSweepLevel)
  1358.  
  1359. if sweepOffset > 0
  1360. bld_bull_sweepLevel := bullSweepLevel
  1361. bld_bull_sweepBar := bar_index
  1362. bld_bull_sweepOffset := sweepOffset
  1363. bld_bull_htfPrevStart := ta.valuewhen(ta.change(time(bullSweepTF)), bar_index, 1)
  1364. bld_bull_pivotBar := lastSwHiBar
  1365. bld_bull_bbTop := bbt
  1366. bld_bull_bbBot := bbb
  1367. bld_bull_bbLen := bblen
  1368. bld_bull_liqLabel := bullSweepLabel
  1369. bld_bull_manipLow := low
  1370. bld_bull_hasFvg := false
  1371. bld_bull_fvgTop := na
  1372. bld_bull_fvgBot := na
  1373. bld_bull_fvgIdx := na
  1374.  
  1375. if anyBearSweep and f_inSession() and (na(bld_bear_bbBot) or bearSweepLevel >= bld_bear_sweepLevel)
  1376. pivotOffset = bar_index - lastSwLoBar
  1377. [bbt, bbb, bblen] = f_findBearBB(pivotOffset)
  1378. if not na(bbt) and not na(bbb)
  1379. isOhlc = str.contains(bearSweepLabel, "OHLC")
  1380. sweepOffset = isOhlc ? f_findOHLCOrigin(false, bearSweepLevel, bearSweepTF) : f_findLevelOrigin(false, bearSweepLevel)
  1381.  
  1382. if sweepOffset > 0
  1383. bld_bear_sweepLevel := bearSweepLevel
  1384. bld_bear_sweepBar := bar_index
  1385. bld_bear_sweepOffset := sweepOffset
  1386. bld_bear_htfPrevStart := ta.valuewhen(ta.change(time(bearSweepTF)), bar_index, 1)
  1387. bld_bear_pivotBar := lastSwLoBar
  1388. bld_bear_bbTop := bbt
  1389. bld_bear_bbBot := bbb
  1390. bld_bear_bbLen := bblen
  1391. bld_bear_liqLabel := bearSweepLabel
  1392. bld_bear_manipHigh := high
  1393. bld_bear_hasFvg := false
  1394. bld_bear_fvgTop := na
  1395. bld_bear_fvgBot := na
  1396. bld_bear_fvgIdx := na
  1397.  
  1398. if not na(bld_bull_bbTop) and (bar_index - bld_bull_sweepBar) > 25
  1399. bld_bull_bbTop := na
  1400. if not na(bld_bear_bbBot) and (bar_index - bld_bear_sweepBar) > 25
  1401. bld_bear_bbBot := na
  1402.  
  1403. currentDay = time("D", effectiveTz)
  1404. if currentDay != array.get(dailyStats, 2)
  1405. array.set(dailyStats, 0, 0)
  1406. array.set(dailyStats, 1, 0)
  1407. array.set(dailyStats, 2, currentDay)
  1408.  
  1409. dailyWinCount = array.get(dailyStats, 0)
  1410. dailyLossCount = array.get(dailyStats, 1)
  1411. dailyLimitReached = i_useDailyLimit and (dailyWinCount >= i_maxDailyWins or dailyLossCount >= i_maxDailyLosses)
  1412.  
  1413. bullActivate = not na(bld_bull_bbTop)
  1414. and close > bld_bull_bbTop
  1415. and close > open
  1416. and bar_index > bld_bull_sweepBar
  1417. and f_inSession()
  1418. and f_biasOk(true)
  1419. and barstate.isconfirmed
  1420. and not dailyLimitReached
  1421.  
  1422. bearActivate = not na(bld_bear_bbBot)
  1423. and close < bld_bear_bbBot
  1424. and close < open
  1425. and bar_index > bld_bear_sweepBar
  1426. and f_inSession()
  1427. and f_biasOk(false)
  1428. and barstate.isconfirmed
  1429. and not dailyLimitReached
  1430.  
  1431. var box potBullBox = na
  1432. var box potBearBox = na
  1433.  
  1434. bullPotActive = i_showPotential
  1435. and not na(bld_bull_bbTop)
  1436. and (close > bld_bull_bbTop)
  1437. and (low <= bld_bull_bbTop)
  1438. and not bullActivate
  1439. and f_biasOk(true)
  1440. and f_inSession()
  1441.  
  1442. if bullPotActive
  1443. if na(potBullBox)
  1444. potBullBox := box.new(bld_bull_sweepBar, bld_bull_bbTop, bar_index + 6, bld_bull_bbBot,
  1445. border_color=color.new(color.gray, 100), border_width=0,
  1446. bgcolor=color.new(color.gray, 92),
  1447. text="Potential +Breaker", text_color=color.gray,
  1448. text_size=f_lblSize(i_lblSize), text_halign=text.align_right)
  1449. else
  1450. box.set_top(potBullBox, bld_bull_bbTop)
  1451. box.set_bottom(potBullBox, bld_bull_bbBot)
  1452. box.set_right(potBullBox, bar_index + 6)
  1453. else
  1454. box.delete(potBullBox)
  1455. potBullBox := na
  1456.  
  1457. bearPotActive = i_showPotential
  1458. and not na(bld_bear_bbBot)
  1459. and (close < bld_bear_bbBot)
  1460. and (high >= bld_bear_bbBot)
  1461. and not bearActivate
  1462. and f_biasOk(false)
  1463. and f_inSession()
  1464.  
  1465. if bearPotActive
  1466. if na(potBearBox)
  1467. potBearBox := box.new(bld_bear_sweepBar, bld_bear_bbTop, bar_index + 6, bld_bear_bbBot,
  1468. border_color=color.new(color.gray, 100), border_width=0,
  1469. bgcolor=color.new(color.gray, 92),
  1470. text="Potential -Breaker", text_color=color.gray,
  1471. text_size=f_lblSize(i_lblSize), text_halign=text.align_right)
  1472. else
  1473. box.set_top(potBearBox, bld_bear_bbTop)
  1474. box.set_bottom(potBearBox, bld_bear_bbBot)
  1475. box.set_right(potBearBox, bar_index + 6)
  1476. else
  1477. box.delete(potBearBox)
  1478. potBearBox := na
  1479.  
  1480. f_registerSetup(isBull, bbTop, bbBot, sweepLevel, sweepBar, sweepOffset, bbLeft, manipExtreme, hasFvg, fvgTops, fvgBots, fvgLefts, fvgRights, sweepLbl) =>
  1481. isUni = hasFvg
  1482. showThis = i_modelMode == "Breaker" or (i_modelMode == "Unicorn" and hasFvg) or (i_modelMode == "Breaker + Unicorn")
  1483.  
  1484. if showThis
  1485. entry = isBull ? bbTop : bbBot
  1486. invalLvl = i_swingInval ? manipExtreme : (isBull ? bbBot : bbTop)
  1487. riskSz = math.abs(entry - invalLvl)
  1488.  
  1489. if f_sizeOk(riskSz) and f_biasOk(isBull)
  1490. extras = f_parseExtras(i_extraStr)
  1491. nExtras = array.size(extras)
  1492.  
  1493. projEntry = i_projCalc == "Confirmation Close" ? close : (isBull ? bbTop : bbBot)
  1494. risk = math.abs(projEntry - invalLvl)
  1495.  
  1496. mainTgt = isBull ? invalLvl + (i_rrMain + 1.0) * risk : invalLvl - (i_rrMain + 1.0) * risk
  1497.  
  1498. extraPrices = array.new_float(0)
  1499. for ei = 0 to nExtras - 1
  1500. mult = array.get(extras, ei)
  1501. t = isBull ? invalLvl + (mult + 1.0) * risk : invalLvl - (mult + 1.0) * risk
  1502. array.push(extraPrices, t)
  1503.  
  1504. extRight = bar_index + 6
  1505.  
  1506. zCol = isBull ? i_bullColor : i_bearColor
  1507. zBorderCol = color.new(zCol, 0)
  1508.  
  1509. lblTxt = isUni ? (isBull ? "+Unicorn" : "-Unicorn")
  1510. : (isBull ? "+Breaker" : "-Breaker")
  1511.  
  1512. zBox = box.new(bbLeft, bbTop, extRight, bbBot,
  1513. border_color=color.new(zCol, 100),
  1514. border_width=0,
  1515. bgcolor=zCol,
  1516. extend=extend.none,
  1517. text=lblTxt,
  1518. text_size=f_lblSize(i_lblSize),
  1519. text_color=color.black,
  1520. text_halign=text.align_right,
  1521. text_valign=text.align_center)
  1522.  
  1523. fBoxArr = array.new<box>(0)
  1524. ceLines = array.new<line>(0)
  1525. if hasFvg
  1526. fvgCol = isBull ? i_bullFvgColor : i_bearFvgColor
  1527. for i = 0 to array.size(fvgTops) - 1
  1528. ft = array.get(fvgTops, i)
  1529. fb = array.get(fvgBots, i)
  1530. fl = array.get(fvgLefts, i)
  1531. fr = array.get(fvgRights, i)
  1532.  
  1533. extendFVG = isBull ? i_extendFVGBull : i_extendFVGBear
  1534. fvgRightCol = extendFVG ? extRight : fr
  1535.  
  1536. fBox = box.new(fl, ft, fvgRightCol, fb,
  1537. border_color=color.new(fvgCol, 100),
  1538. border_width=0,
  1539. bgcolor=fvgCol,
  1540. extend=extend.none)
  1541. array.push(fBoxArr, fBox)
  1542.  
  1543. fMid = (ft + fb) / 2.0
  1544. if (isBull and i_showCEBull) or (not isBull and i_showCEBear)
  1545. cel = line.new(fl, fMid, fr, fMid, color=fvgCol, width=1, style=line.style_dotted)
  1546. array.push(ceLines, cel)
  1547.  
  1548. float bbMid = (bbTop + bbBot) / 2.0
  1549. line bb50L = na
  1550. if (isBull and i_showBB50Bull) or (not isBull and i_showBB50Bear)
  1551. extendLine = isBull ? i_extendBB50Bull : i_extendBB50Bear
  1552. endX = extendLine ? (extRight - 5) : math.max(bbLeft, bar_index - 5)
  1553. bb50L := line.new(bbLeft, bbMid, endX, bbMid, color=i_bb50Color, width=1, style=line.style_dotted)
  1554.  
  1555. originBar = sweepBar - sweepOffset
  1556. sweepSty = f_lineStyle(i_sweepLineStyle)
  1557. sLine = line.new(originBar, sweepLevel, sweepBar, sweepLevel,
  1558. color=i_sweepLineColor, width=i_sweepLineWidth,
  1559. style=sweepSty, extend=extend.none)
  1560.  
  1561. sLabel = label.new(originBar, sweepLevel, sweepLbl,
  1562. style = isBull ? label.style_label_up : label.style_label_down,
  1563. textcolor = i_sweepLblColor,
  1564. color = color.new(color.black, 100),
  1565. size = f_lblSize(i_sweepLblSize),
  1566. yloc = yloc.price)
  1567.  
  1568. zLbl = label(na)
  1569.  
  1570. tLines = array.new<line>(0)
  1571. tLabels = array.new<label>(0)
  1572.  
  1573. projSty = f_lineStyle(i_projLineStyle)
  1574.  
  1575. if i_showRR
  1576. tl = line.new(bbLeft, mainTgt, bbLeft + 10, mainTgt, color=i_projLineColor, width=i_projLineWidth, style=line.style_dotted, extend=extend.none)
  1577. array.push(tLines, tl)
  1578. tl2 = label.new(bbLeft + 12, mainTgt, str.tostring(i_rrMain, "#.#") + "R", style=label.style_none, textcolor=color.new(i_projLineColor, 10), size=size.tiny, yloc=yloc.price)
  1579. array.push(tLabels, tl2)
  1580.  
  1581. if i_showExtra
  1582. for ei = 0 to nExtras - 1
  1583. ep = array.get(extraPrices, ei)
  1584. em = array.get(extras, ei)
  1585. etl = line.new(bbLeft, ep, bbLeft + 10, ep, color=i_projLineColor, width=i_projLineWidth, style=line.style_dotted, extend=extend.none)
  1586. array.push(tLines, etl)
  1587. etl2 = label.new(bbLeft + 12, ep, str.tostring(em, "#.#") + "R", style=label.style_none, textcolor=color.new(i_projLineColor, 10), size=size.tiny, yloc=yloc.price)
  1588. array.push(tLabels, etl2)
  1589.  
  1590. line beLine = na
  1591. label beLabel = na
  1592. if i_useBE and i_showBELine
  1593. beTriggerPrice = entry + (mainTgt - entry) * 0.5
  1594. beSty = f_lineStyle(i_beLineStyle)
  1595. beLine := line.new(bbLeft, beTriggerPrice, bbLeft + 10, beTriggerPrice, color=i_beLineColor, width=i_beLineWidth, style=beSty, extend=extend.none)
  1596. beLabel := label.new(bbLeft + 12, beTriggerPrice, "BE Trigger (50%)", style=label.style_none, textcolor=color.new(i_beLineColor, 20), size=size.tiny, yloc=yloc.price)
  1597.  
  1598. newSetup = UnicornSetup.new(
  1599. isBull = isBull,
  1600. isUnicorn = isUni,
  1601. sweepLabel = sweepLbl,
  1602. zoneTop = bbTop,
  1603. zoneBot = bbBot,
  1604. fvgTops = fvgTops,
  1605. fvgBots = fvgBots,
  1606. sweepLevel = sweepLevel,
  1607. sweepBar = sweepBar,
  1608. activationBar = bar_index,
  1609. invalidLevel = invalLvl,
  1610. useSwingInval = i_swingInval,
  1611. entryPrice = entry,
  1612. riskSize = riskSz,
  1613. mainTarget = mainTgt,
  1614. extraTargets = extraPrices,
  1615. state = 1,
  1616. alertedPotential = false,
  1617. alertedActivation = false,
  1618. alertedTarget = false,
  1619. alertedInvalWarn = false,
  1620. alertedInvalHit = false,
  1621. alertedBE = false,
  1622. isBEActive = false,
  1623. zoneBox = zBox,
  1624. fvgBoxes = fBoxArr,
  1625. sweepLine = sLine,
  1626. sweepLbl = sLabel,
  1627. zoneLbl = zLbl,
  1628. targetLines = tLines,
  1629. targetLabels = tLabels,
  1630. bb50Line = bb50L,
  1631. fvgCeLines = ceLines,
  1632. beTriggerLine = beLine,
  1633. beTriggerLabel = beLabel)
  1634.  
  1635. array.push(setups, newSetup)
  1636.  
  1637. if bullActivate
  1638. [fFound, fTops, fBots, fIdxs] = f_findBullFvg(bld_bull_bbTop, bld_bull_bbBot, bld_bull_sweepBar)
  1639. hasFvg = fFound
  1640.  
  1641. fvgTopsArr = array.new_float(0)
  1642. fvgBotsArr = array.new_float(0)
  1643. fvgLeftsArr = array.new_int(0)
  1644. fvgRightsArr = array.new_int(0)
  1645.  
  1646. if hasFvg
  1647. for i = 0 to array.size(fTops) - 1
  1648. fIdx = array.get(fIdxs, i)
  1649. array.push(fvgTopsArr, array.get(fTops, i))
  1650. array.push(fvgBotsArr, array.get(fBots, i))
  1651. array.push(fvgLeftsArr, bar_index - fIdx - 2)
  1652. array.push(fvgRightsArr, bar_index - fIdx)
  1653.  
  1654. bbLeft = na(bld_bull_pivotBar) ? bld_bull_sweepBar : bld_bull_pivotBar
  1655. f_registerSetup(true, bld_bull_bbTop, bld_bull_bbBot, bld_bull_sweepLevel, bld_bull_sweepBar, bld_bull_sweepOffset, bbLeft, bld_bull_manipLow, hasFvg, fvgTopsArr, fvgBotsArr, fvgLeftsArr, fvgRightsArr, bld_bull_liqLabel)
  1656. bld_bull_bbTop := na
  1657.  
  1658. if bearActivate
  1659. [fFound, fTops, fBots, fIdxs] = f_findBearFvg(bld_bear_bbTop, bld_bear_bbBot, bld_bear_sweepBar)
  1660. hasFvg = fFound
  1661.  
  1662. fvgTopsArr = array.new_float(0)
  1663. fvgBotsArr = array.new_float(0)
  1664. fvgLeftsArr = array.new_int(0)
  1665. fvgRightsArr = array.new_int(0)
  1666.  
  1667. if hasFvg
  1668. for i = 0 to array.size(fTops) - 1
  1669. fIdx = array.get(fIdxs, i)
  1670. array.push(fvgTopsArr, array.get(fTops, i))
  1671. array.push(fvgBotsArr, array.get(fBots, i))
  1672. array.push(fvgLeftsArr, bar_index - fIdx - 2)
  1673. array.push(fvgRightsArr, bar_index - fIdx)
  1674.  
  1675. bbLeft = na(bld_bear_pivotBar) ? bld_bear_sweepBar : bld_bear_pivotBar
  1676. f_registerSetup(false, bld_bear_bbTop, bld_bear_bbBot, bld_bear_sweepLevel, bld_bear_sweepBar, bld_bear_sweepOffset, bbLeft, bld_bear_manipHigh, hasFvg, fvgTopsArr, fvgBotsArr, fvgLeftsArr, fvgRightsArr, bld_bear_liqLabel)
  1677. bld_bear_bbBot := na
  1678.  
  1679. var string lastSweepLabel = "–"
  1680.  
  1681. f_updateSetups(prevLabel) =>
  1682. string retLabel = prevLabel
  1683. n = array.size(setups)
  1684. if n > 0
  1685. for i = n - 1 to 0
  1686. s = array.get(setups, i)
  1687. if s.state == 4 and i_discardInval
  1688. continue
  1689. if s.state >= 3
  1690. continue
  1691.  
  1692. isBull = s.isBull
  1693. if s.state == 1
  1694. retested = isBull ? (low <= s.zoneTop and low >= s.zoneBot) : (high >= s.zoneBot and high <= s.zoneTop)
  1695. if retested
  1696. s.state := 2
  1697. newCol = isBull ? i_bullRetColor : i_bearRetColor
  1698. box.set_bgcolor(s.zoneBox, newCol)
  1699. box.set_border_color(s.zoneBox, color.new(newCol, 100))
  1700. box.set_text_color(s.zoneBox, color.black)
  1701.  
  1702. if s.state == 1 or s.state == 2
  1703. box.set_right(s.zoneBox, bar_index + 6)
  1704. if not na(s.bb50Line)
  1705. extendLine = s.isBull ? i_extendBB50Bull : i_extendBB50Bear
  1706. if extendLine
  1707. boxLeft = box.get_left(s.zoneBox)
  1708. line.set_x2(s.bb50Line, math.max(boxLeft, bar_index + 6))
  1709. if array.size(s.fvgBoxes) > 0
  1710. for fi = 0 to array.size(s.fvgBoxes) - 1
  1711. curFvgBox = array.get(s.fvgBoxes, fi)
  1712. if (s.isBull and i_extendFVGBull) or (s.isBull == false and i_extendFVGBear)
  1713. box.set_right(curFvgBox, bar_index + 6)
  1714. if array.size(s.fvgCeLines) > fi
  1715. line.set_x2(array.get(s.fvgCeLines, fi), bar_index + 6)
  1716. if not na(s.zoneLbl)
  1717. label.set_x(s.zoneLbl, bar_index + 8)
  1718.  
  1719. if i_modelMode == "Breaker + Unicorn" and not s.isUnicorn
  1720. bool fFound = false
  1721. float[] fTops = na
  1722. float[] fBots = na
  1723. int[] fIdxs = na
  1724.  
  1725. if s.isBull
  1726. [found, tops, bots, idxs] = f_findBullFvg(s.zoneTop, s.zoneBot, s.sweepBar)
  1727. fFound := found
  1728. fTops := tops
  1729. fBots := bots
  1730. fIdxs := idxs
  1731. else
  1732. [found, tops, bots, idxs] = f_findBearFvg(s.zoneTop, s.zoneBot, s.sweepBar)
  1733. fFound := found
  1734. fTops := tops
  1735. fBots := bots
  1736. fIdxs := idxs
  1737. if fFound
  1738. s.isUnicorn := true
  1739. box.set_text(s.zoneBox, s.isBull ? "+Unicorn" : "-Unicorn")
  1740. fvgCol = s.isBull ? i_bullFvgColor : i_bearFvgColor
  1741. for i = 0 to array.size(fTops) - 1
  1742. ft = array.get(fTops, i)
  1743. fb = array.get(fBots, i)
  1744. fBox = box.new(bar_index - array.get(fIdxs, i) - 2, ft, bar_index - array.get(fIdxs, i), fb,
  1745. border_color=color.new(fvgCol, 100), border_width=0, bgcolor=fvgCol)
  1746. array.push(s.fvgBoxes, fBox)
  1747. fMid = (ft + fb) / 2.0
  1748. if (s.isBull and i_showCEBull) or (not s.isBull and i_showCEBear)
  1749. cel = line.new(bar_index - array.get(fIdxs, i) - 2, fMid, bar_index - array.get(fIdxs, i), fMid, color=fvgCol, width=1, style=line.style_dotted)
  1750. array.push(s.fvgCeLines, cel)
  1751.  
  1752. if i_useBE and not s.isBEActive and (s.state == 1 or s.state == 2)
  1753. beTriggerPrice = s.entryPrice + (s.mainTarget - s.entryPrice) * 0.5
  1754. isTriggered = isBull ? (high >= beTriggerPrice) : (low <= beTriggerPrice)
  1755. if isTriggered
  1756. s.isBEActive := true
  1757. if not na(s.beTriggerLine)
  1758. line.set_color(s.beTriggerLine, color.new(isBull ? i_bullColor : i_bearColor, 0))
  1759. line.set_style(s.beTriggerLine, line.style_solid)
  1760. if not na(s.beTriggerLabel)
  1761. label.set_text(s.beTriggerLabel, "BE Triggered")
  1762. label.set_textcolor(s.beTriggerLabel, isBull ? i_bullColor : i_bearColor)
  1763. if i_alertEnable and not s.alertedBE
  1764. alert("Unicorn Model° Break-Even Activated | " + syminfo.ticker + " | " + (isBull ? "BULL" : "BEAR"), alert.freq_once_per_bar)
  1765. s.alertedBE := true
  1766.  
  1767. bool beExitHit = false
  1768. if i_useBE and s.isBEActive and (s.state == 1 or s.state == 2)
  1769. beExitHit := isBull ? (low <= s.entryPrice) : (high >= s.entryPrice)
  1770. if beExitHit
  1771. s.state := 5
  1772. box.set_right(s.zoneBox, bar_index)
  1773. box.set_bgcolor(s.zoneBox, i_invalColor)
  1774. box.set_border_color(s.zoneBox, color.new(#9e9e9e, 100))
  1775. box.set_text_color(s.zoneBox, color.new(#9e9e9e, 40))
  1776. box.set_text(s.zoneBox, s.isUnicorn ? (isBull ? "BE +Unicorn" : "BE -Unicorn") : (isBull ? "BE +Breaker" : "BE -Breaker"))
  1777.  
  1778. if not na(s.bb50Line)
  1779. line.set_x2(s.bb50Line, bar_index)
  1780. if array.size(s.fvgBoxes) > 0
  1781. for fi = 0 to array.size(s.fvgBoxes) - 1
  1782. curFvgBox = array.get(s.fvgBoxes, fi)
  1783. box.set_right(curFvgBox, bar_index)
  1784. box.set_bgcolor(curFvgBox, color.new(#9e9e9e, 94))
  1785. box.set_border_color(curFvgBox, color.new(#9e9e9e, 100))
  1786. if array.size(s.fvgCeLines) > fi
  1787. line.set_x2(array.get(s.fvgCeLines, fi), bar_index)
  1788.  
  1789. if not na(s.zoneLbl)
  1790. label.set_textcolor(s.zoneLbl, color.new(#9e9e9e, 40))
  1791. label.set_text(s.zoneLbl, "BE Stopped")
  1792.  
  1793. if timeframe.period == "1" or timeframe.period == "5" or timeframe.period == "15" or timeframe.period == "30" or timeframe.period == "60"
  1794. int actOffset = bar_index - s.activationBar
  1795. array.push(stat_years, year(time[actOffset]))
  1796. array.push(stat_months, month(time[actOffset]))
  1797. array.push(stat_outcomes, 2)
  1798.  
  1799. if i_alertEnable
  1800. alert("Unicorn Model° Break-Even Stopped Out | " + syminfo.ticker + " | " + (isBull ? "BULL" : "BEAR"), alert.freq_once_per_bar)
  1801.  
  1802. if not beExitHit and (s.state == 1 or s.state == 2)
  1803. hitTarget = isBull ? high >= s.mainTarget : low <= s.mainTarget
  1804. if hitTarget
  1805. s.state := 3
  1806. box.set_right(s.zoneBox, bar_index)
  1807. if not na(s.bb50Line)
  1808. extendLine = s.isBull ? i_extendBB50Bull : i_extendBB50Bear
  1809. if extendLine
  1810. boxLeft = box.get_left(s.zoneBox)
  1811. line.set_x2(s.bb50Line, math.max(boxLeft, bar_index - 5))
  1812. if array.size(s.fvgBoxes) > 0
  1813. for fi = 0 to array.size(s.fvgBoxes) - 1
  1814. curFvgBox = array.get(s.fvgBoxes, fi)
  1815. extendFVG = s.isBull ? i_extendFVGBull : i_extendFVGBear
  1816. if extendFVG
  1817. box.set_right(curFvgBox, bar_index)
  1818. if array.size(s.fvgCeLines) > fi
  1819. line.set_x2(array.get(s.fvgCeLines, fi), bar_index)
  1820.  
  1821. if timeframe.period == "1" or timeframe.period == "5" or timeframe.period == "15" or timeframe.period == "30" or timeframe.period == "60"
  1822. int actOffset = bar_index - s.activationBar
  1823. array.push(stat_years, year(time[actOffset]))
  1824. array.push(stat_months, month(time[actOffset]))
  1825. array.push(stat_outcomes, 1)
  1826. array.set(dailyStats, 0, array.get(dailyStats, 0) + 1)
  1827.  
  1828. if i_alertEnable and i_alertTarget and not s.alertedTarget
  1829. alert("Unicorn Model° Target Reached | " + syminfo.ticker + " | " + (isBull ? "BULL" : "BEAR") + " | " + str.tostring(s.mainTarget, format.mintick), alert.freq_once_per_bar)
  1830. s.alertedTarget := true
  1831.  
  1832. if not beExitHit and (s.state == 1 or s.state == 2)
  1833. invalWarn = isBull ? (low < s.invalidLevel + s.riskSize * 0.15) : (high > s.invalidLevel - s.riskSize * 0.15)
  1834. invalHit = isBull ? (low < s.invalidLevel) : (high > s.invalidLevel)
  1835.  
  1836. if invalWarn and not s.alertedInvalWarn
  1837. if i_alertEnable and i_alertWarn
  1838. alert("Unicorn Model° Invalidation Warning | " + syminfo.ticker + " | " + (isBull ? "BULL" : "BEAR"), alert.freq_once_per_bar)
  1839. s.alertedInvalWarn := true
  1840.  
  1841. if invalHit
  1842. s.state := 4
  1843. box.set_bgcolor(s.zoneBox, i_invalColor)
  1844. box.set_border_color(s.zoneBox, color.new(#9e9e9e, 100))
  1845. box.set_right(s.zoneBox, bar_index)
  1846.  
  1847. box.set_text_color(s.zoneBox, color.new(#9e9e9e, 40))
  1848. box.set_text(s.zoneBox, s.isUnicorn ? (isBull ? "✕ +Unicorn" : "✕ -Unicorn") : (isBull ? "✕ +Breaker" : "✕ -Breaker"))
  1849.  
  1850. if not na(s.bb50Line)
  1851. extendLine = s.isBull ? i_extendBB50Bull : i_extendBB50Bear
  1852. if extendLine
  1853. boxLeft = box.get_left(s.zoneBox)
  1854. line.set_x2(s.bb50Line, math.max(boxLeft, bar_index - 5))
  1855.  
  1856. if array.size(s.fvgBoxes) > 0
  1857. for fi = 0 to array.size(s.fvgBoxes) - 1
  1858. curFvgBox = array.get(s.fvgBoxes, fi)
  1859. box.set_bgcolor(curFvgBox, color.new(#9e9e9e, 94))
  1860. box.set_border_color(curFvgBox, color.new(#9e9e9e, 100))
  1861. extendFVG = s.isBull ? i_extendFVGBull : i_extendFVGBear
  1862. if extendFVG
  1863. box.set_right(curFvgBox, bar_index)
  1864. if array.size(s.fvgCeLines) > fi
  1865. line.set_x2(array.get(s.fvgCeLines, fi), bar_index)
  1866. if not na(s.zoneLbl)
  1867. label.set_textcolor(s.zoneLbl, color.new(#9e9e9e, 40))
  1868. label.set_text(s.zoneLbl, s.isUnicorn ? (isBull ? "✕ +Unicorn" : "✕ -Unicorn") : (isBull ? "✕ +Breaker" : "✕ -Breaker"))
  1869.  
  1870. if timeframe.period == "1" or timeframe.period == "5" or timeframe.period == "15" or timeframe.period == "30" or timeframe.period == "60"
  1871. int actOffset = bar_index - s.activationBar
  1872. array.push(stat_years, year(time[actOffset]))
  1873. array.push(stat_months, month(time[actOffset]))
  1874. array.push(stat_outcomes, 0)
  1875. array.set(dailyStats, 1, array.get(dailyStats, 1) + 1)
  1876.  
  1877. if i_alertEnable and i_alertHit and not s.alertedInvalHit
  1878. alert("❌ Unicorn Model° Invalidation Hit | " + syminfo.ticker + " | " + (isBull ? "BULL" : "BEAR"), alert.freq_once_per_bar)
  1879. s.alertedInvalHit := true
  1880.  
  1881. if (s.state == 1 or s.state == 2)
  1882. retLabel := s.sweepLabel
  1883. retLabel
  1884.  
  1885. lastSweepLabel := f_updateSetups(lastSweepLabel)
  1886.  
  1887. bullPotential = not na(bld_bull_bbTop) and high >= bld_bull_bbBot and close < bld_bull_bbTop
  1888. bearPotential = not na(bld_bear_bbBot) and low <= bld_bear_bbTop and close > bld_bear_bbBot
  1889.  
  1890. if i_alertEnable and i_alertPotential
  1891. if bullPotential
  1892. alert("Unicorn Model° Potential Breaker | " + syminfo.ticker + " | BULL | Wick into BB zone", alert.freq_once_per_bar)
  1893. if bearPotential
  1894. alert("Unicorn Model° Potential Breaker | " + syminfo.ticker + " | BEAR | Wick into BB zone", alert.freq_once_per_bar)
  1895.  
  1896. if i_alertEnable and i_alertActiv
  1897. if bullActivate
  1898. alert("Unicorn Model° Activation | " + syminfo.ticker + " | BULL | " + bld_bull_liqLabel, alert.freq_once_per_bar)
  1899. if bearActivate
  1900. alert("Unicorn Model° Activation | " + syminfo.ticker + " | BEAR | " + bld_bear_liqLabel, alert.freq_once_per_bar)
  1901.  
  1902. f_gc() =>
  1903. while array.size(setups) > i_history
  1904. oldest = array.shift(setups)
  1905. box.delete(oldest.zoneBox)
  1906. if array.size(oldest.fvgBoxes) > 0
  1907. for fi = 0 to array.size(oldest.fvgBoxes) - 1
  1908. box.delete(array.get(oldest.fvgBoxes, fi))
  1909. line.delete(oldest.sweepLine)
  1910. label.delete(oldest.sweepLbl)
  1911. label.delete(oldest.zoneLbl)
  1912. line.delete(oldest.bb50Line)
  1913. if array.size(oldest.fvgCeLines) > 0
  1914. for cel in oldest.fvgCeLines
  1915. line.delete(cel)
  1916. tln = array.size(oldest.targetLines)
  1917. if tln > 0
  1918. for ti = 0 to tln - 1
  1919. line.delete(array.get(oldest.targetLines, ti))
  1920. tlabn = array.size(oldest.targetLabels)
  1921. if tlabn > 0
  1922. for ti = 0 to tlabn - 1
  1923. label.delete(array.get(oldest.targetLabels, ti))
  1924. line.delete(oldest.beTriggerLine)
  1925. label.delete(oldest.beTriggerLabel)
  1926.  
  1927. if i_discardInval
  1928. n = array.size(setups)
  1929. if n > 0
  1930. i = n - 1
  1931. while i >= 0
  1932. s = array.get(setups, i)
  1933. if s.state == 4 or s.state == 5
  1934. box.delete(s.zoneBox)
  1935. if array.size(s.fvgBoxes) > 0
  1936. for fi = 0 to array.size(s.fvgBoxes) - 1
  1937. box.delete(array.get(s.fvgBoxes, fi))
  1938. line.delete(s.sweepLine)
  1939. label.delete(s.sweepLbl)
  1940. label.delete(s.zoneLbl)
  1941. line.delete(s.bb50Line)
  1942. if array.size(s.fvgCeLines) > 0
  1943. for cel in s.fvgCeLines
  1944. line.delete(cel)
  1945. tln = array.size(s.targetLines)
  1946. if tln > 0
  1947. for ti = 0 to tln - 1
  1948. line.delete(array.get(s.targetLines, ti))
  1949. tlabn = array.size(s.targetLabels)
  1950. if tlabn > 0
  1951. for ti = 0 to tlabn - 1
  1952. label.delete(array.get(s.targetLabels, ti))
  1953. line.delete(s.beTriggerLine)
  1954. label.delete(s.beTriggerLabel)
  1955. array.remove(setups, i)
  1956. i -= 1
  1957.  
  1958. if fvg_newPeriod and not na(fvg_htfT1)
  1959. string fvg_tfStr = formatTimeframe(fvg_selectedHTF)
  1960.  
  1961. if fvg_showBearish and fvg_htfHasBear and not na(fvg_htfBearBot) and not na(fvg_htfBearTop)
  1962. bool fvg_exists = false
  1963. if array.size(activeHtfFVGs) > 0
  1964. for i = 0 to array.size(activeHtfFVGs) - 1
  1965. item = array.get(activeHtfFVGs, i)
  1966. if not item.isBullish and item.top == fvg_htfBearTop and item.bottom == fvg_htfBearBot
  1967. fvg_exists := true
  1968. break
  1969.  
  1970. if not fvg_exists
  1971. box b = na
  1972. line l = na
  1973. label lbl = na
  1974. fvg_midPrice = (fvg_htfBearTop + fvg_htfBearBot) / 2
  1975.  
  1976. if fvg_showBoxes
  1977. b := box.new(fvg_htfT2, fvg_htfBearTop, time, fvg_htfBearBot, bgcolor = fvg_bearishColor, border_color = color.new(color.gray, 100), xloc = xloc.bar_time)
  1978. if fvg_showMidlines
  1979. l := line.new(fvg_htfT2, fvg_midPrice, time, fvg_midPrice, color = fvg_midlineColor, style = line.style_dotted, width = 1, xloc = xloc.bar_time)
  1980.  
  1981. if fvg_showLabels
  1982. lbl := label.new(time, fvg_midPrice, "FVG-" + fvg_tfStr, color = color.new(color.white, 100), textcolor = fvg_labelTextColor, style = label.style_label_right, size = size.small, xloc = xloc.bar_time, text_font_family = font.family_monospace)
  1983.  
  1984. array.push(activeHtfFVGs, HtfFVG.new(b, l, lbl, fvg_htfBearTop, fvg_htfBearBot, false, fvg_htfT2, false, na))
  1985.  
  1986. if fvg_showBullish and fvg_htfHasBull and not na(fvg_htfBullBot) and not na(fvg_htfBullTop)
  1987. bool fvg_exists = false
  1988. if array.size(activeHtfFVGs) > 0
  1989. for i = 0 to array.size(activeHtfFVGs) - 1
  1990. item = array.get(activeHtfFVGs, i)
  1991. if item.isBullish and item.top == fvg_htfBullTop and item.bottom == fvg_htfBullBot
  1992. fvg_exists := true
  1993. break
  1994.  
  1995. if not fvg_exists
  1996. box b = na
  1997. line l = na
  1998. label lbl = na
  1999. fvg_midPrice = (fvg_htfBullTop + fvg_htfBullBot) / 2
  2000.  
  2001. if fvg_showBoxes
  2002. b := box.new(fvg_htfT2, fvg_htfBullTop, time, fvg_htfBullBot, bgcolor = fvg_bullishColor, border_color = color.new(color.gray, 100), xloc = xloc.bar_time)
  2003. if fvg_showMidlines
  2004. l := line.new(fvg_htfT2, fvg_midPrice, time, fvg_midPrice, color = fvg_midlineColor, style = line.style_dotted, width = 1, xloc = xloc.bar_time)
  2005.  
  2006. if fvg_showLabels
  2007. lbl := label.new(time, fvg_midPrice, "FVG+" + fvg_tfStr, color = color.new(color.white, 100), textcolor = fvg_labelTextColor, style = label.style_label_right, size = size.small, xloc = xloc.bar_time, text_font_family = font.family_monospace)
  2008.  
  2009. array.push(activeHtfFVGs, HtfFVG.new(b, l, lbl, fvg_htfBullTop, fvg_htfBullBot, true, fvg_htfT2, false, na))
  2010. if array.size(activeHtfFVGs) > 0
  2011. for i = 0 to array.size(activeHtfFVGs) - 1
  2012. item = array.get(activeHtfFVGs, i)
  2013. if not item.isBullish and item.top == fvg_htfBearTop and item.bottom == fvg_htfBearBot
  2014. fvg_exists := true
  2015. break
  2016.  
  2017. if not fvg_exists
  2018. box b = na
  2019. line l = na
  2020. label lbl = na
  2021. fvg_midPrice = (fvg_htfBearTop + fvg_htfBearBot) / 2
  2022.  
  2023. if fvg_showBoxes
  2024. b := box.new(fvg_htfT2, fvg_htfBearTop, time, fvg_htfBearBot, bgcolor = fvg_bearishColor, border_color = color.new(color.gray, 100), xloc = xloc.bar_time)
  2025. if fvg_showMidlines
  2026. l := line.new(fvg_htfT2, fvg_midPrice, time, fvg_midPrice, color = fvg_midlineColor, style = line.style_dotted, width = 1, xloc = xloc.bar_time)
  2027.  
  2028. if fvg_showLabels
  2029. lbl := label.new(time, fvg_midPrice, "FVG-" + fvg_tfStr, color = color.new(color.white, 100), textcolor = fvg_labelTextColor, style = label.style_label_right, size = size.small, xloc = xloc.bar_time, text_font_family = font.family_monospace)
  2030.  
  2031. array.push(activeHtfFVGs, HtfFVG.new(b, l, lbl, fvg_htfBearTop, fvg_htfBearBot, false, fvg_htfT2, false, na))
  2032.  
  2033. if fvg_htfHasBull and not na(fvg_htfBullBot) and not na(fvg_htfBullTop)
  2034. bool fvg_exists = false
  2035. if array.size(activeHtfFVGs) > 0
  2036. for i = 0 to array.size(activeHtfFVGs) - 1
  2037. item = array.get(activeHtfFVGs, i)
  2038. if item.isBullish and item.top == fvg_htfBullTop and item.bottom == fvg_htfBullBot
  2039. fvg_exists := true
  2040. break
  2041.  
  2042. if not fvg_exists
  2043. box b = na
  2044. line l = na
  2045. label lbl = na
  2046. fvg_midPrice = (fvg_htfBullTop + fvg_htfBullBot) / 2
  2047.  
  2048. if fvg_showBoxes
  2049. b := box.new(fvg_htfT2, fvg_htfBullTop, time, fvg_htfBullBot, bgcolor = fvg_bullishColor, border_color = color.new(color.gray, 100), xloc = xloc.bar_time)
  2050. if fvg_showMidlines
  2051. l := line.new(fvg_htfT2, fvg_midPrice, time, fvg_midPrice, color = fvg_midlineColor, style = line.style_dotted, width = 1, xloc = xloc.bar_time)
  2052.  
  2053. if fvg_showLabels
  2054. lbl := label.new(time, fvg_midPrice, "FVG+" + fvg_tfStr, color = color.new(color.white, 100), textcolor = fvg_labelTextColor, style = label.style_label_right, size = size.small, xloc = xloc.bar_time, text_font_family = font.family_monospace)
  2055.  
  2056. array.push(activeHtfFVGs, HtfFVG.new(b, l, lbl, fvg_htfBullTop, fvg_htfBullBot, true, fvg_htfT2, false, na))
  2057.  
  2058. if fvg_newPeriod and array.size(activeHtfFVGs) > 0
  2059. for i = array.size(activeHtfFVGs) - 1 to 0
  2060. HtfFVG f = array.get(activeHtfFVGs, i)
  2061.  
  2062. bool fvg_isInvalidated = f.isBullish ? (fvg_htfCloseVal < f.bottom) : (fvg_htfCloseVal > f.top)
  2063.  
  2064. if fvg_isInvalidated
  2065. if not na(f.fvgBox)
  2066. box.delete(f.fvgBox)
  2067. if not na(f.midline)
  2068. line.delete(f.midline)
  2069. if not na(f.fvgLabel)
  2070. label.delete(f.fvgLabel)
  2071. array.remove(activeHtfFVGs, i)
  2072.  
  2073. if array.size(activeHtfFVGs) > 0
  2074. for i = 0 to array.size(activeHtfFVGs) - 1
  2075. HtfFVG f = array.get(activeHtfFVGs, i)
  2076. if not na(f.fvgBox)
  2077. box.set_right(f.fvgBox, time)
  2078. if not na(f.midline)
  2079. line.set_x2(f.midline, time)
  2080. if not na(f.fvgLabel)
  2081. label.set_x(f.fvgLabel, time)
  2082.  
  2083. fvg_totalActive = array.size(activeHtfFVGs)
  2084. if fvg_totalActive > fvg_maxFVGs
  2085. for i = 0 to (fvg_totalActive - fvg_maxFVGs) - 1
  2086. HtfFVG old = array.shift(activeHtfFVGs)
  2087. if not na(old.fvgBox)
  2088. box.delete(old.fvgBox)
  2089. if not na(old.midline)
  2090. line.delete(old.midline)
  2091. if not na(old.fvgLabel)
  2092. label.delete(old.fvgLabel)
  2093.  
  2094. if smt_sPair != "" and bar_index > last_bar_index - 4500
  2095. smt_chartPivDir = not na(ta.pivothigh(3, 3)) ? 1 : not na(ta.pivotlow(3, 3)) ? -1 : 0
  2096.  
  2097. smt_bearD_htf = (not na(smt_htfClose) and smt_htfClose < smt_htfOpen) and smt_htfHigh < smt_htfHigh1 and smt_sH_htf > smt_sH1_htf
  2098. smt_bullD_htf = (not na(smt_htfClose) and smt_htfClose > smt_htfOpen) and smt_htfLow > smt_htfLow1 and smt_sL_htf < smt_sL1_htf
  2099.  
  2100. if high >= smt_currCH or na(smt_currCH)
  2101. smt_currCH := high, smt_currCHT := time
  2102. if low <= smt_currCL or na(smt_currCL)
  2103. smt_currCL := low, smt_currCLT := time
  2104.  
  2105. if smt_newPeriod
  2106. if smt_bearD_htf[1]
  2107. smtArray.push(SMT.new("BEARISH", smt_sPair, smt_prevCH, smt_currCH, smt_prevCHT, smt_currCHT, na, na, na, na, true, bar_index, na, na))
  2108. if smt_bullD_htf[1]
  2109. smtArray.push(SMT.new("BULLISH", smt_sPair, na, na, na, na, smt_prevCL, smt_currCL, smt_prevCLT, smt_currCLT, true, bar_index, na, na))
  2110. smt_prevCH := smt_currCH, smt_prevCHT := smt_currCHT
  2111. smt_prevCL := smt_currCL, smt_prevCLT := smt_currCLT
  2112. smt_currCH := high, smt_currCHT := time
  2113. smt_currCL := low, smt_currCLT := time
  2114. line.delete(smt_liveBearLine), smt_liveBearLine := na
  2115. line.delete(smt_liveBullLine), smt_liveBullLine := na
  2116.  
  2117. if smt_chartPivDir == 1
  2118. if not na(smt_chartPivotHigh)
  2119. smt_prevChartPivotHigh := smt_chartPivotHigh
  2120. smt_prevChartPivotHighTime := smt_chartPivotHighTime
  2121. smt_chartPivotHigh := high[3], smt_chartPivotHighTime := time[3]
  2122.  
  2123. if not na(smt_smtPivotHigh)
  2124. smt_prevSmtPivotHigh := smt_smtPivotHigh
  2125. smt_smtPivotHigh := smt_sH_piv
  2126.  
  2127. if not na(smt_prevChartPivotHigh) and smt_chartPivotHigh > smt_prevChartPivotHigh and smt_smtPivotHigh < smt_prevSmtPivotHigh
  2128. smtArray.push(SMT.new("BEARISH", smt_sPair, smt_prevChartPivotHigh, smt_chartPivotHigh, smt_prevChartPivotHighTime, smt_chartPivotHighTime, na, na, na, na, true, bar_index, na, na))
  2129.  
  2130. if smt_chartPivDir == -1
  2131. if not na(smt_chartPivotLow)
  2132. smt_prevChartPivotLow := smt_chartPivotLow
  2133. smt_prevChartPivotLowTime := smt_chartPivotLowTime
  2134. smt_chartPivotLow := low[3], smt_chartPivotLowTime := time[3]
  2135.  
  2136. if not na(smt_smtPivotLow)
  2137. smt_prevSmtPivotLow := smt_smtPivotLow
  2138. smt_smtPivotLow := smt_sL_piv
  2139.  
  2140. if not na(smt_prevChartPivotLow) and smt_chartPivotLow < smt_prevChartPivotLow and smt_smtPivotLow > smt_prevSmtPivotLow
  2141. smtArray.push(SMT.new("BULLISH", smt_sPair, na, na, na, na, smt_prevChartPivotLow, smt_chartPivotLow, smt_prevChartPivotLowTime, smt_chartPivotLowTime, true, bar_index, na, na))
  2142.  
  2143. if smt_sPair != "" and bar_index > last_bar_index - 4500
  2144. if smt_KeepOnlyLatest and array.size(smtArray) > 0
  2145. int latestBearIdx = -1
  2146. int latestBullIdx = -1
  2147. int maxBearBar = -1
  2148. int maxBullBar = -1
  2149.  
  2150. for i = 0 to array.size(smtArray) - 1
  2151. s_check = array.get(smtArray, i)
  2152. if s_check.smtType == "BEARISH" and s_check.creationBar > maxBearBar
  2153. maxBearBar := s_check.creationBar
  2154. latestBearIdx := i
  2155. if s_check.smtType == "BULLISH" and s_check.creationBar > maxBullBar
  2156. maxBullBar := s_check.creationBar
  2157. latestBullIdx := i
  2158.  
  2159. for i = array.size(smtArray) - 1 to 0
  2160. if (array.get(smtArray, i).smtType == "BEARISH" and i != latestBearIdx) or (array.get(smtArray, i).smtType == "BULLISH" and i != latestBullIdx)
  2161. s_del = array.remove(smtArray, i)
  2162. line.delete(s_del.smtLine)
  2163.  
  2164. int smt_szL = array.size(smtLabels)
  2165. if smt_szL > 0
  2166. for i = 0 to smt_szL - 1
  2167. label.delete(array.get(smtLabels, i))
  2168. array.clear(smtLabels)
  2169.  
  2170. int smt_szA = array.size(smtArray)
  2171. if smt_szA > 0
  2172. for i = smt_szA - 1 to 0
  2173. s = array.get(smtArray, i)
  2174. if bar_index - s.creationBar > 2500
  2175. line.delete(s.smtLine)
  2176. array.remove(smtArray, i)
  2177. continue
  2178.  
  2179. isB = s.smtType == "BEARISH"
  2180. c = isB ? smt_BearColor : smt_BullColor
  2181.  
  2182. p1T = isB ? s.prevChartHighTime : s.prevChartLowTime
  2183. p1P = isB ? s.prevChartHigh : s.prevChartLow
  2184. p2T = isB ? s.currChartHighTime : s.currChartLowTime
  2185. p2P = isB ? s.currChartHigh : s.currChartLow
  2186.  
  2187. if not na(p1T) and not na(p2T)
  2188. if na(s.smtLine)
  2189. s.smtLine := line.new(p1T, p1P, p2T, p2P, xloc=xloc.bar_time, color=c, width=smt_LineWidth)
  2190. else
  2191. line.set_xy1(s.smtLine, p1T, p1P)
  2192. line.set_xy2(s.smtLine, p2T, p2P)
  2193. line.set_color(s.smtLine, c)
  2194.  
  2195. if smt_ShowLabels
  2196. string cleanName = s.smtPair
  2197. if str.contains(cleanName, ":")
  2198. cleanName := array.get(str.split(cleanName, ":"), array.size(str.split(cleanName, ":")) - 1)
  2199. cleanName := str.replace_all(cleanName, ".P", ""), cleanName := str.replace_all(cleanName, "1!", "")
  2200.  
  2201. labelStyle = isB ? label.style_label_down : label.style_label_up
  2202.  
  2203. newL = label.new((p1T+p2T)/2, (p1P+p2P)/2, cleanName,
  2204. color=color.new(color.white, 100),
  2205. textcolor=c,
  2206. style=labelStyle,
  2207. size=size.small,
  2208. xloc=xloc.bar_time)
  2209. array.push(smtLabels, newL)
  2210.  
  2211. while array.size(setups) > i_history
  2212. oldest = array.shift(setups)
  2213. box.delete(oldest.zoneBox)
  2214. if array.size(oldest.fvgBoxes) > 0
  2215. for fi = 0 to array.size(oldest.fvgBoxes) - 1
  2216. box.delete(array.get(oldest.fvgBoxes, fi))
  2217. line.delete(oldest.sweepLine)
  2218. label.delete(oldest.sweepLbl)
  2219. label.delete(oldest.zoneLbl)
  2220. line.delete(oldest.bb50Line)
  2221. if array.size(oldest.fvgCeLines) > 0
  2222. for cel in oldest.fvgCeLines
  2223. line.delete(cel)
  2224. tln = array.size(oldest.targetLines)
  2225. for ti = 0 to ti < tln - 1 ? ti : tln - 1
  2226. line.delete(array.get(oldest.targetLines, ti))
  2227. tlabn = array.size(oldest.targetLabels)
  2228. for ti = 0 to ti < tlabn - 1 ? ti : tlabn - 1
  2229. label.delete(array.get(oldest.targetLabels, ti))
  2230.  
  2231. if i_discardInval
  2232. n = array.size(setups)
  2233. i = n - 1
  2234. while i >= 0
  2235. s = array.get(setups, i)
  2236. if s.state == 4
  2237. box.delete(s.zoneBox)
  2238. if array.size(s.fvgBoxes) > 0
  2239. for fi = 0 to array.size(s.fvgBoxes) - 1
  2240. box.delete(array.get(s.fvgBoxes, fi))
  2241. line.delete(s.sweepLine)
  2242. label.delete(s.sweepLbl)
  2243. label.delete(s.zoneLbl)
  2244. line.delete(s.bb50Line)
  2245. if array.size(s.fvgCeLines) > 0
  2246. for cel in s.fvgCeLines
  2247. line.delete(cel)
  2248. tln = array.size(s.targetLines)
  2249. for ti = 0 to ti < tln - 1 ? ti : tln - 1
  2250. line.delete(array.get(s.targetLines, ti))
  2251. tlabn = array.size(s.targetLabels)
  2252. for ti = 0 to ti < tlabn - 1 ? ti : tlabn - 1
  2253. label.delete(array.get(s.targetLabels, ti))
  2254. array.remove(setups, i)
  2255. i -= 1
  2256.  
  2257. f_gc()
  2258.  
  2259. if htf1.settings.show and isValidTimeframe(htf1.settings.htf)
  2260. htf1.Monitor().Update(settingsCandle.offset)
  2261.  
  2262. tblPos = i_tablePos == "Bottom Right" ? position.bottom_right :
  2263. i_tablePos == "Bottom Left" ? position.bottom_left :
  2264. i_tablePos == "Top Right" ? position.top_right : position.top_left
  2265.  
  2266. TBL_BG = color.new(#0d0d0d, 65)
  2267. TBL_HEAD = color.new(#1a1a1a, 50)
  2268. TBL_TEXT = color.new(#e0e0e0, 0)
  2269. TBL_DIM = color.new(#757575, 0)
  2270. TBL_BULL = color.new(#26a69a, 0)
  2271. TBL_BEAR = color.new(#ef5350, 0)
  2272. TBL_NEUT = color.new(#90a4ae, 0)
  2273. TBL_NONE = color.new(#000000,100)
  2274.  
  2275. var table infoTbl = table(na)
  2276.  
  2277. f_cell(r, c, txt, tc, bg) =>
  2278. table.cell(infoTbl, c, r, txt, text_color=tc, bgcolor=bg, text_size=size.small, text_halign=text.align_left, text_font_family=font.family_monospace)
  2279.  
  2280. if i_showTable and barstate.islast
  2281. isSimple = i_tableMode == "Simple"
  2282. nRows = isSimple ? 4 : 8
  2283. nCols = 2
  2284.  
  2285. infoTbl := table.new(tblPos, nCols, nRows,
  2286. bgcolor = color.new(color.black, 100),
  2287. border_color = color.new(color.black, 100),
  2288. border_width = 0,
  2289. frame_color = color.new(color.black, 100),
  2290. frame_width = 0)
  2291.  
  2292. modelName = i_modelMode + " Model (" + timeframe.period + "m)"
  2293. table.cell(infoTbl, 0, 0, modelName,
  2294. text_color = chart.fg_color,
  2295. bgcolor = color.new(color.black, 100),
  2296. text_size = size.small,
  2297. text_halign = text.align_left,
  2298. text_font_family = font.family_monospace)
  2299. table.merge_cells(infoTbl, 0, 0, 1, 0)
  2300.  
  2301. f_cell(1, 0, "Sweep:", chart.fg_color, color.new(color.black, 100))
  2302. f_cell(1, 1, lastSweepLabel, chart.fg_color, color.new(color.black, 100))
  2303.  
  2304. sessTxt = i_useTimeFilter ? f_sessString() : "All Hours"
  2305. f_cell(2, 0, "Sessions:", chart.fg_color, color.new(color.black, 100))
  2306. f_cell(2, 1, sessTxt, chart.fg_color, color.new(color.black, 100))
  2307.  
  2308. if isSimple
  2309. f_cell(3, 0, "Ticker:", chart.fg_color, color.new(color.black, 100))
  2310. f_cell(3, 1, syminfo.ticker, chart.fg_color, color.new(color.black, 100))
  2311. else
  2312. biasStr = i_biasMode == "Auto" ? ("Auto (" + (autoBull ? "Bull" : "Bear") + ")") : i_biasMode
  2313. f_cell(3, 0, "Bias:", chart.fg_color, color.new(color.black, 100))
  2314. f_cell(3, 1, biasStr, chart.fg_color, color.new(color.black, 100))
  2315.  
  2316. invalStr = i_swingInval ? "Swing" : "Breaker"
  2317. f_cell(4, 0, "Invalidation:",chart.fg_color, color.new(color.black, 100))
  2318. f_cell(4, 1, invalStr, chart.fg_color, color.new(color.black, 100))
  2319.  
  2320. sizeStr = i_sizeFilter == "Custom" ?
  2321. (i_customMin > 0 ? "Min: " + str.tostring(i_customMin,"#") : "") +
  2322. (i_customMax > 0 ? " Max: " + str.tostring(i_customMax,"#") : "") :
  2323. i_sizeFilter
  2324. if sizeStr == ""
  2325. sizeStr := "All"
  2326. f_cell(5, 0, "Breaker Size:", chart.fg_color, color.new(color.black, 100))
  2327. f_cell(5, 1, sizeStr, chart.fg_color, color.new(color.black, 100))
  2328.  
  2329. srcStr = i_srcAuto == "Automatic" ? "Auto (" + i_srcAType + ")" : "Manual"
  2330. f_cell(6, 0, "Sources:", chart.fg_color, color.new(color.black, 100))
  2331. f_cell(6, 1, srcStr, chart.fg_color, color.new(color.black, 100))
  2332.  
  2333. f_cell(7, 0, "Ticker:", chart.fg_color, color.new(color.black, 100))
  2334. f_cell(7, 1, syminfo.ticker, chart.fg_color, color.new(color.black, 100))
  2335.  
  2336. var table statsTbl = table(na)
  2337.  
  2338. if i_showStats and barstate.islast and (timeframe.period == "1" or timeframe.period == "5" or timeframe.period == "15" or timeframe.period == "30" or timeframe.period == "60") and array.size(stat_years) > 0
  2339. unique_years = array.new_int(0)
  2340. unique_months = array.new_int(0)
  2341.  
  2342. for i = 0 to array.size(stat_years) - 1
  2343. y = array.get(stat_years, i)
  2344. m = array.get(stat_months, i)
  2345.  
  2346. exists = false
  2347. if array.size(unique_years) > 0
  2348. for j = 0 to array.size(unique_years) - 1
  2349. if array.get(unique_years, j) == y and array.get(unique_months, j) == m
  2350. exists := true
  2351. break
  2352. if not exists
  2353. array.push(unique_years, y)
  2354. array.push(unique_months, m)
  2355.  
  2356. int n_unique = array.size(unique_years)
  2357.  
  2358. if n_unique > 1
  2359. for i = 0 to n_unique - 2
  2360. for j = i + 1 to n_unique - 1
  2361. valI = array.get(unique_years, i) * 12 + array.get(unique_months, i)
  2362. valJ = array.get(unique_years, j) * 12 + array.get(unique_months, j)
  2363. if valJ > valI
  2364. tempY = array.get(unique_years, i)
  2365. tempM = array.get(unique_months, i)
  2366. array.set(unique_years, i, array.get(unique_years, j))
  2367. array.set(unique_months, i, array.get(unique_months, j))
  2368. array.set(unique_years, j, tempY)
  2369. array.set(unique_months, j, tempM)
  2370.  
  2371. statsTblPos = i_statsPos == "Bottom Right" ? position.bottom_right :
  2372. i_statsPos == "Bottom Left" ? position.bottom_left :
  2373. i_statsPos == "Top Right" ? position.top_right : position.top_left
  2374.  
  2375. statsTbl := table.new(statsTblPos, 6, n_unique + 1,
  2376. bgcolor = color.new(color.black, 100),
  2377. border_color = color.new(#455a64, 40),
  2378. border_width = 1,
  2379. frame_color = color.new(#455a64, 40),
  2380. frame_width = 1)
  2381.  
  2382. table.cell(statsTbl, 0, 0, "Month", text_color=color.white, bgcolor=color.new(#1a1a1a, 10), text_size=size.small, text_font_family=font.family_monospace)
  2383. table.cell(statsTbl, 1, 0, "T", text_color=color.white, bgcolor=color.new(#1a1a1a, 10), text_size=size.small, text_font_family=font.family_monospace)
  2384. table.cell(statsTbl, 2, 0, "W", text_color=color.white, bgcolor=color.new(#1a1a1a, 10), text_size=size.small, text_font_family=font.family_monospace)
  2385. table.cell(statsTbl, 3, 0, "L", text_color=color.white, bgcolor=color.new(#1a1a1a, 10), text_size=size.small, text_font_family=font.family_monospace)
  2386. table.cell(statsTbl, 4, 0, "BE", text_color=color.white, bgcolor=color.new(#1a1a1a, 10), text_size=size.small, text_font_family=font.family_monospace)
  2387. table.cell(statsTbl, 5, 0, "Win%", text_color=color.white, bgcolor=color.new(#1a1a1a, 10), text_size=size.small, text_font_family=font.family_monospace)
  2388.  
  2389. for r = 0 to n_unique - 1
  2390. y = array.get(unique_years, r)
  2391. m = array.get(unique_months, r)
  2392.  
  2393. int total = 0
  2394. int wins = 0
  2395. int losses = 0
  2396. int bes = 0
  2397.  
  2398. for i = 0 to array.size(stat_years) - 1
  2399. if array.get(stat_years, i) == y and array.get(stat_months, i) == m
  2400. total += 1
  2401. outcome = array.get(stat_outcomes, i)
  2402. if outcome == 1
  2403. wins += 1
  2404. else if outcome == 0
  2405. losses += 1
  2406. else if outcome == 2
  2407. bes += 1
  2408.  
  2409. winRate = (wins + losses) > 0 ? (wins * 100.0) / (wins + losses) : 0.0
  2410.  
  2411. cellBg = r % 2 == 0 ? color.new(chart.bg_color, 10) : color.new(chart.bg_color, 25)
  2412.  
  2413. table.cell(statsTbl, 0, r + 1, str.tostring(m) + "/" + str.tostring(y), text_color=chart.fg_color, bgcolor=cellBg, text_size=size.small, text_font_family=font.family_monospace)
  2414. table.cell(statsTbl, 1, r + 1, str.tostring(total), text_color=chart.fg_color, bgcolor=cellBg, text_size=size.small, text_font_family=font.family_monospace)
  2415. table.cell(statsTbl, 2, r + 1, str.tostring(wins), text_color=color.new(#26a69a, 0), bgcolor=cellBg, text_size=size.small, text_font_family=font.family_monospace)
  2416. table.cell(statsTbl, 3, r + 1, str.tostring(losses), text_color=color.new(#ef5350, 0), bgcolor=cellBg, text_size=size.small, text_font_family=font.family_monospace)
  2417. table.cell(statsTbl, 4, r + 1, str.tostring(bes), text_color=color.new(#ff9800, 0), bgcolor=cellBg, text_size=size.small, text_font_family=font.family_monospace)
  2418. table.cell(statsTbl, 5, r + 1, str.tostring(math.round(winRate)) + "%", text_color=chart.fg_color, bgcolor=cellBg, text_size=size.small, text_font_family=font.family_monospace)
Advertisement
Add Comment
Please, Sign In to add comment