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

Wyckoff Accumulation & Distribution, Spring, UTAD, SOS

indicator_wyckoff_accumulation_&_distribution,_spring,_utad,_sos.pine
Вы автор или правообладатель?

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

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

О программе

Индикатор реализует схему Уикоффа на графике TradingView: последовательно отслеживает кульминацию (SC/BC), авторалли/реакцию (AR), вторичное тестирование (ST), пружину/UTAD, знак силы/слабости (SOS/SOW) и последнюю точку поддержки/снабжения (LPS/LPSY). Фазы A–E отмечаются на графике, путь проходит через события, а высота диапазона проецируется как целевые уровни. Все события подтверждаются на закрытых свечах, без перерисовки.

Встроена панель с лестницей фаз, текущим положением цены в диапазоне и историей по символу (количество диапазонов, процент пружин, SOS/SOW, попаданий T2 и отказов). Индикатор поддерживает оповещения TradingView для ключевых событий: кульминация, формирование диапазона, пружина/UTAD, SOS/SOW, LPS/LPSY, попадание цели и завершение/отказ схемы. Отображение включает неоновые и светящиеся свечи.

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

НастройкаОписание
side Выбор схем: «Оба» (аккумуляция и распределение), только «Аккумуляция» или только «Распределение».
trendLen Количество свечей назад для поиска клаймакса: продажа клаймакса должна зафиксировать минимум за этот период, покупка — максимум.
climRng Минимальная ширина свечного диапазона клаймакса в кратных ATR для распознавания кульминационной свечи.
climVol Минимальный объём клаймакса в кратных среднему объёму за 20 свечей. На символах без объёма игнорируется.
pivLen Количество свечей с каждой стороны для подтверждения свечного пика (разгона/замедления).
arMin Минимальная величина авторалли или реакции в кратных ATR, необходимая для подтверждения перехода от фазы клаймакса к формированию диапазона.
maxH Максимальная высота диапазона в кратных ATR. Если разница между клаймаксом и авторалли превышает это значение, схема отклоняется.
minRange Минимальная длина диапазона в свечах. Если цена покидает диапазон раньше, это считается V-разворотом, а не диапазоном Уикоффа, и модель отбрасывается.
stTol Допустимая зона вторичного тестирования как доля высоты диапазона.
sprBars Максимальное количество свечей, на которые пружина или UTAD может выходить за пределы диапазона, прежде чем закрыться обратно внутри.
failDep Глубина пробоя в долях диапазона: если закрытие пробитает этот уровень за пределами клаймакса, диапазон считается пробитым и схема отклоняется.
maxRng Максимальное количество свечей для завершения диапазона. При превышении диапазон считается истёкшим.
maxLeg Максимальное количество свечей от SOS/SOW до завершения маркапа/маркдауна. При превышении диапазон считается истёкшим.
showPh Отображение букв фаз A–E на графике.
showTgt Отображение целевых уровней (T1, T2) и уровня недействительности на графике.
keepN Количество завершённых диапазонов, оставляемых на графике. Более старые диапазоны удаляются, но сохраняются в истории.
lblSize Размер меток на графике.
showTbl Отображение информационной панели с лестницей фаз и статистикой.
tblPos Положение информационной панели на графике.
tblSize Размер текста в информационной панели.
alRange Включает оповещение при обнаружении кульминации и формировании торгового диапазона.
alTest Включает оповещение при подтверждении пружины (Spring) или UTAD.
alSos Включает оповещение при появлении знака силы/слабости (SOS/SOW) и подтверждении последней точки поддержки/снабжения (LPS/LPSY).
alTgt Включает оповещение при достижении целевого уровня, завершении схемы или её отказе.
candOn_ Включает отображение неоновых свечей на графике.
candGlw Включает светящиеся свечи: каждое тело отрисовывается в четырёх полосах, яркость которых возрастает к закрытию, что улучшает считывание направления движения. Выкл = полупрозрачные плоские тела.
Получить полный код

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

indicator("Wyckoff Accumulation & Distribution, Spring, UTAD, SOS [@simpleforextools]", "Wyckoff [@simpleforextools]",
     overlay = true, max_lines_count = 300, max_labels_count = 400, max_boxes_count = 60, max_polylines_count = 60)

gM = "Schematic"
side     = input.string("Both", "Schematics", options = ["Both", "Accumulation", "Distribution"], group = gM)
trendLen = input.int(50, "Climax lookback (bars)", minval = 10, maxval = 300, group = gM,
     tooltip = "A selling climax must print the lowest low of this many bars, a buying climax the highest high.")
