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

HTF 5+1 | Sattam

indicator htf 5+1 sattam for tradingview.pine
Вы автор или правообладатель?

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

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

О программе

Индикатор «HTF 5+1 | Sattam» — это инструмент технического анализа для TradingView, работающий на четырёхчасовом графике. Он реализует методологию 5+1 чек-листа для выявления торговых установок, объединяя разрывы структуры, ликвидные захваты, анализ объёмов, ордер-блоки и уровни Фибоначчи.

Индикатор определяет точки свинга с помощью настраиваемых параметров пивотов, отслеживает разрывы структуры с подтверждением объёмом и выявляет ликвидные захваты на подчинённых уровнях свинга. Ордер-блоки автоматически подсвечиваются и помечаются как смитигированные при касании ценой. Уровни Фибоначчи строятся от защищённых свингов к точкам входа с заданным ретрейсментом.

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

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

НастройкаОписание
iSwing Количество подтвердительных баров для определения свингов. Свинг принимается после закрытия указанного числа баров без нового экстремума. Диапазон от 1 до 10.
iMedium Включает или отключает отображение захватов средней вероятности — спредов подчинённых свингов, не сумевших пробить структуру.
iInternal Включает внутренние установки (контр-трендовые сделки внутри коррекции), которые имеют более низкую вероятность по сравнению с основными.
iInnSwing Количество баров для определения внутренних свингов при активированной настройке внутренних установок. Диапазон от 1 до 5.
iFib Уровень ретрейсмента Фибоначчи для входа в позицию. По умолчанию 0.71 — это уровень, на котором строится лимитный ордер.
iObLimit Включает или отключает второй лимит на ближайший ордер-блок — возможность использования ордер-блока в качестве цели для лимитного ордера.
iObRR Множитель риска/вознаграждения для целевого уровня ордер-блока. Определяет соотношение тейк-профита к риску при использовании ордер-блока как цели.
iMatch Допуск совпадения ордер-блока с уровнем входа в единицах ATR. Определяет, насколько близко ордер-блок должен находиться к уровню для использования в качестве цели.
iLqPiv Количество баров для определения свингов ликвидности. Увеличивается на 1 по сравнению со стандартными свингами для поиска дополнительных ликвидных уровней.
iEqTol Допуск равенства максимумов/минимумов в единицах ATR. Используется для определения уровней с примерно равными экстремумами при поиске дополнительной ликвидности.
iShowBos Включает или отключает отображение разрывов структуры (BOS) и связанных меток на графике.
iShowVol Включает или отключает отображение линий объёма и пропусков объёма на графике.
iShowOb Включает или отключает отображение ордер-блоков на графике.
iObDist Максимальное расстояние от цены для отображения ордер-блоков в единицах ATR. Блоки, находящиеся дальше этого расстояния, не отрисовываются, чтобы не растягивать шкалу графика.
iVolAll При включении линии объёма отрисовываются при каждом прорыве. При отключении — только на прорывах, следующих за ликвидным захватом.
iShowFib Включает или отключает отображение уровней Фибоначчи на графике.
iShowLq Включает или отключает отображение дополнительных уровней ликвидности (+1) на графике.
iPanel Включает или отключает отображение информационной панели с чек-листом условий и данными текущей установки.
iLang Язык отображения панели. Доступны варианты: Arabic и English.
iPos Позиция панели на графике. Доступны варианты: Top right, Bottom right, Top left, Bottom left.

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

indicator("HTF 5+1 | Sattam", shorttitle = "HTF 5+1", overlay = true, max_lines_count = 500, max_boxes_count = 500, max_labels_count = 500)

string G_S = "Structure · Structure"
string G_E = "Entries · Entries"
string G_D = "Drawing · Drawing"
string G_P = "Panel · Panel"

int    iSwing    = input.int(2, "Swing confirmation bars · Swing confirmation candles", minval = 1, maxval = 10, group = G_S, tooltip = "Closed bars without a new extreme before a swing is accepted. · The number of closed candles with no new high or low before the swing point is confirmed.")
bool   iMedium   = input.bool(true, "Medium-probability sweeps · Medium-probability sweeps", group = G_S, tooltip = "Sweep of a subordinate swing that failed to break structure. · A sweep of a subordinate swing point that failed to break structure.")
bool   iInternal = input.bool(false, "Internal setups (ibos) · Internal setups", group = G_S, tooltip = "Counter-trend setups inside the pullback while the main limit waits. Lower probability. · Counter-trend trades inside the pullback while the main limit is pending, with lower probability.")
int    iInnSwing = input.int(1, "Internal swing bars · Internal swing candles", minval = 1, maxval = 5, group = G_S)

