ajiim

🎁

Oct 6th, 2026
1,314
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 48.62 KB | None | 0 0
  1. //@version=6
  2. indicator("Manipulation Model [FB]", shorttitle = "Manipulation Model [FB]", overlay = true, max_lines_count = 500, max_boxes_count = 500, max_labels_count = 500, max_bars_back = 500)
  3.  
  4.  
  5. GRP_GEN = "General Configuration"
  6. GRP_SU = "Sessions Used"
  7. GRP_KLU = "Key Levels Used"
  8. GRP_TRAP = "Trap Confirmation"
  9. GRP_FVG = "Higher Timeframe FVG Settings"
  10. GRP_SES = "Sessions"
  11. GRP_KL = "Key Levels"
  12. GRP_STY = "Style Customization"
  13. GRP_DB = "Dashboard"
  14. GRP_AL = "Alerts"
  15.  
  16. candleTypeInput = input.string("Both", "Candle Type", options = ["Manipulation Candle (MC)", "Almost Manipulation Candle (AMC)", "Both"], group = GRP_GEN, tooltip = "Choose which candle type is used to generate signals: Manipulation Candles only, Almost Manipulation Candles only, or Both.", display = display.none)
  17. entryMethodInput = input.string("Both", "Entry Method", options = ["Key Levels", "Fair Value Gaps", "Both"], group = GRP_GEN, tooltip = "Determines whether signals are generated from Key Levels, Higher Timeframe Fair Value Gaps, or Both.", display = display.none)
  18. longSetupsInput = input.bool(true, "Long Setups", group = GRP_GEN, inline = "setA")
  19. shortSetupsInput = input.bool(true, "Short Setups", group = GRP_GEN, inline = "setA")
  20. bulltrapInput = input.bool(true, "Bulltrap Setups", group = GRP_GEN, inline = "setB")
  21. beartrapInput = input.bool(true, "Beartrap Setups", group = GRP_GEN, inline = "setB")
  22. slMultInput = input.float(1.0, "SL Multiplier", minval = 0.1, step = 0.1, group = GRP_GEN, tooltip = "Extends or contracts the stop loss distance measured from the entry.", display = display.none)
  23. tpMultInput = input.float(1.0, "TP Multiplier", minval = 0.1, step = 0.1, group = GRP_GEN, tooltip = "Take profit distance = (Entry - Stop Loss distance) x TP Multiplier.", display = display.none)
  24. biasTfInput = input.timeframe("60", "HTF Bias EMA", group = GRP_GEN, inline = "bias", display = display.none)
  25. biasLenInput = input.int(50, "Length", minval = 1, group = GRP_GEN, inline = "bias", tooltip = "Higher timeframe EMA bias filter. Above the EMA only bullish setups are allowed, below the EMA only bearish setups are allowed.", display = display.none)
  26.  
  27. useAsiaInput = input.bool(true, "Asia", group = GRP_SU, inline = "su1")
  28. sigAsiaInput = input.session("2000-0000", "", group = GRP_SU, inline = "su1", display = display.none)
  29. useLonInput = input.bool(true, "London", group = GRP_SU, inline = "su2")
  30. sigLonInput = input.session("0200-0500", "", group = GRP_SU, inline = "su2", display = display.none)
  31. useNyamInput = input.bool(true, "NY AM", group = GRP_SU, inline = "su3")
  32. sigNyamInput = input.session("0800-0930", "", group = GRP_SU, inline = "su3", display = display.none)
  33. useNyseInput = input.bool(true, "NYSE", group = GRP_SU, inline = "su4")
  34. sigNyseInput = input.session("0930-1000", "", group = GRP_SU, inline = "su4", display = display.none)
  35. useLcInput = input.bool(true, "London Close", group = GRP_SU, inline = "su5")
  36. sigLcInput = input.session("1000-1100", "", group = GRP_SU, inline = "su5", display = display.none)
  37. useNypmInput = input.bool(true, "NY PM", group = GRP_SU, inline = "su6")
  38. sigNypmInput = input.session("1100-1400", "", group = GRP_SU, inline = "su6", tooltip = "Only sessions enabled here produce signals. Signals can not be detected outside of these session windows.", display = display.none)
  39.  
  40. useDOLvlInput = input.bool(true, "Daily Open", group = GRP_KLU)
  41. usePDLvlInput = input.bool(true, "Previous Day High/Low", group = GRP_KLU)
  42. useWOLvlInput = input.bool(true, "Weekly Open", group = GRP_KLU)
  43. usePWLvlInput = input.bool(true, "Previous Week High/Low", group = GRP_KLU)
  44. useMOLvlInput = input.bool(true, "Monthly Open", group = GRP_KLU)
  45. usePMLvlInput = input.bool(true, "Previous Month High/Low", group = GRP_KLU)
  46. useAsiaLvlInput = input.bool(true, "Asia Session H/L", group = GRP_KLU)
  47. useLonLvlInput = input.bool(true, "London Session H/L", group = GRP_KLU)
  48. useNyamLvlInput = input.bool(true, "NY AM Session H/L", group = GRP_KLU)
  49. useNyseLvlInput = input.bool(true, "NYSE Session H/L", group = GRP_KLU)
  50. useNypmLvlInput = input.bool(true, "NY PM Session H/L", group = GRP_KLU)
  51. useLcLvlInput = input.bool(true, "London Close Session H/L", group = GRP_KLU)
  52. useMidLvlInput = input.bool(true, "Midnight Open", group = GRP_KLU, tooltip = "Only the levels enabled here are used to confirm Long, Short, Bulltrap and Beartrap setups.")
  53.  
  54. trapBarsInput = input.int(5, "Candles Between Confirmation", minval = 1, maxval = 100, group = GRP_TRAP, tooltip = "Maximum number of candles allowed between the initial (Almost) Manipulation Candle and the confirmation candle.")
  55. trapRatioInput = input.float(0.5, "Trap Wick-to-Body Ratio", minval = 0.0, step = 0.05, group = GRP_TRAP, tooltip = "Total wick size divided by body size of the confirmation candle. The confirmation candle is valid when its ratio is less than or equal to this value.", display = display.none)
  56. chopFilterInput = input.bool(true, "Choppy Market Filter", group = GRP_TRAP, inline = "chop")
  57. chopAtrInput = input.float(0.5, "Min Range (x ATR)", minval = 0.0, step = 0.05, group = GRP_TRAP, inline = "chop", tooltip = "Extra confirmation: the (Almost) Manipulation Candle range must be at least this multiple of ATR(14). Reduces signals during choppy market conditions.", display = display.none)
  58.  
  59. fvgShow1Input = input.bool(true, "Timeframe 1", group = GRP_FVG, inline = "tf1")
  60. fvgTf1Input = input.timeframe("60", "", group = GRP_FVG, inline = "tf1", display = display.none)
  61. fvgBull1Input = input.color(color.new(#089981, 80), "", group = GRP_FVG, inline = "tf1")
  62. fvgBear1Input = input.color(color.new(#f23645, 80), "", group = GRP_FVG, inline = "tf1")
  63. fvgShow2Input = input.bool(true, "Timeframe 2", group = GRP_FVG, inline = "tf2")
  64. fvgTf2Input = input.timeframe("240", "", group = GRP_FVG, inline = "tf2", display = display.none)
  65. fvgBull2Input = input.color(color.new(#00bfa5, 82), "", group = GRP_FVG, inline = "tf2")
  66. fvgBear2Input = input.color(color.new(#ff5252, 82), "", group = GRP_FVG, inline = "tf2")
  67. fvgShow3Input = input.bool(true, "Timeframe 3", group = GRP_FVG, inline = "tf3")
  68. fvgTf3Input = input.timeframe("D", "", group = GRP_FVG, inline = "tf3", display = display.none)
  69. fvgBull3Input = input.color(color.new(#4caf50, 84), "", group = GRP_FVG, inline = "tf3")
  70. fvgBear3Input = input.color(color.new(#e91e63, 84), "", group = GRP_FVG, inline = "tf3", tooltip = "Disabling a timeframe only removes it visually. All selected timeframes are always used for signal generation.")
  71. fvgCombineInput = input.bool(true, "Combine Zones", group = GRP_FVG, tooltip = "Merge overlapping FVGs of the same type on the same higher timeframe into a single zone.")
  72. fvgMidlineInput = input.bool(true, "Midline", group = GRP_FVG, inline = "fmid")
  73. fvgMidColInput = input.color(color.new(color.white, 35), "", group = GRP_FVG, inline = "fmid")
  74. fvgLabelsInput = input.bool(true, "Labels", group = GRP_FVG, inline = "flbl")
  75. fvgLblColInput = input.color(color.white, "", group = GRP_FVG, inline = "flbl")
  76. fvgLblSizeInput = input.string("Small", "", options = ["Tiny", "Small", "Normal", "Large", "Huge"], group = GRP_FVG, inline = "flbl", display = display.none)
  77. fvgLimitInput = input.int(3, "FVG Display Limit", minval = 1, maxval = 20, group = GRP_FVG, tooltip = "Only the nearest X active higher timeframe FVGs to current price are displayed.", display = display.none)
  78.  
  79. showAsiaInput = input.bool(true, "Asia", group = GRP_SES, inline = "s1")
  80. asiaSesInput = input.session("2000-0000", "", group = GRP_SES, inline = "s1", display = display.none)
  81. asiaColInput = input.color(color.new(#2962ff, 88), "", group = GRP_SES, inline = "s1")
  82. showLonInput = input.bool(true, "London", group = GRP_SES, inline = "s2")
  83. lonSesInput = input.session("0200-0500", "", group = GRP_SES, inline = "s2", display = display.none)
  84. lonColInput = input.color(color.new(#2962ff, 88), "", group = GRP_SES, inline = "s2")
  85. showNyamInput = input.bool(true, "NY AM", group = GRP_SES, inline = "s3")
  86. nyamSesInput = input.session("0800-0930", "", group = GRP_SES, inline = "s3", display = display.none)
  87. nyamColInput = input.color(color.new(#2962ff, 88), "", group = GRP_SES, inline = "s3")
  88. showNyseInput = input.bool(true, "NYSE", group = GRP_SES, inline = "s4")
  89. nyseSesInput = input.session("0930-1000", "", group = GRP_SES, inline = "s4", display = display.none)
  90. nyseColInput = input.color(color.new(#2962ff, 88), "", group = GRP_SES, inline = "s4")
  91. showLcInput = input.bool(true, "London Close", group = GRP_SES, inline = "s5")
  92. lcSesInput = input.session("1000-1100", "", group = GRP_SES, inline = "s5", display = display.none)
  93. lcColInput = input.color(color.new(#2962ff, 88), "", group = GRP_SES, inline = "s5")
  94. showNypmInput = input.bool(true, "NY PM", group = GRP_SES, inline = "s6")
  95. nypmSesInput = input.session("1100-1400", "", group = GRP_SES, inline = "s6", display = display.none)
  96. nypmColInput = input.color(color.new(#2962ff, 88), "", group = GRP_SES, inline = "s6")
  97. sesTzInput = input.string("America/New_York", "Timezone", options = ["America/New_York", "America/Chicago", "America/Los_Angeles", "Europe/London", "Europe/Berlin", "Asia/Tokyo", "Asia/Hong_Kong", "Australia/Sydney", "Etc/UTC"], group = GRP_SES, display = display.none)
  98. showSesBoxInput = input.bool(true, "Session Boxes", group = GRP_SES)
  99. showSesHLInput = input.bool(true, "Session Highs/Lows", group = GRP_SES, inline = "shl")
  100. sesHLStyleInput = input.string("Dashed", "", options = ["Solid", "Dashed", "Dotted"], group = GRP_SES, inline = "shl", display = display.none)
  101. showSesLblInput = input.bool(true, "Labels", group = GRP_SES, inline = "slb")
  102. sesLblColInput = input.color(#d1d4dc, "", group = GRP_SES, inline = "slb")
  103. sesLblSizeInput = input.string("Small", "", options = ["Tiny", "Small", "Normal", "Large", "Huge"], group = GRP_SES, inline = "slb", display = display.none)
  104. showSesPriceInput = input.bool(false, "Show Price", group = GRP_SES, inline = "slb")
  105. sesExtendInput = input.bool(true, "Extend Levels", group = GRP_SES, inline = "sext")
  106. sesExtBarsInput = input.int(10, "", minval = 1, maxval = 450, group = GRP_SES, inline = "sext", tooltip = "Extend unbroken session highs/lows forward by the set number of bars.", display = display.none)
  107. showSesTitleInput = input.bool(true, "Session Titles", group = GRP_SES)
  108. sesShowLastInput = input.int(1, "Show Last", minval = 1, maxval = 10, group = GRP_SES, tooltip = "Number of recent sessions of each type displayed on the chart.", display = display.none)
  109.  
  110. showDOInput = input.bool(true, "Daily Open", group = GRP_KL, inline = "kd")
  111. showPDInput = input.bool(true, "PDH/PDL", group = GRP_KL, inline = "kd")
  112. dailyColInput = input.color(color.white, "", group = GRP_KL, inline = "kd")
  113. showWOInput = input.bool(false, "Weekly Open", group = GRP_KL, inline = "kw")
  114. showPWInput = input.bool(false, "PWH/PWL", group = GRP_KL, inline = "kw")
  115. weeklyColInput = input.color(#ffb74d, "", group = GRP_KL, inline = "kw")
  116. showMOInput = input.bool(false, "Monthly Open", group = GRP_KL, inline = "km")
  117. showPMInput = input.bool(false, "PMH/PML", group = GRP_KL, inline = "km")
  118. monthlyColInput = input.color(#26c6da, "", group = GRP_KL, inline = "km")
  119. klStyleInput = input.string("Solid", "Line Style", options = ["Solid", "Dashed", "Dotted"], group = GRP_KL, display = display.none)
  120. showMidInput = input.bool(false, "Midnight Open", group = GRP_KL, inline = "kmo")
  121. midColInput = input.color(#b2b5be, "", group = GRP_KL, inline = "kmo")
  122. midStyleInput = input.string("Dotted", "", options = ["Solid", "Dashed", "Dotted"], group = GRP_KL, inline = "kmo", display = display.none)
  123. showKLLblInput = input.bool(true, "Show Labels", group = GRP_KL, inline = "kll")
  124. klLblColInput = input.color(#d1d4dc, "", group = GRP_KL, inline = "kll")
  125.  
  126. colorMCInput = input.bool(true, "Manipulation Candlestick", group = GRP_STY, inline = "mc")
  127. mcColInput = input.color(#cc7a00, "", group = GRP_STY, inline = "mc")
  128. colorAMCInput = input.bool(true, "Almost Manipulation Candlestick", group = GRP_STY, inline = "amc")
  129. amcColInput = input.color(#ffeb3b, "", group = GRP_STY, inline = "amc")
  130. longLblColInput = input.color(#4caf50, "Long / Beartrap Label", group = GRP_STY)
  131. shortLblColInput = input.color(#f23645, "Short / Bulltrap Label", group = GRP_STY)
  132. lblTextColInput = input.color(color.white, "Label Text", group = GRP_STY)
  133. showSLLblInput = input.bool(true, "SL Labels", group = GRP_STY, inline = "sll")
  134. slLblColInput = input.color(#f23645, "", group = GRP_STY, inline = "sll")
  135. showTPLblInput = input.bool(true, "TP Labels", group = GRP_STY, inline = "tpl")
  136. tpLblColInput = input.color(#4caf50, "", group = GRP_STY, inline = "tpl")
  137. showEntryLnInput = input.bool(false, "Entry Line", group = GRP_STY, inline = "eln")
  138. showEntryLnLblInput = input.bool(true, "Label", group = GRP_STY, inline = "eln")
  139. entryLnColInput = input.color(#b2b5be, "", group = GRP_STY, inline = "eln")
  140. showSLLnInput = input.bool(false, "Stop Loss Line", group = GRP_STY, inline = "sln")
  141. showSLLnLblInput = input.bool(true, "Label", group = GRP_STY, inline = "sln")
  142. slLnColInput = input.color(#f23645, "", group = GRP_STY, inline = "sln")
  143. showTPLnInput = input.bool(false, "Take Profit Line", group = GRP_STY, inline = "tln")
  144. showTPLnLblInput = input.bool(true, "Label", group = GRP_STY, inline = "tln")
  145. tpLnColInput = input.color(#4caf50, "", group = GRP_STY, inline = "tln")
  146.  
  147. showDashInput = input.bool(true, "Show Dashboard", group = GRP_DB)
  148. dashLookInput = input.int(5000, "Lookback (Bars)", minval = 50, group = GRP_DB, tooltip = "Number of bars used to calculate the win rates.", display = display.none)
  149. dashBgInput = input.color(color.white, "Background Color", group = GRP_DB)
  150. dashFrameInput = input.color(#363a45, "Frame Color", group = GRP_DB)
  151. dashBorderInput = input.color(#363a45, "Border Color", group = GRP_DB)
  152. dashTextInput = input.color(color.black, "Text Color", group = GRP_DB)
  153.  
  154. alLongInput = input.bool(true, "Long Setup", group = GRP_AL)
  155. alShortInput = input.bool(true, "Short Setup", group = GRP_AL)
  156. alBulltrapInput = input.bool(true, "Bulltrap Setup", group = GRP_AL)
  157. alBeartrapInput = input.bool(true, "Beartrap Setup", group = GRP_AL)
  158. alMCInput = input.bool(false, "Manipulation Candle", group = GRP_AL)
  159. alAMCInput = input.bool(false, "Almost Manipulation Candle", group = GRP_AL)
  160. alPDInput = input.bool(false, "Previous Day High/Low Break", group = GRP_AL)
  161. alDOInput = input.bool(false, "Current Day Open Break", group = GRP_AL)
  162. alPWInput = input.bool(false, "Previous Week High/Low Break", group = GRP_AL)
  163. alWOInput = input.bool(false, "Current Week Open Break", group = GRP_AL)
  164. alPMInput = input.bool(false, "Previous Month High/Low Break", group = GRP_AL)
  165. alMOInput = input.bool(false, "Current Month Open Break", group = GRP_AL)
  166. alAsiaInput = input.bool(false, "Asia Session High/Low Break", group = GRP_AL)
  167. alLonInput = input.bool(false, "London Session High/Low Break", group = GRP_AL)
  168. alNyamInput = input.bool(false, "NY AM Session High/Low Break", group = GRP_AL)
  169. alNyseInput = input.bool(false, "NYSE Session High/Low Break", group = GRP_AL)
  170. alLcInput = input.bool(false, "London Close Session High/Low Break", group = GRP_AL)
  171. alNypmInput = input.bool(false, "NY PM Session High/Low Break", group = GRP_AL)
  172. alMidInput = input.bool(false, "Midnight Open Break", group = GRP_AL, tooltip = "Create a TradingView alert with the 'Any alert() function call' condition to receive all selected alerts.")
  173.  
  174. int MAX_SIGNAL_LABELS = 180
  175. int MAX_TRADE_VISUALS = 50
  176. int MAX_FVG_STORE = 300
  177. int MAX_TRADE_AGE = 5000
  178. int FVG_EXTEND_BARS = 10
  179. int KL_EXTEND_BARS = 10
  180. string SES_DAYS = ":1234567"
  181. int TF_MS = timeframe.in_seconds() * 1000
  182. int CHART_SECS = timeframe.in_seconds()
  183. color CLEAR = color.new(color.black, 100)
  184.  
  185. var array<string> KIND_NAMES = array.from("Long", "Short", "Bulltrap", "Beartrap")
  186.  
  187. type FVG
  188. int tfIdx
  189. string tfLbl
  190. bool isBull = true
  191. float top
  192. float bottom
  193. int startTime
  194.  
  195. type SessionDraw
  196. box bx
  197. line hiLine
  198. line loLine
  199. label hiLbl
  200. label loLbl
  201. float hi
  202. float lo
  203. int endTime
  204. bool ended = false
  205. bool hiBroken = false
  206. bool loBroken = false
  207.  
  208. type SessionState
  209. string name
  210. float runHi
  211. float runLo
  212. int lastInTime
  213. bool wasIn = false
  214. float lastHi
  215. float lastLo
  216. SessionDraw cur
  217. array<SessionDraw> draws
  218.  
  219. type PeriodTracker
  220. float hiRun
  221. float loRun
  222. int hiTimeRun
  223. int loTimeRun
  224. int openTime
  225. int prevHiTime
  226. int prevLoTime
  227.  
  228. type Trade
  229. int kindIdx
  230. bool isLong = true
  231. float entry
  232. float sl
  233. float tp
  234. int entryBar
  235. bool counted = false
  236. line eLine
  237. line sLine
  238. line tLine
  239. label eLbl
  240. label sLbl
  241. label tLbl
  242.  
  243. var array<FVG> fvgs = array.new<FVG>()
  244. var array<SessionState> sesStates = array.new<SessionState>()
  245. var array<Trade> openTrades = array.new<Trade>()
  246. var array<Trade> tradeVisuals = array.new<Trade>()
  247. var array<label> signalLabels = array.new<label>()
  248. var array<int> winsArr = array.from(0, 0, 0, 0)
  249. var array<int> lossArr = array.from(0, 0, 0, 0)
  250. var array<box> fvgBoxes = array.new<box>()
  251. var array<line> fvgMids = array.new<line>()
  252. var array<label> fvgLbls = array.new<label>()
  253. var array<line> klLines = array.new<line>()
  254. var array<label> klLbls = array.new<label>()
  255.  
  256. lineStyleOf(string s) =>
  257. s == "Dashed" ? line.style_dashed : s == "Dotted" ? line.style_dotted : line.style_solid
  258.  
  259. sizeOf(string s) =>
  260. switch s
  261. "Tiny" => size.tiny
  262. "Small" => size.small
  263. "Normal" => size.normal
  264. "Large" => size.large
  265. "Huge" => size.huge
  266. => size.small
  267.  
  268. solidColor(color c) =>
  269. color.rgb(color.r(c), color.g(c), color.b(c), 0)
  270.  
  271. tfToLabel(simple string tf) =>
  272. int secs = timeframe.in_seconds(tf)
  273. string result = ""
  274. if secs < 60
  275. result := str.tostring(secs) + "s"
  276. else if secs < 3600
  277. result := str.tostring(math.round(secs / 60.0)) + "m"
  278. else if secs < 86400
  279. result := str.tostring(math.round(secs / 3600.0)) + "H"
  280. else if secs < 604800
  281. result := str.tostring(math.round(secs / 86400.0)) + "D"
  282. else if secs < 2419200
  283. result := str.tostring(math.round(secs / 604800.0)) + "W"
  284. else
  285. result := str.tostring(math.round(secs / 2628000.0)) + "M"
  286. result
  287.  
  288. inSession(string sess) =>
  289. not na(time(timeframe.period, sess + SES_DAYS, sesTzInput))
  290.  
  291. wickBodyRatio() =>
  292. float body = math.abs(close - open)
  293. float wick = (high - math.max(open, close)) + (math.min(open, close) - low)
  294. body > 0 ? wick / body : 1e10
  295.  
  296. sesLabelText(string nm, bool isHigh, float price) =>
  297. string base = nm + (isHigh ? " High" : " Low")
  298. showSesPriceInput ? base + " (" + str.tostring(price, format.mintick) + ")" : base
  299.  
  300. alertMsg(string s) =>
  301. syminfo.ticker + " (" + timeframe.period + ") | Manipulation Model [FB] | " + s
  302.  
  303. crossUp(float lvl, float prevC) =>
  304. not na(lvl) and not na(prevC) and close > lvl and prevC <= lvl
  305.  
  306. crossDn(float lvl, float prevC) =>
  307. not na(lvl) and not na(prevC) and close < lvl and prevC >= lvl
  308.  
  309. pushLevel(array<float> arr, bool use, float v) =>
  310. if use and not na(v)
  311. arr.push(v)
  312. true
  313.  
  314. touchLevels(array<float> lvls, int mode) =>
  315. bool hit = false
  316. for lv in lvls
  317. bool touched = high >= lv and low <= lv
  318. bool closeOK = mode == 1 ? close > lv : mode == -1 ? close < lv : true
  319. if touched and closeOK
  320. hit := true
  321. break
  322. hit
  323.  
  324. touchFVG(int mode) =>
  325. bool hit = false
  326. for fz in fvgs
  327. bool typeOK = mode == 0 or (mode == 1 and fz.isBull) or (mode == -1 and not fz.isBull)
  328. if typeOK and high >= fz.bottom and low <= fz.top
  329. hit := true
  330. break
  331. hit
  332.  
  333. method deleteAll(SessionDraw this) =>
  334. box.delete(this.bx)
  335. line.delete(this.hiLine)
  336. line.delete(this.loLine)
  337. label.delete(this.hiLbl)
  338. label.delete(this.loLbl)
  339. true
  340.  
  341. method update(PeriodTracker this, bool isNew) =>
  342. if isNew
  343. this.prevHiTime := this.hiTimeRun
  344. this.prevLoTime := this.loTimeRun
  345. this.openTime := time
  346. this.hiRun := high
  347. this.loRun := low
  348. this.hiTimeRun := time
  349. this.loTimeRun := time
  350. else
  351. if na(this.hiRun) or high > this.hiRun
  352. this.hiRun := high
  353. this.hiTimeRun := time
  354. if na(this.loRun) or low < this.loRun
  355. this.loRun := low
  356. this.loTimeRun := time
  357. this
  358.  
  359. method setEnd(Trade this, int t) =>
  360. if not na(this.eLine)
  361. this.eLine.set_x2(t)
  362. if not na(this.sLine)
  363. this.sLine.set_x2(t)
  364. if not na(this.tLine)
  365. this.tLine.set_x2(t)
  366. if not na(this.eLbl)
  367. this.eLbl.set_x(t)
  368. if not na(this.sLbl)
  369. this.sLbl.set_x(t)
  370. if not na(this.tLbl)
  371. this.tLbl.set_x(t)
  372. this
  373.  
  374. method clearVisuals(Trade this) =>
  375. line.delete(this.eLine)
  376. line.delete(this.sLine)
  377. line.delete(this.tLine)
  378. label.delete(this.eLbl)
  379. label.delete(this.sLbl)
  380. label.delete(this.tLbl)
  381. this.eLine := na
  382. this.sLine := na
  383. this.tLine := na
  384. this.eLbl := na
  385. this.sLbl := na
  386. this.tLbl := na
  387. this
  388.  
  389. pushSignalLabel(label lb) =>
  390. signalLabels.push(lb)
  391. if signalLabels.size() > MAX_SIGNAL_LABELS
  392. label.delete(signalLabels.shift())
  393. true
  394.  
  395. tradeText(Trade t) =>
  396. "Entry: " + str.tostring(t.entry, format.mintick) + " | SL: " + str.tostring(t.sl, format.mintick) + " | TP: " + str.tostring(t.tp, format.mintick)
  397.  
  398. processFVG(int tfIdx, string tfLbl, bool valid, bool isNew, float h1, float l1, float h3, float l3, float c2, float o2, int t3, float c1) =>
  399. if valid and isNew and not na(h3) and not na(l3) and not na(c1)
  400. int n = fvgs.size()
  401. if n > 0
  402. for i = n - 1 to 0
  403. FVG fm = fvgs.get(i)
  404. if fm.tfIdx == tfIdx and ((fm.isBull and c1 < fm.bottom) or (not fm.isBull and c1 > fm.top))
  405. fvgs.remove(i)
  406. bool bullGap = l1 > h3 and c2 > o2
  407. bool bearGap = h1 < l3 and c2 < o2
  408. if bullGap or bearGap
  409. float gTop = bullGap ? l1 : l3
  410. float gBot = bullGap ? h3 : h1
  411. bool merged = false
  412. if fvgCombineInput
  413. for fc in fvgs
  414. if fc.tfIdx == tfIdx and fc.isBull == bullGap and gTop >= fc.bottom and gBot <= fc.top
  415. fc.top := math.max(fc.top, gTop)
  416. fc.bottom := math.min(fc.bottom, gBot)
  417. fc.startTime := math.min(fc.startTime, t3)
  418. merged := true
  419. break
  420. if not merged
  421. fvgs.push(FVG.new(tfIdx = tfIdx, tfLbl = tfLbl, isBull = bullGap, top = gTop, bottom = gBot, startTime = t3))
  422. if fvgs.size() > MAX_FVG_STORE
  423. fvgs.shift()
  424. true
  425.  
  426. openTrade(int kindIdx, bool isLong, float entry, float stopRef) =>
  427. Trade t = na
  428. float risk = math.abs(entry - stopRef) * slMultInput
  429. if not na(risk) and risk > 0
  430. float sl = isLong ? entry - risk : entry + risk
  431. float tp = isLong ? entry + risk * tpMultInput : entry - risk * tpMultInput
  432. string nm = KIND_NAMES.get(kindIdx)
  433. color lc = isLong ? longLblColInput : shortLblColInput
  434. string tip = nm + " Setup\nEntry: " + str.tostring(entry, format.mintick) + "\nStop Loss: " + str.tostring(sl, format.mintick) + "\nTake Profit: " + str.tostring(tp, format.mintick)
  435. pushSignalLabel(label.new(bar_index, isLong ? low : high, nm, xloc = xloc.bar_index, yloc = isLong ? yloc.belowbar : yloc.abovebar, color = lc, style = isLong ? label.style_label_up : label.style_label_down, textcolor = lblTextColInput, size = size.small, tooltip = tip))
  436. t := Trade.new(kindIdx = kindIdx, isLong = isLong, entry = entry, sl = sl, tp = tp, entryBar = bar_index, counted = bar_index >= last_bar_index - dashLookInput)
  437. bool hasVis = false
  438. if showEntryLnInput
  439. t.eLine := line.new(time, entry, time, entry, xloc = xloc.bar_time, color = entryLnColInput, style = line.style_solid, width = 1)
  440. if showEntryLnLblInput
  441. t.eLbl := label.new(time, entry, "Entry", xloc = xloc.bar_time, style = label.style_label_left, color = CLEAR, textcolor = entryLnColInput, size = size.tiny)
  442. hasVis := true
  443. if showSLLnInput
  444. t.sLine := line.new(time, sl, time, sl, xloc = xloc.bar_time, color = slLnColInput, style = line.style_solid, width = 1)
  445. if showSLLnLblInput
  446. t.sLbl := label.new(time, sl, "SL", xloc = xloc.bar_time, style = label.style_label_left, color = CLEAR, textcolor = slLnColInput, size = size.tiny)
  447. hasVis := true
  448. if showTPLnInput
  449. t.tLine := line.new(time, tp, time, tp, xloc = xloc.bar_time, color = tpLnColInput, style = line.style_solid, width = 1)
  450. if showTPLnLblInput
  451. t.tLbl := label.new(time, tp, "TP", xloc = xloc.bar_time, style = label.style_label_left, color = CLEAR, textcolor = tpLnColInput, size = size.tiny)
  452. hasVis := true
  453. openTrades.push(t)
  454. if hasVis
  455. tradeVisuals.push(t)
  456. if tradeVisuals.size() > MAX_TRADE_VISUALS
  457. Trade oldT = tradeVisuals.shift()
  458. oldT.clearVisuals()
  459. t
  460.  
  461. drawKeyLevel(bool show, float price, int x1, int x2, string txt, color col, string sty, array<float> lblPrices, array<string> lblTexts) =>
  462. if show and not na(price) and not na(x1)
  463. klLines.push(line.new(x1, price, x2, price, xloc = xloc.bar_time, color = col, style = sty, width = 1))
  464. int found = -1
  465. for [j, p] in lblPrices
  466. if math.abs(p - price) < syminfo.mintick * 0.5
  467. found := j
  468. break
  469. if found >= 0
  470. lblTexts.set(found, lblTexts.get(found) + " / " + txt)
  471. else
  472. lblPrices.push(price)
  473. lblTexts.push(txt)
  474. true
  475.  
  476. if sesStates.size() == 0
  477. for nm in array.from("Asia", "London", "NY AM", "NYSE", "London Close", "NY PM")
  478. sesStates.push(SessionState.new(name = nm, draws = array.new<SessionDraw>()))
  479.  
  480. float prevClose = close[1]
  481.  
  482. float htfEma = request.security(syminfo.tickerid, biasTfInput, ta.ema(close, biasLenInput)[1], lookahead = barmerge.lookahead_on)
  483.  
  484. [dOpen, pdh, pdl] = request.security(syminfo.tickerid, "D", [open, high[1], low[1]], lookahead = barmerge.lookahead_on)
  485. [wOpen, pwh, pwl] = request.security(syminfo.tickerid, "W", [open, high[1], low[1]], lookahead = barmerge.lookahead_on)
  486. [mOpen, pmh, pml] = request.security(syminfo.tickerid, "M", [open, high[1], low[1]], lookahead = barmerge.lookahead_on)
  487.  
  488. [f1H1, f1L1, f1H3, f1L3, f1C2, f1O2, f1T3, f1C1, f1T1] = request.security(syminfo.tickerid, fvgTf1Input, [high[1], low[1], high[3], low[3], close[2], open[2], time[3], close[1], time[1]], lookahead = barmerge.lookahead_on)
  489. [f2H1, f2L1, f2H3, f2L3, f2C2, f2O2, f2T3, f2C1, f2T1] = request.security(syminfo.tickerid, fvgTf2Input, [high[1], low[1], high[3], low[3], close[2], open[2], time[3], close[1], time[1]], lookahead = barmerge.lookahead_on)
  490. [f3H1, f3L1, f3H3, f3L3, f3C2, f3O2, f3T3, f3C1, f3T1] = request.security(syminfo.tickerid, fvgTf3Input, [high[1], low[1], high[3], low[3], close[2], open[2], time[3], close[1], time[1]], lookahead = barmerge.lookahead_on)
  491.  
  492. bool fvgNew1 = not na(f1T1) and (na(f1T1[1]) or f1T1 != f1T1[1])
  493. bool fvgNew2 = not na(f2T1) and (na(f2T1[1]) or f2T1 != f2T1[1])
  494. bool fvgNew3 = not na(f3T1) and (na(f3T1[1]) or f3T1 != f3T1[1])
  495.  
  496. bool fvgValid1 = timeframe.in_seconds(fvgTf1Input) > CHART_SECS
  497. bool fvgValid2 = timeframe.in_seconds(fvgTf2Input) > CHART_SECS
  498. bool fvgValid3 = timeframe.in_seconds(fvgTf3Input) > CHART_SECS
  499.  
  500. string FVG_LBL1 = tfToLabel(fvgTf1Input)
  501. string FVG_LBL2 = tfToLabel(fvgTf2Input)
  502. string FVG_LBL3 = tfToLabel(fvgTf3Input)
  503.  
  504. processFVG(1, FVG_LBL1, fvgValid1, fvgNew1, f1H1, f1L1, f1H3, f1L3, f1C2, f1O2, f1T3, f1C1)
  505. processFVG(2, FVG_LBL2, fvgValid2, fvgNew2, f2H1, f2L1, f2H3, f2L3, f2C2, f2O2, f2T3, f2C1)
  506. processFVG(3, FVG_LBL3, fvgValid3, fvgNew3, f3H1, f3L1, f3H3, f3L3, f3C2, f3O2, f3T3, f3C1)
  507.  
  508. var PeriodTracker dTrk = PeriodTracker.new()
  509. var PeriodTracker wTrk = PeriodTracker.new()
  510. var PeriodTracker mTrk = PeriodTracker.new()
  511. dTrk.update(timeframe.change("D"))
  512. wTrk.update(timeframe.change("W"))
  513. mTrk.update(timeframe.change("M"))
  514.  
  515. int nyDom = dayofmonth(time, sesTzInput)
  516. var float midnightOpen = na
  517. var int midnightTime = na
  518. if bar_index > 0 and nyDom != nyDom[1]
  519. midnightOpen := open
  520. midnightTime := time
  521.  
  522. bool vAsia = inSession(asiaSesInput)
  523. bool vLon = inSession(lonSesInput)
  524. bool vNyam = inSession(nyamSesInput)
  525. bool vNyse = inSession(nyseSesInput)
  526. bool vLc = inSession(lcSesInput)
  527. bool vNypm = inSession(nypmSesInput)
  528. array<bool> visIn = array.from(vAsia, vLon, vNyam, vNyse, vLc, vNypm)
  529.  
  530. bool inSignalSession = (useAsiaInput and inSession(sigAsiaInput)) or (useLonInput and inSession(sigLonInput)) or (useNyamInput and inSession(sigNyamInput)) or (useNyseInput and inSession(sigNyseInput)) or (useLcInput and inSession(sigLcInput)) or (useNypmInput and inSession(sigNypmInput))
  531.  
  532. var array<bool> sesShowArr = array.from(showAsiaInput, showLonInput, showNyamInput, showNyseInput, showLcInput, showNypmInput)
  533. var array<color> sesColArr = array.from(asiaColInput, lonColInput, nyamColInput, nyseColInput, lcColInput, nypmColInput)
  534. var array<bool> sesLvlUseArr = array.from(useAsiaLvlInput, useLonLvlInput, useNyamLvlInput, useNyseLvlInput, useLcLvlInput, useNypmLvlInput)
  535. var array<bool> sesAlertArr = array.from(alAsiaInput, alLonInput, alNyamInput, alNyseInput, alLcInput, alNypmInput)
  536.  
  537. string sesLnStyle = lineStyleOf(sesHLStyleInput)
  538. string sesLblSize = sizeOf(sesLblSizeInput)
  539. int sesExtTime = time + sesExtBarsInput * TF_MS
  540. array<bool> sesBreakArr = array.new<bool>(6, false)
  541. array<string> sesBreakTxt = array.new<string>(6, "")
  542.  
  543. for i = 0 to 5
  544. SessionState st = sesStates.get(i)
  545. bool inS = visIn.get(i)
  546. bool showS = sesShowArr.get(i)
  547. color cBox = sesColArr.get(i)
  548. color cLine = solidColor(cBox)
  549. bool started = inS and not st.wasIn
  550. bool ended = not inS and st.wasIn
  551.  
  552. if ended
  553. st.lastHi := st.runHi
  554. st.lastLo := st.runLo
  555. if not na(st.cur)
  556. SessionDraw sdEnd = st.cur
  557. sdEnd.ended := true
  558. sdEnd.endTime := st.lastInTime
  559. if not na(sdEnd.hiLine)
  560. sdEnd.hiLine.set_x2(sdEnd.endTime)
  561. if not na(sdEnd.loLine)
  562. sdEnd.loLine.set_x2(sdEnd.endTime)
  563. if not na(sdEnd.hiLbl)
  564. sdEnd.hiLbl.set_x(sdEnd.endTime)
  565. if not na(sdEnd.loLbl)
  566. sdEnd.loLbl.set_x(sdEnd.endTime)
  567. st.cur := na
  568.  
  569. if started
  570. st.runHi := high
  571. st.runLo := low
  572. if showS and (showSesBoxInput or showSesTitleInput or showSesHLInput)
  573. SessionDraw sdNew = SessionDraw.new(hi = high, lo = low)
  574. if showSesBoxInput or showSesTitleInput
  575. sdNew.bx := box.new(time, high, time, low, xloc = xloc.bar_time, bgcolor = showSesBoxInput ? cBox : CLEAR, border_color = CLEAR, border_width = 1, text = showSesTitleInput ? st.name : "", text_color = cLine, text_size = size.small, text_halign = text.align_left, text_valign = text.align_bottom)
  576. if showSesHLInput
  577. sdNew.hiLine := line.new(time, high, time, high, xloc = xloc.bar_time, color = cLine, style = sesLnStyle, width = 1)
  578. sdNew.loLine := line.new(time, low, time, low, xloc = xloc.bar_time, color = cLine, style = sesLnStyle, width = 1)
  579. if showSesLblInput
  580. sdNew.hiLbl := label.new(time, high, sesLabelText(st.name, true, high), xloc = xloc.bar_time, style = label.style_label_left, color = CLEAR, textcolor = sesLblColInput, size = sesLblSize)
  581. sdNew.loLbl := label.new(time, low, sesLabelText(st.name, false, low), xloc = xloc.bar_time, style = label.style_label_left, color = CLEAR, textcolor = sesLblColInput, size = sesLblSize)
  582. st.cur := sdNew
  583. st.draws.push(sdNew)
  584. if st.draws.size() > sesShowLastInput
  585. SessionDraw sdOld = st.draws.shift()
  586. sdOld.deleteAll()
  587. else if inS
  588. st.runHi := math.max(st.runHi, high)
  589. st.runLo := math.min(st.runLo, low)
  590.  
  591. if inS
  592. st.lastInTime := time
  593. if not na(st.cur)
  594. SessionDraw sdCur = st.cur
  595. sdCur.hi := st.runHi
  596. sdCur.lo := st.runLo
  597. if not na(sdCur.bx)
  598. sdCur.bx.set_top(sdCur.hi)
  599. sdCur.bx.set_bottom(sdCur.lo)
  600. sdCur.bx.set_right(time)
  601. if not na(sdCur.hiLine)
  602. sdCur.hiLine.set_y1(sdCur.hi)
  603. sdCur.hiLine.set_y2(sdCur.hi)
  604. sdCur.hiLine.set_x2(time)
  605. if not na(sdCur.loLine)
  606. sdCur.loLine.set_y1(sdCur.lo)
  607. sdCur.loLine.set_y2(sdCur.lo)
  608. sdCur.loLine.set_x2(time)
  609. if not na(sdCur.hiLbl)
  610. sdCur.hiLbl.set_xy(time, sdCur.hi)
  611. sdCur.hiLbl.set_text(sesLabelText(st.name, true, sdCur.hi))
  612. if not na(sdCur.loLbl)
  613. sdCur.loLbl.set_xy(time, sdCur.lo)
  614. sdCur.loLbl.set_text(sesLabelText(st.name, false, sdCur.lo))
  615.  
  616. for dr in st.draws
  617. if dr.ended
  618. if not dr.hiBroken and close > dr.hi
  619. dr.hiBroken := true
  620. if sesExtendInput
  621. if not na(dr.hiLine)
  622. dr.hiLine.set_x2(time)
  623. label.delete(dr.hiLbl)
  624. dr.hiLbl := na
  625. if not dr.loBroken and close < dr.lo
  626. dr.loBroken := true
  627. if sesExtendInput
  628. if not na(dr.loLine)
  629. dr.loLine.set_x2(time)
  630. label.delete(dr.loLbl)
  631. dr.loLbl := na
  632. if sesExtendInput
  633. if not dr.hiBroken
  634. if not na(dr.hiLine)
  635. dr.hiLine.set_x2(sesExtTime)
  636. if not na(dr.hiLbl)
  637. dr.hiLbl.set_x(sesExtTime)
  638. if not dr.loBroken
  639. if not na(dr.loLine)
  640. dr.loLine.set_x2(sesExtTime)
  641. if not na(dr.loLbl)
  642. dr.loLbl.set_x(sesExtTime)
  643.  
  644. if not na(st.lastHi) and not na(st.lastLo)
  645. if crossUp(st.lastHi, prevClose)
  646. sesBreakArr.set(i, true)
  647. sesBreakTxt.set(i, st.name + " Session High Break")
  648. else if crossDn(st.lastLo, prevClose)
  649. sesBreakArr.set(i, true)
  650. sesBreakTxt.set(i, st.name + " Session Low Break")
  651.  
  652. st.wasIn := inS
  653.  
  654. float upperWick = high - math.max(open, close)
  655. float lowerWick = math.min(open, close) - low
  656. bool sweepBoth = bar_index > 0 and high > high[1] and low < low[1]
  657. bool insidePrev = close <= high[1] and close >= low[1]
  658.  
  659. bool bullMC = sweepBoth and close > high[1] and (high - close) < (open - low)
  660. bool bearMC = sweepBoth and close < low[1] and (close - low) < (high - open)
  661. bool bullAMC = sweepBoth and insidePrev and lowerWick > upperWick and close > open
  662. bool bearAMC = sweepBoth and insidePrev and upperWick > lowerWick and close < open
  663.  
  664. array<float> keyLvls = array.new<float>()
  665. if sweepBoth
  666. pushLevel(keyLvls, useDOLvlInput, dOpen)
  667. pushLevel(keyLvls, usePDLvlInput, pdh)
  668. pushLevel(keyLvls, usePDLvlInput, pdl)
  669. pushLevel(keyLvls, useWOLvlInput, wOpen)
  670. pushLevel(keyLvls, usePWLvlInput, pwh)
  671. pushLevel(keyLvls, usePWLvlInput, pwl)
  672. pushLevel(keyLvls, useMOLvlInput, mOpen)
  673. pushLevel(keyLvls, usePMLvlInput, pmh)
  674. pushLevel(keyLvls, usePMLvlInput, pml)
  675. for i = 0 to 5
  676. SessionState stL = sesStates.get(i)
  677. pushLevel(keyLvls, sesLvlUseArr.get(i), stL.lastHi)
  678. pushLevel(keyLvls, sesLvlUseArr.get(i), stL.lastLo)
  679. pushLevel(keyLvls, useMidLvlInput, midnightOpen)
  680.  
  681. bool useMC = candleTypeInput != "Almost Manipulation Candle (AMC)"
  682. bool useAMC = candleTypeInput != "Manipulation Candle (MC)"
  683. bool useKL = entryMethodInput != "Fair Value Gaps"
  684. bool useFVG = entryMethodInput != "Key Levels"
  685.  
  686. bool bullCandle = (useMC and bullMC) or (useAMC and bullAMC)
  687. bool bearCandle = (useMC and bearMC) or (useAMC and bearAMC)
  688.  
  689. float atrVal = ta.atr(14)
  690. bool chopOK = not chopFilterInput or na(atrVal) or (high - low) >= chopAtrInput * atrVal
  691.  
  692. bool biasBull = not na(htfEma) and close > htfEma
  693. bool biasBear = not na(htfEma) and close < htfEma
  694.  
  695. int nOpen = openTrades.size()
  696. if nOpen > 0
  697. for i = nOpen - 1 to 0
  698. Trade tr = openTrades.get(i)
  699. if bar_index > tr.entryBar
  700. bool hitSL = tr.isLong ? low <= tr.sl : high >= tr.sl
  701. bool hitTP = tr.isLong ? high >= tr.tp : low <= tr.tp
  702. if hitSL or hitTP
  703. bool win = hitTP and not hitSL
  704. if tr.counted
  705. if win
  706. winsArr.set(tr.kindIdx, winsArr.get(tr.kindIdx) + 1)
  707. else
  708. lossArr.set(tr.kindIdx, lossArr.get(tr.kindIdx) + 1)
  709. if win and showTPLblInput
  710. pushSignalLabel(label.new(bar_index, tr.isLong ? high : low, "TP", xloc = xloc.bar_index, yloc = tr.isLong ? yloc.abovebar : yloc.belowbar, color = tpLblColInput, style = tr.isLong ? label.style_label_down : label.style_label_up, textcolor = lblTextColInput, size = size.small, tooltip = KIND_NAMES.get(tr.kindIdx) + " Take Profit: " + str.tostring(tr.tp, format.mintick)))
  711. if not win and showSLLblInput
  712. pushSignalLabel(label.new(bar_index, tr.isLong ? low : high, "SL", xloc = xloc.bar_index, yloc = tr.isLong ? yloc.belowbar : yloc.abovebar, color = slLblColInput, style = tr.isLong ? label.style_label_up : label.style_label_down, textcolor = lblTextColInput, size = size.small, tooltip = KIND_NAMES.get(tr.kindIdx) + " Stop Loss: " + str.tostring(tr.sl, format.mintick)))
  713. tr.setEnd(time)
  714. openTrades.remove(i)
  715. else
  716. tr.setEnd(time)
  717. if bar_index - tr.entryBar > MAX_TRADE_AGE
  718. openTrades.remove(i)
  719.  
  720. var float bearTrapHigh = na
  721. var int bearTrapBar = na
  722. var float bullTrapLow = na
  723. var int bullTrapBar = na
  724.  
  725. bool longSignal = false
  726. bool shortSignal = false
  727. bool bulltrapSignal = false
  728. bool beartrapSignal = false
  729.  
  730. if barstate.isconfirmed
  731. float wbRatio = wickBodyRatio()
  732.  
  733. if not na(bearTrapBar)
  734. int distBear = bar_index - bearTrapBar
  735. if distBear > trapBarsInput
  736. bearTrapBar := na
  737. bearTrapHigh := na
  738. else if close > bearTrapHigh and close > open and wbRatio <= trapRatioInput and inSignalSession and biasBull and beartrapInput
  739. beartrapSignal := true
  740. bearTrapBar := na
  741. bearTrapHigh := na
  742.  
  743. if not na(bullTrapBar)
  744. int distBull = bar_index - bullTrapBar
  745. if distBull > trapBarsInput
  746. bullTrapBar := na
  747. bullTrapLow := na
  748. else if close < bullTrapLow and close < open and wbRatio <= trapRatioInput and inSignalSession and biasBear and bulltrapInput
  749. bulltrapSignal := true
  750. bullTrapBar := na
  751. bullTrapLow := na
  752.  
  753. longSignal := not beartrapSignal and longSetupsInput and bullCandle and chopOK and inSignalSession and biasBull and ((useKL and touchLevels(keyLvls, 1)) or (useFVG and touchFVG(1)))
  754. shortSignal := not bulltrapSignal and shortSetupsInput and bearCandle and chopOK and inSignalSession and biasBear and ((useKL and touchLevels(keyLvls, -1)) or (useFVG and touchFVG(-1)))
  755.  
  756. if bearCandle and chopOK and ((useKL and touchLevels(keyLvls, 0)) or (useFVG and touchFVG(0)))
  757. bearTrapBar := bar_index
  758. bearTrapHigh := high
  759. if bullCandle and chopOK and ((useKL and touchLevels(keyLvls, 0)) or (useFVG and touchFVG(0)))
  760. bullTrapBar := bar_index
  761. bullTrapLow := low
  762.  
  763. if longSignal
  764. Trade tL = openTrade(0, true, close, low)
  765. if not na(tL) and alLongInput
  766. alert(alertMsg("Long Setup | " + tradeText(tL)), alert.freq_once_per_bar_close)
  767. if shortSignal
  768. Trade tS = openTrade(1, false, close, high)
  769. if not na(tS) and alShortInput
  770. alert(alertMsg("Short Setup | " + tradeText(tS)), alert.freq_once_per_bar_close)
  771. if bulltrapSignal
  772. Trade tBu = openTrade(2, false, close, high)
  773. if not na(tBu) and alBulltrapInput
  774. alert(alertMsg("Bulltrap Setup | " + tradeText(tBu)), alert.freq_once_per_bar_close)
  775. if beartrapSignal
  776. Trade tBe = openTrade(3, true, close, low)
  777. if not na(tBe) and alBeartrapInput
  778. alert(alertMsg("Beartrap Setup | " + tradeText(tBe)), alert.freq_once_per_bar_close)
  779.  
  780. color candleColor = colorMCInput and (bullMC or bearMC) ? mcColInput : colorAMCInput and (bullAMC or bearAMC) ? amcColInput : na
  781. barcolor(candleColor, title = "Manipulation Candles", editable = false)
  782.  
  783. if barstate.islast
  784. for ln in klLines
  785. line.delete(ln)
  786. klLines.clear()
  787. for lb in klLbls
  788. label.delete(lb)
  789. klLbls.clear()
  790.  
  791. int klX2 = time + KL_EXTEND_BARS * TF_MS
  792. string klSty = lineStyleOf(klStyleInput)
  793. string midSty = lineStyleOf(midStyleInput)
  794. array<float> lblPrices = array.new<float>()
  795. array<string> lblTexts = array.new<string>()
  796.  
  797. drawKeyLevel(showDOInput, dOpen, dTrk.openTime, klX2, "Daily Open", dailyColInput, klSty, lblPrices, lblTexts)
  798. drawKeyLevel(showPDInput, pdh, nz(dTrk.prevHiTime, dTrk.openTime), klX2, "PDH", dailyColInput, klSty, lblPrices, lblTexts)
  799. drawKeyLevel(showPDInput, pdl, nz(dTrk.prevLoTime, dTrk.openTime), klX2, "PDL", dailyColInput, klSty, lblPrices, lblTexts)
  800. drawKeyLevel(showWOInput, wOpen, wTrk.openTime, klX2, "Weekly Open", weeklyColInput, klSty, lblPrices, lblTexts)
  801. drawKeyLevel(showPWInput, pwh, nz(wTrk.prevHiTime, wTrk.openTime), klX2, "PWH", weeklyColInput, klSty, lblPrices, lblTexts)
  802. drawKeyLevel(showPWInput, pwl, nz(wTrk.prevLoTime, wTrk.openTime), klX2, "PWL", weeklyColInput, klSty, lblPrices, lblTexts)
  803. drawKeyLevel(showMOInput, mOpen, mTrk.openTime, klX2, "Monthly Open", monthlyColInput, klSty, lblPrices, lblTexts)
  804. drawKeyLevel(showPMInput, pmh, nz(mTrk.prevHiTime, mTrk.openTime), klX2, "PMH", monthlyColInput, klSty, lblPrices, lblTexts)
  805. drawKeyLevel(showPMInput, pml, nz(mTrk.prevLoTime, mTrk.openTime), klX2, "PML", monthlyColInput, klSty, lblPrices, lblTexts)
  806. drawKeyLevel(showMidInput, midnightOpen, midnightTime, klX2, "Midnight Open", midColInput, midSty, lblPrices, lblTexts)
  807.  
  808. if showKLLblInput
  809. for [j, p] in lblPrices
  810. klLbls.push(label.new(klX2, p, lblTexts.get(j), xloc = xloc.bar_time, style = label.style_label_left, color = CLEAR, textcolor = klLblColInput, size = size.small))
  811.  
  812. for bx in fvgBoxes
  813. box.delete(bx)
  814. fvgBoxes.clear()
  815. for ln in fvgMids
  816. line.delete(ln)
  817. fvgMids.clear()
  818. for lb in fvgLbls
  819. label.delete(lb)
  820. fvgLbls.clear()
  821.  
  822. array<float> fvgDist = array.new<float>()
  823. array<int> fvgIdx = array.new<int>()
  824. for [i, fz] in fvgs
  825. bool visTf = (fz.tfIdx == 1 and fvgShow1Input) or (fz.tfIdx == 2 and fvgShow2Input) or (fz.tfIdx == 3 and fvgShow3Input)
  826. if visTf
  827. float d = close > fz.top ? close - fz.top : close < fz.bottom ? fz.bottom - close : 0.0
  828. fvgDist.push(d)
  829. fvgIdx.push(i)
  830.  
  831. if fvgDist.size() > 0
  832. array<int> sortedIdx = fvgDist.sort_indices(order.ascending)
  833. int cnt = math.min(fvgLimitInput, sortedIdx.size())
  834. int fvgX2 = time + FVG_EXTEND_BARS * TF_MS
  835. string fvgLSz = sizeOf(fvgLblSizeInput)
  836. for k = 0 to cnt - 1
  837. FVG fd = fvgs.get(fvgIdx.get(sortedIdx.get(k)))
  838. color bg = fd.tfIdx == 1 ? (fd.isBull ? fvgBull1Input : fvgBear1Input) : fd.tfIdx == 2 ? (fd.isBull ? fvgBull2Input : fvgBear2Input) : (fd.isBull ? fvgBull3Input : fvgBear3Input)
  839. fvgBoxes.push(box.new(fd.startTime, fd.top, fvgX2, fd.bottom, xloc = xloc.bar_time, bgcolor = bg, border_color = CLEAR, border_width = 1))
  840. float mid = (fd.top + fd.bottom) / 2.0
  841. if fvgMidlineInput
  842. fvgMids.push(line.new(fd.startTime, mid, fvgX2, mid, xloc = xloc.bar_time, color = fvgMidColInput, style = line.style_dashed, width = 1))
  843. if fvgLabelsInput
  844. fvgLbls.push(label.new(fvgX2, mid, fd.tfLbl + (fd.isBull ? " Bullish FVG" : " Bearish FVG"), xloc = xloc.bar_time, style = label.style_label_right, color = CLEAR, textcolor = fvgLblColInput, size = fvgLSz))
  845.  
  846. var table dash = showDashInput ? table.new(position.top_right, 2, 5, bgcolor = dashBgInput, frame_color = dashFrameInput, frame_width = 1, border_color = dashBorderInput, border_width = 1) : na
  847.  
  848. if barstate.islast and showDashInput and not na(dash)
  849. array<bool> enabledArr = array.from(longSetupsInput, shortSetupsInput, bulltrapInput, beartrapInput)
  850. int row = 0
  851. int totalTrades = 0
  852. for k = 0 to 3
  853. if enabledArr.get(k)
  854. int w = winsArr.get(k)
  855. int l = lossArr.get(k)
  856. int tot = w + l
  857. float wr = tot > 0 ? 100.0 * w / tot : 0.0
  858. totalTrades += tot
  859. table.cell(dash, 0, row, KIND_NAMES.get(k) + " Winrate", text_color = dashTextInput, text_size = size.small, bgcolor = dashBgInput, text_halign = text.align_center)
  860. table.cell(dash, 1, row, str.tostring(wr, "0.00") + "%", text_color = dashTextInput, text_size = size.small, bgcolor = dashBgInput, text_halign = text.align_center)
  861. row += 1
  862. table.cell(dash, 0, row, "Total Trades", text_color = dashTextInput, text_size = size.small, bgcolor = dashBgInput, text_halign = text.align_center)
  863. table.cell(dash, 1, row, str.tostring(totalTrades), text_color = dashTextInput, text_size = size.small, bgcolor = dashBgInput, text_halign = text.align_center)
  864.  
  865. if barstate.isconfirmed
  866. if alMCInput and (bullMC or bearMC)
  867. alert(alertMsg((bullMC ? "Bullish" : "Bearish") + " Manipulation Candle"), alert.freq_once_per_bar_close)
  868. if alAMCInput and (bullAMC or bearAMC)
  869. alert(alertMsg((bullAMC ? "Bullish" : "Bearish") + " Almost Manipulation Candle"), alert.freq_once_per_bar_close)
  870.  
  871. if alPDInput
  872. if crossUp(pdh, prevClose)
  873. alert(alertMsg("Previous Day High Break"), alert.freq_once_per_bar_close)
  874. if crossDn(pdl, prevClose)
  875. alert(alertMsg("Previous Day Low Break"), alert.freq_once_per_bar_close)
  876. if alDOInput and (crossUp(dOpen, prevClose) or crossDn(dOpen, prevClose))
  877. alert(alertMsg("Current Day Open Break"), alert.freq_once_per_bar_close)
  878.  
  879. if alPWInput
  880. if crossUp(pwh, prevClose)
  881. alert(alertMsg("Previous Week High Break"), alert.freq_once_per_bar_close)
  882. if crossDn(pwl, prevClose)
  883. alert(alertMsg("Previous Week Low Break"), alert.freq_once_per_bar_close)
  884. if alWOInput and (crossUp(wOpen, prevClose) or crossDn(wOpen, prevClose))
  885. alert(alertMsg("Current Week Open Break"), alert.freq_once_per_bar_close)
  886.  
  887. if alPMInput
  888. if crossUp(pmh, prevClose)
  889. alert(alertMsg("Previous Month High Break"), alert.freq_once_per_bar_close)
  890. if crossDn(pml, prevClose)
  891. alert(alertMsg("Previous Month Low Break"), alert.freq_once_per_bar_close)
  892. if alMOInput and (crossUp(mOpen, prevClose) or crossDn(mOpen, prevClose))
  893. alert(alertMsg("Current Month Open Break"), alert.freq_once_per_bar_close)
  894.  
  895. for i = 0 to 5
  896. if sesAlertArr.get(i) and sesBreakArr.get(i)
  897. alert(alertMsg(sesBreakTxt.get(i)), alert.freq_once_per_bar_close)
  898.  
  899. if alMidInput and (crossUp(midnightOpen, prevClose) or crossDn(midnightOpen, prevClose))
  900. alert(alertMsg("Midnight Open Break"), alert.freq_once_per_bar_close)
Advertisement
Add Comment
Please, Sign In to add comment