climRng  = input.float(1.2, "Climax bar range (× ATR)", minval = 0.5, maxval = 5.0, step = 0.1, group = gM)
climVol  = input.float(1.5, "Climax volume (× 20-bar average)", minval = 1.0, maxval = 6.0, step = 0.1, group = gM,
     tooltip = "Ignored on symbols that publish no volume.")
pivLen   = input.int(3, "Swing strength", minval = 2, maxval = 10, group = gM, tooltip = "Bars on each side that confirm a swing high or low.")
arMin    = input.float(2.0, "Min. automatic rally / reaction (× ATR)", minval = 0.5, maxval = 10.0, step = 0.1, group = gM)
maxH     = input.float(10.0, "Max. range height (× ATR)", minval = 3.0, maxval = 30.0, step = 0.5, group = gM)
minRange = input.int(15, "Min. range length (bars)", minval = 5, maxval = 200, group = gM,
     tooltip = "If price leaves the range sooner than this, it was a V-turn, not a Wyckoff range, and the model is dropped.")
stTol    = input.float(0.35, "Secondary test zone (part of range)", minval = 0.1, maxval = 0.6, step = 0.05, group = gM)
sprBars  = input.int(3, "Spring / UTAD max. bars outside", minval = 1, maxval = 10, group = gM,
     tooltip = "A spring (or UTAD) is a break of the climax side that closes back inside the range within this many bars.")
failDep  = input.float(0.30, "Break depth (part of range)", minval = 0.1, maxval = 1.0, step = 0.05, group = gM,
     tooltip = "A close this far beyond the climax side breaks the range, and the schematic fails.")
maxRng   = input.int(300, "Range expiry (bars)", minval = 50, maxval = 2000, group = gM)
maxLeg   = input.int(300, "Markup / markdown expiry (bars)", minval = 50, maxval = 2000, group = gM)

gD = "Drawing"
showPath = input.bool(true, "Draw the schematic path", group = gD)
showPh   = input.bool(true, "Phase letters A–E", group = gD)
showTgt  = input.bool(true, "Targets and invalidation", group = gD)
keepN    = input.int(3, "Ranges drawn", minval = 1, maxval = 20, group = gD, tooltip = "Finished ranges older than this are removed from the chart. The track record keeps all of them.")
lblSize  = input.string("Normal", "Label size", options = ["Small", "Normal", "Large"], group = gD)

gP = "Panel"
showTbl  = input.bool(true, "Show panel", group = gP)
tblPos   = input.string("Top Right", "Position", options = ["Top Right", "Bottom Right", "Top Left", "Bottom Left"], group = gP)
tblSize  = input.string("Normal", "Text size", options = ["Small", "Normal", "Large"], group = gP)

gA = "Alerts"
alRange  = input.bool(true, "Alert: climax and trading range", group = gA)
alTest   = input.bool(true, "Alert: spring / UTAD", group = gA)
alSos    = input.bool(true, "Alert: SOS / SOW and LPS / LPSY", group = gA)
alTgt    = input.bool(true, "Alert: target hit / complete / failed", group = gA)

candOn_  = input.bool(true, "Neon candles", group = "Visuals")
candGlw  = input.bool(true, "Glow candles", group = "Visuals", tooltip = "Each body is drawn in four bands that brighten towards the close, so the candle reads in the direction it moved. Off = flat translucent bodies.")

bgLum   = 0.2126 * color.r(chart.bg_color) + 0.7152 * color.g(chart.bg_color) + 0.0722 * color.b(chart.bg_color)
isLight = bgLum > 128
UP      = isLight ? #4E9A06 : #B4FF39   // acid lime: accumulation, rising candles
DN      = isLight ? #D9480F : #FF6B2C   // ember: distribution, falling candles
ACC     = isLight ? #3F4BD9 : #7C8CFF   // electric indigo: trading range and phases
ACCX    = isLight ? #2F38A8 : #B4BDFF   // light indigo for text
GREY    = isLight ? #8A8F9C : #5A6070
TXT     = isLight ? #1A1D24 : #ECEEF4
MUTE    = isLight ? #5E6472 : #969CAB
PANEL   = isLight ? #FFFFFF : #0A0C12
ROW     = isLight ? #F0F2F8 : #13161F
INK     = #0A0C12
NONE    = color.new(color.black, 100)

lSize = lblSize == "Small" ? size.small : lblSize == "Large" ? size.large : size.normal
tSize = tblSize == "Small" ? size.small : tblSize == "Large" ? size.large : size.normal

px(float v) =>
    str.tostring(v, format.mintick)

pct(int a, int b) =>
    b > 0 ? str.tostring(a * 100.0 / b, "0") + "%" : "—"

