Advertisement IC Markets

Free SMC Trading Setups

Discuss 1-minute to 15-minute price action setups, fading intraday momentum, key support/resistance zones, and proven short-term trading methodologies.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

How to use this script in TradingView:

Open TradingView and navigate to the Pine Editor tab at the bottom of the screen.

Delete any existing code, paste the script above, and click Add to Chart.

Application: Apply this to a Daily or 4-Hour chart. The indicator will map the zones (from candle body to wick tip) and extend them to the right. As new, more relevant swing points develop, the oldest ones are automatically deleted, ensuring your chart never looks like a spiderweb.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Recommended broker for automated trading & scalping IC Markets
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

To elevate this from a standard retail strategy to a professional framework, we must introduce Smart Money Concepts (SMC) and Liquidity Dynamics.

Amateurs see support and resistance as concrete walls; professionals see them as pools of liquidity. A "pro" system doesn't just draw zones—it tracks whether those zones have been mitigated (orders filled) or swept (stops taken), and it automatically manages role reversals (Breaker Blocks).

Here is the upgraded professional methodology, followed by a significantly advanced Pine Script.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

The Professional Framework: Liquidity & Mitigation

1. Point of Interest (POI) vs. Line in the Sand

Pros don't trade levels; they trade Points of Interest. A POI is a swing point where institutional capital left a footprint (an Order Block or heavy volume rejection). When price returns to a POI, you are not predicting a bounce. You are watching to see how the algorithms interact with the liquidity resting there.

2. The Sweep vs. The Break (The Close Matters)

Retail traders get stopped out because they trade the wick. A true professional waits for the candle close.

The Sweep (Turtle Soup): Price wicks through the zone to trigger retail stop-losses, but the candle body closes inside or ahead of the zone. This is a high-probability reversal signal. Institutions just engineered liquidity to fill their bags.

The Break (Mitigation): A full-bodied candle closes through the zone. The level is now dead (mitigated). Institutional defense failed.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

3. The Breaker Block (Automated Role Reversal)

When a major resistance zone is violently broken by a bullish momentum candle, the institutions who were selling at that resistance are now trapped underwater. When price pulls back to that broken zone, those trapped sellers buy to close their positions at break-even. This turns the old resistance into new support—known professionally as a Breaker Block.

4. The Entry Model (LTF Confirmation)

Never set a limit order at a Daily or 4H zone. When price enters the HTF zone, drop to the 15-minute or 5-minute chart. Wait for a Market Structure Shift (MSS)—price failing to make a new low, followed by a break of the previous lower high. You enter on the pullback of that lower timeframe shift, placing your stop loss safely beneath the HTF sweep.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

Pro Pine Script: Dynamic Mitigation & Breaker Blocks

This upgraded script uses Pine v5's User-Defined Types (UDTs) to treat zones as intelligent objects.

Mitigation: If a candle closes through a zone, the script instantly stops extending it. Your chart remains perfectly clean.

Role Reversal (Breakers): If enabled, broken support turns into resistance (and vice versa) and changes color, remaining active until tested from the other side.

Alerts: Built-in alerts fire only the first time price touches an unmitigated zone.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

Pine code PRO version

Code: Select all

//@version=5
indicator("Pro Institutional S&R Zones [Mitigation & Breakers]", overlay=true, max_boxes_count=50)

// ==============================================================================
// PROFESSIONAL INPUTS
// ==============================================================================
leftLen      = input.int(20, title="Swing Lookback (Left)", minval=5)
rightLen     = input.int(15, title="Swing Lookback (Right)", minval=5)
showBreakers = input.bool(true, title="Show Role Reversal (Breaker Blocks)")
maxZones     = input.int(5, title="Max Active Zones", minval=1, maxval=20)

