← К каталогу
Исходный код · ID 4191

Wedge & Channel Detector

indicator_automatic_wedge_&_channel_detector_for_tradingview.pine
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Индикатор «Wedge & Channel Detector» предназначен для автоматического и ручного обнаружения схожих ценовых структур — клиньев и каналов — на графиках TradingView. Он определяет пивоты (вершины и впадины), строит верхнюю и нижнюю граничные линии, рассчитывает их характеристики и отображает результаты прямо на графике в виде линий и заливок.

Индикатор оценивает качество каждой структуры по совокупности касаний границ, нарушений, баланса между верхней и нижней сторонами, ширины и давности. На основе этих оценок присваивается текстовая категория качества (Excellent, Good, Fair, Poor) и уровень уверенности (High, Medium, Low). Также определяется тип структуры: канал, симметричный треугольник, нисходящий/возрастающий треугольник или клин, расширяющаяся структура.

Встроена система жизненного цикла структуры: отслеживаются подтверждённые пробои вверх и вниз, восстановление ценой внутри структуры, поздняя стадия схождения и прохождение вершины. Пользователь может настраивать все ключевые параметры через панель настроек, включая режим выбора структуры, пороги качества, визуальные элементы и условия оповещений. Доступны два условных оповещения — на подтверждённый пробой вверх и вниз.

Индикатор работает поверх графика (overlay), поддерживает до 60 линий и 100 меток, позволяет задавать пользовательский источник данных и отображает дополнительные зоны: центральную линию, зону без торговли, а также зоны поддержки и сопротивления.

Настройки программы