atr    = ta.atr(50)
avgV   = ta.sma(nz(volume), 20)
hasVol = avgV > 0
rngOk  = not na(atr) and high - low >= climRng * atr
volOk  = not hasVol or nz(volume) >= climVol * avgV
newLo  = low <= ta.lowest(low, trendLen)
newHi  = high >= ta.highest(high, trendLen)
ph     = ta.pivothigh(high, pivLen, pivLen)
pl     = ta.pivotlow(low, pivLen, pivLen)
pBar   = bar_index - pivLen

var int   stage  = 0
var int   dir    = 0
var int   startBar = na
var float ext    = na      // climax extreme
var int   extBar = na
var float arP    = na
var int   arBar  = na
var float trTop  = na
var float trBot  = na
var float trMid  = na
var float rngH   = na
var float cs     = na      // climax side of the range (support in accumulation)
var float bs     = na      // breakout side: the creek in accumulation, the ice in distribution
var bool  stOn   = false
var bool  sprOn  = false
var float sprExt = na
var int   sprBar = na
var bool  pend   = false
var int   pendN  = 0
var float pendExt = na
var int   pendExtBar = na
var int   sosBar = na
var bool  lpsOn  = false
var float t1     = na
var float t2     = na
var float inv    = na
var int   hitMax = 0

var array<chart.point> pts = array.new<chart.point>()

var box      trBox  = na
var line     bsLn   = na
var label    bsLb   = na
var label    climLb = na
var polyline schPl  = na
var line     t1Ln = na
var line     t2Ln = na
var line     invLn = na
var label    t1Lb = na
var label    t2Lb = na
var label    invLb = na

var array<int> rN    = array.new_int(2, 0)
var array<int> rSpr  = array.new_int(2, 0)
var array<int> rSos  = array.new_int(2, 0)
var array<int> rT1   = array.new_int(2, 0)
var array<int> rT2   = array.new_int(2, 0)
var array<int> rFail = array.new_int(2, 0)
var array<int> rLen  = array.new_int(2, 0)

evClim  = false
evRange = false
evSpr   = false
evSos   = false
evLps   = false
evHit   = 0
evFrom  = 0
evDone  = false
evFail  = false
evExp   = false
evDrop  = false
evEnd   = false

bump(array<int> a, int i, int add) =>
    array.set(a, i, array.get(a, i) + add)

var int mId = 0
var array<line>     gLn  = array.new<line>()
var array<int>      gLnI = array.new_int()
var array<label>    gLb  = array.new<label>()
var array<int>      gLbI = array.new_int()
var array<box>      gBx  = array.new<box>()
var array<int>      gBxI = array.new_int()
var array<polyline> gPl  = array.new<polyline>()
var array<int>      gPlI = array.new_int()

regLn(line o) =>
    array.push(gLn, o)
    array.push(gLnI, mId)
regLb(label o) =>
    array.push(gLb, o)
    array.push(gLbI, mId)
regBx(box o) =>
    array.push(gBx, o)
    array.push(gBxI, mId)
regPl(polyline o) =>
    array.push(gPl, o)
    array.push(gPlI, mId)

prune(int upTo) =>
    while array.size(gLnI) > 0 and array.get(gLnI, 0) <= upTo
        line.delete(array.shift(gLn))
        array.shift(gLnI)
    while array.size(gLbI) > 0 and array.get(gLbI, 0) <= upTo
        label.delete(array.shift(gLb))
        array.shift(gLbI)
    while array.size(gBxI) > 0 and array.get(gBxI, 0) <= upTo
        box.delete(array.shift(gBx))
        array.shift(gBxI)
    while array.size(gPlI) > 0 and array.get(gPlI, 0) <= upTo
        polyline.delete(array.shift(gPl))
        array.shift(gPlI)

dropTail(int id) =>
    while array.size(gLnI) > 0 and array.last(gLnI) == id
        line.delete(array.pop(gLn))
        array.pop(gLnI)
    while array.size(gLbI) > 0 and array.last(gLbI) == id
        label.delete(array.pop(gLb))
        array.pop(gLbI)
    while array.size(gBxI) > 0 and array.last(gBxI) == id
        box.delete(array.pop(gBx))
        array.pop(gBxI)
    while array.size(gPlI) > 0 and array.last(gPlI) == id
        polyline.delete(array.pop(gPl))
        array.pop(gPlI)

evLb(int x, float y, string t, bool below, color bg, color fg) =>
    lb = label.new(x, y, t, style = below ? label.style_label_up : label.style_label_down, color = bg, textcolor = fg, size = lSize)
    regLb(lb)
    lb

phLb(int x, string t) =>
    if showPh
        regLb(label.new(x, trTop, t, style = label.style_label_down, color = NONE, textcolor = ACCX, size = lSize))