// Styling
colorSup     = input.color(color.new(#00E676, 80), title="Support Zone")
colorRes     = input.color(color.new(#FF5252, 80), title="Resistance Zone")
colorBrkSup  = input.color(color.new(#2962FF, 80), title="Breaker (Res turned Sup)")
colorBrkRes  = input.color(color.new(#FF9800, 80), title="Breaker (Sup turned Res)")

// ==============================================================================
// UDT: INTELLIGENT ZONE TRACKING
// ==============================================================================
type Zone
    box   id
    float top
    float bot
    bool  isSup
    bool  isActive
    bool  isBreaker
    bool  alertFired

var Zone[] activeZones = array.new<Zone>()

// ==============================================================================
// SWING DETECTION
// ==============================================================================
ph = ta.pivothigh(high, leftLen, rightLen)
pl = ta.pivotlow(low, leftLen, rightLen)

// Function to clean up old zones
f_cleanupZones() =>
    if array.size(activeZones) > maxZones
        // Find the oldest active zone and terminate it to keep chart clean
        for i = array.size(activeZones) - 1 to 0
            Zone z = array.get(activeZones, i)
            if z.isActive
                box.set_extend(z.id, extend.none)
                box.set_right(z.id, bar_index)
                z.isActive := false
                break

// ==============================================================================
// CREATE NEW ZONES
// ==============================================================================
if not na(ph)
    top = high[rightLen]
    bot = math.max(close[rightLen], open[rightLen])
    b = box.new(left=bar_index[rightLen], top=top, right=bar_index, bottom=bot, 
                border_color=colorRes, border_width=1, bgcolor=colorRes, extend=extend.right)
    array.unshift(activeZones, Zone.new(b, top, bot, false, true, false, false))
    f_cleanupZones()

if not na(pl)
    bot = low[rightLen]
    top = math.min(close[rightLen], open[rightLen])
    b = box.new(left=bar_index[rightLen], top=top, right=bar_index, bottom=bot, 
                border_color=colorSup, border_width=1, bgcolor=colorSup, extend=extend.right)
    array.unshift(activeZones, Zone.new(b, top, bot, true, true, false, false))
    f_cleanupZones()

// ==============================================================================
// ZONE MITIGATION, BREAKER LOGIC & ALERTS
// ==============================================================================
if array.size(activeZones) > 0
    for i = array.size(activeZones) - 1 to 0
        Zone z = array.get(activeZones, i)
        
        if z.isActive
            // 1. Alert Logic: Trigger when price enters the zone for the first time
            if (high >= z.bot and low <= z.top) and not z.alertFired
                alert("Price entered Institutional POI at " + str.tostring(close), alert.freq_once_per_bar_close)
                z.alertFired := true
            
            // 2. Mitigation Logic: Check if candle CLOSES outside the zone
            brokenUp   = close > z.top
            brokenDown = close < z.bot
            
            if (z.isSup and brokenDown) or (not z.isSup and brokenUp)
                // Stop extending the original box
                box.set_extend(z.id, extend.none)
                box.set_right(z.id, bar_index)
                z.isActive := false
                
                // 3. Role Reversal (Breaker Block) Logic
                if showBreakers
                    // Create a new box starting from the breakout candle
                    newTypeIsSup = not z.isSup
                    newBgColor   = newTypeIsSup ? colorBrkSup : colorBrkRes
                    
                    newBox = box.new(left=bar_index, top=z.top, right=bar_index, bottom=z.bot, 
                                     border_color=newBgColor, border_width=1, bgcolor=newBgColor, extend=extend.right)
                    
                    // Add the breaker block to the active zones array
                    array.unshift(activeZones, Zone.new(newBox, z.top, z.bot, newTypeIsSup, true, true, false))
                    f_cleanupZones()
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

How to use this like a Professional:

Apply to HTF: Put this indicator on a 1-Hour, 4-Hour, or Daily chart.

Observe the Mitigation: Notice how the chart stays pristine. The moment a zone is invalidated by a hard candle close, the script cuts the zone off. It no longer exists as a valid pool of liquidity.

Trade the Breakers: If a red resistance zone gets broken, it instantly terminates and spawns a blue Breaker Block extending forward. Watch how often price returns to this blue zone, perfectly testing the trapped liquidity before continuing the trend.

Set an Alert: In TradingView, create a new alert, select this indicator, and choose "Any alert() function call." You will now get pinged on your phone only when price taps a fresh, unmitigated institutional level.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

Translating this institutional methodology to MetaTrader requires a shift in how we handle graphics. Unlike TradingView (Pine Script) where you can easily say extend.right, MetaTrader uses Graphical Objects (OBJ_RECTANGLE).

To make a zone "extend," we project its second time-coordinate far into the future. When a zone is mitigated (a candle closes through it), the code automatically pulls that future time-coordinate back to the current candle, freezing the box in the past and cleaning your chart.

Here are the complete, professional-grade indicators for both MetaTrader 4 (MQL4) and MetaTrader 5 (MQL5).
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

1. MetaTrader 4 (MQL4) Code

Save this file as Pro_SMC_Zones.mq4 in your MQL4/Indicators folder.

Code: Select all

//+------------------------------------------------------------------+
//|                                                Pro_SMC_Zones.mq4 |
//|                                  Institutional S&R with Breakers |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window

//--- Inputs
input int      LeftLen        = 20;            // Pivot Lookback (Left)
input int      RightLen       = 15;            // Pivot Lookback (Right)
input bool     ShowBreakers   = true;          // Show Breaker Blocks
input int      MaxZones       = 5;             // Max Active Zones
input color    ColorSup       = clrMediumSeaGreen; // Support Zone
input color    ColorRes       = clrRed;        // Resistance Zone
input color    ColorBrkSup    = clrDodgerBlue; // Breaker (Res -> Sup)
input color    ColorBrkRes    = clrDarkOrange; // Breaker (Sup -> Res)

//--- Struct to track zones intelligently
struct Zone {
    string name;
    double top;
    double bot;
    bool   isSup;
    bool   isActive;
    bool   isBreaker;
};

Zone activeZones[];
datetime lastBarTime = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
    ObjectsDeleteAll(0, "SMC_ZONE_"); // Clean up old zones on reload
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
    ObjectsDeleteAll(0, "SMC_ZONE_");
}

//+------------------------------------------------------------------+
//| Create or update rectangle object                                |
//+------------------------------------------------------------------+
void DrawZone(string name, datetime t1, double p1, datetime t2, double p2, color clr) {
    if(ObjectFind(0, name) < 0) {
        ObjectCreate(0, name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
        ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
        ObjectSetInteger(0, name, OBJPROP_BACK, true); // Send to background
        ObjectSetInteger(0, name, OBJPROP_FILL, true); // Fill with color
    } else {
        ObjectSetInteger(0, name, OBJPROP_TIME2, t2); // Extend or retract
    }
}

//+------------------------------------------------------------------+
//| Check if index is a Pivot                                        |
//+------------------------------------------------------------------+
bool IsPivotHigh(int index) {
    double val = High[index];
    for(int i=1; i<=LeftLen; i++)  if(index+i < Bars && High[index+i] > val) return false;
    for(int i=1; i<=RightLen; i++) if(index-i >= 0 && High[index-i] >= val) return false;
    return true;
}

bool IsPivotLow(int index) {
    double val = Low[index];
    for(int i=1; i<=LeftLen; i++)  if(index+i < Bars && Low[index+i] < val) return false;
    for(int i=1; i<=RightLen; i++) if(index-i >= 0 && Low[index-i] <= val) return false;
    return true;
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) {
    // Only run on new bar close to save CPU
    if(Time[0] == lastBarTime) return(rates_total);
    lastBarTime = Time[0];

    int limit = MathMax(rates_total - prev_calculated, RightLen + 1);
    datetime futureTime = Time[0] + PeriodSeconds() * 100; // Extend into future

    // 1. Process active zones for mitigation
    for(int i = ArraySize(activeZones) - 1; i >= 0; i--) {
        if(activeZones[i].isActive) {
            bool brokenUp = Close[1] > activeZones[i].top;
            bool brokenDn = Close[1] < activeZones[i].bot;

            if((activeZones[i].isSup && brokenDn) || (!activeZones[i].isSup && brokenUp)) {
                // Zone Mitigated - lock its end time to current bar
                activeZones[i].isActive = false;
                DrawZone(activeZones[i].name, 0, activeZones[i].top, Time[0], activeZones[i].bot, clrNONE); 
                
                // Alert
                Alert("Institutional Zone Mitigated at ", DoubleToStr(Close[1], Digits));

                // Breaker Block Logic
                if(ShowBreakers) {
                    int size = ArraySize(activeZones);
                    ArrayResize(activeZones, size + 1);
                    bool newIsSup = !activeZones[i].isSup;
                    activeZones[size].name = "SMC_ZONE_BRK_" + IntegerToString(Time[0]);
                    activeZones[size].top = activeZones[i].top;
                    activeZones[size].bot = activeZones[i].bot;
                    activeZones[size].isSup = newIsSup;
                    activeZones[size].isActive = true;
                    activeZones[size].isBreaker = true;
                    
                    color clr = newIsSup ? ColorBrkSup : ColorBrkRes;
                    DrawZone(activeZones[size].name, Time[1], activeZones[size].top, futureTime, activeZones[size].bot, clr);
                }
            } else {
                // Keep extending active zone
                ObjectSetInteger(0, activeZones[i].name, OBJPROP_TIME2, futureTime);
            }
        }
    }

    // 2. Scan for new Swing Points
    for(int i = limit; i >= RightLen; i--) {
        if(IsPivotHigh(i)) {
            int size = ArraySize(activeZones);
            ArrayResize(activeZones, size + 1);
            activeZones[size].name = "SMC_ZONE_RES_" + IntegerToString(Time[i]);
            activeZones[size].top = High[i];
            activeZones[size].bot = MathMax(Close[i], Open[i]);
            activeZones[size].isSup = false;
            activeZones[size].isActive = true;
            activeZones[size].isBreaker = false;
            
            DrawZone(activeZones[size].name, Time[i], activeZones[size].top, futureTime, activeZones[size].bot, ColorRes);
        }

        if(IsPivotLow(i)) {
            int size = ArraySize(activeZones);
            ArrayResize(activeZones, size + 1);
            activeZones[size].name = "SMC_ZONE_SUP_" + IntegerToString(Time[i]);
            activeZones[size].top = MathMin(Close[i], Open[i]);
            activeZones[size].bot = Low[i];
            activeZones[size].isSup = true;
            activeZones[size].isActive = true;
            activeZones[size].isBreaker = false;
            
            DrawZone(activeZones[size].name, Time[i], activeZones[size].top, futureTime, activeZones[size].bot, ColorSup);
        }
    }
    
    return(rates_total);
}
//+------------------------------------------------------------------+
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 3349
Joined: Mon Jul 20, 2026 1:28 pm

Re: Free SMC Trading Setups

Post by PTScalper »

2. MetaTrader 5 (MQL5) Code

Save this file as Pro_SMC_Zones.mq5 in your MQL5/Indicators folder. MQL5 requires strict array indexing management, which this code handles automatically by setting the time series arrays as series (0 = current bar).

Code: Select all

//+------------------------------------------------------------------+
//|                                                Pro_SMC_Zones.mq5 |
//|                                  Institutional S&R with Breakers |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

input int      LeftLen        = 20;            // Pivot Lookback (Left)
input int      RightLen       = 15;            // Pivot Lookback (Right)
input bool     ShowBreakers   = true;          // Show Breaker Blocks
input int      MaxZones       = 5;             // Max Active Zones
input color    ColorSup       = clrMediumSeaGreen; 
input color    ColorRes       = clrRed;        
input color    ColorBrkSup    = clrDodgerBlue; 
input color    ColorBrkRes    = clrDarkOrange; 

struct Zone {
    string name;
    double top;
    double bot;
    bool   isSup;
    bool   isActive;
    bool   isBreaker;
};

Zone activeZones[];
datetime lastBarTime = 0;

int OnInit() {
    ObjectsDeleteAll(0, "SMC_ZONE_"); 
    return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {
    ObjectsDeleteAll(0, "SMC_ZONE_");
}

void DrawZone(string name, datetime t1, double p1, datetime t2, double p2, color clr) {
    if(ObjectFind(0, name) < 0) {
        ObjectCreate(0, name, OBJ_RECTANGLE, 0, t1, p1, t2, p2);
        ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
        ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clr);
        ObjectSetInteger(0, name, OBJPROP_BACK, true); 
        ObjectSetInteger(0, name, OBJPROP_FILL, true); 
    } else {
        ObjectSetInteger(0, name, OBJPROP_TIME2, t2); 
    }
}

bool IsPivotHigh(int index, const double &h[]) {
    double val = h[index];
    for(int i=1; i<=LeftLen; i++)  if(index+i < ArraySize(h) && h[index+i] > val) return false;
    for(int i=1; i<=RightLen; i++) if(index-i >= 0 && h[index-i] >= val) return false;
    return true;
}

bool IsPivotLow(int index, const double &l[]) {
    double val = l[index];
    for(int i=1; i<=LeftLen; i++)  if(index+i < ArraySize(l) && l[index+i] < val) return false;
    for(int i=1; i<=RightLen; i++) if(index-i >= 0 && l[index-i] <= val) return false;
    return true;
}

int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) {
    
    // Format arrays to match MT4 indexing (0 = newest bar)
    ArraySetAsSeries(time, true);
    ArraySetAsSeries(open, true);
    ArraySetAsSeries(high, true);
    ArraySetAsSeries(low, true);
    ArraySetAsSeries(close, true);

    if(rates_total < LeftLen + RightLen) return(0);
    if(time[0] == lastBarTime) return(rates_total);
    lastBarTime = time[0];

    int limit = prev_calculated == 0 ? rates_total - LeftLen - 1 : MathMax(rates_total - prev_calculated, RightLen + 1);
    datetime futureTime = time[0] + PeriodSeconds() * 100; 

    // 1. Process active zones for mitigation
    for(int i = ArraySize(activeZones) - 1; i >= 0; i--) {
        if(activeZones[i].isActive) {
            bool brokenUp = close[1] > activeZones[i].top;
            bool brokenDn = close[1] < activeZones[i].bot;

            if((activeZones[i].isSup && brokenDn) || (!activeZones[i].isSup && brokenUp)) {
                activeZones[i].isActive = false;
                ObjectSetInteger(0, activeZones[i].name, OBJPROP_TIME2, time[0]); 
                Alert("Institutional Zone Mitigated!");

                if(ShowBreakers) {
                    int size = ArraySize(activeZones);
                    ArrayResize(activeZones, size + 1);
                    bool newIsSup = !activeZones[i].isSup;
                    activeZones[size].name = "SMC_ZONE_BRK_" + IntegerToString(time[0]);
                    activeZones[size].top = activeZones[i].top;
                    activeZones[size].bot = activeZones[i].bot;
                    activeZones[size].isSup = newIsSup;
                    activeZones[size].isActive = true;
                    activeZones[size].isBreaker = true;
                    
                    color clr = newIsSup ? ColorBrkSup : ColorBrkRes;
                    DrawZone(activeZones[size].name, time[1], activeZones[size].top, futureTime, activeZones[size].bot, clr);
                }
            } else {
                ObjectSetInteger(0, activeZones[i].name, OBJPROP_TIME2, futureTime);
            }
        }
    }

    // 2. Scan for new Swing Points
    for(int i = limit; i >= RightLen; i--) {
        if(IsPivotHigh(i, high)) {
            int size = ArraySize(activeZones);
            ArrayResize(activeZones, size + 1);
            activeZones[size].name = "SMC_ZONE_RES_" + IntegerToString(time[i]);
            activeZones[size].top = high[i];
            activeZones[size].bot = MathMax(close[i], open[i]);
            activeZones[size].isSup = false;
            activeZones[size].isActive = true;
            
            DrawZone(activeZones[size].name, time[i], activeZones[size].top, futureTime, activeZones[size].bot, ColorRes);
        }

        if(IsPivotLow(i, low)) {
            int size = ArraySize(activeZones);
            ArrayResize(activeZones, size + 1);
            activeZones[size].name = "SMC_ZONE_SUP_" + IntegerToString(time[i]);
            activeZones[size].top = MathMin(close[i], open[i]);
            activeZones[size].bot = low[i];
            activeZones[size].isSup = true;
            activeZones[size].isActive = true;
            
            DrawZone(activeZones[size].name, time[i], activeZones[size].top, futureTime, activeZones[size].bot, ColorSup);
        }
    }
    return(rates_total);
}
//+------------------------------------------------------------------+
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Post Reply