float  iFib      = input.float(0.71, "Entry level · Entry level", minval = 0.5, maxval = 0.9, step = 0.01, group = G_E)
bool   iObLimit  = input.bool(true, "Second limit on closest Order Block · Second limit on nearest Order Block", group = G_E)
float  iObRR     = input.float(2.0, "Order Block limit target (R) · Order Block limit target", minval = 1.0, step = 0.5, group = G_E)
float  iMatch    = input.float(0.10, "Block/level match tolerance (ATR) · Block/level match tolerance", minval = 0.0, step = 0.05, group = G_E)
int    iLqPiv    = input.int(2, "Liquidity swing bars (+1) · Liquidity swing candles", minval = 1, maxval = 5, group = G_E)
float  iEqTol    = input.float(0.15, "Equal highs/lows tolerance (ATR) · Equal highs/lows tolerance", minval = 0.01, step = 0.01, group = G_E)

bool   iShowBos  = input.bool(true, "BOS and sweeps · BOS and sweeps", group = G_D)
bool   iShowVol  = input.bool(true, "Volume gaps · Volume gaps", group = G_D)
bool   iShowOb   = input.bool(true, "Order Blocks · Order Blocks", group = G_D)
float  iObDist   = input.float(8.0, "Extend blocks within (ATR) · Extend blocks within (ATR)", minval = 1.0, step = 1.0, group = G_D, tooltip = "Blocks farther than this from price stop extending so they do not stretch the chart scale. · Blocks farther than this distance from price stop extending so they do not stretch the chart scale.")
bool   iVolAll   = input.bool(false, "Volume on every break · Volume on every break", group = G_D, tooltip = "Off: volume lines only on breaks that follow a sweep. · When off, volume lines are drawn only on breaks that follow a liquidity sweep.")
bool   iShowFib  = input.bool(true, "Fibonacci levels · Fibonacci levels", group = G_D)
bool   iShowLq   = input.bool(true, "Extra liquidity (+1) · Extra liquidity", group = G_D)

bool   iPanel    = input.bool(true, "Show panel · Show panel", group = G_P)
string iLang     = input.string("Arabic", "Panel language · Panel language", options = ["Arabic", "English"], group = G_P)
string iPos      = input.string("Top right", "Position · Position", options = ["Top right", "Bottom right", "Top left", "Bottom left"], group = G_P)