redraw(polyline old, color c) =>
    polyline.delete(old)
    polyline p = na
    if showPath and array.size(pts) > 1
        p := polyline.new(pts, curved = true, line_color = color.new(c, 25), line_width = 2, line_style = line.style_solid)
        regPl(p)
    p

tgtLn(float y, color c, int w, string st) =>
    l = line.new(sosBar, y, bar_index + 3, y, color = c, width = w, style = st)
    regLn(l)
    l

tgtLb(float y, string t, color c) =>
    l = label.new(bar_index + 3, y, t, style = label.style_label_left, color = INK, textcolor = c, size = lSize)
    regLb(l)
    l
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)

if barstate.isconfirmed and not na(atr)
    age    = bar_index - startBar
    early  = age < minRange
    wickC  = dir == 1 ? low : high       // the wick on the climax side
    fav    = dir == 1 ? high : low       // the wick on the breakout side
    dc     = dir == 1 ? UP : DN

    if stage >= 4
        prevHit = hitMax
        if (fav - t2) * dir >= 0
            hitMax := 2
        else if hitMax < 1 and (fav - t1) * dir >= 0
            hitMax := 1
        if hitMax > prevHit
            evHit  := hitMax
            evFrom := prevHit
        if hitMax == 2
            evDone := true
        else if (inv - close) * dir > 0
            evFail := true
        else if bar_index - sosBar > maxLeg
            evExp := true
        if stage == 4 and not evDone and not evFail
            pv = dir == 1 ? pl : ph
            if not na(pv) and pBar > sosBar and (pv - trMid) * dir > 0
                stage := 5
                lpsOn := true
                evLps := true
                evLb(pBar, pv, dir == 1 ? "LPS" : "LPSY", dir == 1, dc, INK)
                phLb(pBar, "E")
                array.push(pts, chart.point.from_index(pBar, pv))
                schPl := redraw(schPl, dc)

    else if stage == 2 or stage == 3
        if stage == 2 and not pend and not stOn
            pv = dir == 1 ? pl : ph
            if not na(pv) and pBar > arBar and (pv - cs) * dir >= 0 and (pv - cs) * dir <= stTol * rngH
                stOn := true
                evLb(pBar, pv, "ST", dir == 1, GREY, color.white)
                phLb(pBar, "B")
                array.push(pts, chart.point.from_index(pBar, pv))
                schPl := redraw(schPl, dc)
        if (close - bs) * dir > 0
            if early
                evDrop := true
            else
                stage  := 4
                sosBar := bar_index
                evSos  := true
                t1  := bs + dir * rngH
                t2  := bs + dir * 2 * rngH
                inv := sprOn ? sprExt : cs
                evLb(bar_index, fav, dir == 1 ? "SOS" : "SOW", dir == -1, dc, INK)
                phLb(bar_index, "D")
                array.push(pts, chart.point.from_index(bar_index, fav))
                schPl := redraw(schPl, dc)
                box.set_right(trBox, bar_index)
                line.set_x2(bsLn, bar_index)
                label.set_x(bsLb, bar_index)
                if showTgt
                    t1Ln  := tgtLn(t1, color.new(dc, 10), 2, line.style_solid)
                    t2Ln  := tgtLn(t2, color.new(dc, 10), 2, line.style_dashed)
                    invLn := tgtLn(inv, color.new(GREY, 10), 1, line.style_dotted)
                    t1Lb  := tgtLb(t1, "T1 · 1× range  " + px(t1), dc)
                    t2Lb  := tgtLb(t2, "T2 · 2× range  " + px(t2), dc)
                    invLb := tgtLb(inv, "INVALID  " + px(inv), MUTE)
        else if stage == 2
            if pend
                pendN += 1
                if (pendExt - wickC) * dir > 0
                    pendExt    := wickC
                    pendExtBar := bar_index
                if (close - cs) * dir >= 0
                    pend := false
                    if not early
                        sprOn  := true
                        sprExt := pendExt
                        sprBar := pendExtBar
                else if (cs - close) * dir > failDep * rngH or pendN > sprBars
                    if early
                        evDrop := true
                    else
                        evFail := true
            else if (cs - wickC) * dir > 0
                if (close - cs) * dir >= 0
                    if not early
                        sprOn  := true
                        sprExt := wickC
                        sprBar := bar_index
                else if (cs - close) * dir > failDep * rngH
                    if early
                        evDrop := true
                    else
                        evFail := true
                else
                    pend       := true
                    pendN      := 1
                    pendExt    := wickC
                    pendExtBar := bar_i

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

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

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

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

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

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

Стоимость полного кода
1 914,80₽ ≈ $23.43