НастройкаОписание
selectionMode Режим подбора структуры: автоматический (поиск наилучшей по качеству) или ручной (выбор конкретных пивотов).
autoPivotCount Число наиболее недавних пивотов, используемых для автоматического подбора верхней и нижней границ структуры.
autoLookbackBars Количество баров назад, в пределах которых оценивается качество и релевантность обнаруженной структуры при автоматическом режиме выбора.
minAnchorSpacing Минимальное расстояние в барах между двумя якорными точками одной границы структуры.
upperLen Период обнаружения пивота высоких цен, определяющий чувствительность поиска верхних якорных точек.
lowerLen Период обнаружения пивота низких цен, определяющий чувствительность поиска нижних якорных точек.
manualUpperStart Номер начального пивота для ручного выбора верхней границы структуры.
manualUpperEnd Номер конечного пивота для ручного выбора верхней границы структуры.
manualLowerStart Номер начального пивота для ручного выбора нижней границы структуры.
manualLowerEnd Номер конечного пивота для ручного выбора нижней границы структуры (отсчёт от текущего бара).
useCustomSource Переключатель, активирующий использование пользовательского источника данных вместо стандартных значений High и Low.
customSource Источник данных, используемый для расчёта верхних и нижних пивотов при включённом переключателе пользовательского источника.
showCenterline Включает или отключает отображение центральной линии структуры, проведённой посередине между верхней и нижней границами.
showNoTradeZone Включает или отключает отображение центральной зоны без торговли между верхним и нижним процентными порогами.
noTradeLowPct Нижний процент от ширины структуры, определяющий границу центральной зоны без торговли.
noTradeHighPct Верхний процент от ширины структуры, определяющий границу центральной зоны без торговли.
showBoundaryZones Включает или отключает отображение зон поддержки и сопротивления у нижней и верхней границ структуры.
boundaryZonePct Процент от общей ширины структуры, определяющий толщину зон поддержки и сопротивления у нижней и верхней границ.
breakoutATR Множитель ATR, задающий минимальное расстояние от границы структуры для подтверждения пробоя ценой.
breakoutConfirmBars Количество последовательных баров, на которых цена должна оставаться за пределами границы для подтверждения пробоя.
expireAfterBreakBars Количество баров после подтверждённого пробоя, по истечении которого структура считается истёкшей и перестаёт отображаться как активная.
reclaimBars Количество баров, в течение которых цена должна вернуться внутрь структуры после пробоя для подтверждения восстановления.
lateStageWidthATR Максимальная нормализованная ширина структуры (в единицах ATR), при которой она считается находящейся в поздней стадии схождения.
lateStageApexBars Максимальное расстояние в барах до расчётной вершины схождения, при котором структура считается находящейся в поздней стадии.
showBrokenStructures Определяет, продолжают ли отображаться линии и зоны структуры после её пробоя или истечения.
touchToleranceATR Множитель ATR, задающий допустимое отклонение цены от линии границы для распознавания касания.
violationToleranceATR Множитель ATR, задающий порог, превышение которого ценой считается нарушением границы структуры.
minTouchSpacing Минимальное количество баров между двумя последовательными касаниями одной и той же границы структуры.
minStructureWidthATR Минимальная нормализованная ширина структуры в единицах ATR; структуры уже получают сниженную оценку.
maxStructureWidthATR Максимальная допустимая нормализованная ширина структуры в единицах ATR; структуры шире получают сниженную оценку.
balancePenaltyStart Порог отношения количества касаний верхней и нижней сторон, при превышении которого начинается штраф за дисбаланс в итоговой оценке качества.
balancePenaltyStrength Множитель, определяющий силу штрафа за дисбаланс касаний между верхней и нижней сторонами структуры.
convergenceProjectionBars Количество баров вперёд, на которое проецируется оценка силы конвергенции границ структуры.
weakConvergencePct Порог процентного сжатия структуры, при превышении которого конвергенция классифицируется как слабая.
strongConvergencePct Порог процентного сжатия структуры, при превышении которого конвергенция классифицируется как сильная.
highConfidenceQuality Минимальная оценка качества структуры, необходимая для присвоения категории высокой уверенности.
mediumConfidenceQuality Минимальная оценка качества структуры, необходимая для присвоения категории средней уверенности.
highConfidenceMinTouches Минимальное количество касаний каждой из сторон структуры, требуемое для категории высокой уверенности.
mediumConfidenceMinTouches Минимальное количество касаний каждой из сторон структуры, требуемое для категории средней уверенности.
highConfidenceMaxViolations Максимальное допустимое суммарное количество нарушений границ для присвоения структуре категории высокой уверенности.
mediumConfidenceMaxViolations Максимальное допустимое суммарное количество нарушений границ для присвоения структуре категории средней уверенности.
lineWidth Толщина линий верхней и нижней границ структуры, отображаемых на графике.
showPivotMarkers Включает или отключает отображение графических маркеров на графике в местах обнаруженных пивотов высоких и низких цен.
Получить полный код

Поиск по коду файла

indicator(
     "Wedge & Channel Detector",
     overlay = true,
     max_bars_back = 5000,
     max_lines_count = 60,
     max_labels_count = 100
)

groupMode = "Structure Selection"

selectionMode = input.string(
     "Auto",
     "Selection Mode",
     options = ["Auto", "Manual"],
     group = groupMode
)

autoPivotCount = input.int(
     5,
     "Recent Pivots To Test",
     minval = 3,
     maxval = 7,
     group = groupMode
)

autoLookbackBars = input.int(
     250,
     "Auto Scoring Lookback",
     minval = 50,
     maxval = 500,
     group = groupMode
)

minAnchorSpacing = input.int(
     10,
     "Minimum Anchor Spacing",
     minval = 2,
     maxval = 200,
     group = groupMode
)

groupPivot = "Pivot Detection"

upperLen = input.int(
     20,
     "Upper Pivot Length",
     minval = 1,
     group = groupPivot
)

lowerLen = input.int(
     20,
     "Lower Pivot Length",
     minval = 1,
     group = groupPivot
)

groupManual = "Manual Pivot Selection"

manualUpperStart = input.int(
     2,
     "Upper: From Pivot #",
     minval = 0,
     group = groupManual,
     inline = "upper"
)

manualUpperEnd = input.int(
     0,
     "To Pivot #",
     minval = 0,
     group = groupManual,
     inline = "upper"
)

manualLowerStart = input.int(
     3,
     "Lower: From Pivot #",
     minval = 0,
     group = groupManual,
     inline = "lower"
)