color C_FG   = chart.fg_color
color C_TAN  = #e0a96d
color C_GREY = #787b86
color C_RED  = #f23645
color C_GRN  = #22ab94
color C_BLU  = #2962ff
color C_NONE = color.new(#000000, 100)

var array<float> A_O = array.new<float>()
var array<float> A_H = array.new<float>()
var array<float> A_L = array.new<float>()
var array<float> A_C = array.new<float>()
A_O.push(open)
A_H.push(high)
A_L.push(low)
A_C.push(close)

float atr14  = ta.atr(14)
float pHi    = ta.pivothigh(high, iSwing, iSwing)
float pLo    = ta.pivotlow(low, iSwing, iSwing)
float ipHi   = ta.pivothigh(high, iInnSwing, iInnSwing)
float ipLo   = ta.pivotlow(low, iInnSwing, iInnSwing)
float lqHi   = ta.pivothigh(high, iLqPiv, iLqPiv)
float lqLo   = ta.pivotlow(low, iLqPiv, iLqPiv)

type Side
    float p
    int   b
    bool  wait = false
    float runP
    int   runB
    bool  pulled = false

type Sweep
    bool  active = false
    int   kind = 0
    float lvl
    int   lvlB
    int   bar

type Ob
    int   s
    float top
    float bot
    int   left
    bool  mit = false
    box   bx
    bool  inner = false
    int   gaps = 1
    bool  stopG = false

type Ord
    int   s
    int   kind
    float entry
    float sl
    float tp
    int   st = 0
    int   placed
    int   fillB
    int   gid
    float plan
    line  l0
    line  l71
    line  l1
    label t0
    label t71
    label t1

type Setup
    int    s
    int    kind
    float  anchor
    int    anchorB
    float  swing
    int    swingB
    int    st = 0
    bool   missed = false
    int    gid
    Ob     ob
    float  mnrP
    int    mnrB
    Ord    fib
    Ord    obo
    int    plus = 0
    string plusTx = ""
    line   lq
    label  lqT

type Eng
    bool   internal
    int    n
    int    dir = 0
    Side   up
    Side   dn
    Sweep  sw
    int    pS = 0
    int    pBar
    float  pLvl
    int    pLvlB
    bool   pWick = false
    int    cnt = 0
    bool   wOn = false
    float  wLvl
    int    wLvlB
    int    wBar
    float  wSub
    int    wSubB
    float  subP
    int    subB
    line   lastLn
    label  lastLb
    Setup  aL
    Setup  aS

type Stats
    int    fW = 0
    int    fL = 0
    int    oW = 0
    int    oL = 0
    int    iW = 0
    int    iL = 0
    float  fR = 0.0
    float  oR = 0.0
    float  iR = 0.0
    int    gid = 0
    bool   cBos = false
    bool   cVol = false
    bool   cOb = false
    int    cSw = 0
    int    cDir = 0
    Setup  last
    Ob     lastOb

var array<Ob>    obs   = array.new<Ob>()
var array<Ord>   live  = array.new<Ord>()
var array<float> PHp   = array.new<float>()
var array<int>   PHb   = array.new<int>()
var array<float> PLp   = array.new<float>()
var array<int>   PLb   = array.new<int>()
var Stats        g     = Stats.new()
var Eng          ext   = Eng.new(internal = false, n = iSwing, up = Side.new(), dn = Side.new(), sw = Sweep.new())
var Eng          inn   = Eng.new(internal = true, n = iInnSwing, up = Side.new(), dn = Side.new(), sw = Sweep.new())

f_t(string ar, string en) => iLang == "English" ? en : ar

f_x(int s, int i) => s == 1 ? A_H.get(i) : A_L.get(i)

f_extreme(int s, int fromB, int toB) =>
    float best = na
    int   bestB = na
    for i = fromB to toB
        float v = f_x(s, i)
        if na(best) or s * (v - best) > 0
            best := v
            bestB := i
    [best, bestB]

f_wickPush(int s, int m) =>
    bool past = s == 1 ? A_L.get(m) < A_L.get(m - 1) : A_H.get(m) > A_H.get(m - 1)
    past and s * (A_C.get(m) - A_O.get(m)) > 0

f_isGap(int s, int m) =>
    bool res = s == 1 ? A_H.get(m - 1) < A_L.get(m + 1) : A_L.get(m - 1) > A_H.get(m + 1)
    if f_wickPush(s, m)
        float edge = s == 1 ? math.min(A_O.get(m), A_C.get(m)) : math.max(A_O.get(m), A_C.get(m))
        res := s == 1 ? edge < A_L.get(m + 1) : edge > A_H.get(m + 1)
    res

f_gap(int s, int fromB, int toB) =>
    int found = na
    if toB >= fromB + 1
        for m = toB to fromB + 1
            if f_isGap(s, m)
                found := m
                break
    if not na(found)
        while found - 1 >= fromB + 1
            if f_isGap(s, found - 1)
                found -= 1
            else
                break
    found

f_gapRun(int s, int m) =>
    int cntG = 1
    int k = m + 1
    while k <= bar_index - 1
        if f_isGap(s, k)
            cntG += 1
            k += 1
        else
            break
    [cntG, cntG == 1 and m + 1 <= bar_index - 1]

f_txt(int x, float y, string tx, string st, color c) =>
    label.new(x, y, text = tx, style = st, color = C_NONE, textcolor = c, size = size.tiny)

f_bR(box b, int x) =>
    if not na(b)
        box.set_right(b, x)

f_lX(line l, int x) =>
    if not na(l)
        line.set_x2(l, x)

f_tX(label l, int x) =>
    if not na(l)
        label.set_x(l, x)

method side(Eng e, int s) => s == 1 ? e.up : e.dn

method slot(Eng e, int s) => s == 1 ? e.aL : e.aS

method setSlot(Eng e, int s, Setup a) =>
    if s == 1
        e.aL := a
    else
        e.aS := a

f_visible(Eng e, int s) =>
    bool res = not e.internal
    if e.internal
        Setup x = ext.slot(-s)
        if not na(x)
            res := x.st == 1
    res

f_kill(Ord o) =>
    if not na(o)
        line.delete(o.l0)
        line.delete(o.l71)
        line.delete(o.l1)
        label.delete(o.t0)
        label.delete(o.t71)
        label.delete(o.t1)
        o.st := 9

f_clearOrders(Setup a) =>
    f_kill(a.fib)
    f_kill(a.obo)
    a.fib := na
    a.obo := na
    line.delete(a.lq)
    label.delete(a.lqT)
    a.lq := na
    a.lqT := na
    a.plus := 0
    a.plusTx := ""

f_newOb(int s, int m, bool show, bool showVol) =>
    int   first = m - 1
    int   third = m + 1
    bool  isWick = f_wickPush(s, m)
    float obTop = A_H.get(first)
    float obBot = A_L.get(first)
    int   leftB = first
    if isWick
        float bodyTop = math.max(A_O.get(m), A_C.get(m))
        float bodyBot = math.min(A_O.get(m), A_C.get(m))
        obTop := s == 1 ? bodyBot : A_H.get(m)
        obBot := s == 1 ? A_L.get(m) : bodyTop
        leftB := m
    int mitB = na
    if third <= bar_index
        for i = third to bar_index
            bool touched = s == 1 ? A_L.get(i) <= obTop : A_H.get(i) >= obBot
            if touched
                mitB := i
                break
    Ob o = Ob.new(s, obTop, obBot, leftB, not na(mitB))
    [nG, stopG] = f_gapRun(s, m)
    o.gaps := nG
    o.stopG := stopG
    if show and iShowOb
        color  fillC = s == 1 ? color.new(C_TAN, 78) : color.new(C_GREY, 72)
        int    rightB = na(mitB) ? bar_index + 5 : mitB
        string boxTx = na(mitB) ? "Order Block" : ""
        o.bx := box.new(leftB, obTop, rightB, obBot, border_color = C_NONE, bgcolor = fillC, text = boxTx, text_size = size.tiny, text_color = C_FG)
    if show and showVol and iShowVol
        float near = s == 1 ? obTop : obBot
        float v1 = isWick ? near : (s == 1 ? A_H.get(first) : A_L.get(first))
        float v2 = s == 1 ? A_L.get(third) : A_H.get(third)
        line.new(first, v1, m + 8, v1, color = C_RED, width = 1)
        line.new(third, v2, m + 8, v2, color = C_RED, width = 1)
        string volTx = nG >= 2 ? "Volume x" + str.tostring(nG) : stopG ? "Volume, gap stop" : "Volume"
        f_txt(m + 4, (v1 + v2) / 2, volTx, label.style_none, C_FG)
    o

f_pickOb(int s, float fib, float sl) =>
    Ob    best = na
    float bestD = na
    for o in obs
        if o.s == s and not o.mit and not o.inner
            float nearE = s == 1 ? o.top : o.bot
            float farE  = s == 1 ? o.bot : o.top
            if s * (fib - farE) > 0 and s * (nearE - sl) > 0
                float d = math.max(s * (fib - nearE), 0.0)
                if na(bestD) or d < bestD
                    best := o
                    bestD := d
    best

f_lqScan(Setup a) =>
    if not na(a.fib) and not na(atr14)
        line.delete(a.lq)
        label.delete(a.lqT)
        a.lq := na
        a.lqT := na
        a.plus := 0
        a.plusTx := ""
        float entry = a.fib.entry
        array<float> ps = a.s == 1 ? PLp : PHp
        array<int>   bs = a.s == 1 ? PLb : PHb
        array<float> xp = array.new<float>()
        array<int>   xb = array.new<int>()
        for [i, v] in ps
            if bs.get(i) > a.anchorB and a.s * (v - entry) > 0
                xp.push(v)
                xb.push(bs.get(i))
        int   n = xp.size()
        int   tlA = na
        int   tlB = na
        int   eqA = na
        int   eqB = na
        float tolEq = atr14 * iEqTol
        float tolTl = atr14 * iEqTol * 2
        if n >= 2
            for i = 0 to n - 2
                int j = i
                while j + 1 < n
                    if a.s * (xp.get(j + 1) - xp.get(j)) > 0
                        j += 1
                    else
                        break
                if j - i >= 2
                    bool fits = true
                    float slope = (xp.get(j) - xp.get(i)) / (xb.get(j) - xb.get(i))
                    for k = i + 1 to j - 1
                        float yL = xp.get(i) + slope * (xb.get(k) - xb.get(i))
                        if math.abs(xp.get(k) - yL) > tolTl
                            fits := false
                    if fits and (na(tlA) or j - i > tlB - tlA)
                        tlA := i
                        tlB := j
                int q = i
                while q + 1 < n
                    if math.abs(xp.get(q + 1) - xp.get(i)) <= tolEq
                        q += 1
                    else
                        break
                if q > i and (na(eqA) or q - i > eqB - eqA)
                    eqA := i
                    eqB := q
        bool mnrOk = not na(a.mnrP) and a.s * (a.mnrP - entry) > 0
        if not na(tlA)
            a.plus := 4
            a.plusTx := "trendline LQ"
            if iShowLq
                a.lq := line.new(xb.get(tlA), xp.get(tlA), xb.get(tlB), xp.get(tlB), color = C_FG, width = 1)
                a.lqT := f_txt(int((xb.get(tlA) + xb.get(tlB)) / 2), (xp.get(tlA) + xp.get(tlB)) / 2, a.plusTx, a.s == 1 ? label.style_label_up : label.style_label_down, C_FG)
        else if not na(eqA)
            int cnt = eqB - eqA + 1
            a.plus := cnt >= 3 ? 3 : 2
            string word = a.s == 1 ? (cnt >= 3 ? " equal lows" : " equal bottoms") : (cnt >= 3 ? " equal highs" : " equal tops")
            a.plusTx := str.tostring(cnt) + word
            if iShowLq
                a.lq := line.new(xb.get(eqA), xp.get(eqA), xb.get(eqB), xp.get(eqA), color = C_FG, style = line.style_dotted, width = 1)
                a.lqT := f_txt(int((xb.get(eqA) + xb.get(eqB)) / 2), xp.get(eqA), a.plusTx + " $", a.s == 1 ? label.style_label_up : label.style_label_down, C_FG)
        else if mnrOk
            a.plus := 1
            a.plusTx := "MNR = LQ+"
            if iShowLq
                a.lq := line.new(a.mnrB, a.mnrP, a.mnrB + 6, a.mnrP, color = C_GRN, width = 1)
                a.lqT := label.new(a.mnrB, a.mnrP, text = "MNR = LQ+", style = a.s == 1 ? label.style_label_up : label.style_label_down, color = color.new(C_GRN, 60), textcolor = C_FG, size = size.tiny)

f_price(float p) => str.tostring(p, format.mintick)

method place(Eng e, Setup a, Side S) =>
    int t = bar_index
    a.swing := S.p
    a.swingB := S.b
    a.st := 1
    float entry = a.swing + (a.anchor - a.swing) * iFib
    int   k = e.internal ? 2 : 0
    Ord   f = Ord.new(s = a.s, kind = k, entry = entry, sl = a.anchor, tp = a.swing, placed = t, gid = a.gid, plan = math.abs(entry - a.anchor))
    color fC = e.internal ? C_BLU : C_FG
    string grade = a.kind == 2 ? " M" : ""
    if iShowFib
        f.l0  := line.new(a.swingB, a.swing, t + 10, a.swing, color = color.new(fC, 25), width = 1)
        f.l71 := line.new(math.min(a.anchorB, a.swingB), entry, t + 10, entry, color = fC, width = 1)
        f.l1  := line.new(a.anchorB, a.anchor, t + 10, a.anchor, color = color.new(fC, 25), width = 1)
        f.t0  := f_txt(t + 10, a.swing, "0 (" + f_price(a.swing) + ")", label.style_label_left, C_FG)
        f.t71 := f_txt(t + 10, entry, str.tostring(iFib) + " (" + f_price(entry) + ")" + grade, label.style_label_left, C_FG)
        f.t1  := f_txt(t + 10, a.anchor, "1 (" + f_price(a.anchor) + ")", label.style_label_left, C_FG)
    a.fib := f
    live.push(f)
    if not e.internal and iObLimit
        Ob o = f_pickOb(a.s, entry, a.anchor)
        if not na(o)
            float nearE = a.s == 1 ? o.top : o.bot
            float midE  = (o.top + o.bot) / 2
            float tol   = na(atr14) ? 0.0 : atr14 * iMatch
      

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