Untitled

 avatar
unknown
plain_text
4 months ago
8.5 kB
4
Indexable
//@version=6
indicator('Support and Resistance', overlay = true)

// Inputs
pivotLength = input.int(10, 'Pivot Length', minval = 3)
maxLevels = input.int(2, 'Maximum Levels to Display', minval = 1, maxval = 20)
minDistance = input.float(1.0, 'Minimum Distance Between Levels (%)', minval = 0.1)
touchSensitivity = input.float(0.005, 'Minimum gap to get a touch i.e touch Sensitivity', minval = 0.001)
levelStrength = input.int(3, 'Required Touches for Strong Level', minval = 2, maxval = 10)
showStrength = input.bool(true, 'Show Level Strength')
lineStyle = input.string('Solid', 'Line Style', options = ['Solid', 'Dashed', 'Dotted'])

// Set line style based on input
var lineType = lineStyle == 'Solid' ? line.style_solid : lineStyle == 'Dashed' ? line.style_dashed : line.style_dotted

// Calculate pivot points
float ph = ta.pivothigh(high, pivotLength, pivotLength)
float pl = ta.pivotlow(low, pivotLength, pivotLength)

// Store significant levels and their data
var array<float> resistanceLevels = array.new_float(0)
var array<float> supportLevels = array.new_float(0)
var array<line> resistanceLines = array.new_line(0)
var array<line> supportLines = array.new_line(0)
var array<int> resistanceTouches = array.new_int(0)
var array<int> supportTouches = array.new_int(0)
var array<label> resistanceLabels = array.new_label(0)
var array<label> supportLabels = array.new_label(0)
var array<label> touchResistantLabels = array.new_label(0)
var array<label> touchSupportLabels = array.new_label(0)
var array<int> touchResistanceLevelIndex = array.new_int(0)
var array<int> touchSupportLevelIndex = array.new_int(0)

// Function to check if a new level is unique
isUniqueLevel(float newLevel, array<float> levels) =>
    if array.size(levels) == 0
        true
    else
        isUnique = true
        for i = 0 to array.size(levels) - 1 by 1
            existingLevel = array.get(levels, i)
            if not na(existingLevel) and not na(newLevel)
                if math.abs((newLevel - existingLevel) / existingLevel * 100) < minDistance
                    isUnique := false
                    break
        isUnique

// Function to remove oldest line and data
removeOldestLine(array<line> lines, array<float> levels, array<int> touches, array<label> labels, array<label> touchLabels, array<int> touchLevelIndex) =>
    if array.size(lines) > 0
        // Delete visual elements
        line.delete(array.get(lines, 0))
        label.delete(array.get(labels, 0))

        // Delete only touch labels for the oldest level (index 0)
        if array.size(touchLabels) > 0
            for i = array.size(touchLabels) - 1 to 0 by 1
                if array.get(touchLevelIndex, i) == 0
                    label.delete(array.get(touchLabels, i))
                    array.remove(touchLabels, i)
                    array.remove(touchLevelIndex, i)
                else
                    array.set(touchLevelIndex, i, array.get(touchLevelIndex, i) - 1)

        // Remove ONE item from main arrays
        array.shift(lines)
        array.shift(levels)
        array.shift(touches)
        array.shift(labels)

// Function to get level strength text
getLevelStrength(int touches) =>
    str = ''
    if touches >= levelStrength
        str := 'Strong'
        str
    else if touches > 1
        str := 'Moderate'
        str
    else
        str := 'New'
        str
    str

// Handle resistance levels
if not na(ph)
    if isUniqueLevel(ph, resistanceLevels)
        if array.size(resistanceLevels) >= maxLevels
            removeOldestLine(resistanceLines, resistanceLevels, resistanceTouches, resistanceLabels, touchResistantLabels, touchResistanceLevelIndex)

        array.push(resistanceLevels, ph)
        array.push(resistanceTouches, 1)

        strengthText = showStrength ? ' (' + getLevelStrength(1) + ')' : ''
        labelText = 'R: ' + str.tostring(ph, '#.##') + strengthText + ' [1]'

        newLine = line.new(bar_index[pivotLength], ph, bar_index + 20, ph, color = color.red, style = lineType, width = 1)
        array.push(resistanceLines, newLine)

        newLabel = label.new(bar_index[pivotLength], ph, text = labelText, style = label.style_label_down, color = color.red, textcolor = color.white, size = size.small)
        array.push(resistanceLabels, newLabel)

