ajiim

🎁

Oct 12th, 2026
940
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 60.69 KB | None | 0 0
  1. //@version=6
  2. indicator("IFVG Model [PJ Trades]", shorttitle = "IFVG Model [PJ Trades]", overlay = true, max_boxes_count = 500, max_lines_count = 500, max_labels_count = 500, max_bars_back = 500)
  3.  
  4. const string G_SES = "Sessions"
  5. const string G_KL = "Key Levels"
  6. const string G_SW = "Swing Levels"
  7. const string G_HTF = "Higher Timeframe FVGs"
  8. const string G_IF = "Inversion FVGs"
  9. const string G_MAC = "Macros"
  10. const string G_SIG = "Signal Settings"
  11. const string G_STY = "Style Customization"
  12. const string G_GAP = "Opening Gaps"
  13. const string G_SMT = "SMT Divergences"
  14. const string G_DB = "Dashboard"
  15. const string G_AL = "Alerts"
  16.  
  17. bool showSessIn = input.bool(true, "Show Sessions", group = G_SES, tooltip = "Hides session visuals only. Session highs/lows are always used by the signal logic. Sessions auto-hide on timeframes above 1H.")
  18. string tzIn = input.string("America/New_York", "Timezone", group = G_SES)
  19. bool s1On = input.bool(true, "", group = G_SES, inline = "s1")
  20. string s1Name = input.string("Asia", "", group = G_SES, inline = "s1")
  21. string s1Sess = input.session("2000-0000", "", group = G_SES, inline = "s1")
  22. color s1Col = input.color(color.new(#787B86, 80), "", group = G_SES, inline = "s1")
  23. bool s2On = input.bool(true, "", group = G_SES, inline = "s2")
  24. string s2Name = input.string("London", "", group = G_SES, inline = "s2")
  25. string s2Sess = input.session("0200-0500", "", group = G_SES, inline = "s2")
  26. color s2Col = input.color(color.new(#F23645, 80), "", group = G_SES, inline = "s2")
  27. bool s3On = input.bool(true, "", group = G_SES, inline = "s3")
  28. string s3Name = input.string("NY AM", "", group = G_SES, inline = "s3")
  29. string s3Sess = input.session("0930-1215", "", group = G_SES, inline = "s3")
  30. color s3Col = input.color(color.new(#2962FF, 80), "", group = G_SES, inline = "s3")
  31. bool s4On = input.bool(true, "", group = G_SES, inline = "s4")
  32. string s4Name = input.string("NY Lunch", "", group = G_SES, inline = "s4")
  33. string s4Sess = input.session("1215-1330", "", group = G_SES, inline = "s4")
  34. color s4Col = input.color(color.new(#089981, 80), "", group = G_SES, inline = "s4")
  35. bool s5On = input.bool(true, "", group = G_SES, inline = "s5")
  36. string s5Name = input.string("NY PM", "", group = G_SES, inline = "s5")
  37. string s5Sess = input.session("1330-1600", "", group = G_SES, inline = "s5")
  38. color s5Col = input.color(color.new(#FF9800, 80), "", group = G_SES, inline = "s5")
  39. bool sessLblIn = input.bool(true, "Session Labels", group = G_SES, inline = "sl")
  40. bool sessTimeIn = input.bool(false, "Time", group = G_SES, inline = "sl")
  41. bool sessHLIn = input.bool(true, "Session Highs/Lows", group = G_SES, inline = "hl")
  42. string sessStyleIn = input.string("Solid", "", options = ["Solid", "Dashed", "Dotted"], group = G_SES, inline = "hl")
  43. int sessWidthIn = input.int(1, "Width", minval = 1, maxval = 5, group = G_SES, inline = "hl")
  44. color sessLblColIn = input.color(#787B86, "High/Low Label Color", group = G_SES, inline = "hll")
  45. string sessLblSizeIn = input.string("Small", "Size", options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], group = G_SES, inline = "hll")
  46. string sessLblPosIn = input.string("Right", "High/Low Label Position", options = ["Left", "Center", "Right"], group = G_SES)
  47. bool sessHideSwIn = input.bool(true, "Hide Labels After Sweep", group = G_SES)
  48. bool sessExtIn = input.bool(false, "Extend Levels", group = G_SES, inline = "se")
  49. int sessExtBarsIn = input.int(10, "Bars", minval = 1, maxval = 500, group = G_SES, inline = "se")
  50. int sessLastIn = input.int(3, "Show Last", minval = 1, maxval = 20, group = G_SES)
  51.  
  52. bool kDOIn = input.bool(true, "Daily Open", group = G_KL, inline = "k1")
  53. color kDOCol = input.color(#787B86, "", group = G_KL, inline = "k1")
  54. bool kPDHIn = input.bool(true, "Previous Day High", group = G_KL, inline = "k2")
  55. color kPDHCol = input.color(#F23645, "", group = G_KL, inline = "k2")
  56. bool kPDLIn = input.bool(true, "Previous Day Low", group = G_KL, inline = "k3")
  57. color kPDLCol = input.color(#089981, "", group = G_KL, inline = "k3")
  58. bool kWOIn = input.bool(false, "Weekly Open", group = G_KL, inline = "k4")
  59. color kWOCol = input.color(#9598A1, "", group = G_KL, inline = "k4")
  60. bool kPWHIn = input.bool(true, "Previous Week High", group = G_KL, inline = "k5")
  61. color kPWHCol = input.color(#FF5252, "", group = G_KL, inline = "k5")
  62. bool kPWLIn = input.bool(true, "Previous Week Low", group = G_KL, inline = "k6")
  63. color kPWLCol = input.color(#22AB94, "", group = G_KL, inline = "k6")
  64. bool kMOIn = input.bool(false, "Monthly Open", group = G_KL, inline = "k7")
  65. color kMOCol = input.color(#B2B5BE, "", group = G_KL, inline = "k7")
  66. bool kPMHIn = input.bool(false, "Previous Month High", group = G_KL, inline = "k8")
  67. color kPMHCol = input.color(#E91E63, "", group = G_KL, inline = "k8")
  68. bool kPMLIn = input.bool(false, "Previous Month Low", group = G_KL, inline = "k9")
  69. color kPMLCol = input.color(#00BCD4, "", group = G_KL, inline = "k9")
  70. bool kMidIn = input.bool(false, "Midnight Open", group = G_KL, inline = "k10")
  71. color kMidCol = input.color(#2962FF, "", group = G_KL, inline = "k10")
  72. bool k830In = input.bool(false, "08:30 Open", group = G_KL, inline = "k11")
  73. color k830Col = input.color(#AB47BC, "", group = G_KL, inline = "k11")
  74. bool kLblIn = input.bool(true, "Show Labels", group = G_KL, inline = "kl")
  75. string kLblSizeIn = input.string("Small", "Size", options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], group = G_KL, inline = "kl")
  76. string kLblPosIn = input.string("Right", "Label Position", options = ["Left", "Right"], group = G_KL)
  77. string kStyleIn = input.string("Dashed", "Line Style", options = ["Solid", "Dashed", "Dotted"], group = G_KL)
  78. bool kExtIn = input.bool(true, "Extend Levels", group = G_KL, inline = "ke")
  79. int kExtBarsIn = input.int(10, "Bars", minval = 1, maxval = 500, group = G_KL, inline = "ke")
  80.  
  81. bool swShowIn = input.bool(true, "Show Swing Levels", group = G_SW)
  82. color swActiveCol = input.color(#787B86, "Active Levels", group = G_SW, inline = "sw")
  83. color swSweptCol = input.color(color.new(#787B86, 65), "Swept Levels", group = G_SW, inline = "sw")
  84. int swNearestIn = input.int(2, "Show Nearest", minval = 1, maxval = 10, group = G_SW)
  85.  
  86. bool hfAOn = input.bool(true, "", group = G_HTF, inline = "ha")
  87. string hfATf = input.timeframe("15", "", group = G_HTF, inline = "ha")
  88. color hfABull = input.color(color.new(#089981, 85), "", group = G_HTF, inline = "ha")
  89. color hfABear = input.color(color.new(#F23645, 85), "", group = G_HTF, inline = "ha")
  90. bool hfBOn = input.bool(true, "", group = G_HTF, inline = "hb")
  91. string hfBTf = input.timeframe("60", "", group = G_HTF, inline = "hb")
  92. color hfBBull = input.color(color.new(#089981, 85), "", group = G_HTF, inline = "hb")
  93. color hfBBear = input.color(color.new(#F23645, 85), "", group = G_HTF, inline = "hb")
  94. bool hfCOn = input.bool(false, "", group = G_HTF, inline = "hc")
  95. string hfCTf = input.timeframe("240", "", group = G_HTF, inline = "hc")
  96. color hfCBull = input.color(color.new(#089981, 85), "", group = G_HTF, inline = "hc")
  97. color hfCBear = input.color(color.new(#F23645, 85), "", group = G_HTF, inline = "hc")
  98. bool hfPlotIn = input.bool(true, "Plot HTF FVGs", group = G_HTF, tooltip = "When disabled the zones are hidden, the logic stays active for signals.")
  99. bool hfMidIn = input.bool(true, "Midline", group = G_HTF, inline = "hm")
  100. string hfMidStyle = input.string("Dashed", "", options = ["Solid", "Dashed", "Dotted"], group = G_HTF, inline = "hm")
  101. color hfMidCol = input.color(#787B86, "", group = G_HTF, inline = "hm")
  102. bool hfLblIn = input.bool(true, "Labels", group = G_HTF, inline = "hl")
  103. color hfLblCol = input.color(#787B86, "", group = G_HTF, inline = "hl")
  104. int hfNearestIn = input.int(2, "Show Nearest", minval = 1, maxval = 10, group = G_HTF)
  105.  
  106. bool ifShowIn = input.bool(true, "Show IFVGs", group = G_IF)
  107. color ifBullCol = input.color(color.new(#089981, 80), "Bullish", group = G_IF, inline = "ic")
  108. color ifBearCol = input.color(color.new(#F23645, 80), "Bearish", group = G_IF, inline = "ic")
  109. bool ifMidIn = input.bool(false, "Midline", group = G_IF, inline = "im")
  110. string ifMidStyle = input.string("Dashed", "", options = ["Solid", "Dashed", "Dotted"], group = G_IF, inline = "im")
  111. color ifMidCol = input.color(#787B86, "", group = G_IF, inline = "im")
  112.  
  113. bool m1On = input.bool(true, "", group = G_MAC, inline = "m1")
  114. string m1Name = input.string("Macro 1", "", group = G_MAC, inline = "m1")
  115. string m1Sess = input.session("0950-1010", "", group = G_MAC, inline = "m1")
  116. color m1Col = input.color(color.new(#9598A1, 85), "", group = G_MAC, inline = "m1")
  117. bool m2On = input.bool(true, "", group = G_MAC, inline = "m2")
  118. string m2Name = input.string("Macro 2", "", group = G_MAC, inline = "m2")
  119. string m2Sess = input.session("1050-1110", "", group = G_MAC, inline = "m2")
  120. color m2Col = input.color(color.new(#9598A1, 85), "", group = G_MAC, inline = "m2")
  121. bool m3On = input.bool(true, "", group = G_MAC, inline = "m3")
  122. string m3Name = input.string("Macro 3", "", group = G_MAC, inline = "m3")
  123. string m3Sess = input.session("1150-1210", "", group = G_MAC, inline = "m3")
  124. color m3Col = input.color(color.new(#9598A1, 85), "", group = G_MAC, inline = "m3")
  125. bool m4On = input.bool(true, "", group = G_MAC, inline = "m4")
  126. string m4Name = input.string("Macro 4", "", group = G_MAC, inline = "m4")
  127. string m4Sess = input.session("1250-1310", "", group = G_MAC, inline = "m4")
  128. color m4Col = input.color(color.new(#9598A1, 85), "", group = G_MAC, inline = "m4")
  129. bool m5On = input.bool(true, "", group = G_MAC, inline = "m5")
  130. string m5Name = input.string("Macro 5", "", group = G_MAC, inline = "m5")
  131. string m5Sess = input.session("1350-1410", "", group = G_MAC, inline = "m5")
  132. color m5Col = input.color(color.new(#9598A1, 85), "", group = G_MAC, inline = "m5")
  133. bool macZonesIn = input.bool(true, "Show Zones", group = G_MAC)
  134. bool macLblIn = input.bool(true, "Labels", group = G_MAC, inline = "ml")
  135. color macLblCol = input.color(#9598A1, "", group = G_MAC, inline = "ml")
  136. string macLblSizeIn = input.string("Tiny", "", options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], group = G_MAC, inline = "ml")
  137. bool macLinesIn = input.bool(true, "Macro Lines", group = G_MAC, inline = "mln")
  138. string macLineStyle = input.string("Solid", "Macro Line", options = ["Solid", "Dashed", "Dotted"], group = G_MAC, inline = "mln")
  139. string macSEStyle = input.string("Dotted", "Start/End Lines", options = ["Solid", "Dashed", "Dotted"], group = G_MAC)
  140.  
  141. string liqUsedIn = input.string("Both", "Liquidity Levels Used", options = ["Swing Points", "Session Highs/Lows", "Both"], group = G_SIG)
  142. string biasModeIn = input.string("Manual", "Bias", options = ["Manual", "Automatic"], group = G_SIG, inline = "bias")
  143. string manualBiasIn = input.string("Both", "", options = ["Bullish", "Bearish", "Both"], group = G_SIG, inline = "bias")
  144. float sensIn = input.float(0.1, "IFVG Sensitivity", minval = 0.0, step = 0.05, group = G_SIG, tooltip = "Minimum FVG size (ATR multiple) to qualify as an Inversion FVG. Higher values allow only larger gaps.")
  145. bool firstIfvgIn = input.bool(false, "Use First Presented IFVG", group = G_SIG)
  146. bool onlyTradesIn = input.bool(false, "Only Take Trades", group = G_SIG, inline = "ot", tooltip = "Uses the chart's native time zone.")
  147. string tradeWinIn = input.session("0930-1200", "", group = G_SIG, inline = "ot")
  148. bool useMacroIn = input.bool(false, "Use Macro Times", group = G_SIG, tooltip = "Signals only trigger during enabled Macro Time Windows.")
  149. float minRRIn = input.float(1.0, "Minimum R:R", minval = 0.0, step = 0.1, group = G_SIG)
  150. string ratingMinIn = input.string("A", "Signal Rating Minimum", options = ["A", "A+", "A++"], group = G_SIG)
  151. bool trailingIn = input.bool(false, "Trailing Stop-Loss", group = G_SIG, tooltip = "Once Breakeven is reached the stop-loss moves to Entry. After TP 1 is hit the stop-loss moves to Breakeven.")
  152.  
  153. bool showLongIn = input.bool(true, "Long Signals", group = G_STY, inline = "ls")
  154. color longCol = input.color(#089981, "", group = G_STY, inline = "ls")
  155. color longTxtCol = input.color(#FFFFFF, "Text", group = G_STY, inline = "ls")
  156. string longSizeIn = input.string("Small", "", options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], group = G_STY, inline = "ls")
  157. bool showShortIn = input.bool(true, "Short Signals", group = G_STY, inline = "ss")
  158. color shortCol = input.color(#F23645, "", group = G_STY, inline = "ss")
  159. color shortTxtCol = input.color(#FFFFFF, "Text", group = G_STY, inline = "ss")
  160. string shortSizeIn = input.string("Small", "", options = ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], group = G_STY, inline = "ss")
  161. bool entryLnIn = input.bool(true, "Entry Line", group = G_STY, inline = "le")
  162. color entryCol = input.color(#2962FF, "", group = G_STY, inline = "le")
  163. bool entryPxIn = input.bool(true, "Price", group = G_STY, inline = "le")
  164. bool slLnIn = input.bool(true, "Stop Loss Line", group = G_STY, inline = "lsl")
  165. color slCol = input.color(#F23645, "", group = G_STY, inline = "lsl")
  166. bool slPxIn = input.bool(true, "Price", group = G_STY, inline = "lsl")
  167. bool beLnIn = input.bool(true, "Breakeven Line", group = G_STY, inline = "lbe")
  168. color beCol = input.color(#4CAF50, "", group = G_STY, inline = "lbe")
  169. bool bePxIn = input.bool(true, "Price", group = G_STY, inline = "lbe")
  170. bool tpLnIn = input.bool(true, "Take Profit 1 & 2 Lines", group = G_STY, inline = "ltp")
  171. color tp1Col = input.color(#4CAF50, "", group = G_STY, inline = "ltp")
  172. color tp2Col = input.color(#4CAF50, "", group = G_STY, inline = "ltp")
  173. bool tpPxIn = input.bool(true, "Price", group = G_STY, inline = "ltp")
  174. bool showPtsIn = input.bool(false, "Show Points", group = G_STY)
  175.  
  176. bool ndogIn = input.bool(false, "Show New Day Opening Gap", group = G_GAP)
  177. color ndogBull = input.color(color.new(#089981, 85), "Bullish NDOG", group = G_GAP, inline = "nd")
  178. color ndogBear = input.color(color.new(#F23645, 85), "Bearish NDOG", group = G_GAP, inline = "nd")
  179. bool ndogMidIn = input.bool(true, "NDOG Midline", group = G_GAP, inline = "ndm")
  180. bool ndogLblIn = input.bool(true, "Label", group = G_GAP, inline = "ndm")
  181. bool nwogIn = input.bool(false, "Show New Week Opening Gap", group = G_GAP)
  182. color nwogBull = input.color(color.new(#2962FF, 85), "Bullish NWOG", group = G_GAP, inline = "nw")
  183. color nwogBear = input.color(color.new(#FF9800, 85), "Bearish NWOG", group = G_GAP, inline = "nw")
  184. bool nwogMidIn = input.bool(true, "NWOG Midline", group = G_GAP, inline = "nwm")
  185. bool nwogLblIn = input.bool(true, "Label", group = G_GAP, inline = "nwm")
  186. color gapTxtCol = input.color(#9598A1, "Gap Text / Midline", group = G_GAP)
  187.  
  188. bool smtIn = input.bool(true, "Show SMT Divergences", group = G_SMT)
  189. int smtLenIn = input.int(3, "Length", minval = 1, maxval = 20, group = G_SMT)
  190. int smtDivLenIn = input.int(3, "Divergence Length", minval = 0, maxval = 50, group = G_SMT)
  191. int smtLastIn = input.int(3, "Show Last", minval = 1, maxval = 20, group = G_SMT)
  192. string smtTickerIn = input.symbol("CME_MINI:ES1!", "Divergence Ticker", group = G_SMT)
  193. color smtCol = input.color(#D1D4DC, "Line / Text Color", group = G_SMT)
  194.  
  195. bool dbIn = input.bool(true, "Show Dashboard", group = G_DB)
  196. string dbSizeIn = input.string("Small", "Dashboard Size", options = ["Tiny", "Small", "Normal", "Large"], group = G_DB)
  197. string dbPosIn = input.string("Top Right", "Dashboard Position", options = ["Top Right", "Middle Right", "Bottom Right", "Top Left", "Middle Left", "Bottom Left", "Top Center", "Bottom Center"], group = G_DB)
  198. string dbThemeIn = input.string("Dark", "Mode", options = ["Dark", "Light"], group = G_DB)
  199. color dbStatsCol = input.color(#FFFFFF, "Trade Stats Text Color", group = G_DB)
  200. bool dbRatingIn = input.bool(true, "Setup Rating", group = G_DB, inline = "d1")
  201. bool dbEntryIn = input.bool(true, "Entry", group = G_DB, inline = "d1")
  202. bool dbSLIn = input.bool(true, "Stop-Loss", group = G_DB, inline = "d1")
  203. bool dbBEIn = input.bool(true, "Breakeven", group = G_DB, inline = "d2")
  204. bool dbTP1In = input.bool(true, "Take Profit 1", group = G_DB, inline = "d2")
  205. bool dbTP2In = input.bool(true, "Take Profit 2", group = G_DB, inline = "d2")
  206. bool dbBiasIn = input.bool(true, "Bias", group = G_DB, inline = "d3")
  207. bool dbSweepIn = input.bool(true, "Liquidity Sweep", group = G_DB, inline = "d3")
  208. bool dbHtfIn = input.bool(true, "HTF FVG", group = G_DB, inline = "d3")
  209. bool dbVIn = input.bool(true, "V Shape Recovery", group = G_DB, inline = "d4")
  210. bool dbIfvgIn = input.bool(true, "Inversion FVG", group = G_DB, inline = "d4")
  211. bool dbDolIn = input.bool(true, "Clear Opposite DOL", group = G_DB, inline = "d5")
  212. bool dbSmtIn = input.bool(true, "SMT Divergence", group = G_DB, inline = "d5")
  213. bool dbStatsIn = input.bool(true, "Trade Stats", group = G_DB)
  214.  
  215. bool alLongIn = input.bool(true, "Long Signal", group = G_AL, inline = "a1")
  216. bool alShortIn = input.bool(true, "Short Signal", group = G_AL, inline = "a1")
  217. bool alBEIn = input.bool(true, "Breakeven Hit", group = G_AL, inline = "a2")
  218. bool alTP1In = input.bool(true, "TP1 Hit", group = G_AL, inline = "a2")
  219. bool alTP2In = input.bool(true, "TP2 Hit", group = G_AL, inline = "a3")
  220. bool alSLIn = input.bool(true, "Stop-Loss Hit", group = G_AL, inline = "a3")
  221. bool alSweepIn = input.bool(false, "Liquidity Sweep Detected", group = G_AL)
  222. bool alSmtIn = input.bool(false, "SMT Divergence Detected", group = G_AL)
  223. bool alTrEntIn = input.bool(true, "Trailing SL Moved To Entry", group = G_AL)
  224. bool alTrBEIn = input.bool(true, "Trailing SL Moved To BE", group = G_AL)
  225.  
  226. const string NAME = "IFVG Model [PJ Trades]"
  227. const int LINE_LEN = 20
  228. const int V_WINDOW = 3
  229. const float V_BODY_ATR = 0.6
  230. const float V_BODY_PCT = 0.5
  231. const int TAP_WINDOW = 2
  232. const int SETUP_MAX = 30
  233. const int LEG_LOOK = 30
  234. const int MAX_LVL = 150
  235. const int MAX_FVG = 60
  236. const int MAX_HTF = 90
  237. const int STATE_BARS = 20
  238. const int MAX_SIG = 100
  239. const int MAX_IFVG = 40
  240. const int MAX_MAC = 25
  241. const string CHECK = "✅"
  242. const string CROSS = "❌"
  243.  
  244. type Level
  245. float price
  246. int bar
  247. string name
  248. int kind
  249. bool isHigh
  250. bool swept = false
  251. int sweptBar
  252. bool dead = false
  253. line ln
  254. label lb
  255.  
  256. type Fvg
  257. float top
  258. float bot
  259. int bar
  260. bool inverted = false
  261.  
  262. type HFvg
  263. float top
  264. float bot
  265. bool bull
  266. string tfLbl
  267. int t
  268. color col
  269.  
  270. type SessDraw
  271. box bx
  272. line hl
  273. line ll
  274. label hb
  275. label lbl
  276.  
  277. type Sess
  278. string name
  279. string sess
  280. color col
  281. bool show
  282. bool active = false
  283. float hi
  284. float lo
  285. int hiBar
  286. int loBar
  287. array<SessDraw> draws
  288. SessDraw cur
  289.  
  290. type Macro
  291. string title
  292. string sess
  293. color col
  294. bool on
  295. bool active = false
  296. float hi
  297. float lo
  298. int startBar
  299. float startHigh
  300. box bx
  301. label lb
  302.  
  303. type Setup
  304. int state = 0
  305. float ext
  306. float extMid
  307. int extBar
  308. int legStart
  309. int count = 0
  310. string names = ""
  311. bool tap = false
  312. string tapTf = ""
  313. int sweepBar
  314.  
  315. type Trade
  316. bool long
  317. int bar
  318. string rating
  319. int rank
  320. float entry
  321. float sl
  322. float be
  323. float tp1
  324. float tp2
  325. float curSL
  326. bool beHit = false
  327. bool tp1Hit = false
  328. bool open = true
  329. string tip
  330. line lE
  331. line lS
  332. line lB
  333. line l1
  334. line l2
  335. label bE
  336. label bS
  337. label bB
  338. label b1
  339. label b2
  340. label sig
  341.  
  342. type Gap
  343. box bx
  344. line md
  345. label lb
  346. float top
  347. float bot
  348. bool bull
  349.  
  350. var array<Level> liqHighs = array.new<Level>()
  351. var array<Level> liqLows = array.new<Level>()
  352. var array<Fvg> bullFvgs = array.new<Fvg>()
  353. var array<Fvg> bearFvgs = array.new<Fvg>()
  354. var array<HFvg> htfFvgs = array.new<HFvg>()
  355. array<string> alertList = array.new<string>()
  356.  
  357. lineStyle(string s) =>
  358. s == "Dashed" ? line.style_dashed : s == "Dotted" ? line.style_dotted : line.style_solid
  359.  
  360. txtSize(string s) =>
  361. switch s
  362. "Auto" => size.auto
  363. "Tiny" => size.tiny
  364. "Normal" => size.normal
  365. "Large" => size.large
  366. "Huge" => size.huge
  367. => size.small
  368.  
  369. fmt(float x) =>
  370. str.tostring(x, format.mintick)
  371.  
  372. timeTxt(string s) =>
  373. str.substring(s, 0, 2) + ":" + str.substring(s, 2, 4) + "-" + str.substring(s, 5, 7) + ":" + str.substring(s, 7, 9)
  374.  
  375. tfTxt(string tf) =>
  376. int sec = timeframe.in_seconds(tf)
  377. sec < 3600 ? str.tostring(math.round(sec / 60)) + "M" : sec < 86400 ? str.tostring(math.round(sec / 3600)) + "H" : sec < 604800 ? str.tostring(math.round(sec / 86400)) + "D" : str.tostring(math.round(sec / 604800)) + "W"
  378.  
  379. pushAlert(bool on, string msg) =>
  380. if on and barstate.isrealtime
  381. alertList.push(NAME + " | " + syminfo.ticker + " (" + timeframe.period + ") | " + msg)
  382.  
  383. kindAllowed(int k) =>
  384. k == 0 ? liqUsedIn != "Session Highs/Lows" : liqUsedIn != "Swing Points"
  385.  
  386. addLevel(array<Level> arr, Level lv) =>
  387. arr.push(lv)
  388. if arr.size() > MAX_LVL
  389. Level old = arr.shift()
  390. if old.kind == 2
  391. line.delete(old.ln)
  392. label.delete(old.lb)
  393.  
  394. delSessDraw(SessDraw d) =>
  395. box.delete(d.bx)
  396. line.delete(d.hl)
  397. line.delete(d.ll)
  398. label.delete(d.hb)
  399. label.delete(d.lbl)
  400.  
  401. drawKey(Level lv, color col) =>
  402. int x2 = bar_index + (kExtIn ? kExtBarsIn : 0)
  403. lv.ln := line.new(lv.bar, lv.price, x2, lv.price, color = col, style = lineStyle(kStyleIn), width = 1)
  404. if kLblIn
  405. lv.lb := label.new(kLblPosIn == "Right" ? x2 : lv.bar, lv.price, lv.name, style = kLblPosIn == "Right" ? label.style_label_left : label.style_label_right, color = color.new(col, 100), textcolor = col, size = txtSize(kLblSizeIn))
  406.  
  407. newKey(Level old, float price, int bar, string name, bool isHigh, bool show, color col, bool isLiq) =>
  408. if not na(old)
  409. old.dead := true
  410. line.delete(old.ln)
  411. label.delete(old.lb)
  412. Level lv = Level.new(price = price, bar = bar, name = name, kind = isLiq ? 2 : 3, isHigh = isHigh)
  413. if show and not na(price)
  414. drawKey(lv, col)
  415. if isLiq and not na(price)
  416. addLevel(isHigh ? liqHighs : liqLows, lv)
  417. lv
  418.  
  419. legOrigin(bool downLeg) =>
  420. int best = 0
  421. float v = downLeg ? high : low
  422. int n = math.min(LEG_LOOK, bar_index)
  423. if n >= 1
  424. for i = 1 to n
  425. if downLeg ? high[i] > v : low[i] < v
  426. v := downLeg ? high[i] : low[i]
  427. best := i
  428. bar_index - best
  429.  
  430. tapHtf(bool bull) =>
  431. bool hit = false
  432. string tf = ""
  433. for f in htfFvgs
  434. if f.bull == bull and low <= f.top and high >= f.bot
  435. hit := true
  436. tf := f.tfLbl
  437. break
  438. [hit, tf]
  439.  
  440. insideHtf() =>
  441. bool hit = false
  442. for f in htfFvgs
  443. if close <= f.top and close >= f.bot
  444. hit := true
  445. break
  446. hit
  447.  
  448. findIfvg(array<Fvg> arr, bool long, int legStart, int extBar) =>
  449. Fvg pick = na
  450. if firstIfvgIn
  451. Fvg first = na
  452. for f in arr
  453. if f.bar >= legStart and f.bar <= extBar
  454. if na(first) or f.bar < first.bar
  455. first := f
  456. if not na(first)
  457. if not first.inverted and (long ? close > first.top : close < first.bot)
  458. pick := first
  459. else
  460. for f in arr
  461. if not f.inverted and f.bar >= legStart and (long ? close > f.top : close < f.bot)
  462. pick := f
  463. break
  464. pick
  465.  
  466. tradeLevels(bool long, float entry, float ext) =>
  467. float sl = na
  468. array<float> tg = array.new<float>()
  469. for lv in (long ? liqLows : liqHighs)
  470. if lv.kind == 0 and not lv.swept and (long ? lv.price < entry : lv.price > entry)
  471. sl := na(sl) ? lv.price : long ? math.max(sl, lv.price) : math.min(sl, lv.price)
  472. for lv in (long ? liqHighs : liqLows)
  473. if lv.kind == 0 and not lv.swept and (long ? lv.price > entry : lv.price < entry)
  474. tg.push(lv.price)
  475. tg.sort(long ? order.ascending : order.descending)
  476. if na(sl)
  477. sl := ext
  478. array<float> t = array.new<float>()
  479. for p in tg
  480. if t.size() == 0 or p != t.last()
  481. t.push(p)
  482. if t.size() == 3
  483. break
  484. float risk = math.abs(entry - sl)
  485. float dir = long ? 1.0 : -1.0
  486. float be = t.size() > 0 ? t.get(0) : entry + dir * risk
  487. float tp1 = t.size() > 1 ? t.get(1) : entry + dir * 2 * risk
  488. float tp2 = t.size() > 2 ? t.get(2) : entry + dir * 3 * risk
  489. [sl, be, tp1, tp2]
  490.  
  491. lvlText(string name, float price, float entry, bool showPx, bool hit) =>
  492. name + (showPx ? ": " + fmt(price) : "") + (showPtsIn and name != "Entry" ? " (" + fmt(math.abs(price - entry)) + " pts)" : "") + (hit ? " " + CHECK : "")
  493.  
  494. mkLine(float price, color col) =>
  495. line.new(bar_index, price, bar_index + LINE_LEN, price, color = col, width = 1)
  496.  
  497. mkLbl(string txt, float price, color col) =>
  498. label.new(bar_index + LINE_LEN, price, txt, style = label.style_label_left, color = color.new(col, 100), textcolor = col, size = size.small)
  499.  
  500. closeLines(Trade t) =>
  501. line.delete(t.lE)
  502. line.delete(t.lS)
  503. line.delete(t.lB)
  504. line.delete(t.l1)
  505. line.delete(t.l2)
  506. label.delete(t.bE)
  507. label.delete(t.bS)
  508. label.delete(t.bB)
  509. label.delete(t.b1)
  510. label.delete(t.b2)
  511.  
  512. closeTrade(Trade t) =>
  513. closeLines(t)
  514. t.open := false
  515.  
  516. newGap(float top, float bot, bool bull, color cBull, color cBear, bool mid, bool lbl, string name) =>
  517. Gap g = Gap.new(top = top, bot = bot, bull = bull)
  518. g.bx := box.new(bar_index - 1, top, bar_index + 5, bot, border_color = color.new(#000000, 100), bgcolor = bull ? cBull : cBear)
  519. if mid
  520. g.md := line.new(bar_index - 1, (top + bot) / 2, bar_index + 5, (top + bot) / 2, color = gapTxtCol, style = line.style_dotted)
  521. if lbl
  522. g.lb := label.new(bar_index + 5, (top + bot) / 2, name, style = label.style_label_left, color = color.new(#000000, 100), textcolor = gapTxtCol, size = size.tiny)
  523. g
  524.  
  525. delGap(Gap g) =>
  526. if not na(g)
  527. box.delete(g.bx)
  528. line.delete(g.md)
  529. label.delete(g.lb)
  530.  
  531. updGap(Gap g) =>
  532. bool filled = g.bull ? low <= g.bot : high >= g.top
  533. if not filled
  534. g.bx.set_right(bar_index + 5)
  535. if not na(g.md)
  536. g.md.set_x2(bar_index + 5)
  537. if not na(g.lb)
  538. g.lb.set_x(bar_index + 5)
  539. filled
  540.  
  541. float atr = nz(ta.atr(14))
  542.  
  543. bool in1 = not na(time(timeframe.period, s1Sess, tzIn))
  544. bool in2 = not na(time(timeframe.period, s2Sess, tzIn))
  545. bool in3 = not na(time(timeframe.period, s3Sess, tzIn))
  546. bool in4 = not na(time(timeframe.period, s4Sess, tzIn))
  547. bool in5 = not na(time(timeframe.period, s5Sess, tzIn))
  548. array<bool> sessIn = array.from(in1, in2, in3, in4, in5)
  549. bool mIn1 = not na(time(timeframe.period, m1Sess, tzIn))
  550. bool mIn2 = not na(time(timeframe.period, m2Sess, tzIn))
  551. bool mIn3 = not na(time(timeframe.period, m3Sess, tzIn))
  552. bool mIn4 = not na(time(timeframe.period, m4Sess, tzIn))
  553. bool mIn5 = not na(time(timeframe.period, m5Sess, tzIn))
  554. array<bool> macIn = array.from(mIn1, mIn2, mIn3, mIn4, mIn5)
  555. bool inMacro = (m1On and mIn1) or (m2On and mIn2) or (m3On and mIn3) or (m4On and mIn4) or (m5On and mIn5)
  556. bool inWindow = not onlyTradesIn or not na(time(timeframe.period, tradeWinIn))
  557.  
  558. bool intraday = timeframe.isintraday
  559. bool sessVis = showSessIn and intraday and timeframe.in_seconds() <= 3600
  560. bool macVis = intraday and timeframe.in_seconds() <= 3600
  561.  
  562. htfReq(string tf) =>
  563. request.security(syminfo.tickerid, tf, [low[1] > high[3], low[1], high[3], high[1] < low[3], low[3], high[1], time[3]], lookahead = barmerge.lookahead_on)
  564.  
  565. [aBn, aBt, aBb, aSn, aSt, aSb, aT] = htfReq(hfATf)
  566. [bBn, bBt, bBb, bSn, bSt, bSb, bT] = htfReq(hfBTf)
  567. [cBn, cBt, cBb, cSn, cSt, cSb, cT] = htfReq(hfCTf)
  568. bool aChg = timeframe.change(hfATf)
  569. bool bChg = timeframe.change(hfBTf)
  570. bool cChg = timeframe.change(hfCTf)
  571. bool aOk = hfAOn and timeframe.in_seconds(hfATf) >= timeframe.in_seconds()
  572. bool bOk = hfBOn and timeframe.in_seconds(hfBTf) >= timeframe.in_seconds()
  573. bool cOk = hfCOn and timeframe.in_seconds(hfCTf) >= timeframe.in_seconds()
  574. string aLbl = tfTxt(hfATf)
  575. string bLbl = tfTxt(hfBTf)
  576. string cLbl = tfTxt(hfCTf)
  577.  
  578. [h1PH, h1PL] = request.security(syminfo.tickerid, "60", [high[1], low[1]], lookahead = barmerge.lookahead_on)
  579. [h4PH, h4PL] = request.security(syminfo.tickerid, "240", [high[1], low[1]], lookahead = barmerge.lookahead_on)
  580.  
  581. [smtH, smtL] = request.security(smtTickerIn, timeframe.period, [high, low], ignore_invalid_symbol = true)
  582.  
  583. var array<Sess> sessions = array.from(Sess.new(name = s1Name, sess = s1Sess, col = s1Col, show = s1On, draws = array.new<SessDraw>()), Sess.new(name = s2Name, sess = s2Sess, col = s2Col, show = s2On, draws = array.new<SessDraw>()), Sess.new(name = s3Name, sess = s3Sess, col = s3Col, show = s3On, draws = array.new<SessDraw>()), Sess.new(name = s4Name, sess = s4Sess, col = s4Col, show = s4On, draws = array.new<SessDraw>()), Sess.new(name = s5Name, sess = s5Sess, col = s5Col, show = s5On, draws = array.new<SessDraw>()))
  584. var array<Macro> macros = array.from(Macro.new(title = m1Name, sess = m1Sess, col = m1Col, on = m1On), Macro.new(title = m2Name, sess = m2Sess, col = m2Col, on = m2On), Macro.new(title = m3Name, sess = m3Sess, col = m3Col, on = m3On), Macro.new(title = m4Name, sess = m4Sess, col = m4Col, on = m4On), Macro.new(title = m5Name, sess = m5Sess, col = m5Col, on = m5On))
  585. var float lastSessHi = na
  586. var float lastSessLo = na
  587.  
  588. for [i, s] in sessions
  589. bool nowIn = sessIn.get(i)
  590. bool vis = sessVis and s.show
  591. if nowIn and not s.active
  592. s.active := true
  593. s.hi := high
  594. s.lo := low
  595. s.hiBar := bar_index
  596. s.loBar := bar_index
  597. s.cur := na
  598. if vis
  599. string txt = sessLblIn ? s.name + (sessTimeIn ? " (" + timeTxt(s.sess) + ")" : "") : ""
  600. SessDraw d = SessDraw.new(bx = box.new(bar_index, high, bar_index, low, border_color = color.new(s.col, 50), border_style = line.style_dashed, bgcolor = s.col, text = txt, text_size = size.small, text_color = color.new(s.col, 20), text_valign = text.align_top, text_halign = text.align_center))
  601. s.cur := d
  602. s.draws.push(d)
  603. while s.draws.size() > sessLastIn
  604. delSessDraw(s.draws.shift())
  605. else if nowIn and s.active
  606. if high > s.hi
  607. s.hi := high
  608. s.hiBar := bar_index
  609. if low < s.lo
  610. s.lo := low
  611. s.loBar := bar_index
  612. if not na(s.cur)
  613. SessDraw d = s.cur
  614. d.bx.set_top(s.hi)
  615. d.bx.set_bottom(s.lo)
  616. d.bx.set_right(bar_index)
  617. else if not nowIn and s.active
  618. s.active := false
  619. lastSessHi := s.hi
  620. lastSessLo := s.lo
  621. Level lh = Level.new(price = s.hi, bar = s.hiBar, name = s.name + " High", kind = 1, isHigh = true)
  622. Level ll = Level.new(price = s.lo, bar = s.loBar, name = s.name + " Low", kind = 1, isHigh = false)
  623. if vis and sessHLIn and not na(s.cur)
  624. SessDraw d = s.cur
  625. int x2 = bar_index - 1 + (sessExtIn ? sessExtBarsIn : 0)
  626. color lc = color.new(s.col, 0)
  627. d.hl := line.new(s.hiBar, s.hi, x2, s.hi, color = lc, style = lineStyle(sessStyleIn), width = sessWidthIn)
  628. d.ll := line.new(s.loBar, s.lo, x2, s.lo, color = lc, style = lineStyle(sessStyleIn), width = sessWidthIn)
  629. int hx = sessLblPosIn == "Left" ? s.hiBar : sessLblPosIn == "Center" ? int((s.hiBar + x2) / 2) : x2
  630. int lx = sessLblPosIn == "Left" ? s.loBar : sessLblPosIn == "Center" ? int((s.loBar + x2) / 2) : x2
  631. d.hb := label.new(hx, s.hi, s.name + " High", style = label.style_label_down, color = color.new(#000000, 100), textcolor = sessLblColIn, size = txtSize(sessLblSizeIn))
  632. d.lbl := label.new(lx, s.lo, s.name + " Low", style = label.style_label_up, color = color.new(#000000, 100), textcolor = sessLblColIn, size = txtSize(sessLblSizeIn))
  633. lh.lb := d.hb
  634. ll.lb := d.lbl
  635. addLevel(liqHighs, lh)
  636. addLevel(liqLows, ll)
  637.  
  638. bool newDay = timeframe.change("D")
  639. bool newWeek = timeframe.change("W")
  640. bool newMonth = timeframe.change("M")
  641. var float dHi = na, var float dLo = na, var int dHiB = na, var int dLoB = na
  642. var float wHi = na, var float wLo = na, var int wHiB = na, var int wLoB = na
  643. var float mHi = na, var float mLo = na, var int mHiB = na, var int mLoB = na
  644. var Level lvDO = na
  645. var Level lvPDH = na
  646. var Level lvPDL = na
  647. var Level lvWO = na
  648. var Level lvPWH = na
  649. var Level lvPWL = na
  650. var Level lvMO = na
  651. var Level lvPMH = na
  652. var Level lvPML = na
  653. var Level lvMid = na
  654. var Level lv830 = na
  655.  
  656. if newDay and bar_index > 0
  657. lvDO := newKey(lvDO, open, bar_index, "Daily Open", true, kDOIn, kDOCol, false)
  658. lvPDH := newKey(lvPDH, dHi, dHiB, "PDH", true, kPDHIn, kPDHCol, true)
  659. lvPDL := newKey(lvPDL, dLo, dLoB, "PDL", false, kPDLIn, kPDLCol, true)
  660. dHi := high, dLo := low, dHiB := bar_index, dLoB := bar_index
  661. else
  662. if na(dHi) or high > dHi
  663. dHi := high, dHiB := bar_index
  664. if na(dLo) or low < dLo
  665. dLo := low, dLoB := bar_index
  666.  
  667. if newWeek and bar_index > 0
  668. lvWO := newKey(lvWO, open, bar_index, "Weekly Open", true, kWOIn, kWOCol, false)
  669. lvPWH := newKey(lvPWH, wHi, wHiB, "PWH", true, kPWHIn, kPWHCol, true)
  670. lvPWL := newKey(lvPWL, wLo, wLoB, "PWL", false, kPWLIn, kPWLCol, true)
  671. wHi := high, wLo := low, wHiB := bar_index, wLoB := bar_index
  672. else
  673. if na(wHi) or high > wHi
  674. wHi := high, wHiB := bar_index
  675. if na(wLo) or low < wLo
  676. wLo := low, wLoB := bar_index
  677.  
  678. if newMonth and bar_index > 0
  679. lvMO := newKey(lvMO, open, bar_index, "Monthly Open", true, kMOIn, kMOCol, false)
  680. lvPMH := newKey(lvPMH, mHi, mHiB, "PMH", true, kPMHIn, kPMHCol, true)
  681. lvPML := newKey(lvPML, mLo, mLoB, "PML", false, kPMLIn, kPMLCol, true)
  682. mHi := high, mLo := low, mHiB := bar_index, mLoB := bar_index
  683. else
  684. if na(mHi) or high > mHi
  685. mHi := high, mHiB := bar_index
  686. if na(mLo) or low < mLo
  687. mLo := low, mLoB := bar_index
  688.  
  689. int nyDay = dayofmonth(time, tzIn)
  690. int nyTod = hour(time, tzIn) * 60 + minute(time, tzIn)
  691. bool newNyDay = nyDay != nyDay[1]
  692. if intraday and newNyDay and bar_index > 0
  693. lvMid := newKey(lvMid, open, bar_index, "Midnight Open", true, kMidIn, kMidCol, false)
  694. if intraday and nyTod >= 510 and (nz(nyTod[1]) < 510 or newNyDay) and bar_index > 0
  695. lv830 := newKey(lv830, open, bar_index, "08:30 Open", true, k830In, k830Col, false)
  696.  
  697. if bar_index >= 2 and high[1] > high[2] and high[1] > high
  698. addLevel(liqHighs, Level.new(price = high[1], bar = bar_index - 1, name = "Swing High", kind = 0, isHigh = true))
  699. if bar_index >= 2 and low[1] < low[2] and low[1] < low
  700. addLevel(liqLows, Level.new(price = low[1], bar = bar_index - 1, name = "Swing Low", kind = 0, isHigh = false))
  701.  
  702. scanSweeps(array<Level> arr, bool isHigh) =>
  703. int n = 0
  704. string names = ""
  705. for lv in arr
  706. if not lv.swept and not lv.dead and lv.bar < bar_index and (isHigh ? high > lv.price : low < lv.price)
  707. lv.swept := true
  708. lv.sweptBar := bar_index
  709. if lv.kind == 2
  710. line.delete(lv.ln)
  711. label.delete(lv.lb)
  712. else if lv.kind == 1 and sessHideSwIn
  713. label.delete(lv.lb)
  714. if kindAllowed(lv.kind)
  715. n += 1
  716. names := names + (names == "" ? "" : ", ") + lv.name
  717. [n, names]
  718.  
  719. [nBsl, bslNames] = scanSweeps(liqHighs, true)
  720. [nSsl, sslNames] = scanSweeps(liqLows, false)
  721. if nBsl > 0
  722. pushAlert(alSweepIn, "Buyside Liquidity Sweep: " + bslNames)
  723. if nSsl > 0
  724. pushAlert(alSweepIn, "Sellside Liquidity Sweep: " + sslNames)
  725.  
  726. collectHtf(bool ok, bool chg, bool bn, float bTop, float bBot, bool sn, float sTop, float sBot, int t0, string lbl, color cBull, color cBear) =>
  727. if ok and chg
  728. if bn and bTop > bBot
  729. htfFvgs.push(HFvg.new(bTop, bBot, true, lbl, t0, cBull))
  730. if sn and sTop > sBot
  731. htfFvgs.push(HFvg.new(sTop, sBot, false, lbl, t0, cBear))
  732.  
  733. collectHtf(aOk, aChg, aBn, aBt, aBb, aSn, aSt, aSb, aT, aLbl, hfABull, hfABear)
  734. collectHtf(bOk, bChg, bBn, bBt, bBb, bSn, bSt, bSb, bT, bLbl, hfBBull, hfBBear)
  735. collectHtf(cOk, cChg, cBn, cBt, cBb, cSn, cSt, cSb, cT, cLbl, hfCBull, hfCBear)
  736. while htfFvgs.size() > MAX_HTF
  737. htfFvgs.shift()
  738. if htfFvgs.size() > 0
  739. for i = htfFvgs.size() - 1 to 0
  740. HFvg f = htfFvgs.get(i)
  741. if f.bull ? close < f.bot : close > f.top
  742. htfFvgs.remove(i)
  743.  
  744. int curSess = in1 ? 0 : in2 ? 1 : in3 ? 2 : in4 ? 3 : in5 ? 4 : -1
  745. var int prevSess = -1
  746. var int recIdx = -1
  747. var bool recSwHigh = false
  748. var bool recSwLow = false
  749. var int recLast = 0
  750. var int autoBias = 0
  751. var float refSessHi = na
  752. var float refSessLo = na
  753. if curSess != -1 and curSess != prevSess
  754. if recIdx != -1
  755. autoBias := recSwHigh or recSwLow ? (recLast == 1 ? -1 : 1) : 0
  756. recIdx := curSess
  757. recSwHigh := false
  758. recSwLow := false
  759. recLast := 0
  760. refSessHi := lastSessHi
  761. refSessLo := lastSessLo
  762. prevSess := curSess
  763. if curSess != -1
  764. bool dolHigh = (not na(h1PH) and high > h1PH) or (not na(h4PH) and high > h4PH) or (not na(refSessHi) and high > refSessHi) or (not na(lvPDH) and high > lvPDH.price)
  765. bool dolLow = (not na(h1PL) and low < h1PL) or (not na(h4PL) and low < h4PL) or (not na(refSessLo) and low < refSessLo) or (not na(lvPDL) and low < lvPDL.price)
  766. if dolHigh and not recSwHigh and not recSwLow and autoBias == 0
  767. autoBias := -1
  768. else if dolLow and not recSwHigh and not recSwLow and autoBias == 0
  769. autoBias := 1
  770. if dolHigh
  771. recSwHigh := true
  772. recLast := 1
  773. if dolLow
  774. recSwLow := true
  775. recLast := -1
  776. bool allowLong = biasModeIn == "Manual" ? manualBiasIn != "Bearish" : autoBias == 1
  777. bool allowShort = biasModeIn == "Manual" ? manualBiasIn != "Bullish" : autoBias == -1
  778.  
  779. var Setup setL = Setup.new()
  780. var Setup setS = Setup.new()
  781.  
  782. if nSsl > 0
  783. if setL.state == 0
  784. setL.count := nSsl
  785. setL.names := sslNames
  786. setL.tap := false
  787. setL.tapTf := ""
  788. setL.sweepBar := bar_index
  789. else
  790. setL.count += nSsl
  791. setL.names := setL.names + ", " + sslNames
  792. if setL.state == 0 or low <= setL.ext
  793. setL.ext := low
  794. setL.extMid := hl2
  795. setL.extBar := bar_index
  796. setL.legStart := legOrigin(true)
  797. setL.state := 1
  798. else if setL.state >= 1 and low < setL.ext
  799. setL.ext := low
  800. setL.extMid := hl2
  801. setL.extBar := bar_index
  802. setL.legStart := legOrigin(true)
  803. setL.state := 1
  804.  
  805. if nBsl > 0
  806. if setS.state == 0
  807. setS.count := nBsl
  808. setS.names := bslNames
  809. setS.tap := false
  810. setS.tapTf := ""
  811. setS.sweepBar := bar_index
  812. else
  813. setS.count += nBsl
  814. setS.names := setS.names + ", " + bslNames
  815. if setS.state == 0 or high >= setS.ext
  816. setS.ext := high
  817. setS.extMid := hl2
  818. setS.extBar := bar_index
  819. setS.legStart := legOrigin(false)
  820. setS.state := 1
  821. else if setS.state >= 1 and high > setS.ext
  822. setS.ext := high
  823. setS.extMid := hl2
  824. setS.extBar := bar_index
  825. setS.legStart := legOrigin(false)
  826. setS.state := 1
  827.  
  828. if setL.state == 1 and bar_index - setL.extBar <= TAP_WINDOW and not setL.tap
  829. [t, tf] = tapHtf(true)
  830. if t
  831. setL.tap := true
  832. setL.tapTf := tf
  833. if setS.state == 1 and bar_index - setS.extBar <= TAP_WINDOW and not setS.tap
  834. [t, tf] = tapHtf(false)
  835. if t
  836. setS.tap := true
  837. setS.tapTf := tf
  838.  
  839. float body = math.abs(close - open)
  840. float rng = high - low
  841. bool strong = body >= V_BODY_ATR * atr and rng > 0 and body / rng >= V_BODY_PCT
  842. if setL.state == 1 and bar_index > setL.extBar
  843. if bar_index - setL.extBar <= V_WINDOW and close > open and strong and close > setL.extMid
  844. setL.state := 2
  845. else if bar_index - setL.extBar > V_WINDOW
  846. setL.state := 0
  847. if setS.state == 1 and bar_index > setS.extBar
  848. if bar_index - setS.extBar <= V_WINDOW and close < open and strong and close < setS.extMid
  849. setS.state := 2
  850. else if bar_index - setS.extBar > V_WINDOW
  851. setS.state := 0
  852. if setL.state == 2 and bar_index - setL.extBar > SETUP_MAX
  853. setL.state := 0
  854. if setS.state == 2 and bar_index - setS.extBar > SETUP_MAX
  855. setS.state := 0
  856.  
  857. if bar_index >= 2 and low > high[2] and (low - high[2]) >= sensIn * atr
  858. bullFvgs.push(Fvg.new(top = low, bot = high[2], bar = bar_index - 1))
  859. if bar_index >= 2 and high < low[2] and (low[2] - high) >= sensIn * atr
  860. bearFvgs.push(Fvg.new(top = low[2], bot = high, bar = bar_index - 1))
  861. while bullFvgs.size() > MAX_FVG
  862. bullFvgs.shift()
  863. while bearFvgs.size() > MAX_FVG
  864. bearFvgs.shift()
  865.  
  866. var array<int> statWin = array.new<int>(5, 0)
  867. var array<int> statTot = array.new<int>(5, 0)
  868. var Trade tr = na
  869.  
  870. recordStat(Trade t, bool win) =>
  871. int w = win ? 1 : 0
  872. statWin.set(t.rank, statWin.get(t.rank) + w)
  873. statTot.set(t.rank, statTot.get(t.rank) + 1)
  874. int d = t.long ? 3 : 4
  875. statWin.set(d, statWin.get(d) + w)
  876. statTot.set(d, statTot.get(d) + 1)
  877.  
  878. winRate(int i) =>
  879. int t = statTot.get(i)
  880. t > 0 ? str.tostring(statWin.get(i) * 100.0 / t, "#.##") + "%" : "-"
  881.  
  882. if not na(tr)
  883. if tr.open and bar_index > tr.bar
  884. bool L = tr.long
  885. string side = L ? "Long" : "Short"
  886. if L ? low <= tr.curSL : high >= tr.curSL
  887. if not tr.beHit
  888. recordStat(tr, false)
  889. string res = tr.tp1Hit ? "🟢TP 1" : tr.beHit ? "🔹BE" : "🔴SL"
  890. tr.sig.set_tooltip(tr.tip + "\n\nResult: " + res)
  891. pushAlert(alSLIn, side + " Stop-Loss Hit @ " + fmt(tr.curSL))
  892. closeTrade(tr)
  893. else
  894. if not tr.beHit and (L ? high >= tr.be : low <= tr.be)
  895. tr.beHit := true
  896. recordStat(tr, true)
  897. tr.bB.set_text(lvlText("BE", tr.be, tr.entry, bePxIn, true))
  898. tr.sig.set_tooltip(tr.tip + "\n\nResult: 🔹BE")
  899. pushAlert(alBEIn, side + " Breakeven Hit @ " + fmt(tr.be))
  900. if trailingIn
  901. tr.curSL := tr.entry
  902. tr.lS.set_y1(tr.entry)
  903. tr.lS.set_y2(tr.entry)
  904. tr.bS.set_y(tr.entry)
  905. tr.bS.set_text(lvlText("SL", tr.entry, tr.entry, slPxIn, false))
  906. pushAlert(alTrEntIn, side + " Trailing Stop-Loss moved to Entry @ " + fmt(tr.entry))
  907. if not tr.tp1Hit and (L ? high >= tr.tp1 : low <= tr.tp1)
  908. tr.tp1Hit := true
  909. tr.b1.set_text(lvlText("TP 1", tr.tp1, tr.entry, tpPxIn, true))
  910. tr.sig.set_tooltip(tr.tip + "\n\nResult: 🟢TP 1")
  911. pushAlert(alTP1In, side + " TP1 Hit @ " + fmt(tr.tp1))
  912. if trailingIn
  913. tr.curSL := tr.be
  914. tr.lS.set_y1(tr.be)
  915. tr.lS.set_y2(tr.be)
  916. tr.bS.set_y(tr.be)
  917. tr.bS.set_text(lvlText("SL", tr.be, tr.entry, slPxIn, false))
  918. pushAlert(alTrBEIn, side + " Trailing Stop-Loss moved to BE @ " + fmt(tr.be))
  919. if L ? high >= tr.tp2 : low <= tr.tp2
  920. tr.sig.set_tooltip(tr.tip + "\n\nResult: 🟢TP 2")
  921. pushAlert(alTP2In, side + " TP2 Hit @ " + fmt(tr.tp2))
  922. closeTrade(tr)
  923.  
  924. var array<label> sigLabels = array.new<label>()
  925. var array<box> ifvgBoxes = array.new<box>()
  926. var array<line> ifvgMids = array.new<line>()
  927. var int lastIfvgBar = na
  928. int minRank = ratingMinIn == "A++" ? 2 : ratingMinIn == "A+" ? 1 : 0
  929.  
  930. fireSignal(bool long, Setup st, Fvg f, float sl, float be, float tp1, float tp2, int rank) =>
  931. string rating = rank == 2 ? "A++" : rank == 1 ? "A+" : "A"
  932. color col = long ? longCol : shortCol
  933. string tip = "Setup Rating: " + rating + "\nDirection: " + (long ? "Long" : "Short") + "\nLiquidity Swept: " + st.names + "\nMulti-Liquidity Sweep: " + (st.count >= 2 ? "Yes" : "No") + "\nHTF FVG Tap: " + (st.tap ? "Yes (" + st.tapTf + ")" : "No") + "\nInside Macro: " + (inMacro ? "Yes" : "No") + "\n\nEntry: " + fmt(close) + "\nSL: " + fmt(sl) + "\nBE: " + fmt(be) + "\nTP 1: " + fmt(tp1) + "\nTP 2: " + fmt(tp2)
  934. label sig = label.new(bar_index, long ? low : high, rating, style = long ? label.style_label_up : label.style_label_down, color = col, textcolor = long ? longTxtCol : shortTxtCol, size = txtSize(long ? longSizeIn : shortSizeIn), tooltip = tip)
  935. sigLabels.push(sig)
  936. while sigLabels.size() > MAX_SIG
  937. label.delete(sigLabels.shift())
  938. Trade t = Trade.new(long = long, bar = bar_index, rating = rating, rank = rank, entry = close, sl = sl, be = be, tp1 = tp1, tp2 = tp2, curSL = sl, tip = tip, sig = sig)
  939. if entryLnIn
  940. t.lE := mkLine(close, entryCol)
  941. t.bE := mkLbl(lvlText("Entry", close, close, entryPxIn, false), close, entryCol)
  942. if slLnIn
  943. t.lS := mkLine(sl, slCol)
  944. t.bS := mkLbl(lvlText("SL", sl, close, slPxIn, false), sl, slCol)
  945. if beLnIn
  946. t.lB := mkLine(be, beCol)
  947. t.bB := mkLbl(lvlText("BE", be, close, bePxIn, false), be, beCol)
  948. if tpLnIn
  949. t.l1 := mkLine(tp1, tp1Col)
  950. t.b1 := mkLbl(lvlText("TP 1", tp1, close, tpPxIn, false), tp1, tp1Col)
  951. t.l2 := mkLine(tp2, tp2Col)
  952. t.b2 := mkLbl(lvlText("TP 2", tp2, close, tpPxIn, false), tp2, tp2Col)
  953. if ifShowIn
  954. color ic = long ? ifBullCol : ifBearCol
  955. ifvgBoxes.push(box.new(f.bar - 1, f.top, bar_index, f.bot, border_color = color.new(ic, 40), bgcolor = ic))
  956. if ifMidIn
  957. ifvgMids.push(line.new(f.bar - 1, (f.top + f.bot) / 2, bar_index, (f.top + f.bot) / 2, color = ifMidCol, style = lineStyle(ifMidStyle)))
  958. while ifvgBoxes.size() > MAX_IFVG
  959. box.delete(ifvgBoxes.shift())
  960. while ifvgMids.size() > MAX_IFVG
  961. line.delete(ifvgMids.shift())
  962. pushAlert(long ? alLongIn : alShortIn, (long ? "Long" : "Short") + " Signal (" + rating + ") | Entry " + fmt(close) + " | SL " + fmt(sl) + " | BE " + fmt(be) + " | TP1 " + fmt(tp1) + " | TP2 " + fmt(tp2))
  963. t
  964.  
  965. evalSetup(bool long, Setup st) =>
  966. Trade out = na
  967. bool ifvg = false
  968. Fvg f = findIfvg(long ? bearFvgs : bullFvgs, long, st.legStart, st.extBar)
  969. if not na(f)
  970. ifvg := true
  971. [sl, be, tp1, tp2] = tradeLevels(long, close, st.ext)
  972. float risk = math.abs(close - sl)
  973. float rr = risk > 0 ? math.abs(tp2 - close) / risk : 0.0
  974. int conf = (st.tap ? 1 : 0) + (st.count >= 2 ? 1 : 0) + (inMacro ? 1 : 0)
  975. int rank = math.min(conf, 2)
  976. bool dirOk = long ? (allowLong and showLongIn) : (allowShort and showShortIn)
  977. bool slOk = long ? sl < close : sl > close
  978. if dirOk and inWindow and (not useMacroIn or inMacro) and risk > 0 and slOk and rr >= minRRIn and rank >= minRank
  979. out := fireSignal(long, st, f, sl, be, tp1, tp2, rank)
  980. [out, ifvg]
  981.  
  982. if setL.state == 2
  983. [t, ifvg] = evalSetup(true, setL)
  984. if ifvg
  985. lastIfvgBar := bar_index
  986. if not na(t)
  987. if not na(tr)
  988. closeTrade(tr)
  989. tr := t
  990. setL.state := 0
  991. if setS.state == 2
  992. [t, ifvg] = evalSetup(false, setS)
  993. if ifvg
  994. lastIfvgBar := bar_index
  995. if not na(t)
  996. if not na(tr)
  997. closeTrade(tr)
  998. tr := t
  999. setS.state := 0
  1000.  
  1001. for f in bearFvgs
  1002. if not f.inverted and close > f.top
  1003. f.inverted := true
  1004. for f in bullFvgs
  1005. if not f.inverted and close < f.bot
  1006. f.inverted := true
  1007.  
  1008. float pHc = ta.pivothigh(high, smtLenIn, smtLenIn)
  1009. float pLc = ta.pivotlow(low, smtLenIn, smtLenIn)
  1010. float pHo = ta.pivothigh(smtH, smtLenIn, smtLenIn)
  1011. float pLo = ta.pivotlow(smtL, smtLenIn, smtLenIn)
  1012. var float oH1 = na, var int oH1B = na, var float oH0 = na, var int oH0B = na
  1013. var float oL1 = na, var int oL1B = na, var float oL0 = na, var int oL0B = na
  1014. var float cHp = na, var int cHpB = na
  1015. var float cLp = na, var int cLpB = na
  1016. var array<line> smtLines = array.new<line>()
  1017. var array<label> smtLabels = array.new<label>()
  1018. var int smtBar = na
  1019.  
  1020. if not na(pHo)
  1021. oH0 := oH1, oH0B := oH1B
  1022. oH1 := pHo, oH1B := bar_index - smtLenIn
  1023. if not na(pLo)
  1024. oL0 := oL1, oL0B := oL1B
  1025. oL1 := pLo, oL1B := bar_index - smtLenIn
  1026.  
  1027. if smtIn and not na(pHc)
  1028. int pb = bar_index - smtLenIn
  1029. if not na(cHp) and not na(oH1) and not na(oH0) and math.abs(oH1B - pb) <= smtDivLenIn and math.abs(oH0B - cHpB) <= smtDivLenIn
  1030. if (pHc > cHp) != (oH1 > oH0)
  1031. smtLines.push(line.new(cHpB, cHp, pb, pHc, color = smtCol, style = line.style_dashed))
  1032. smtLabels.push(label.new(int((cHpB + pb) / 2), math.max(cHp, pHc), "SMT", style = label.style_label_down, color = color.new(#000000, 100), textcolor = smtCol, size = size.tiny))
  1033. smtBar := bar_index
  1034. pushAlert(alSmtIn, "Bearish SMT Divergence vs " + smtTickerIn)
  1035. cHp := pHc
  1036. cHpB := pb
  1037. if smtIn and not na(pLc)
  1038. int pb = bar_index - smtLenIn
  1039. if not na(cLp) and not na(oL1) and not na(oL0) and math.abs(oL1B - pb) <= smtDivLenIn and math.abs(oL0B - cLpB) <= smtDivLenIn
  1040. if (pLc < cLp) != (oL1 < oL0)
  1041. smtLines.push(line.new(cLpB, cLp, pb, pLc, color = smtCol, style = line.style_dashed))
  1042. smtLabels.push(label.new(int((cLpB + pb) / 2), math.min(cLp, pLc), "SMT", style = label.style_label_up, color = color.new(#000000, 100), textcolor = smtCol, size = size.tiny))
  1043. smtBar := bar_index
  1044. pushAlert(alSmtIn, "Bullish SMT Divergence vs " + smtTickerIn)
  1045. cLp := pLc
  1046. cLpB := pb
  1047. while smtLines.size() > smtLastIn
  1048. line.delete(smtLines.shift())
  1049. while smtLabels.size() > smtLastIn
  1050. label.delete(smtLabels.shift())
  1051.  
  1052. var array<box> macBoxes = array.new<box>()
  1053. var array<label> macLabels = array.new<label>()
  1054. var array<line> macLines = array.new<line>()
  1055.  
  1056. for [i, m] in macros
  1057. bool nowIn = macIn.get(i) and m.on
  1058. if nowIn and not m.active
  1059. m.active := true
  1060. m.hi := high
  1061. m.lo := low
  1062. m.startBar := bar_index
  1063. m.startHigh := high
  1064. m.bx := na
  1065. m.lb := na
  1066. if macVis and macZonesIn
  1067. m.bx := box.new(bar_index, high, bar_index, low, border_color = color.new(m.col, 100), bgcolor = m.col)
  1068. macBoxes.push(m.bx)
  1069. if macVis and macLblIn
  1070. m.lb := label.new(bar_index, high, m.title + " (" + timeTxt(m.sess) + ")", style = label.style_label_down, color = color.new(#000000, 100), textcolor = macLblCol, size = txtSize(macLblSizeIn))
  1071. macLabels.push(m.lb)
  1072. else if nowIn and m.active
  1073. m.hi := math.max(m.hi, high)
  1074. m.lo := math.min(m.lo, low)
  1075. if not na(m.bx)
  1076. m.bx.set_top(m.hi)
  1077. m.bx.set_bottom(m.lo)
  1078. m.bx.set_right(bar_index)
  1079. if not na(m.lb)
  1080. m.lb.set_y(m.hi)
  1081. else if not nowIn and m.active
  1082. m.active := false
  1083. if macVis and macLinesIn
  1084. int eb = bar_index - 1
  1085. color lc = color.new(m.col, 0)
  1086. macLines.push(line.new(m.startBar, m.lo, m.startBar, m.hi, color = lc, style = lineStyle(macSEStyle)))
  1087. macLines.push(line.new(eb, m.lo, eb, m.hi, color = lc, style = lineStyle(macSEStyle)))
  1088. macLines.push(line.new(m.startBar, m.startHigh, eb, high[1], color = lc, style = lineStyle(macLineStyle)))
  1089. while macBoxes.size() > MAX_MAC
  1090. box.delete(macBoxes.shift())
  1091. while macLabels.size() > MAX_MAC
  1092. label.delete(macLabels.shift())
  1093. while macLines.size() > MAX_MAC * 3
  1094. line.delete(macLines.shift())
  1095.  
  1096. var Gap ndog = na
  1097. var Gap nwog = na
  1098.  
  1099. if ndogIn
  1100. if newDay and bar_index > 0
  1101. delGap(ndog)
  1102. ndog := na
  1103. if open != close[1]
  1104. ndog := newGap(math.max(open, close[1]), math.min(open, close[1]), open > close[1], ndogBull, ndogBear, ndogMidIn, ndogLblIn, "NDOG")
  1105. else if not na(ndog)
  1106. if updGap(ndog)
  1107. delGap(ndog)
  1108. ndog := na
  1109. if nwogIn
  1110. if newWeek and bar_index > 0
  1111. delGap(nwog)
  1112. nwog := na
  1113. if open != close[1]
  1114. nwog := newGap(math.max(open, close[1]), math.min(open, close[1]), open > close[1], nwogBull, nwogBear, nwogMidIn, nwogLblIn, "NWOG")
  1115. else if not na(nwog)
  1116. if updGap(nwog)
  1117. delGap(nwog)
  1118. nwog := na
  1119.  
  1120. var array<line> swDraw = array.new<line>()
  1121. var array<box> hfBoxes = array.new<box>()
  1122. var array<line> hfMids = array.new<line>()
  1123.  
  1124. if barstate.islast
  1125. for lv in array.from(lvDO, lvPDH, lvPDL, lvWO, lvPWH, lvPWL, lvMO, lvPMH, lvPML, lvMid, lv830)
  1126. if not na(lv)
  1127. if not lv.dead and not lv.swept and not na(lv.ln)
  1128. int x2 = bar_index + (kExtIn ? kExtBarsIn : 0)
  1129. lv.ln.set_x2(x2)
  1130. if not na(lv.lb) and kLblPosIn == "Right"
  1131. lv.lb.set_x(x2)
  1132.  
  1133. while swDraw.size() > 0
  1134. line.delete(swDraw.shift())
  1135. if swShowIn
  1136. for side = 0 to 1
  1137. array<Level> src = side == 0 ? liqHighs : liqLows
  1138. array<int> used = array.new<int>()
  1139. for k = 1 to swNearestIn
  1140. int bi = -1
  1141. float bd = na
  1142. for [j, lv] in src
  1143. if lv.kind == 0 and not used.includes(j)
  1144. float d = math.abs(lv.price - close)
  1145. if na(bd) or d < bd
  1146. bd := d
  1147. bi := j
  1148. if bi >= 0
  1149. used.push(bi)
  1150. Level lv = src.get(bi)
  1151. swDraw.push(line.new(lv.bar, lv.price, lv.swept ? lv.sweptBar : bar_index, lv.price, color = lv.swept ? swSweptCol : swActiveCol, width = 1))
  1152.  
  1153. while hfBoxes.size() > 0
  1154. box.delete(hfBoxes.shift())
  1155. while hfMids.size() > 0
  1156. line.delete(hfMids.shift())
  1157. if hfPlotIn and htfFvgs.size() > 0
  1158. int rightT = time + 10 * timeframe.in_seconds() * 1000
  1159. for side = 0 to 1
  1160. array<int> used = array.new<int>()
  1161. for k = 1 to hfNearestIn
  1162. int bi = -1
  1163. float bd = na
  1164. for [j, f] in htfFvgs
  1165. if f.bull == (side == 0) and not used.includes(j)
  1166. float d = math.abs((f.top + f.bot) / 2 - close)
  1167. if na(bd) or d < bd
  1168. bd := d
  1169. bi := j
  1170. if bi >= 0
  1171. used.push(bi)
  1172. HFvg f = htfFvgs.get(bi)
  1173. hfBoxes.push(box.new(f.t, f.top, rightT, f.bot, xloc = xloc.bar_time, border_color = color.new(f.col, 100), bgcolor = f.col, text = hfLblIn ? f.tfLbl + " FVG" : "", text_color = hfLblCol, text_size = size.small, text_halign = text.align_right, text_valign = text.align_center))
  1174. if hfMidIn
  1175. hfMids.push(line.new(f.t, (f.top + f.bot) / 2, rightT, (f.top + f.bot) / 2, xloc = xloc.bar_time, color = hfMidCol, style = lineStyle(hfMidStyle)))
  1176.  
  1177. dbPos = switch dbPosIn
  1178. "Middle Right" => position.middle_right
  1179. "Bottom Right" => position.bottom_right
  1180. "Top Left" => position.top_left
  1181. "Middle Left" => position.middle_left
  1182. "Bottom Left" => position.bottom_left
  1183. "Top Center" => position.top_center
  1184. "Bottom Center" => position.bottom_center
  1185. => position.top_right
  1186.  
  1187. dbSize = switch dbSizeIn
  1188. "Tiny" => size.tiny
  1189. "Normal" => size.normal
  1190. "Large" => size.large
  1191. => size.small
  1192.  
  1193. bool dark = dbThemeIn == "Dark"
  1194. color hdrBg = dark ? #363A45 : #D1D4DC
  1195. color cellBg = dark ? #131722 : #FFFFFF
  1196. color txtCol = dark ? #FFFFFF : #131722
  1197. color accent = #089981
  1198.  
  1199. var table dash = table.new(dbPos, 2, 24, bgcolor = cellBg, frame_color = dark ? #000000 : #B2B5BE, frame_width = 1, border_color = dark ? #000000 : #B2B5BE, border_width = 1)
  1200.  
  1201. dbCell(int r, string k, string v, color bg, color kc, color vc) =>
  1202. table.cell(dash, 0, r, k, text_color = kc, text_size = dbSize, bgcolor = bg)
  1203. table.cell(dash, 1, r, v, text_color = vc, text_size = dbSize, bgcolor = bg)
  1204.  
  1205. if barstate.islast and dbIn
  1206. table.clear(dash, 0, 0, 1, 23)
  1207. bool hasTr = not na(tr)
  1208. color rCol = hasTr ? (tr.long ? longCol : shortCol) : txtCol
  1209. int curDir = setL.state > 0 and setS.state > 0 ? (setL.sweepBar >= setS.sweepBar ? 1 : -1) : setL.state > 0 ? 1 : setS.state > 0 ? -1 : hasTr ? (tr.long ? 1 : -1) : 0
  1210. bool recent = hasTr and tr.open
  1211. bool swOk = (curDir == 1 and setL.state >= 1) or (curDir == -1 and setS.state >= 1) or recent
  1212. bool vOk = (curDir == 1 and setL.state >= 2) or (curDir == -1 and setS.state >= 2) or recent
  1213. bool ifOk = not na(lastIfvgBar) and bar_index - lastIfvgBar <= STATE_BARS
  1214. bool htfOk = insideHtf() or (curDir == 1 and setL.state >= 1 and setL.tap) or (curDir == -1 and setS.state >= 1 and setS.tap)
  1215. bool dolUp = false
  1216. bool dolDn = false
  1217. for lv in liqHighs
  1218. if not lv.swept and not lv.dead and lv.price > close
  1219. dolUp := true
  1220. break
  1221. for lv in liqLows
  1222. if not lv.swept and not lv.dead and lv.price < close
  1223. dolDn := true
  1224. break
  1225. bool dolOk = curDir == 1 ? dolUp : curDir == -1 ? dolDn : (dolUp or dolDn)
  1226. bool smtOk = not na(smtBar) and bar_index - smtBar <= STATE_BARS
  1227. int bv = biasModeIn == "Manual" ? (manualBiasIn == "Bullish" ? 1 : manualBiasIn == "Bearish" ? -1 : 0) : autoBias
  1228. string biasT = bv == 1 ? "🐂 Bullish" : bv == -1 ? "🐻 Bearish" : biasModeIn == "Manual" ? "Both" : "-"
  1229. int r = 0
  1230. if dbRatingIn
  1231. dbCell(r, "Setup Rating", hasTr ? tr.rating : "-", hdrBg, txtCol, rCol)
  1232. r += 1
  1233. if dbEntryIn
  1234. dbCell(r, "Entry", hasTr ? fmt(tr.entry) : "-", cellBg, txtCol, txtCol)
  1235. r += 1
  1236. if dbSLIn
  1237. dbCell(r, "Stop-Loss", hasTr ? fmt(tr.curSL) : "-", cellBg, txtCol, txtCol)
  1238. r += 1
  1239. if dbBEIn
  1240. dbCell(r, "BE", hasTr ? fmt(tr.be) : "-", cellBg, txtCol, txtCol)
  1241. r += 1
  1242. if dbTP1In
  1243. dbCell(r, "TP 1", hasTr ? fmt(tr.tp1) : "-", cellBg, txtCol, txtCol)
  1244. r += 1
  1245. if dbTP2In
  1246. dbCell(r, "TP 2", hasTr ? fmt(tr.tp2) : "-", cellBg, txtCol, txtCol)
  1247. r += 1
  1248. dbCell(r, "Checklist", "State", hdrBg, txtCol, accent)
  1249. r += 1
  1250. if dbBiasIn
  1251. dbCell(r, "Bias", biasT, cellBg, txtCol, txtCol)
  1252. r += 1
  1253. if dbSweepIn
  1254. dbCell(r, "Liquidity Sweep", swOk ? CHECK : CROSS, cellBg, txtCol, txtCol)
  1255. r += 1
  1256. if dbHtfIn
  1257. dbCell(r, "HTF FVG", htfOk ? CHECK : CROSS, cellBg, txtCol, txtCol)
  1258. r += 1
  1259. if dbVIn
  1260. dbCell(r, "V Shape Recovery", vOk ? CHECK : CROSS, cellBg, txtCol, txtCol)
  1261. r += 1
  1262. if dbIfvgIn
  1263. dbCell(r, "Inversion FVG", ifOk ? CHECK : CROSS, cellBg, txtCol, txtCol)
  1264. r += 1
  1265. if dbDolIn
  1266. dbCell(r, "Clear Opposite DOL", dolOk ? CHECK : CROSS, cellBg, txtCol, txtCol)
  1267. r += 1
  1268. if dbSmtIn
  1269. dbCell(r, "SMT Divergence", smtOk ? CHECK : CROSS, cellBg, txtCol, txtCol)
  1270. r += 1
  1271. if dbStatsIn
  1272. dbCell(r, "Trade Stats", "", hdrBg, txtCol, txtCol)
  1273. r += 1
  1274. dbCell(r, "A Setups", winRate(0), cellBg, txtCol, dbStatsCol)
  1275. r += 1
  1276. dbCell(r, "A+ Setups", winRate(1), cellBg, txtCol, dbStatsCol)
  1277. r += 1
  1278. dbCell(r, "A++ Setups", winRate(2), cellBg, txtCol, dbStatsCol)
  1279. r += 1
  1280. dbCell(r, "Long Trades", winRate(3), cellBg, txtCol, dbStatsCol)
  1281. r += 1
  1282. dbCell(r, "Short Trades", winRate(4), cellBg, txtCol, dbStatsCol)
  1283. r += 1
  1284. dbCell(r, "Total Trades", str.tostring(statTot.get(3) + statTot.get(4)), cellBg, txtCol, dbStatsCol)
  1285.  
  1286. if alertList.size() > 0
  1287. alert(alertList.join("\n"), alert.freq_once_per_bar_close)
Advertisement
Add Comment
Please, Sign In to add comment