manualLowerEnd = input.int(
     0,
     "To Pivot #",
     minval = 0,
     group = groupManual,
     inline = "lower"
)

groupSource = "Source"

useCustomSource = input.bool(
     false,
     "Use Custom Source",
     group = groupSource
)

customSource = input.source(
     close,
     "Custom Source",
     group = groupSource
)

groupZones = "Structure Zones"

showCenterline = input.bool(
     true,
     "Show Centerline",
     group = groupZones
)

showNoTradeZone = input.bool(
     true,
     "Show Middle No-Trade Zone",
     group = groupZones
)

noTradeLowPct = input.float(
     40.0,
     "No-Trade Lower %",
     minval = 0.0,
     maxval = 100.0,
     step = 1.0,
     group = groupZones
)

noTradeHighPct = input.float(
     60.0,
     "No-Trade Upper %",
     minval = 0.0,
     maxval = 100.0,
     step = 1.0,
     group = groupZones
)

showBoundaryZones = input.bool(
     true,
     "Show Support / Resistance Zones",
     group = groupZones
)

boundaryZonePct = input.float(
     20.0,
     "Boundary Zone %",
     minval = 1.0,
     maxval = 49.0,
     step = 1.0,
     group = groupZones
)

groupLifecycle = "Structure Lifecycle"

breakoutATR = input.float(
     0.30,
     "Breakout Distance (ATR)",
     minval = 0.05,
     maxval = 3.0,
     step = 0.05,
     group = groupLifecycle
)

breakoutConfirmBars = input.int(
     2,
     "Breakout Confirmation Bars",
     minval = 1,
     maxval = 10,
     group = groupLifecycle
)

expireAfterBreakBars = input.int(
     10,
     "Expire After Break Bars",
     minval = 1,
     maxval = 100,
     group = groupLifecycle
)

reclaimBars = input.int(
     2,
     "Reclaim Bars",
     minval = 1,
     maxval = 10,
     group = groupLifecycle
)

lateStageWidthATR = input.float(
     1.5,
     "Late Stage Width (ATR)",
     minval = 0.1,
     maxval = 10.0,
     step = 0.1,
     group = groupLifecycle
)

lateStageApexBars = input.int(
     15,
     "Late Stage Apex Distance",
     minval = 1,
     maxval = 100,
     group = groupLifecycle
)

showBrokenStructures = input.bool(
     true,
     "Keep Broken Structure Visible",
     group = groupLifecycle
)

groupQuality = "Structure Quality"

touchToleranceATR = input.float(
     0.20,
     "Touch Tolerance (ATR)",
     minval = 0.05,
     maxval = 2.0,
     step = 0.05,
     group = groupQuality
)

violationToleranceATR = input.float(
     0.35,
     "Violation Tolerance (ATR)",
     minval = 0.05,
     maxval = 3.0,
     step = 0.05,
     group = groupQuality
)

minTouchSpacing = input.int(
     5,
     "Minimum Bars Between Touches",
     minval = 1,
     maxval = 100,
     group = groupQuality
)

minStructureWidthATR = input.float(
     1.0,
     "Minimum Width (ATR)",
     minval = 0.1,
     maxval = 20.0,
     step = 0.1,
     group = groupQuality
)

maxStructureWidthATR = input.float(
     20.0,
     "Maximum Preferred Width (ATR)",
     minval = 2.0,
     maxval = 100.0,
     step = 1.0,
     group = groupQuality
)

balancePenaltyStart = input.float(
     1.50,
     "Touch Imbalance Penalty Starts At",
     minval = 1.0,
     maxval = 5.0,
     step = 0.25,
     group = groupQuality
)

balancePenaltyStrength = input.float(
     8.0,
     "Touch Imbalance Penalty Strength",
     minval = 1.0,
     maxval = 20.0,
     step = 1.0,
     group = groupQuality
)

groupConvergence = "Convergence Strength"

convergenceProjectionBars = input.int(
     50,
     "Measure Convergence Over Bars",
     minval = 10,
     maxval = 250,
     group = groupConvergence
)