// Handle support levels
if not na(pl)
    if isUniqueLevel(pl, supportLevels)
        if array.size(supportLevels) >= maxLevels
            removeOldestLine(supportLines, supportLevels, supportTouches, supportLabels, touchSupportLabels, touchSupportLevelIndex)

        array.push(supportLevels, pl)
        array.push(supportTouches, 1)

        strengthText = showStrength ? ' (' + getLevelStrength(1) + ')' : ''
        labelText = 'S: ' + str.tostring(pl, '#.##') + strengthText + ' [1]'

        newLine = line.new(bar_index[pivotLength], pl, bar_index + 20, pl, color = color.green, style = lineType, width = 1)
        array.push(supportLines, newLine)

        newLabel = label.new(bar_index[pivotLength], pl, text = labelText, style = label.style_label_up, color = color.green, textcolor = color.white, size = size.small)
        array.push(supportLabels, newLabel)

// Update touches and labels for existing levels
if array.size(resistanceLevels) > 0
    for i = 0 to array.size(resistanceLevels) - 1 by 1
        level = array.get(resistanceLevels, i)
        if not na(level) and not na(high)
            if math.abs((high - level) / level * 100) < touchSensitivity
                touches = array.get(resistanceTouches, i)
                array.set(resistanceTouches, i, touches + 1)
                newTouches = touches + 1

                // Improved touch label visibility
                newLabelTouch = label.new(bar_index, high, text = '⬇', style = label.style_label_down, color = color.new(color.red, 20), textcolor = color.white, size = size.normal)
                array.push(touchResistantLabels, newLabelTouch)
                array.push(touchResistanceLevelIndex, i)

                if array.size(resistanceLabels) > i
                    label = array.get(resistanceLabels, i)
                    strengthText = showStrength ? ' (' + getLevelStrength(newTouches) + ')' : ''
                    labelText = 'R: ' + str.tostring(level, '#.##') + strengthText + ' [' + str.tostring(newTouches) + ']'
                    label.set_text(label, labelText)
                    label.set_color(label, newTouches >= levelStrength ? color.green : color.red)

if array.size(supportLevels) > 0
    for i = 0 to array.size(supportLevels) - 1 by 1
        level = array.get(supportLevels, i)
        if not na(level) and not na(low)
            if math.abs((low - level) / level * 100) < touchSensitivity
                touches = array.get(supportTouches, i)
                array.set(supportTouches, i, touches + 1)
                newTouches = touches + 1

                // Improved touch label visibility
                newLabelTouchSupport = label.new(bar_index, low, text = '⬆', style = label.style_label_up, color = color.new(color.green, 20), textcolor = color.white, size = size.normal)
                array.push(touchSupportLabels, newLabelTouchSupport)
                array.push(touchSupportLevelIndex, i)

                if array.size(supportLabels) > i
                    label = array.get(supportLabels, i)
                    strengthText = showStrength ? ' (' + getLevelStrength(newTouches) + ')' : ''
                    labelText = 'S: ' + str.tostring(level, '#.##') + strengthText + ' [' + str.tostring(newTouches) + ']'
                    label.set_text(label, labelText)
                    label.set_color(label, newTouches >= levelStrength ? color.green : color.red)

// Update line endpoints
if array.size(resistanceLines) > 0
    for i = 0 to array.size(resistanceLines) - 1 by 1
        line.set_x2(array.get(resistanceLines, i), bar_index + 20)
        touches = array.get(resistanceTouches, i)
        line.set_width(array.get(resistanceLines, i), touches >= levelStrength ? 2 : 1)

if array.size(supportLines) > 0
    for i = 0 to array.size(supportLines) - 1 by 1
        line.set_x2(array.get(supportLines, i), bar_index + 20)
        touches = array.get(supportTouches, i)
        line.set_width(array.get(supportLines, i), touches >= levelStrength ? 2 : 1)
Editor is loading...
Leave a Comment