tvpinescript

open
close

FluidTrades – SMC Lite: A Smart Money Concept (SMC) Trading Tool for Precision Market Analysis

January 21, 2025 | by admin

bandicam 2025-01-21 11-30-04-869

Trading in financial markets can be challenging, especially when it comes to identifying key supply and demand zones, market structure shifts, and optimal entry points. FluidTrades – SMC Lite aims to simplify this by offering traders a structured approach based on Smart Money Concepts (SMC).

This script is designed to help traders visualize supply and demand zones, detect trend reversals, and manage trades more efficiently. However, it’s important to note that no indicator guarantees profitability—trading success depends on a well-structured strategy, sound risk management, and continuous learning.

Key Features of the Script:

  1. Swing High/Low Detection:
    • Identifies key swing highs and swing lows, offering traders an understanding of market structure.
    • Adjustable swing length to fine-tune sensitivity based on different market conditions.
  2. Supply and Demand Zones Visualization:
    • Automatically plots supply and demand zones with customizable colors and widths.
    • Helps traders spot key reversal and breakout areas.
  3. Break of Structure (BOS) Detection:
    • Tracks BOS and CHoCH (Change of Character) to identify trend reversals.
    • Displays visual labels and alerts when market structure shifts occur.
  4. Point of Interest (POI) Labeling:
    • Highlights critical price levels where liquidity accumulates.
    • Provides clear visual cues for potential trade setups.
  5. Customizable Visual Settings:
    • Users can modify zone colors, opacity, and outline styles for enhanced chart readability.
    • Option to toggle zigzag patterns for better trend visualization.
  6. ATR-Based Zone Calculation:
    • Incorporates the Average True Range (ATR) for accurate positioning of supply and demand zones.
    • Helps avoid overlapping zones and improves trade precision.
  7. Historical Zone Tracking:
    • Retains historical demand and supply levels to monitor key price interactions over time.
    • Supports long-term strategy development.
  8. Real-Time Updates and Alerts:
    • Keeps traders informed with live BOS, POI, and demand/supply changes.
    • Helps make timely trading decisions without constantly watching the charts.

Recommended Usage:

  1. Scalping:
    • Optimal for 5-minute to 15-minute charts.
    • Use BOS and POI labels for short-term trading opportunities.
  2. Day Trading:
    • Works well on 30-minute to 1-hour charts.
    • Utilize supply and demand zones to identify intraday reversal levels.
  3. Swing Trading:
    • Effective on 4-hour to daily charts.
    • Track BOS levels and monitor historical demand zones for long-term positions.
  4. Risk Management Strategy:
    • Leverage ATR-based zone width to set dynamic stop-loss and take-profit levels.
    • Avoid trading inside overlapping zones to minimize risk exposure.

Script Evaluation:

  • Functionality: 4.8/5
    Provides an all-in-one solution for traders focusing on market structure and key trading zones.
  • Ease of Use: 4.3/5
    Offers a user-friendly interface, but beginners may need some time to fully utilize its capabilities.
  • Accuracy: 4.6/5
    Accurate detection of market structure shifts, but should be used alongside confirmation indicators for better reliability.
  • Repainting Analysis:
    This script does not repaint.
    All calculations are based on confirmed bar data, ensuring consistency in both live and backtesting scenarios.
  • Optimal Timeframes:
    • Scalping: 5-minute to 15-minute charts.
    • Day Trading: 30-minute to 1-hour charts.
    • Swing Trading: 4-hour to daily charts.
  • Author and Development Quality:
    The script is well-coded with a clear focus on SMC principles, but no specific author attribution was found.
  • Overall Score: 4.7/5
    A reliable tool for traders looking to integrate supply and demand strategies into their market analysis.

//@version=5
indicator("FluidTrades - SMC Lite ", overlay = true, max_labels_count = 500, max_boxes_count = 500, max_lines_count = 500, max_bars_back = 1000)

//
//SETTINGS
//

//      INDICATOR SETTINGS
swing_length = input.int(10, title = 'Swing High/Low Length', group = 'Settings', minval = 1, maxval = 50)
history_of_demand_to_keep = input.int(20, title = 'History To Keep', minval = 5, maxval = 50)
box_width = input.float(2.5, title = 'Supply/Demand Box Width', group = 'Settings', minval = 1, maxval = 10, step = 0.5)

//      INDICATOR VISUAL SETTINGS
show_zigzag = input.bool(false, title = 'Show Zig Zag', group = 'Visual Settings', inline = '1')
show_price_action_labels = input.bool(false, title = 'Show Price Action Labels', group = 'Visual Settings', inline = '2')

