1 //@version=5 2 indicator("Smart Money Concepts [LuxAlgo]", "Smart Money Concepts [LuxAlgo]" 3 , overlay = true 4 , max_labels_count = 500 5 , max_lines_count = 500 6 , max_boxes_count = 500 7 , max_bars_back = 500) 8 //-----------------------------------------------------------------------------{ 9 //Constants 10 //-----------------------------------------------------------------------------{ 11 color TRANSP_CSS = #ffffff00 12 13 //Tooltips 14 string MODE_TOOLTIP = 'Allows to display historical Structure or only the recent ones' 15 string STYLE_TOOLTIP = 'Indicator color theme' 16 string COLOR_CANDLES_TOOLTIP = 'Display additional candles with a color reflecting the current trend detected by structure' 17 string SHOW_INTERNAL = 'Display internal market structure' 18 string CONFLUENCE_FILTER = 'Filter non significant internal structure breakouts' 19 string SHOW_SWING = 'Display swing market Structure' 20 string SHOW_SWING_POINTS = 'Display swing point as labels on the chart' 21 string SHOW_SWHL_POINTS = 'Highlight most recent strong and weak high/low points on the chart' 22 string INTERNAL_OB = 'Display internal order blocks on the chart\n\nNumber of internal order blocks to display on the chart' 23 string SWING_OB = 'Display swing order blocks on the chart\n\nNumber of internal swing blocks to display on the chart' 24 string FILTER_OB = 'Method used to filter out volatile order blocks \n\nIt is recommended to use the cumulative mean range method when a low amount of data is available' 25 string SHOW_EQHL = 'Display equal highs and equal lows on the chart' 26 string EQHL_BARS = 'Number of bars used to confirm equal highs and equal lows' 27 string EQHL_THRESHOLD = 'Sensitivity threshold in a range (0, 1) used for the detection of equal highs & lows\n\nLower values will return fewer but more pertinent results' 28 string SHOW_FVG = 'Display fair values gaps on the chart' 29 string AUTO_FVG = 'Filter out non significant fair value gaps' 30 string FVG_TF = 'Fair value gaps timeframe' 31 string EXTEND_FVG = 'Determine how many bars to extend the Fair Value Gap boxes on chart' 32 string PED_ZONES = 'Display premium, discount, and equilibrium zones on chart' 33 34 //-----------------------------------------------------------------------------{ 35 //Settings 36 //-----------------------------------------------------------------------------{ 37 //General 38 //----------------------------------------{ 39 mode = input.string('Historical' 40 , options = ['Historical', 'Present'] 41 , group = 'Smart Money Concepts' 42 , tooltip = MODE_TOOLTIP) 43 44 style = input.string('Colored' 45 , options = ['Colored', 'Monochrome'] 46 , group = 'Smart Money Concepts' 47 , tooltip = STYLE_TOOLTIP) 48 49 show_trend = input(false, 'Color Candles' 50 , group = 'Smart Money Concepts' 51 , tooltip = COLOR_CANDLES_TOOLTIP) 52 53 //----------------------------------------} 54 //Internal Structure 55 //----------------------------------------{ 56 show_internals = input(true, 'Show Internal Structure' 57 , group = 'Real Time Internal Structure' 58 , tooltip = SHOW_INTERNAL) 59 60 show_ibull = input.string('All', 'Bullish Structure' 61 , options = ['All', 'BOS', 'CHoCH'] 62 , inline = 'ibull' 63 , group = 'Real Time Internal Structure') 64 65 swing_ibull_css = input(#089981, '' 66 , inline = 'ibull' 67 , group = 'Real Time Internal Structure') 68 69 //Bear Structure 70 show_ibear = input.string('All', 'Bearish Structure' 71 , options = ['All', 'BOS', 'CHoCH'] 72 , inline = 'ibear' 73 , group = 'Real Time Internal Structure') 74 75 swing_ibear_css = input(#f23645, '' 76 , inline = 'ibear' 77 , group = 'Real Time Internal Structure') 78 79 ifilter_confluence = input(false, 'Confluence Filter' 80 , group = 'Real Time Internal Structure' 81 , tooltip = CONFLUENCE_FILTER) 82 83 internal_structure_size = input.string('Tiny', 'Internal Label Size' 84 , options = ['Tiny', 'Small', 'Normal'] 85 , group = 'Real Time Internal Structure') 86 87 //----------------------------------------} 88 //Swing Structure 89 //----------------------------------------{ 90 show_Structure = input(true, 'Show Swing Structure' 91 , group = 'Real Time Swing Structure' 92 , tooltip = SHOW_SWING) 93 94 //Bull Structure 95 show_bull = input.string('All', 'Bullish Structure' 96 , options = ['All', 'BOS', 'CHoCH'] 97 , inline = 'bull' 98 , group = 'Real Time Swing Structure') 99 100 swing_bull_css = input(#089981, '' 101 , inline = 'bull' 102 , group = 'Real Time Swing Structure') 103 104 //Bear Structure 105 show_bear = input.string('All', 'Bearish Structure' 106 , options = ['All', 'BOS', 'CHoCH'] 107 , inline = 'bear' 108 , group = 'Real Time Swing Structure') 109 110 swing_bear_css = input(#f23645, '' 111 , inline = 'bear' 112 , group = 'Real Time Swing Structure') 113 114 swing_structure_size = input.string('Small', 'Swing Label Size' 115 , options = ['Tiny', 'Small', 'Normal'] 116 , group = 'Real Time Swing Structure') 117 118 //Swings 119 show_swings = input(false, 'Show Swings Points' 120 , inline = 'swings' 121 , group = 'Real Time Swing Structure' 122 , tooltip = SHOW_SWING_POINTS) 123 124 length = input.int(50, '' 125 , minval = 10 126 , inline = 'swings' 127 , group = 'Real Time Swing Structure') 128 129 show_hl_swings = input(true, 'Show Strong/Weak High/Low' 130 , group = 'Real Time Swing Structure' 131 , tooltip = SHOW_SWHL_POINTS) 132 133 //----------------------------------------} 134 //Order Blocks 135 //----------------------------------------{ 136 show_iob = input(true, 'Internal Order Blocks' 137 , inline = 'iob' 138 , group = 'Order Blocks' 139 , tooltip = INTERNAL_OB) 140 141 iob_showlast = input.int(5, '' 142 , minval = 1 143 , inline = 'iob' 144 , group = 'Order Blocks') 145 146 show_ob = input(false, 'Swing Order Blocks' 147 , inline = 'ob' 148 , group = 'Order Blocks' 149 , tooltip = SWING_OB) 150 151 ob_showlast = input.int(5, '' 152 , minval = 1 153 , inline = 'ob' 154 , group = 'Order Blocks') 155 156 ob_filter = input.string('Atr', 'Order Block Filter' 157 , options = ['Atr', 'Cumulative Mean Range'] 158 , group = 'Order Blocks' 159 , tooltip = FILTER_OB) 160 161 ibull_ob_css = input.color(color.new(#3179f5, 80), 'Internal Bullish OB' 162 , group = 'Order Blocks') 163 164 ibear_ob_css = input.color(color.new(#f77c80, 80), 'Internal Bearish OB' 165 , group = 'Order Blocks') 166 167 bull_ob_css = input.color(color.new(#1848cc, 80), 'Bullish OB' 168 , group = 'Order Blocks') 169 170 bear_ob_css = input.color(color.new(#b22833, 80), 'Bearish OB' 171 , group = 'Order Blocks') 172 173 //----------------------------------------} 174 //EQH/EQL 175 //----------------------------------------{ 176 show_eq = input(true, 'Equal High/Low' 177 , group = 'EQH/EQL' 178 , tooltip = SHOW_EQHL) 179 180 eq_len = input.int(3, 'Bars Confirmation' 181 , minval = 1 182 , group = 'EQH/EQL' 183 , tooltip = EQHL_BARS) 184 185 eq_threshold = input.float(0.1, 'Threshold' 186 , minval = 0 187 , maxval = 0.5 188 , step = 0.1 189 , group = 'EQH/EQL' 190 , tooltip = EQHL_THRESHOLD) 191 192 eq_size = input.string('Tiny', 'Label Size' 193 , options = ['Tiny', 'Small', 'Normal'] 194 , group = 'EQH/EQL') 195 196 //----------------------------------------} 197 //Fair Value Gaps 198 //----------------------------------------{ 199 show_fvg = input(false, 'Fair Value Gaps' 200 , group = 'Fair Value Gaps' 201 , tooltip = SHOW_FVG) 202 203 fvg_auto = input(true, "Auto Threshold" 204 , group = 'Fair Value Gaps' 205 , tooltip = AUTO_FVG) 206 207 fvg_tf = input.timeframe('', "Timeframe" 208 , group = 'Fair Value Gaps' 209 , tooltip = FVG_TF) 210 211 bull_fvg_css = input.color(color.new(#00ff68, 70), 'Bullish FVG' 212 , group = 'Fair Value Gaps') 213 214 bear_fvg_css = input.color(color.new(#ff0008, 70), 'Bearish FVG' 215 , group = 'Fair Value Gaps') 216 217 fvg_extend = input.int(1, "Extend FVG" 218 , minval = 0 219 , group = 'Fair Value Gaps' 220 , tooltip = EXTEND_FVG) 221 222 //----------------------------------------} 223 //Previous day/week high/low 224 //----------------------------------------{ 225 //Daily 226 show_pdhl = input(false, 'Daily' 227 , inline = 'daily' 228 , group = 'Highs & Lows MTF') 229 230 pdhl_style = input.string('⎯⎯⎯', '' 231 , options = ['⎯⎯⎯', '----', '····'] 232 , inline = 'daily' 233 , group = 'Highs & Lows MTF') 234 235 pdhl_css = input(#2157f3, '' 236 , inline = 'daily' 237 , group = 'Highs & Lows MTF') 238 239 //Weekly 240 show_pwhl = input(false, 'Weekly' 241 , inline = 'weekly' 242 , group = 'Highs & Lows MTF') 243 244 pwhl_style = input.string('⎯⎯⎯', '' 245 , options = ['⎯⎯⎯', '----', '····'] 246 , inline = 'weekly' 247 , group = 'Highs & Lows MTF') 248 249 pwhl_css = input(#2157f3, '' 250 , inline = 'weekly' 251 , group = 'Highs & Lows MTF') 252 253 //Monthly 254 show_pmhl = input(false, 'Monthly' 255 , inline = 'monthly' 256 , group = 'Highs & Lows MTF') 257 258 pmhl_style = input.string('⎯⎯⎯', '' 259 , options = ['⎯⎯⎯', '----', '····'] 260 , inline = 'monthly' 261 , group = 'Highs & Lows MTF') 262 263 pmhl_css = input(#2157f3, '' 264 , inline = 'monthly' 265 , group = 'Highs & Lows MTF') 266 267 //----------------------------------------} 268 //Premium/Discount zones 269 //----------------------------------------{ 270 show_sd = input(false, 'Premium/Discount Zones' 271 , group = 'Premium & Discount Zones' 272 , tooltip = PED_ZONES) 273 274 premium_css = input.color(#f23645, 'Premium Zone' 275 , group = 'Premium & Discount Zones') 276 277 eq_css = input.color(#b2b5be, 'Equilibrium Zone' 278 , group = 'Premium & Discount Zones') 279 280 discount_css = input.color(#089981, 'Discount Zone' 281 , group = 'Premium & Discount Zones') 282 283 //-----------------------------------------------------------------------------} 284 //Functions 285 //-----------------------------------------------------------------------------{ 286 n = bar_index 287 288 atr = ta.atr(200) 289 cmean_range = ta.cum(high - low) / n 290 291 //HL Output function 292 hl() => [high, low] 293 294 //Get ohlc values function 295 get_ohlc()=> [close[1], open[1], high, low, high[2], low[2]] 296 297 //Display Structure function 298 display_Structure(x, y, txt, css, dashed, down, lbl_size)=> 299 structure_line = line.new(x, y, n, y 300 , color = css 301 , style = dashed ? line.style_dashed : line.style_solid) 302 303 structure_lbl = label.new(int(math.avg(x, n)), y, txt 304 , color = TRANSP_CSS 305 , textcolor = css 306 , style = down ? label.style_label_down : label.style_label_up 307 , size = lbl_size) 308 309 if mode == 'Present' 310 line.delete(structure_line[1]) 311 label.delete(structure_lbl[1]) 312 313 //Swings detection/measurements 314 swings(len)=> 315 var os = 0 316 317 upper = ta.highest(len) 318 lower = ta.lowest(len) 319 320 os := high[len] > upper ? 0 : low[len] < lower ? 1 : os[1] 321 322 top = os == 0 and os[1] != 0 ? high[len] : 0 323 btm = os == 1 and os[1] != 1 ? low[len] : 0 324 325 [top, btm] 326 327 //Order block coordinates function 328 ob_coord(use_max, loc, target_top, target_btm, target_left, target_type)=> 329 min = 99999999. 330 max = 0. 331 idx = 1 332 333 ob_threshold = ob_filter == 'Atr' ? atr : cmean_range 334 335 //Search for highest/lowest high within the structure interval and get range 336 if use_max 337 for i = 1 to (n - loc)-1 338 if (high[i] - low[i]) < ob_threshold[i] * 2 339 max := math.max(high[i], max) 340 min := max == high[i] ? low[i] : min 341 idx := max == high[i] ? i : idx 342 else 343 for i = 1 to (n - loc)-1 344 if (high[i] - low[i]) < ob_threshold[i] * 2 345 min := math.min(low[i], min) 346 max := min == low[i] ? high[i] : max 347 idx := min == low[i] ? i : idx 348 349 array.unshift(target_top, max) 350 array.unshift(target_btm, min) 351 array.unshift(target_left, time[idx]) 352 array.unshift(target_type, use_max ? -1 : 1) 353 354 //Set order blocks 355 display_ob(boxes, target_top, target_btm, target_left, target_type, show_last, swing, size)=> 356 for i = 0 to math.min(show_last-1, size-1) 357 get_box = array.get(boxes, i) 358 359 box.set_lefttop(get_box, array.get(target_left, i), array.get(target_top, i)) 360 box.set_rightbottom(get_box, array.get(target_left, i), array.get(target_btm, i)) 361 box.set_extend(get_box, extend.right) 362 363 color css = na 364 365 if swing 366 if style == 'Monochrome' 367 css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80) 368 border_css = array.get(target_type, i) == 1 ? #b2b5be : #5d606b 369 box.set_border_color(get_box, border_css) 370 else 371 css := array.get(target_type, i) == 1 ? bull_ob_css : bear_ob_css 372 box.set_border_color(get_box, css) 373 374 box.set_bgcolor(get_box, css) 375 else 376 if style == 'Monochrome' 377 css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80) 378 else 379 css := array.get(target_type, i) == 1 ? ibull_ob_css : ibear_ob_css 380 381 box.set_border_color(get_box, css) 382 box.set_bgcolor(get_box, css) 383 384 //Line Style function 385 get_line_style(style) => 386 out = switch style 387 '⎯⎯⎯' => line.style_solid 388 '----' => line.style_dashed 389 '····' => line.style_dotted 390 391 //Set line/labels function for previous high/lows 392 phl(h, l, tf, css)=> 393 var line high_line = line.new(na,na,na,na 394 , xloc = xloc.bar_time 395 , color = css 396 , style = get_line_style(pdhl_style)) 397 398 var label high_lbl = label.new(na,na 399 , xloc = xloc.bar_time 400 , text = str.format('P{0}H', tf) 401 , color = TRANSP_CSS 402 , textcolor = css 403 , size = size.small 404 , style = label.style_label_left) 405 406 var line low_line = line.new(na,na,na,na 407 , xloc = xloc.bar_time 408 , color = css 409 , style = get_line_style(pdhl_style)) 410 411 var label low_lbl = label.new(na,na 412 , xloc = xloc.bar_time 413 , text = str.format('P{0}L', tf) 414 , color = TRANSP_CSS 415 , textcolor = css 416 , size = size.small 417 , style = label.style_label_left) 418 419 hy = ta.valuewhen(h != h[1], h, 1) 420 hx = ta.valuewhen(h == high, time, 1) 421 422 ly = ta.valuewhen(l != l[1], l, 1) 423 lx = ta.valuewhen(l == low, time, 1) 424 425 if barstate.islast 426 ext = time + (time - time[1])*20 427 428 //High 429 line.set_xy1(high_line, hx, hy) 430 line.set_xy2(high_line, ext, hy) 431 432 label.set_xy(high_lbl, ext, hy) 433 434 //Low 435 line.set_xy1(low_line, lx, ly) 436 line.set_xy2(low_line, ext, ly) 437 438 label.set_xy(low_lbl, ext, ly) 439 440 //-----------------------------------------------------------------------------} 441 //Global variables 442 //-----------------------------------------------------------------------------{ 443 var trend = 0, var itrend = 0 444 445 var top_y = 0., var top_x = 0 446 var btm_y = 0., var btm_x = 0 447 448 var itop_y = 0., var itop_x = 0 449 var ibtm_y = 0., var ibtm_x = 0 450 451 var trail_up = high, var trail_dn = low 452 var trail_up_x = 0, var trail_dn_x = 0 453 454 var top_cross = true, var btm_cross = true 455 var itop_cross = true, var ibtm_cross = true 456 457 var txt_top = '', var txt_btm = '' 458 459 //Alerts 460 bull_choch_alert = false 461 bull_bos_alert = false 462 463 bear_choch_alert = false 464 bear_bos_alert = false 465 466 bull_ichoch_alert = false 467 bull_ibos_alert = false 468 469 bear_ichoch_alert = false 470 bear_ibos_alert = false 471 472 bull_iob_break = false 473 bear_iob_break = false 474 475 bull_ob_break = false 476 bear_ob_break = false 477 478 eqh_alert = false 479 eql_alert = false 480 481 //Structure colors 482 var bull_css = style == 'Monochrome' ? #b2b5be 483 : swing_bull_css 484 485 var bear_css = style == 'Monochrome' ? #b2b5be 486 : swing_bear_css 487 488 var ibull_css = style == 'Monochrome' ? #b2b5be 489 : swing_ibull_css 490 491 var ibear_css = style == 'Monochrome' ? #b2b5be 492 : swing_ibear_css 493 494 //Labels size 495 var internal_structure_lbl_size = internal_structure_size == 'Tiny' 496 ? size.tiny 497 : internal_structure_size == 'Small' 498 ? size.small 499 : size.normal 500 501 var swing_structure_lbl_size = swing_structure_size == 'Tiny' 502 ? size.tiny 503 : swing_structure_size == 'Small' 504 ? size.small 505 : size.normal 506 507 var eqhl_lbl_size = eq_size == 'Tiny' 508 ? size.tiny 509 : eq_size == 'Small' 510 ? size.small 511 : size.normal 512 513 //Swings 514 [top, btm] = swings(length) 515 516 [itop, ibtm] = swings(5) 517 518 //-----------------------------------------------------------------------------} 519 //Pivot High 520 //-----------------------------------------------------------------------------{ 521 var line extend_top = na 522 523 var label extend_top_lbl = label.new(na, na 524 , color = TRANSP_CSS 525 , textcolor = bear_css 526 , style = label.style_label_down 527 , size = size.tiny) 528 529 if top 530 top_cross := true 531 txt_top := top > top_y ? 'HH' : 'LH' 532 533 if show_swings 534 top_lbl = label.new(n-length, top, txt_top 535 , color = TRANSP_CSS 536 , textcolor = bear_css 537 , style = label.style_label_down 538 , size = swing_structure_lbl_size) 539 540 if mode == 'Present' 541 label.delete(top_lbl[1]) 542 543 //Extend recent top to last bar 544 line.delete(extend_top[1]) 545 extend_top := line.new(n-length, top, n, top 546 , color = bear_css) 547 548 top_y := top 549 top_x := n - length 550 551 trail_up := top 552 trail_up_x := n - length 553 554 if itop 555 itop_cross := true 556 557 itop_y := itop 558 itop_x := n - 5 559 560 //Trailing maximum 561 trail_up := math.max(high, trail_up) 562 trail_up_x := trail_up == high ? n : trail_up_x 563 564 //Set top extension label/line 565 if barstate.islast and show_hl_swings 566 line.set_xy1(extend_top, trail_up_x, trail_up) 567 line.set_xy2(extend_top, n + 20, trail_up) 568 569 label.set_x(extend_top_lbl, n + 20) 570 label.set_y(extend_top_lbl, trail_up) 571 label.set_text(extend_top_lbl, trend < 0 ? 'Strong High' : 'Weak High') 572 573 //-----------------------------------------------------------------------------} 574 //Pivot Low 575 //-----------------------------------------------------------------------------{ 576 var line extend_btm = na 577 578 var label extend_btm_lbl = label.new(na, na 579 , color = TRANSP_CSS 580 , textcolor = bull_css 581 , style = label.style_label_up 582 , size = size.tiny) 583 584 if btm 585 btm_cross := true 586 txt_btm := btm < btm_y ? 'LL' : 'HL' 587 588 if show_swings 589 btm_lbl = label.new(n - length, btm, txt_btm 590 , color = TRANSP_CSS 591 , textcolor = bull_css 592 , style = label.style_label_up 593 , size = swing_structure_lbl_size) 594 595 if mode == 'Present' 596 label.delete(btm_lbl[1]) 597 598 //Extend recent btm to last bar 599 line.delete(extend_btm[1]) 600 extend_btm := line.new(n - length, btm, n, btm 601 , color = bull_css) 602 603 btm_y := btm 604 btm_x := n-length 605 606 trail_dn := btm 607 trail_dn_x := n-length 608 609 if ibtm 610 ibtm_cross := true 611 612 ibtm_y := ibtm 613 ibtm_x := n - 5 614 615 //Trailing minimum 616 trail_dn := math.min(low, trail_dn) 617 trail_dn_x := trail_dn == low ? n : trail_dn_x 618 619 //Set btm extension label/line 620 if barstate.islast and show_hl_swings 621 line.set_xy1(extend_btm, trail_dn_x, trail_dn) 622 line.set_xy2(extend_btm, n + 20, trail_dn) 623 624 label.set_x(extend_btm_lbl, n + 20) 625 label.set_y(extend_btm_lbl, trail_dn) 626 label.set_text(extend_btm_lbl, trend > 0 ? 'Strong Low' : 'Weak Low') 627 628 //-----------------------------------------------------------------------------} 629 //Order Blocks Arrays 630 //-----------------------------------------------------------------------------{ 631 var iob_top = array.new_float(0) 632 var iob_btm = array.new_float(0) 633 var iob_left = array.new_int(0) 634 var iob_type = array.new_int(0) 635 636 var ob_top = array.new_float(0) 637 var ob_btm = array.new_float(0) 638 var ob_left = array.new_int(0) 639 var ob_type = array.new_int(0) 640 641 //-----------------------------------------------------------------------------} 642 //Pivot High BOS/CHoCH 643 //-----------------------------------------------------------------------------{ 644 //Filtering 645 var bull_concordant = true 646 647 if ifilter_confluence 648 bull_concordant := high - math.max(close, open) > math.min(close, open - low) 649 650 //Detect internal bullish Structure 651 if ta.crossover(close, itop_y) and itop_cross and top_y != itop_y and bull_concordant 652 bool choch = na 653 654 if itrend < 0 655 choch := true 656 bull_ichoch_alert := true 657 else 658 bull_ibos_alert := true 659 660 txt = choch ? 'CHoCH' : 'BOS' 661 662 if show_internals 663 if show_ibull == 'All' or (show_ibull == 'BOS' and not choch) or (show_ibull == 'CHoCH' and choch) 664 display_Structure(itop_x, itop_y, txt, ibull_css, true, true, internal_structure_lbl_size) 665 666 itop_cross := false 667 itrend := 1 668 669 //Internal Order Block 670 if show_iob 671 ob_coord(false, itop_x, iob_top, iob_btm, iob_left, iob_type) 672 673 //Detect bullish Structure 674 if ta.crossover(close, top_y) and top_cross 675 bool choch = na 676 677 if trend < 0 678 choch := true 679 bull_choch_alert := true 680 else 681 bull_bos_alert := true 682 683 txt = choch ? 'CHoCH' : 'BOS' 684 685 if show_Structure 686 if show_bull == 'All' or (show_bull == 'BOS' and not choch) or (show_bull == 'CHoCH' and choch) 687 display_Structure(top_x, top_y, txt, bull_css, false, true, swing_structure_lbl_size) 688 689 //Order Block 690 if show_ob 691 ob_coord(false, top_x, ob_top, ob_btm, ob_left, ob_type) 692 693 top_cross := false 694 trend := 1 695 696 //-----------------------------------------------------------------------------} 697 //Pivot Low BOS/CHoCH 698 //-----------------------------------------------------------------------------{ 699 var bear_concordant = true 700 701 if ifilter_confluence 702 bear_concordant := high - math.max(close, open) < math.min(close, open - low) 703 704 //Detect internal bearish Structure 705 if ta.crossunder(close, ibtm_y) and ibtm_cross and btm_y != ibtm_y and bear_concordant 706 bool choch = false 707 708 if itrend > 0 709 choch := true 710 bear_ichoch_alert := true 711 else 712 bear_ibos_alert := true 713 714 txt = choch ? 'CHoCH' : 'BOS' 715 716 if show_internals 717 if show_ibear == 'All' or (show_ibear == 'BOS' and not choch) or (show_ibear == 'CHoCH' and choch) 718 display_Structure(ibtm_x, ibtm_y, txt, ibear_css, true, false, internal_structure_lbl_size) 719 720 ibtm_cross := false 721 itrend := -1 722 723 //Internal Order Block 724 if show_iob 725 ob_coord(true, ibtm_x, iob_top, iob_btm, iob_left, iob_type) 726 727 //Detect bearish Structure 728 if ta.crossunder(close, btm_y) and btm_cross 729 bool choch = na 730 731 if trend > 0 732 choch := true 733 bear_choch_alert := true 734 else 735 bear_bos_alert := true 736 737 txt = choch ? 'CHoCH' : 'BOS' 738 739 if show_Structure 740 if show_bear == 'All' or (show_bear == 'BOS' and not choch) or (show_bear == 'CHoCH' and choch) 741 display_Structure(btm_x, btm_y, txt, bear_css, false, false, swing_structure_lbl_size) 742 743 //Order Block 744 if show_ob 745 ob_coord(true, btm_x, ob_top, ob_btm, ob_left, ob_type) 746 747 btm_cross := false 748 trend := -1 749 750 //-----------------------------------------------------------------------------} 751 //Order Blocks 752 //-----------------------------------------------------------------------------{ 753 //Set order blocks 754 var iob_boxes = array.new_box(0) 755 var ob_boxes = array.new_box(0) 756 757 //Delete internal order blocks box coordinates if top/bottom is broken 758 for element in iob_type 759 index = array.indexof(iob_type, element) 760 761 if close < array.get(iob_btm, index) and element == 1 762 array.remove(iob_top, index) 763 array.remove(iob_btm, index) 764 array.remove(iob_left, index) 765 array.remove(iob_type, index) 766 bull_iob_break := true 767 768 else if close > array.get(iob_top, index) and element == -1 769 array.remove(iob_top, index) 770 array.remove(iob_btm, index) 771 array.remove(iob_left, index) 772 array.remove(iob_type, index) 773 bear_iob_break := true 774 775 //Delete internal order blocks box coordinates if top/bottom is broken 776 for element in ob_type 777 index = array.indexof(ob_type, element) 778 779 if close < array.get(ob_btm, index) and element == 1 780 array.remove(ob_top, index) 781 array.remove(ob_btm, index) 782 array.remove(ob_left, index) 783 array.remove(ob_type, index) 784 bull_ob_break := true 785 786 else if close > array.get(ob_top, index) and element == -1 787 array.remove(ob_top, index) 788 array.remove(ob_btm, index) 789 array.remove(ob_left, index) 790 array.remove(ob_type, index) 791 bear_ob_break := true 792 793 iob_size = array.size(iob_type) 794 ob_size = array.size(ob_type) 795 796 if barstate.isfirst 797 if show_iob 798 for i = 0 to iob_showlast-1 799 array.push(iob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time)) 800 if show_ob 801 for i = 0 to ob_showlast-1 802 array.push(ob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time)) 803 804 if iob_size > 0 805 if barstate.islast 806 display_ob(iob_boxes, iob_top, iob_btm, iob_left, iob_type, iob_showlast, false, iob_size) 807 808 if ob_size > 0 809 if barstate.islast 810 display_ob(ob_boxes, ob_top, ob_btm, ob_left, ob_type, ob_showlast, true, ob_size) 811 812 //-----------------------------------------------------------------------------} 813 //EQH/EQL 814 //-----------------------------------------------------------------------------{ 815 var eq_prev_top = 0. 816 var eq_top_x = 0 817 818 var eq_prev_btm = 0. 819 var eq_btm_x = 0 820 821 if show_eq 822 eq_top = ta.pivothigh(eq_len, eq_len) 823 eq_btm = ta.pivotlow(eq_len, eq_len) 824 825 if eq_top 826 max = math.max(eq_top, eq_prev_top) 827 min = math.min(eq_top, eq_prev_top) 828 829 if max < min + atr * eq_threshold 830 eqh_line = line.new(eq_top_x, eq_prev_top, n-eq_len, eq_top 831 , color = bear_css 832 , style = line.style_dotted) 833 834 eqh_lbl = label.new(int(math.avg(n-eq_len, eq_top_x)), eq_top, 'EQH' 835 , color = #00000000 836 , textcolor = bear_css 837 , style = label.style_label_down 838 , size = eqhl_lbl_size) 839 840 if mode == 'Present' 841 line.delete(eqh_line[1]) 842 label.delete(eqh_lbl[1]) 843 844 eqh_alert := true 845 846 eq_prev_top := eq_top 847 eq_top_x := n-eq_len 848 849 if eq_btm 850 max = math.max(eq_btm, eq_prev_btm) 851 min = math.min(eq_btm, eq_prev_btm) 852 853 if min > max - atr * eq_threshold 854 eql_line = line.new(eq_btm_x, eq_prev_btm, n-eq_len, eq_btm 855 , color = bull_css 856 , style = line.style_dotted) 857 858 eql_lbl = label.new(int(math.avg(n-eq_len, eq_btm_x)), eq_btm, 'EQL' 859 , color = #00000000 860 , textcolor = bull_css 861 , style = label.style_label_up 862 , size = eqhl_lbl_size) 863 864 eql_alert := true 865 866 if mode == 'Present' 867 line.delete(eql_line[1]) 868 label.delete(eql_lbl[1]) 869 870 eq_prev_btm := eq_btm 871 eq_btm_x := n-eq_len 872 873 //-----------------------------------------------------------------------------} 874 //Fair Value Gaps 875 //-----------------------------------------------------------------------------{ 876 var bullish_fvg_max = array.new_box(0) 877 var bullish_fvg_min = array.new_box(0) 878 879 var bearish_fvg_max = array.new_box(0) 880 var bearish_fvg_min = array.new_box(0) 881 882 float bullish_fvg_avg = na 883 float bearish_fvg_avg = na 884 885 bullish_fvg_cnd = false 886 bearish_fvg_cnd = false 887 888 [src_c1, src_o1, src_h, src_l, src_h2, src_l2] = 889 request.security(syminfo.tickerid, fvg_tf, get_ohlc()) 890 891 if show_fvg 892 delta_per = (src_c1 - src_o1) / src_o1 * 100 893 894 change_tf = timeframe.change(fvg_tf) 895 896 threshold = fvg_auto ? ta.cum(math.abs(change_tf ? delta_per : 0)) / n * 2 897 : 0 898 899 //FVG conditions 900 bullish_fvg_cnd := src_l > src_h2 901 and src_c1 > src_h2 902 and delta_per > threshold 903 and change_tf 904 905 bearish_fvg_cnd := src_h < src_l2 906 and src_c1 < src_l2 907 and -delta_per > threshold 908 and change_tf 909 910 //FVG Areas 911 if bullish_fvg_cnd 912 array.unshift(bullish_fvg_max, box.new(n-1, src_l, n + fvg_extend, math.avg(src_l, src_h2) 913 , border_color = bull_fvg_css 914 , bgcolor = bull_fvg_css)) 915 916 array.unshift(bullish_fvg_min, box.new(n-1, math.avg(src_l, src_h2), n + fvg_extend, src_h2 917 , border_color = bull_fvg_css 918 , bgcolor = bull_fvg_css)) 919 920 if bearish_fvg_cnd 921 array.unshift(bearish_fvg_max, box.new(n-1, src_h, n + fvg_extend, math.avg(src_h, src_l2) 922 , border_color = bear_fvg_css 923 , bgcolor = bear_fvg_css)) 924 925 array.unshift(bearish_fvg_min, box.new(n-1, math.avg(src_h, src_l2), n + fvg_extend, src_l2 926 , border_color = bear_fvg_css 927 , bgcolor = bear_fvg_css)) 928 929 for bx in bullish_fvg_min 930 if low < box.get_bottom(bx) 931 box.delete(bx) 932 box.delete(array.get(bullish_fvg_max, array.indexof(bullish_fvg_min, bx))) 933 934 for bx in bearish_fvg_max 935 if high > box.get_top(bx) 936 box.delete(bx) 937 box.delete(array.get(bearish_fvg_min, array.indexof(bearish_fvg_max, bx))) 938 939 //-----------------------------------------------------------------------------} 940 //Previous day/week high/lows 941 //-----------------------------------------------------------------------------{ 942 //Daily high/low 943 [pdh, pdl] = request.security(syminfo.tickerid, 'D', hl() 944 , lookahead = barmerge.lookahead_on) 945 946 //Weekly high/low 947 [pwh, pwl] = request.security(syminfo.tickerid, 'W', hl() 948 , lookahead = barmerge.lookahead_on) 949 950 //Monthly high/low 951 [pmh, pml] = request.security(syminfo.tickerid, 'M', hl() 952 , lookahead = barmerge.lookahead_on) 953 954 //Display Daily 955 if show_pdhl 956 phl(pdh, pdl, 'D', pdhl_css) 957 958 //Display Weekly 959 if show_pwhl 960 phl(pwh, pwl, 'W', pwhl_css) 961 962 //Display Monthly 963 if show_pmhl 964 phl(pmh, pml, 'M', pmhl_css) 965 966 //-----------------------------------------------------------------------------} 967 //Premium/Discount/Equilibrium zones 968 //-----------------------------------------------------------------------------{ 969 var premium = box.new(na, na, na, na 970 , bgcolor = color.new(premium_css, 80) 971 , border_color = na) 972 973 var premium_lbl = label.new(na, na 974 , text = 'Premium' 975 , color = TRANSP_CSS 976 , textcolor = premium_css 977 , style = label.style_label_down 978 , size = size.small) 979 980 var eq = box.new(na, na, na, na 981 , bgcolor = color.rgb(120, 123, 134, 80) 982 , border_color = na) 983 984 var eq_lbl = label.new(na, na 985 , text = 'Equilibrium' 986 , color = TRANSP_CSS 987 , textcolor = eq_css 988 , style = label.style_label_left 989 , size = size.small) 990 991 var discount = box.new(na, na, na, na 992 , bgcolor = color.new(discount_css, 80) 993 , border_color = na) 994 995 var discount_lbl = label.new(na, na 996 , text = 'Discount' 997 , color = TRANSP_CSS 998 , textcolor = discount_css 999 , style = label.style_label_up 1000 , size = size.small) 1001 1002 //Show Premium/Discount Areas 1003 if barstate.islast and show_sd 1004 avg = math.avg(trail_up, trail_dn) 1005 1006 box.set_lefttop(premium, math.max(top_x, btm_x), trail_up) 1007 box.set_rightbottom(premium, n, .95 * trail_up + .05 * trail_dn) 1008 1009 label.set_xy(premium_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_up) 1010 1011 box.set_lefttop(eq, math.max(top_x, btm_x), .525 * trail_up + .475*trail_dn) 1012 box.set_rightbottom(eq, n, .525 * trail_dn + .475 * trail_up) 1013 1014 label.set_xy(eq_lbl, n, avg) 1015 1016 box.set_lefttop(discount, math.max(top_x, btm_x), .95 * trail_dn + .05 * trail_up) 1017 box.set_rightbottom(discount, n, trail_dn) 1018 label.set_xy(discount_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_dn) 1019 1020 //-----------------------------------------------------------------------------} 1021 //Trend 1022 //-----------------------------------------------------------------------------{ 1023 var color trend_css = na 1024 1025 if show_trend 1026 if style == 'Colored' 1027 trend_css := itrend == 1 ? bull_css : bear_css 1028 else if style == 'Monochrome' 1029 trend_css := itrend == 1 ? #b2b5be : #5d606b 1030 1031 plotcandle(open, high, low, close 1032 , color = trend_css 1033 , wickcolor = trend_css 1034 , bordercolor = trend_css 1035 , editable = false) 1036 1037 //-----------------------------------------------------------------------------} 1038 //Alerts 1039 //-----------------------------------------------------------------------------{ 1040 //Internal Structure 1041 alertcondition(bull_ibos_alert, 'Internal Bullish BOS', 'Internal Bullish BOS formed') 1042 alertcondition(bull_ichoch_alert, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH formed') 1043 1044 alertcondition(bear_ibos_alert, 'Internal Bearish BOS', 'Internal Bearish BOS formed') 1045 alertcondition(bear_ichoch_alert, 'Internal Bearish CHoCH', 'Internal Bearish CHoCH formed') 1046 1047 //Swing Structure 1048 alertcondition(bull_bos_alert, 'Bullish BOS', 'Internal Bullish BOS formed') 1049 alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed') 1050 1051 alertcondition(bear_bos_alert, 'Bearish BOS', 'Bearish BOS formed') 1052 alertcondition(bear_choch_alert, 'Bearish CHoCH', 'Bearish CHoCH formed') 1053 1054 //order Blocks 1055 alertcondition(bull_iob_break, 'Bullish Internal OB Breakout', 'Price broke bullish internal OB') 1056 alertcondition(bear_iob_break, 'Bearish Internal OB Breakout', 'Price broke bearish internal OB') 1057 1058 alertcondition(bull_ob_break, 'Bullish Swing OB Breakout', 'Price broke bullish swing OB') 1059 alertcondition(bear_ob_break, 'Bearish Swing OB Breakout', 'Price broke bearish swing OB') 1060 1061 //EQH/EQL 1062 alertcondition(eqh_alert, 'Equal Highs', 'Equal highs detected') 1063 alertcondition(eql_alert, 'Equal Lows', 'Equal lows detected') 1064 1065 //FVG 1066 alertcondition(bullish_fvg_cnd, 'Bullish FVG', 'Bullish FVG formed') 1067 alertcondition(bearish_fvg_cnd, 'Bearish FVG', 'Bearish FVG formed') 1068 1069 //-----------------------------------------------------------------------------} 1070