OrderBlockIncyte CorporationBATS:INCYvnaresh2711// ================================================================================ // ORDER BLOCK DETECTOR V3 - STRICT 4-RULE VALIDATION (FIXED) // ================================================================================ // Based on: "Order Blocks — 4 Rules That Separate Real Ones From Fake Ones" // // RULE 1: Liquidity Sweep (MANDATORY) // RULE 2: FVG/Imbalance (3rd wick check) // RULE 3: Unmitigated // RULE 4: Break of Structure + Inducement // ================================================================================ //@version=5 indicator("Order Blocks V3 - 4 Rules", overlay=true, max_boxes_count=500, max_lines_count=500, max_labels_count=500) // ============================================================================= // INPUTS // ============================================================================= grp_main = "Main Settings" swing_length = input.int(5, "Swing Detection Length", minval=2, maxval=20, group=grp_main) min_move_pct = input.float(0.8, "Min Move After OB (%)", minval=0.1, step=0.1, group=grp_main) max_ob_display = input.int(50, "Max OB History Bars", minval=10, maxval=200, group=grp_main) grp_fvg = "FVG Settings" min_fvg_pct = input.float(0.2, "Min FVG Size (%)", minval=0.05, step=0.05, group=grp_fvg) show_fvg = input.bool(true, "Show FVG Zones", group=grp_fvg) grp_filter = "Quality Filter" min_rules = input.int(2, "Min Rules to Pass", minval=1, maxval=4, group=grp_filter) show_mitigated = input.bool(false, "Show Mitigated OBs", group=grp_filter) grp_visual = "Visual Settings" bull_ob_color = input.color(color.new(color.green, 75), "Bullish OB Color", group=grp_visual) bear_ob_color = input.color(color.new(color.red, 75), "Bearish OB Color", group=grp_visual) bull_fvg_color = input.color(color.new(color.teal, 85), "Bullish FVG Color", group=grp_visual) bear_fvg_color = input.color(color.new(color.maroon, 85), "Bearish FVG Color", group=grp_visual) entry_line_color = input.color(color.new(color.yellow, 30), "50% Entry Line", group=grp_visual) mitig_color = input.color(color.new(color.gray, 85), "Mitigated Color", group=grp_visual) show_labels = input.bool(true, "Show Labels", group=grp_visual) show_50pct_line = input.bool(true, "Show 50% Entry Level", group=grp_visual) show_bos_marker = input.bool(true, "Show BOS Markers", group=grp_visual) show_inducement = input.bool(true, "Show Inducement Markers", group=grp_visual) // ============================================================================= // SWING HIGH/LOW DETECTION // ============================================================================= swingHigh = ta.pivothigh(high, swing_length, swing_length) swingLow = ta.pivotlow(low, swing_length, swing_length) var float lastSwingHigh = na var float lastSwingLow = na var int lastSwingHighBar = na var int lastSwingLowBar = na if not na(swingHigh) lastSwingHigh := swingHigh lastSwingHighBar := bar_index - swing_length if not na(swingLow) lastSwingLow := swingLow lastSwingLowBar := bar_index - swing_length // ============================================================================= // RULE 1: LIQUIDITY SWEEP DETECTION // ============================================================================= bullishLiqSweep = low < low bearishLiqSweep = high > high // ============================================================================= // RULE 2: FVG DETECTION WITH 3RD CANDLE WICK CHECK // ============================================================================= bullFVG_gap = low - high bullFVG_exists = bullFVG_gap > 0 bullFVG_size_pct = bullFVG_exists ? (bullFVG_gap / close) * 100 : 0.0 bullFVG_valid = bullFVG_size_pct >= min_fvg_pct bullFVG_3rdWickTapped = low 0 bearFVG_size_pct = bearFVG_exists ? (bearFVG_gap / close) * 100 : 0.0 bearFVG_valid = bearFVG_size_pct >= min_fvg_pct bearFVG_3rdWickTapped = high >= low // ============================================================================= // RULE 4: BREAK OF STRUCTURE DETECTION // ============================================================================= bullishBOS = high > lastSwingHigh and not na(lastSwingHigh) and bar_index - lastSwingHighBar < max_ob_display bearishBOS = low < lastSwingLow and not na(lastSwingLow) and bar_index - lastSwingLowBar < max_ob_display // ============================================================================= // INDUCEMENT DETECTION // ============================================================================= bullishInducement = high > high and close < high bearishInducement = low < low and close > low // ============================================================================= // ORDER BLOCK DATA TYPE // ============================================================================= type OrderBlockData float top float bottom float entry50 int barIdx bool isBullish bool mitigated int rule1 int rule2 int rule3 int rule4 bool hasFVG bool fvgTapped bool hasInducement box obBox line entryLine label obLabel var OrderBlockData orderBlocks = array.new() // ============================================================================= // STRONG MOVE DETECTION // ============================================================================= strongBullMove = (close - close) / close * 100 > min_move_pct strongBearMove = (close - close) / close * 100 > min_move_pct // ============================================================================= // BULLISH ORDER BLOCK DETECTION // ============================================================================= potentialBullOB = bullishLiqSweep and strongBullMove bull_r1 = potentialBullOB ? 1 : 0 bull_r2 = bullFVG_valid and not bullFVG_3rdWickTapped ? 1 : 0 bull_r3 = 1 bull_r4 = bullishBOS ? 1 : 0 bull_hasInducement = bullishInducement or bullishInducement or bullishInducement bull_total_rules = bull_r1 + bull_r2 + bull_r3 + bull_r4 bull_valid = bull_r1 == 1 and bull_total_rules >= min_rules if potentialBullOB and bull_valid ob = OrderBlockData.new() ob.top := high ob.bottom := low ob.entry50 := (high + low) / 2 ob.barIdx := bar_index - 2 ob.isBullish := true ob.mitigated := false ob.rule1 := bull_r1 ob.rule2 := bull_r2 ob.rule3 := bull_r3 ob.rule4 := bull_r4 ob.hasFVG := bullFVG_valid ob.fvgTapped := bullFVG_3rdWickTapped ob.hasInducement := bull_hasInducement ob.obBox := box.new(bar_index - 2, ob.top, bar_index + max_ob_display, ob.bottom, bgcolor=bull_ob_color, border_color=color.green, border_width=1, extend=extend.right) if show_50pct_line ob.entryLine := line.new(bar_index - 2, ob.entry50, bar_index + max_ob_display, ob.entry50, color=entry_line_color, style=line.style_dashed, width=1, extend=extend.right) if show_labels rulesText = "R1:" + (bull_r1==1?"✓":"✗") + " R2:" + (bull_r2==1?"✓":"✗") + " R3:✓ R4:" + (bull_r4==1?"✓":"✗") labelText = "🟢 BULL OB\n" + rulesText if ob.hasInducement labelText := labelText + "\n⚡Induce" if ob.fvgTapped labelText := labelText + "\n⚠️FVG Tap" ob.obLabel := label.new(bar_index - 2, ob.top, labelText, style=label.style_label_down, color=color.new(color.green, 30), textcolor=color.white, size=size.tiny) array.push(orderBlocks, ob) // ============================================================================= // BEARISH ORDER BLOCK DETECTION // ============================================================================= potentialBearOB = bearishLiqSweep and strongBearMove bear_r1 = potentialBearOB ? 1 : 0 bear_r2 = bearFVG_valid and not bearFVG_3rdWickTapped ? 1 : 0 bear_r3 = 1 bear_r4 = bearishBOS ? 1 : 0 bear_hasInducement = bearishInducement or bearishInducement or bearishInducement bear_total_rules = bear_r1 + bear_r2 + bear_r3 + bear_r4 bear_valid = bear_r1 == 1 and bear_total_rules >= min_rules if potentialBearOB and bear_valid ob = OrderBlockData.new() ob.top := high ob.bottom := low ob.entry50 := (high + low) / 2 ob.barIdx := bar_index - 2 ob.isBullish := false ob.mitigated := false ob.rule1 := bear_r1 ob.rule2 := bear_r2 ob.rule3 := bear_r3 ob.rule4 := bear_r4 ob.hasFVG := bearFVG_valid ob.fvgTapped := bearFVG_3rdWickTapped ob.hasInducement := bear_hasInducement ob.obBox := box.new(bar_index - 2, ob.top, bar_index + max_ob_display, ob.bottom, bgcolor=bear_ob_color, border_color=color.red, border_width=1, extend=extend.right) if show_50pct_line ob.entryLine := line.new(bar_index - 2, ob.entry50, bar_index + max_ob_display, ob.entry50, color=entry_line_color, style=line.style_dashed, width=1, extend=extend.right) if show_labels rulesText = "R1:" + (bear_r1==1?"✓":"✗") + " R2:" + (bear_r2==1?"✓":"✗") + " R3:✓ R4:" + (bear_r4==1?"✓":"✗") labelText = "🔴 BEAR OB\n" + rulesText if ob.hasInducement labelText := labelText + "\n⚡Induce" if ob.fvgTapped labelText := labelText + "\n⚠️FVG Tap" ob.obLabel := label.new(bar_index - 2, ob.bottom, labelText, style=label.style_label_up, color=color.new(color.red, 30), textcolor=color.white, size=size.tiny) array.push(orderBlocks, ob) // ============================================================================= // MITIGATION CHECK (Rule 3) // ============================================================================= if array.size(orderBlocks) > 0 for i = array.size(orderBlocks) - 1 to 0 ob = array.get(orderBlocks, i) if ob.mitigated continue mitigated = false if ob.isBullish mitigated := low = ob.bottom if mitigated ob.mitigated := true ob.rule3 := 0 if not na(ob.obBox) if show_mitigated box.set_bgcolor(ob.obBox, mitig_color) box.set_border_color(ob.obBox, color.gray) box.set_right(ob.obBox, bar_index) box.set_extend(ob.obBox, extend.none) else box.delete(ob.obBox) if not na(ob.entryLine) if show_mitigated line.set_x2(ob.entryLine, bar_index) line.set_extend(ob.entryLine, extend.none) line.set_color(ob.entryLine, color.gray) else line.delete(ob.entryLine) if not na(ob.obLabel) and not show_mitigated label.delete(ob.obLabel) if bar_index - ob.barIdx > max_ob_display * 2 if not na(ob.obBox) box.delete(ob.obBox) if not na(ob.entryLine) line.delete(ob.entryLine) if not na(ob.obLabel) label.delete(ob.obLabel) array.remove(orderBlocks, i) // ============================================================================= // DRAW FVG ZONES // ============================================================================= if show_fvg and bullFVG_valid and not bullFVG_3rdWickTapped box.new(bar_index - 1, low, bar_index + 15, high, bgcolor=bull_fvg_color, border_color=color.teal, border_width=1) if show_fvg and bearFVG_valid and not bearFVG_3rdWickTapped box.new(bar_index - 1, low, bar_index + 15, high, bgcolor=bear_fvg_color, border_color=color.maroon, border_width=1) // ============================================================================= // BOS MARKERS // ============================================================================= plotshape(show_bos_marker and bullishBOS, "Bullish BOS", shape.triangleup, location.belowbar, color.green, size=size.tiny, text="BOS") plotshape(show_bos_marker and bearishBOS, "Bearish BOS", shape.triangledown, location.abovebar, color.red, size=size.tiny, text="BOS") // ============================================================================= // INDUCEMENT MARKERS // ============================================================================= plotshape(show_inducement and bullishInducement, "Bull Inducement", shape.xcross, location.abovebar, color.orange, size=size.tiny, text="IND") plotshape(show_inducement and bearishInducement, "Bear Inducement", shape.xcross, location.belowbar, color.orange, size=size.tiny, text="IND") // ============================================================================= // INFO TABLE // ============================================================================= var table infoTbl = table.new(position.top_right, 2, 10, bgcolor=color.new(color.black, 80)) if barstate.islast bull_count = 0 bear_count = 0 if array.size(orderBlocks) > 0 for i = 0 to array.size(orderBlocks) - 1 ob = array.get(orderBlocks, i) if not ob.mitigated if ob.isBullish bull_count += 1 else bear_count += 1 table.cell(infoTbl, 0, 0, "OB Scanner V3", text_color=color.white, text_size=size.small) table.cell(infoTbl, 1, 0, "4-Rule System", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 0, 1, "🟢 Bullish:", text_color=color.green, text_size=size.tiny) table.cell(infoTbl, 1, 1, str.tostring(bull_count), text_color=color.white, text_size=size.tiny) table.cell(infoTbl, 0, 2, "🔴 Bearish:", text_color=color.red, text_size=size.tiny) table.cell(infoTbl, 1, 2, str.tostring(bear_count), text_color=color.white, text_size=size.tiny) table.cell(infoTbl, 0, 3, "───────", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 1, 3, "", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 0, 4, "R1:", text_color=color.white, text_size=size.tiny) table.cell(infoTbl, 1, 4, "Liq Sweep", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 0, 5, "R2:", text_color=color.white, text_size=size.tiny) table.cell(infoTbl, 1, 5, "FVG Check", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 0, 6, "R3:", text_color=color.white, text_size=size.tiny) table.cell(infoTbl, 1, 6, "Unmitigated", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 0, 7, "R4:", text_color=color.white, text_size=size.tiny) table.cell(infoTbl, 1, 7, "BOS+Induce", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 0, 8, "───────", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 1, 8, "", text_color=color.gray, text_size=size.tiny) table.cell(infoTbl, 0, 9, "Min Rules:", text_color=color.white, text_size=size.tiny) table.cell(infoTbl, 1, 9, str.tostring(min_rules) + "/4", text_color=color.yellow, text_size=size.tiny) // ============================================================================= // ALERTS // ============================================================================= alertcondition(potentialBullOB and bull_valid, "Bullish OB Formed", "🟢 Bullish Order Block on {{ticker}}") alertcondition(potentialBearOB and bear_valid, "Bearish OB Formed", "🔴 Bearish Order Block on {{ticker}}") alertcondition(bullishBOS, "Bullish BOS", "📈 Break of Structure UP on {{ticker}}") alertcondition(bearishBOS, "Bearish BOS", "📉 Break of Structure DOWN on {{ticker}}")