weakConvergencePct = input.float(
     10.0,
     "Weak Convergence %",
     minval = 0.0,
     maxval = 100.0,
     step = 1.0,
     group = groupConvergence
)

strongConvergencePct = input.float(
     30.0,
     "Strong Convergence %",
     minval = 0.0,
     maxval = 100.0,
     step = 1.0,
     group = groupConvergence
)

groupConfidence = "Structure Confidence"

highConfidenceQuality = input.float(
     82.0,
     "High Confidence Minimum Quality",
     minval = 0.0,
     maxval = 100.0,
     step = 1.0,
     group = groupConfidence
)

mediumConfidenceQuality = input.float(
     65.0,
     "Medium Confidence Minimum Quality",
     minval = 0.0,
     maxval = 100.0,
     step = 1.0,
     group = groupConfidence
)

highConfidenceMinTouches = input.int(
     3,
     "High Confidence Min Touches Each Side",
     minval = 1,
     maxval = 10,
     group = groupConfidence
)

mediumConfidenceMinTouches = input.int(
     2,
     "Medium Confidence Min Touches Each Side",
     minval = 1,
     maxval = 10,
     group = groupConfidence
)

highConfidenceMaxViolations = input.int(
     2,
     "High Confidence Max Total Violations",
     minval = 0,
     maxval = 25,
     group = groupConfidence
)

mediumConfidenceMaxViolations = input.int(
     5,
     "Medium Confidence Max Total Violations",
     minval = 0,
     maxval = 50,
     group = groupConfidence
)

groupVisual = "Visuals"

