Untitled

 avatar
unknown
plain_text
a month ago
12 kB
19
Indexable
//@version=5
indicator("FluidTrades - SMC Enhanced", overlay = true, max_labels_count = 500, max_boxes_count = 500, max_lines_count = 500, max_bars_back = 1000)

//
// SETTINGS
//

// Temel Ayarlar
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)

// Hacim Ayarları
volume_lookback = input.int(26, "Volume Lookback Periods", minval = 1, maxval = 100, group="Volume Settings")
min_volume_change = input.int(10, "Min Volume Change %", minval = 1, maxval = 100, group="Volume Settings")

// Görsel Ayarlar
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')

// Yapı Tipleri
type Zone
    box     box_obj
    int     touches
    float   volume_change
    int     last_touch_bar
    float   poi_level
    bool    is_valid
    bool    is_broken

//
// FUNCTIONS
//

// Array Yönetimi
f_array_add_pop(array, new_value_to_add) =>
    array.unshift(array, new_value_to_add)
    array.pop(array)

// Hacim Analizi
get_volume_change(lookback) =>
    float vol_sum = 0.0
    for i = 1 to lookback
        vol_sum += volume[i]
    avg_vol = vol_sum / lookback
    curr_vol = volume
    ((curr_vol - avg_vol) / avg_vol) * 100

// Swing High/Low Etiketleri
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)

// Bölge Çakışma Kontrolü
f_check_overlapping(new_poi, zone_array, atr) =>
    atr_threshold = atr * 2
    okay_to_draw = true

    for zone in zone_array
        if not na(zone)
            poi = zone.poi_level
            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

    okay_to_draw

// Bölgeye Temas Kontrolü
is_touching_zone(zone) =>
    var bool touching = false
    if not na(zone)
        box_top = box.get_top(zone.box_obj)
        box_bottom = box.get_bottom(zone.box_obj)
        
        if high >= box_bottom and low <= box_top
            touching := true
            if bar_index - zone.last_touch_bar > 5
                zone.touches += 1
                zone.last_touch_bar := bar_index
    touching

// Supply/Demand Bölgesi Oluşturma
f_supply_demand(value_array, bn_array, zone_array, box_type, atr) =>
    atr_buffer = atr * (box_width / 10)
    box_left = array.get(bn_array, 0)
    box_right = bar_index

    float box_top = 0.0
    float box_bottom = 0.0
    float poi = 0.0

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

    vol_chg = get_volume_change(volume_lookback)
    
    if math.abs(vol_chg) >= min_volume_change and f_check_overlapping(poi, zone_array, atr)
        new_box = box.new(
            left=box_left, 
            top=box_top, 
            right=box_right, 
            bottom=box_bottom,
            border_color=box_type == 1 ? supply_outline_color : demand_outline_color,
            bgcolor=box_type == 1 ? supply_color : demand_color,
            extend=extend.right,
            text=box_type == 1 ? "SUPPLY" : "DEMAND"
            )
            
        new_zone = Zone.new(
            box_obj=new_box,
            touches=0,
            volume_change=vol_chg,
            last_touch_bar=bar_index,
            poi_level=poi,
            is_valid=true,
            is_broken=false
            )
            
        array.unshift(zone_array, new_zone)
        
        if array.size(zone_array) > history_of_demand_to_keep
            old_zone = array.pop(zone_array)
            if not na(old_zone) and not na(old_zone.box_obj)
                box.delete(old_zone.box_obj)

// BOS (Break of Structure) İşleme
f_sd_to_bos(zone_array, bos_array, zone_type) =>
    for zone in zone_array
        if not na(zone) and not zone.is_broken
            level_to_break = zone_type == 1 ? box.get_top(zone.box_obj) : box.get_bottom(zone.box_obj)
            
            if (zone_type == 1 and close >= level_to_break) or (zone_type == -1 and close <= level_to_break)
                copied_box = box.copy(zone.box_obj)
                f_array_add_pop(bos_array, copied_box)
                
                mid = (box.get_top(zone.box_obj) + box.get_bottom(zone.box_obj)) / 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)
                
                zone.is_broken := true
                zone.is_valid := false

// Bölge Etiketlerini Güncelleme
f_update_zone_labels(zone_array) =>
    for zone in zone_array
        if not na(zone) and not na(zone.box_obj) and zone.is_valid
            base_text = box.get_text(zone.box_obj)
            updated_text = base_text + "\nTouches: " + str.tostring(zone.touches) + 
                          "\nVol Δ: " + str.tostring(math.round(zone.volume_change)) + "%"
            box.set_text(zone.box_obj, updated_text)

// Box Bitiş Noktasını Güncelleme
f_extend_box_endpoint(zone_array) =>
    for zone in zone_array
        if not na(zone) and not na(zone.box_obj) and zone.is_valid
            box.set_right(zone.box_obj, bar_index + 100)

//
// CALCULATIONS & VARIABLES
//

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

// Swing High/Low Hesaplama
swing_high = ta.pivothigh(high, swing_length, swing_length)
swing_low = ta.pivotlow(low, swing_length, swing_length)

// Array Tanımlamaları
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)

var supply_zones = array.new<Zone>()
var demand_zones = array.new<Zone>()
var supply_bos = array.new_box(5, na)
var demand_bos = array.new_box(5, na)

//
// MAIN LOGIC
//

// Yeni Swing High İşleme
if not na(swing_high)
    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, supply_zones, 1, atr)

// Yeni Swing Low İşleme
else if not na(swing_low)
    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, demand_zones, -1, atr)

// Bölge Temaslarını Kontrol Et
for zone in supply_zones
    if not na(zone)
        is_touching_zone(zone)
    
for zone in demand_zones
    if not na(zone)
        is_touching_zone(zone)

// BOS Kontrolü
f_sd_to_bos(supply_zones, supply_bos, 1)
f_sd_to_bos(demand_zones, demand_bos, -1)

// Box ve Etiketleri Güncelle
f_extend_box_endpoint(supply_zones)
f_extend_box_endpoint(demand_zones)
f_update_zone_labels(supply_zones)
f_update_zone_labels(demand_zones)

// Zigzag Hesaplama ve Çizim
if show_zigzag
    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() =>
        line.new(timeHigh - swing_length, lastHigh, timeLow - swing_length, lastLow, 
                 xloc.bar_index, color=zigzag_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()
        
        if f_isMax(swing_length) and high[swing_length] > lastLow
            lastHigh := high[swing_length]
            timeHigh := bar_index
            dirUp := false
            li := f_drawLine()

    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()
            
        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()
Editor is loading...
Leave a Comment