supply_color = input.color(color.new(#EDEDED,70), title = 'Supply', group = 'Visual Settings', inline = '3')
supply_outline_color = input.color(color.new(color.white,75), title = 'Outline', group = 'Visual Settings', inline = '3')

demand_color = input.color(color.new(#00FFFF,70), title = 'Demand', group = 'Visual Settings', inline = '4')
demand_outline_color = input.color(color.new(color.white,75), title = 'Outline', group = 'Visual Settings', inline = '4')

bos_label_color = input.color(color.white, title = 'BOS Label', group = 'Visual Settings', inline = '5')
poi_label_color = input.color(color.white, title = 'POI Label', group = 'Visual Settings', inline = '7')

swing_type_color = input.color(color.black, title = 'Price Action Label', group = 'Visual Settings', inline = '8')
zigzag_color = input.color(color.new(#000000,0), title = 'Zig Zag', group = 'Visual Settings', inline = '9')

//
//END SETTINGS
//


//
//FUNCTIONS
//

//      FUNCTION TO ADD NEW AND REMOVE LAST IN ARRAY
f_array_add_pop(array, new_value_to_add) =>
    array.unshift(array, new_value_to_add)
    array.pop(array)

//      FUNCTION SWING H & L LABELS
f_sh_sl_labels(array, swing_type) =>

    var string label_text = na
    if swing_type == 1
        if array.get(array, 0) >= array.get(array, 1)
            label_text := 'HH'
        else
            label_text := 'LH'
        label.new(bar_index - swing_length, array.get(array,0), text = label_text, style=label.style_label_down, textcolor = swing_type_color, color = color.new(swing_type_color, 100), size = size.tiny)
    
    else if swing_type == -1
        if array.get(array, 0) >= array.get(array, 1)
            label_text := 'HL'
        else
            label_text := 'LL'
        label.new(bar_index - swing_length, array.get(array,0), text = label_text, style=label.style_label_up, textcolor = swing_type_color, color = color.new(swing_type_color, 100), size = size.tiny)

//      FUNCTION MAKE SURE SUPPLY ISNT OVERLAPPING
f_check_overlapping(new_poi, box_array, atr) =>

    atr_threshold = atr * 2
    okay_to_draw = true

    for i = 0 to array.size(box_array) - 1
        top = box.get_top(array.get(box_array, i))
        bottom = box.get_bottom(array.get(box_array, i))
        poi = (top + bottom) / 2

        upper_boundary = poi + atr_threshold
        lower_boundary = poi - atr_threshold

        if new_poi >= lower_boundary and new_poi <= upper_boundary
            okay_to_draw := false
            break
        else 
            okay_to_draw := true
    okay_to_draw


//      FUNCTION TO DRAW SUPPLY OR DEMAND ZONE
f_supply_demand(value_array, bn_array, box_array, label_array, box_type, atr) =>

    atr_buffer = atr * (box_width / 10)
    box_left = array.get(bn_array, 0)
    box_right = bar_index

    var float box_top = 0.00
    var float box_bottom = 0.00
    var float poi = 0.00


    if box_type == 1
        box_top := array.get(value_array, 0)
        box_bottom := box_top - atr_buffer
        poi := (box_top + box_bottom) / 2
    else if box_type == -1
        box_bottom := array.get(value_array, 0)
        box_top := box_bottom + atr_buffer
        poi := (box_top + box_bottom) / 2

    okay_to_draw = f_check_overlapping(poi, box_array, atr)
    // okay_to_draw = true

    //delete oldest box, and then create a new box and add it to the array
    if box_type == 1 and okay_to_draw
        box.delete( array.get(box_array, array.size(box_array) - 1) )
        f_array_add_pop(box_array, box.new( left = box_left, top = box_top, right = box_right, bottom = box_bottom, border_color = supply_outline_color,
             bgcolor = supply_color, extend = extend.right, text = 'SUPPLY', text_halign = text.align_center, text_valign = text.align_center, text_color = poi_label_color, text_size = size.small, xloc = xloc.bar_index))
        
        box.delete( array.get(label_array, array.size(label_array) - 1) )
        f_array_add_pop(label_array, box.new( left = box_left, top = poi, right = box_right, bottom = poi, border_color = color.new(poi_label_color,90),
             bgcolor = color.new(poi_label_color,90), extend = extend.right, text = 'POI', text_halign = text.align_left, text_valign = text.align_center, text_color = poi_label_color, text_size = size.small, xloc = xloc.bar_index))

    else if box_type == -1 and okay_to_draw
        box.delete( array.get(box_array, array.size(box_array) - 1) )
        f_array_add_pop(box_array, box.new( left = box_left, top = box_top, right = box_right, bottom = box_bottom, border_color = demand_outline_color,
             bgcolor = demand_color, extend = extend.right,  text = 'DEMAND', text_halign = text.align_center, text_valign = text.align_center, text_color = poi_label_color, text_size = size.small, xloc = xloc.bar_index))
        
        box.delete( array.get(label_array, array.size(label_array) - 1) )
        f_array_add_pop(label_array, box.new( left = box_left, top = poi, right = box_right, bottom = poi, border_color = color.new(poi_label_color,90),
             bgcolor = color.new(poi_label_color,90), extend = extend.right,  text = 'POI', text_halign = text.align_left, text_valign = text.align_center, text_color = poi_label_color, text_size = size.small, xloc = xloc.bar_index))


//      FUNCTION TO CHANGE SUPPLY/DEMAND TO A BOS IF BROKEN
f_sd_to_bos(box_array, bos_array, label_array, zone_type) =>

    if zone_type == 1
        for i = 0 to array.size(box_array) - 1
            level_to_break = box.get_top(array.get(box_array,i))
            // if ta.crossover(close, level_to_break)
            if close >= level_to_break
                copied_box = box.copy(array.get(box_array,i))
                f_array_add_pop(bos_array, copied_box)
                mid = (box.get_top(array.get(box_array,i)) + box.get_bottom(array.get(box_array,i))) / 2
                box.set_top(array.get(bos_array,0), mid)
                box.set_bottom(array.get(bos_array,0), mid)
                box.set_extend( array.get(bos_array,0), extend.none)
                box.set_right( array.get(bos_array,0), bar_index)
                box.set_text( array.get(bos_array,0), 'BOS' )
                box.set_text_color( array.get(bos_array,0), bos_label_color)
                box.set_text_size( array.get(bos_array,0), size.small)
                box.set_text_halign( array.get(bos_array,0), text.align_center)
                box.set_text_valign( array.get(bos_array,0), text.align_center)
                box.delete(array.get(box_array, i))
                box.delete(array.get(label_array, i))


    if zone_type == -1
        for i = 0 to array.size(box_array) - 1
            level_to_break = box.get_bottom(array.get(box_array,i))
            // if ta.crossunder(close, level_to_break)
            if close <= level_to_break
                copied_box = box.copy(array.get(box_array,i))
                f_array_add_pop(bos_array, copied_box)
                mid = (box.get_top(array.get(box_array,i)) + box.get_bottom(array.get(box_array,i))) / 2
                box.set_top(array.get(bos_array,0), mid)
                box.set_bottom(array.get(bos_array,0), mid)
                box.set_extend( array.get(bos_array,0), extend.none)
                box.set_right( array.get(bos_array,0), bar_index)
                box.set_text( array.get(bos_array,0), 'BOS' )
                box.set_text_color( array.get(bos_array,0), bos_label_color)
                box.set_text_size( array.get(bos_array,0), size.small)
                box.set_text_halign( array.get(bos_array,0), text.align_center)
                box.set_text_valign( array.get(bos_array,0), text.align_center)
                box.delete(array.get(box_array, i))
                box.delete(array.get(label_array, i))



//      FUNCTION MANAGE CURRENT BOXES BY CHANGING ENDPOINT
f_extend_box_endpoint(box_array) =>

    for i = 0 to array.size(box_array) - 1
        box.set_right(array.get(box_array, i), bar_index + 100)


//
//END FUNCTIONS
//  


//
//CALCULATIONS
//

//      CALCULATE ATR 
atr = ta.atr(50)

//      CALCULATE SWING HIGHS & SWING LOWS
swing_high = ta.pivothigh(high, swing_length, swing_length)
swing_low = ta.pivotlow(low, swing_length, swing_length)

//      ARRAYS FOR SWING H/L & BN 
var swing_high_values = array.new_float(5,0.00)
var swing_low_values = array.new_float(5,0.00)

var swing_high_bns = array.new_int(5,0)
var swing_low_bns = array.new_int(5,0)

//      ARRAYS FOR SUPPLY / DEMAND
var current_supply_box = array.new_box(history_of_demand_to_keep, na)
var current_demand_box = array.new_box(history_of_demand_to_keep, na)

//      ARRAYS FOR SUPPLY / DEMAND POI LABELS
var current_supply_poi = array.new_box(history_of_demand_to_keep, na)
var current_demand_poi = array.new_box(history_of_demand_to_keep, na)

//      ARRAYS FOR BOS
var supply_bos = array.new_box(5, na)
var demand_bos = array.new_box(5, na)
//
//END CALCULATIONS
//

//      NEW SWING HIGH
if not na(swing_high)

    //MANAGE SWING HIGH VALUES
    f_array_add_pop(swing_high_values, swing_high)
    f_array_add_pop(swing_high_bns, bar_index[swing_length])
    if show_price_action_labels
        f_sh_sl_labels(swing_high_values, 1)

    f_supply_demand(swing_high_values, swing_high_bns, current_supply_box, current_supply_poi, 1, atr)

//      NEW SWING LOW
else if not na(swing_low)

    //MANAGE SWING LOW VALUES
    f_array_add_pop(swing_low_values, swing_low)
    f_array_add_pop(swing_low_bns, bar_index[swing_length])
    if show_price_action_labels
        f_sh_sl_labels(swing_low_values, -1)
    
    f_supply_demand(swing_low_values, swing_low_bns, current_demand_box, current_demand_poi, -1, atr)


f_sd_to_bos(current_supply_box, supply_bos, current_supply_poi, 1)
f_sd_to_bos(current_demand_box, demand_bos, current_demand_poi, -1)

f_extend_box_endpoint(current_supply_box)
f_extend_box_endpoint(current_demand_box)

//ZIG ZAG
h = ta.highest(high, swing_length * 2 + 1)
l = ta.lowest(low, swing_length * 2 + 1)
f_isMin(len) =>
    l == low[len]
f_isMax(len) =>
    h == high[len]

var dirUp = false
var lastLow = high * 100
var lastHigh = 0.0
var timeLow = bar_index
var timeHigh = bar_index
var line li = na

f_drawLine() =>
    _li_color = show_zigzag ? zigzag_color : color.new(#ffffff,100)
    line.new(timeHigh - swing_length, lastHigh, timeLow - swing_length, lastLow, xloc.bar_index, color=_li_color, width=2)

if dirUp
    if f_isMin(swing_length) and low[swing_length] < lastLow
        lastLow := low[swing_length]
        timeLow := bar_index
        line.delete(li)
        li := f_drawLine()
        li

    if f_isMax(swing_length) and high[swing_length] > lastLow
        lastHigh := high[swing_length]
        timeHigh := bar_index
        dirUp := false
        li := f_drawLine()
        li

if not dirUp
    if f_isMax(swing_length) and high[swing_length] > lastHigh
        lastHigh := high[swing_length]
        timeHigh := bar_index
        line.delete(li)
        li := f_drawLine()
        li
    if f_isMin(swing_length) and low[swing_length] < lastHigh
        lastLow := low[swing_length]
        timeLow := bar_index
        dirUp := true
        li := f_drawLine()
        if f_isMax(swing_length) and high[swing_length] > lastLow
            lastHigh := high[swing_length]
            timeHigh := bar_index
            dirUp := false
            li := f_drawLine()
            li
// if barstate.islast
    // label.new(x = bar_index + 10, y = close[1], text = str.tostring( array.size(current_supply_poi) ))
//     label.new(x = bar_index + 20, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 0))))
//     label.new(x = bar_index + 30, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 1))))
//     label.new(x = bar_index + 40, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 2))))
//     label.new(x = bar_index + 50, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 3))))
//     label.new(x = bar_index + 60, y = close[1], text = str.tostring( box.get_bottom( array.get(current_supply_box, 4))))

How to Apply Pine Script in TradingView:

  1. Open TradingView and log in to your account.
  2. Navigate to the Pine Script Editor at the bottom of the screen.
  3. Copy and paste the provided script code.
  4. Click Save, then name the script (e.g., “FluidTrades – SMC Lite”).
  5. Click Add to Chart to apply the indicator.
  6. Customize settings to align with your trading style.

Additional Trading Tips:

  • Combine with Confirmation Indicators:
    Use this script alongside indicators like RSI, MACD, or volume to validate entry points.
  • Backtest Before Live Trading:
    Ensure the settings are optimized for your trading style by conducting thorough backtesting.
  • Avoid Trading in Congestion Areas:
    Focus on clean supply and demand zones where price has shown significant reaction.

Final Thoughts:

The FluidTrades – SMC Lite script is an essential tool for traders who rely on Smart Money Concepts to analyze market structure and identify trading opportunities. Its non-repainting nature ensures reliability, making it suitable for scalping, day trading, and swing trading.


Remember: No indicator can replace a sound trading plan and disciplined risk management. Use this tool wisely and stay ahead of the market!

RELATED POSTS

View all

view all

You cannot copy content of this page