color upperColor = #A83A68
color lowerColor = #26C6B8
color centerColor = #667582
color noTradeColor = color.new(#667582, 88)
color supportZoneColor = color.new(#26C6B8, 90)
color resistanceZoneColor = color.new(#A83A68, 90)
color brokenColor = #FF4F87
color lateStageColor = #67F5C4

lineWidth = input.int(
     2,
     "Boundary Width",
     minval = 1,
     maxval = 4,
     group = groupVisual
)

showPivotMarkers = input.bool(
     true,
     "Show Pivot Markers",
     group = groupVisual
)

float upperSource = useCustomSource ? customSource : high
float lowerSource = useCustomSource ? customSource : low
float atr = ta.atr(14)

f_line_price(
     int x1,
     float y1,
     int x2,
     float y2,
     int targetX
) =>
    float result = na

    if (
         not na(x1) and
         not na(x2) and
         x1 != x2
    )
        float slope = (y2 - y1) / float(x2 - x1)
        result := y1 + slope * float(targetX - x1)

    result

f_score_structure(
     int ux1,
     float uy1,
     int ux2,
     float uy2,
     int lx1,
     float ly1,
     int lx2,
     float ly2
) =>
    float finalScore = na

    int upperTouchesLocal = 0
    int lowerTouchesLocal = 0
    int upperViolationsLocal = 0
    int lowerViolationsLocal = 0

    int lastUpperTouchX = na
    int lastLowerTouchX = na

    bool candidateValid = (
         ux2 > ux1 and
         lx2 > lx1 and
         ux2 - ux1 >= minAnchorSpacing and
         lx2 - lx1 >= minAnchorSpacing
    )

    if candidateValid

        float uSlope = (uy2 - uy1) / float(ux2 - ux1)
        float lSlope = (ly2 - ly1) / float(lx2 - lx1)

        int structureStart = math.max(
             ux1,
             lx1
        )

        float upperAtStart = f_line_price(
             ux1,
             uy1,
             ux2,
             uy2,
             structureStart
        )

        float lowerAtStart = f_line_price(
             lx1,
             ly1,
             lx2,
             ly2,
             structureStart
        )

        float widthAtStart = (
             upperAtStart -
             lowerAtStart
        )

        float upperCurrent = f_line_price(
             ux1,
             uy1,
             ux2,
             uy2,
             bar_index
        )

        float lowerCurrent = f_line_price(
             lx1,
             ly1,
             lx2,
             ly2,
             bar_index
        )

        float currentWidthLocal = (
             upperCurrent -
             lowerCurrent
        )

        bool convergingCandidate = (
             uSlope < lSlope
        )

        float candidateApexX = na

        float denominator = (
             uSlope -
             lSlope
        )

        if math.abs(denominator) > 0.0000001

            float upperIntercept = (
                 uy1 -
                 uSlope *
                 float(ux1)
            )

            float lowerIntercept = (
                 ly1 -
                 lSlope *
                 float(lx1)
            )

            candidateApexX := (
                 lowerIntercept -
                 upperIntercept
            ) / denominator

        bool apexAlreadyPassed = (
             convergingCandidate and
             not na(candidateApexX) and
             candidateApexX <= float(bar_index)
        )

        bool orderedAtStart = (
             widthAtStart > 0.0
        )

        bool orderedNow = (
             currentWidthLocal > 0.0
        )

        if (
             orderedAtStart and
             orderedNow and
             not apexAlreadyPassed
        )

            int availableBars = (
                 bar_index -
                 structureStart
            )

            int scanBars = math.min(
                 autoLookbackBars,
                 math.max(
                      0,
                      availableBars
                 )
            )

            for offset = 0 to scanBars

                int testX = (
                     bar_index -
                     offset
                )

                if testX >= structureStart

                    float testUpper = f_line_price(
                         ux1,
                         uy1,
                         ux2,
                         uy2,
                         testX
                    )

                    float testLower = f_line_price(
                         lx1,
                         ly1,
                         lx2,
                         ly2,
                         testX
                    )

                    float testATR = atr[offset]

                    float touchTol = (
                         not na(testATR)
                         ? testATR * touchToleranceATR
                         : 0.0
                    )

                    float violationTol = (
                         not na(testATR)
                         ? testATR * violationToleranceATR
                         : 0.0
                    )

                    bool upperNear = (
                         math.abs(
                              high[offset] -
                              testUpper
                         ) <= touchTol
                    )

                    bool lowerNear = (
                         math.abs(
                              low[offset] -
                              testLower
                         ) <= touchTol
                    )

                    bool upperViolation = (
                         close[offset] >
                         testUpper +
                         violationTol
                    )

                    bool lowerViolation = (
                         close[offset] <
                         testLower -
                         violationTol
                    )

                    if upperNear

                        bool spacedUpper = (
                             na(lastUpperTouchX) or
                             math.abs(
                                  testX -
                                  lastUpperTouchX
                             ) >= minTouchSpacing
                        )

                        if spacedUpper
                            upperTouchesLocal += 1
                            lastUpperTouchX := testX

                    if lowerNear

                        bool spacedLower = (
                             na(lastLowerTouchX) or
                             math.abs(
                                  testX -
                                  lastLowerTouchX
                             ) >= minTouchSpacing
                        )

                        if spacedLower
                            lowerTouchesLocal += 1
                            lastLowerTouchX := testX

                    if upperViolation
                        upperViolationsLocal += 1

                    if lowerViolation
                        lowerViolationsLocal += 1

            int totalTouchesLocal = (
                 upperTouchesLocal +
                 lowerTouchesLocal
            )

            int totalViolationsLocal = (
                 upperViolationsLocal +
                 lowerViolationsLocal
            )

            int minTouches = math.min(
                 upperTouchesLocal,
                 lowerTouchesLocal
            )

            int maxTouches = math.max(
                 upperTouchesLocal,
                 lowerTouchesLocal
            )

            float touchScore = math.min(
                 35.0,
                 float(totalTouchesLocal) *
                 5.0
            )

            float balanceFactor = (
                 totalTouchesLocal > 0
                 ? (
                      1.0 -
                      math.abs(
                           float(
                                upperTouchesLocal -
                                lowerTouchesLocal
                           )
                      ) /
                      float(totalTouchesLocal)
                   )
                 : 0.0
            )

            float balanceScore = (
                 balanceFactor *
                 15.0
            )

            float violationScore = math.max(
                 0.0,
                 25.0 -
                 float(totalViolationsLocal) *
                 3.0
            )

            int upperSpan = (
                 ux2 -
                 ux1
            )

            int lowerSpan = (
                 lx2 -
                 lx1
            )

            float averageSpan = (
                 float(upperSpan) +
                 float(lowerSpan)
            ) / 2.0

            float spanScore = math.min(
                 10.0,
                 averageSpan /
                 15.0
            )

            int newestAnchor = math.max(
                 ux2,
                 lx2
            )

            float recencyScore = math.max(
                 0.0,
                 10.0 -
                 float(
                      bar_index -
                      newestAnchor
                 ) *
                 0.15
            )

            float candidateWidthATR = (
                 atr > 0.0
                 ? currentWidthLocal /
                   atr
                 : na
            )

            float widthScore = 0.0

            if not na(candidateWidthATR)

                if (
                     candidateWidthATR >= minStructureWidthATR and
                     candidateWidthATR <= maxStructureWidthATR
                )

                    widthScore := 5.0

                else if (
                     candidateWidthATR <
                     minStructureWidthATR
                )

                    widthScore := math.max(
                         0.0,
                         (
                              candidateWidthATR /
                              minStructureWidthATR
                         ) *
                         5.0
                    )

                else

                    widthScore := math.max(
                         0.0,
                         5.0 -
                         (
                              candidateWidthATR -
                              maxStructureWidthATR
                         ) *
                         0.25
                    )

            finalScore := (
                 touchScore +
                 balanceScore +
                 violationScore +
                 spanScore +
                 recencyScore +
                 widthScore
            )

            if minTouches < 2

                finalScore := math.min(
                     finalScore,
                     59.0
                )

            else if minTouches < 3

                finalScore := math.min(
                     finalScore,
                     84.0
                )

            if minTouches > 0

                float touchRatio = float(maxTouches) / float(minTouches)

                if touchRatio > balancePenaltyStart

                    float imbalancePenalty = (touchRatio - balancePenaltyStart) * balancePenaltyStrength

                    finalScore -= imbalancePenalty

                if touchRatio >= 2.0
                    finalScore := math.min(finalScore, 84.0)

                if touchRatio >= 2.5
                    finalScore := math.min(finalScore, 74.0)

                if touchRatio >= 3.0
                    finalScore := math.min(finalScore, 59.0)

            finalScore := math.max(0.0, math.min(100.0, finalScore))

float pivotHigh = ta.pivothigh(
     upperSource,
     upperLen,
     upperLen
)

float pivotLow = ta.pivotlow(
     lowerSource,
     lowerLen,
     lowerLen
)

bool newUpperPivot = (
     not na(pivotHigh)
)

bool newLowerPivot = (
     not na(pivotLow)
)

var array<int> upperPivotBars = array.new_int()
var array<float> upperPivotPrices = array.new_float()

var array<int> lowerPivotBars = array.new_int()
var array<float> lowerPivotPrices = array.new_float()

if newUpperPivot

    array.unshift(
         upperPivotBars,
         bar_index -
         upperLen
    )

    array.unshift(
         upperPivotPrices,
         pivotHigh
    )

    if (
         array.size(
              upperPivotBars
         ) >
         autoPivotCount
    )

        array.pop(
             upperPivotBars
        )

        array.pop(
             upperPivotPrices
        )

if newLowerPivot

    array.unshift(
         lowerPivotBars,
         bar_index -
         lowerLen
    )

    array.unshift(
         lowerPivotPrices,
         pivotLow
    )

    if (
         array.size(
              lowerPivotBars
         ) >
         autoPivotCount
    )

        array.pop(
             lowerPivotBars
        )

        array.pop(
             lowerPivotPrices
        )

var int autoUpperX1 = na
var float autoUpperY1 = na

var int autoUpperX2 = na
var float autoUpperY2 = na

var int autoLowerX1 = na
var float autoLowerY1 = na

var int autoLowerX2 = na
var float autoLowerY2 = na

var float autoSelectionScore = na

bool shouldRescanAuto = (
     selectionMode == "Auto" and
     (
          newUpperPivot or
          newLowerPivot or
          na(autoSelectionScore)
     )
)

if (
     shouldRescanAuto and
     array.size(
          upperPivotBars
     ) >= 2 and
     array.size(
          lowerPivotBars
     ) >= 2
)

    float bestScore = na

    int bestUX1 = na
    float bestUY1 = na

    int bestUX2 = na
    float bestUY2 = na

    int bestLX1 = na
    float bestLY1 = na

    int bestLX2 = na
    float bestLY2 = na

    int upperCount = array.size(
         upperPivotBars
    )

    int lowerCount = array.size(
         lowerPivotBars
    )

    for uNew = 0 to upperCount - 2

        for uOld = uNew + 1 to upperCount - 1

            int testUX1 = array.get(
                 upperPivotBars,
                 uOld
            )

            float testUY1 = array.get(
                 upperPivotPrices,
                 uOld
            )

            int testUX2 = array.get(
                 upperPivotBars,
                 uNew
            )

            float testUY2 = array.get(
                 upperPivotPrices,
                 uNew
            )

            for lNew = 0 to lowerCount - 2

                for lOld = lNew + 1 to lowerCount - 1

                    int testLX1 = array.get(
                         lowerPivotBars,
                         lOld
                    )

                    float testLY1 = array.get(
                         lowerPivotPrices,
                         lOld
                    )

                    int testLX2 = array.get(
                         lowerPivotBars,
                         lNew
                    )

                    float testLY2 = array.get(
                         lowerPivotPrices,
                         lNew
                    )

                    float candidateScore = f_score_structure(
                         testUX1,
                         testUY1,
                         testUX2,
                         testUY2,
                         testLX1,
                         testLY1,
                         testLX2,
                         testLY2
                    )

                    bool betterCandidate = (
                         not na(candidateScore) and
                         (
                              na(bestScore) or
                              candidateScore >
                              bestScore
                         )
                    )

                    if betterCandidate

                        bestScore := candidateScore

                        bestUX1 := testUX1
                        bestUY1 := testUY1

                        bestUX2 := testUX2
                        bestUY2 := testUY2

                        bestLX1 := testLX1
                        bestLY1 := testLY1

                        bestLX2 := testLX2
                        bestLY2 := testLY2

    if not na(bestUX1)

        autoUpperX1 := bestUX1
        autoUpperY1 := bestUY1

        autoUpperX2 := bestUX2
        autoUpperY2 := bestUY2

        autoLowerX1 := bestLX1
        autoLowerY1 := bestLY1

        autoLowerX2 := bestLX2
        autoLowerY2 := bestLY2

        autoSelectionScore := bestScore

float manualUpperY1 = ta.valuewhen(
     newUpperPivot,
     pivotHigh,
     manualUpperStart
)

float manualUpperY2 = ta.valuewhen(
     newUpperPivot,
     pivotHigh,
     manualUpperEnd
)

int manualUpperX1 = int(
     ta.valuewhen(
          newUpperPivot,
          bar_index -
          upperLen,
          manualUpperStart
     )
)

int manualUpperX2 = int(
     ta.valuewhen(
          newUpperPivot,
          bar_index -
          upperLen,
          manualUpperEnd
     )
)

float manualLowerY1 = ta.valuewhen(
     newLowerPivot,
     pivotLow,
     manualLowerStart
)

float manualLowerY2 = ta.valuewhen(
     newLowerPivot,
     pivotLow,
     manualLowerEnd
)

int manualLowerX1 = int(
     ta.valuewhen(
          newLowerPivot,
          bar_index -
          lowerLen,
          manualLowerStart
     )
)

int manualLowerX2 = int(
     ta.valuewhen(
          newLowerPivot,
          bar_index -
          lowerLen,
          manualLowerEnd
     )
)
var table wm = table.new(position.bottom_right, 1, 1)
if barstate.isfirst
    table.cell(wm, 0, 0, "Telegram @SimpleForexTools", text_color = color.new(color.gray, 70), text_size = size.large)

int upperX1 = (
     selectionMode ==
     "Auto"
     ? autoUpperX1
     : manualUpperX1
)

float upperY1 = (
     selectionMode ==
     "Auto"
     ? autoUpperY1
     : manualUpperY1
)

int upperX2 = (
     selectionMode ==
     "Auto"
     ? autoUpperX2
     : manualUpperX2
)

float upperY2 = (
     selectionMode ==
     "Auto"
     ? autoUpperY2
     : manualUpperY2
)

int lowerX1 = (
     selectionMode ==
     "Auto"
     ? autoLowerX1
     : manualLowerX1
)

float lowerY1 = (
     selectionMode ==
     "Auto"
     ? autoLowerY1
     : manualLowerY1
)

int lowerX2 = (
     selectionMode ==
     "Auto"
     ? autoLowerX2
     : manualLowerX2
)

float lowerY2 = (
     selectionMode ==
     "Auto"
     ? autoLowerY2
     : manualLowerY2
)

bool validUpper = (
     not na(upperX1) and
     not na(upperX2) and
     not na(upperY1) and
     not na(upperY2) and
     upperX1 != upperX2
)

bool validLower = (
     not na(lowerX1) and
     not na(lowerX2) and
     not na(lowerY1) and
     not na(lowerY2) and
     lowerX1 != lowerX2
)

bool structureValid = (
     validUpper and
     validLower
)

float upperNow = (
     validUpper
     ? f_line_price(
          upperX1,
          upperY1,
          upperX2,
          upperY2,
          bar_index
       )
     : na
)

float lowerNow = (
     validLower
     ? f_line_price(
          lowerX1,
          lowerY1,
          lowerX2,
          lowerY2,
          bar_index
       )
     : na
)

float structureWidth = (
     structureValid
     ? upperNow -
       lowerNow
     : na
)

bool boundariesOrdered = (
     structureValid and
     not na(structureWidth) and
     structureWidth > 0.0
)

float upperSlope = (
     validUpper
     ? (
          upperY2 -
          upperY1
       ) /
       float(
          upperX2 -
          upperX1
       )
     : na
)

float lowerSlope = (
     validLower
     ? (
          lowerY2 -
          lowerY1
       ) /
       float(
          lowerX2 -
          lowerX1
       )
     : na
)

bool converging = (
     structureValid and
     upperSlope <
     lowerSlope
)

bool expanding = (
     structureValid and
     upperSlope >
     lowerSlope
)

float slopeDiff = (
     structureValid
     ? math.abs(
          upperSlope -
          lowerSlope
       )
     : na
)

float largestSlope = (
     structureValid
     ? math.max(
          math.abs(
               upperSlope
          ),
          math.abs(
               lowerSlope
          )
       )
     : na
)

bool roughlyParallel = (
     structureValid and
     (
          largestSlope == 0.0 or
          slopeDiff <=
          largestSlope *
          0.10
     )
)

float apexX = na

if (
     structureValid and
     not roughlyParallel
)

    float upperIntercept = (
         upperY1 -
         upperSlope *
         float(
              upperX1
         )
    )

    float lowerIntercept = (
         lowerY1 -
         lowerSlope *
         float(
              lowerX1
         )
    )

    float denominator = (
         upperSlope -
         lowerSlope
    )

    if (
         math.abs(
              denominator
         ) >
         0.0000001
    )

        apexX := (lowerIntercept - upperIntercept) / denominator

float barsToApex = (
     converging and
     not na(apexX)
     ? apexX -
       float(
            bar_index
       )
     : na
)

bool apexPassed = (
     converging and
     not na(
          barsToApex
     ) and
     barsToApex <= 0.0
)

float widthATR = (
     boundariesOrdered and
     atr > 0.0
     ? structureWidth /
       atr
     : na
)

float projectedUpper = (
     structureValid
     ? f_line_price(
          upperX1,
          upperY1,
          upperX2,
          upperY2,
          bar_index +
          convergenceProjectionBars
       )
     : na
)

float projectedLower = (
     structureValid
     ? f_line_pr

Показано первые 50% кода (символов: 29181)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
2 918,10₽ ≈ $35.66