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

S&R

indicator support & resistance for tradingview.pine
Вы автор или правообладатель?

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

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

О программе

Индикатор для TradingView, отображающий зоны поддержки и сопротивления на графике. Зоны строятся на основе уровней пивотов и отрисовываются в виде горизонтальных полос с линиями и подписями. Поддерживается расчёт зон как на текущем таймфрейме, так и на более высоком (MTF). При пробое зоны удаляются с графика после подтверждения по закрытию свечи. Реализованы условия для оповещений TradingView при пробое уровней. Каждая зона отображает процентное расстояние цены от её границы, показывающее степень проникновения в зону. Отображение зон, подписей и оповещений настраивается пользователем через параметры индикатора.

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

НастройкаОписание
enableSR Enable S/R module — Включает или отключает модуль расчёта зон поддержки и сопротивления.
sr_sourceMode Zone source mode — Выбирает источник данных для расчёта зон: текущий таймфрейм графика или более высокий (MTF).
sr_mtfTF MTF zone timeframe — Таймфрейм, на котором рассчитываются зоны, если режим источника установлен на MTF.
sr_pivotLen Pivot length (L = R) — Количество баров слева и справа от точки для подтверждения уровня пивота.
maxZones Number of visible zones — Максимальное количество видимых зон поддержки и сопротивления, отображаемых на графике.
showSRLabels Show S/R labels — Показывать или скрывать текстовые подписи в центре каждой зоны.
showOnlyLast2 Show only 2 active zones (zones) — При включении оставляет на графике только последнюю активную зону сопротивления и последнюю активную зону поддержки.
minZoneDist Minimum distance between zones (%) — Минимальный вертикальный зазор между зонами одного типа. Зоны, расположенные ближе, объединяются.
zoneLeftExt Zone left extension (bars) — Расширяет каждую зону влево от исходной точки пивота на заданное количество баров.
zoneRightExt Zone right extension (bars) — Расширяет каждую зону вправо за текущий бар на заданное количество баров.
confirm_on_close Confirm breaks only on candle close — Подтверждение пробоя зоны происходит только после закрытия свечи.
useStrongBodyBreak Break = full body outside zone + strong candle — Требует, чтобы всё тело свечи закрылось за пределами зоны с достаточной силой для подтверждения пробоя.
dojiMaxBodyToRange Max doji (body/range) — Максимальное соотношение тела свечи к диапазону для классификации свечи как доджи.
minBodyToRange Min strength (body/range) — Минимальное соотношение тела свечи к диапазону, необходимое для подтверждения сильного пробоя.
minBodyAtr Min strength (body >= ATR*x) — Минимальный размер тела свечи в кратных значениях ATR, необходимый для подтверждения сильного пробоя.
showForcePct Show Force % (zone penetration) — Показывать или скрывать процент проникновения цены в зону внутри подписи.
capForce Cap Force % (prevent huge values) — Ограничивает отображаемое значение процента проникновения, предотвращая чрезмерно большие значения.
capForceMax Max cap (%) — Максимальное значение отображаемого процента проникновения при включённом ограничении.
alertBreakRes Alert: Break Resistance — Включает оповещение при пробое зоны сопротивления по фильтрованной логике подтверждения.
alertBreakSup Alert: Break Support — Включает оповещение при пробое зоны поддержки по фильтрованной логике подтверждения.
Получить полный код

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

indicator("S&R", overlay = true, max_labels_count = 500, max_boxes_count = 500, max_bars_back = 1000)

group_SR = "🧱 Support & Resistance"
enableSR       = input.bool(true,  "Enable S/R module", group = group_SR, tooltip = "Enable or disable the support and resistance zone module.")
sr_sourceMode  = input.string("Chart", "Zone source mode", options = ["Chart", "MTF"], group = group_SR, tooltip = "Select Chart to calculate zones from the current chart timeframe, or MTF to calculate zones from a higher/custom timeframe while displaying them on the current chart.")
sr_mtfTF      = input.timeframe("D", "MTF zone timeframe", options = ["15", "30", "60", "240", "D", "W", "M"], group = group_SR, tooltip = "Timeframe used to calculate support and resistance zones when Zone source mode is set to MTF. Example: use D to display daily zones on 1h or 30m charts.")
sr_pivotLen    = input.int(5,      "Pivot length (L = R)", minval = 1, maxval = 50, group = group_SR, tooltip = "Number of bars used on the left and right side of a pivot to confirm a support or resistance level.")
maxZones       = input.int(15,     "Number of visible zones", minval = 1, maxval = 30, group = group_SR, tooltip = "Maximum number of visible support zones and resistance zones kept on the chart.")
showSRLabels   = input.bool(true,  "Show S/R labels", group = group_SR, tooltip = "Show or hide the text labels displayed at the center of each support or resistance zone.")
showOnlyLast2  = input.bool(false, "Show only 2 active zones (zones)", group = group_SR, tooltip = "When enabled, the script keeps only the latest active resistance and the latest active support.")
minZoneDist    = input.float(3,  "Minimum distance between zones (%)", minval = 0.0, step = 0.1, group = group_SR, tooltip = "Minimum vertical gap required between two zones of the same type. If two supports or two resistances touch or are closer than this value, they are merged.")
zoneLeftExt    = input.int(0, "Zone left extension (bars)", minval = 0, maxval = 500, group = group_SR, tooltip = "Extends each zone to the left by the selected number of bars from its original pivot point.")
zoneRightExt   = input.int(200, "Zone right extension (bars)", minval = 0, maxval = 500, group = group_SR, tooltip = "Extends each zone to the right beyond the current bar by the selected number of bars. Maximum is limited to 500 bars.")
confirm_on_close = input.bool(true, "Confirm breaks only on candle close", group="Wizard Volumetric Order Blocks Settings", tooltip = "When enabled, a support or resistance break is confirmed only after the candle closes.")
ok_confirm = not confirm_on_close or barstate.isconfirmed

group_BR = "✅ Break filter"
useStrongBodyBreak   = input.bool(true,  "Break = full body outside zone + strong candle", group = group_BR, tooltip = "Requires the full candle body to close outside the zone with enough strength before deleting a broken zone.")
dojiMaxBodyToRange   = input.float(0.20, "Max doji (body/range)", minval = 0.01, maxval = 0.50, step = 0.01, group = group_BR, tooltip = "Maximum body-to-range ratio used to classify a candle as a doji and avoid weak break confirmations.")
minBodyToRange       = input.float(0.15, "Min strength (body/range)", minval = 0.10, maxval = 0.95, step = 0.01, group = group_BR, tooltip = "Minimum candle body-to-range ratio required to validate a strong support or resistance break.")
minBodyAtr           = input.float(0.15, "Min strength (body >= ATR*x)", minval = 0.00, maxval = 5.00, step = 0.05, group = group_BR, tooltip = "Minimum candle body size expressed as an ATR multiplier required to validate a strong break.")
atrBR = ta.atr(14)

group_F = "💪 Force %"
showForcePct    = input.bool(true,  "Show Force % (zone penetration)", group = group_F, tooltip = "Show or hide the penetration strength percentage inside each support or resistance label.")
capForce        = input.bool(true,  "Cap Force % (prevent huge values)", group = group_F, tooltip = "Caps the displayed force percentage to prevent extremely large values after strong moves beyond a zone.")
capForceMax     = input.float(100.0, "Max cap (%)", minval = 100.0, maxval = 1000.0, step = 10.0, group = group_F, tooltip = "Maximum value allowed for the displayed force percentage when the cap is enabled.")

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)

colRes = color.rgb(255, 3, 3)
colSup = color.rgb(1, 146, 45)

group_AL = "🚨 Alerts — Break S/R"
alertBreakRes = input.bool(true, "Alert: Break Resistance", group=group_AL, tooltip = "Enable an alert condition when a resistance zone is broken by the filtered break logic.")
alertBreakSup = input.bool(true, "Alert: Break Support",    group=group_AL, tooltip = "Enable an alert condition when a support zone is broken by the filtered break logic.")

var bool didBreakRes = false
var bool didBreakSup = false
didBreakRes := false
didBreakSup := false

atrSR = ta.atr(14)

ph = ta.pivothigh(high, sr_pivotLen, sr_pivotLen)
pl = ta.pivotlow(low, sr_pivotLen, sr_pivotLen)
isHigh = not na(ph)
isLow  = not na(pl)

useMTF = sr_sourceMode == "MTF"
f_mtfData() =>
    float _ph = ta.pivothigh(high, sr_pivotLen, sr_pivotLen)
    float _pl = ta.pivotlow(low, sr_pivotLen, sr_pivotLen)
    int _phT = not na(_ph) ? time[sr_pivotLen] : na
    int _plT = not na(_pl) ? time[sr_pivotLen] : na
    [_ph, _pl, _phT, _plT]
[mtfPh, mtfPl, mtfPhTime, mtfPlTime] = request.security(syminfo.tickerid, sr_mtfTF, f_mtfData(), barmerge.gaps_off, barmerge.lookahead_off)
var int lastMtfResTime = na
var int lastMtfSupTime = na

barMs = int(timeframe.in_seconds(timeframe.period) * 1000)

f_safeDenom(y) => math.max(math.abs(y), 1e-6)
f_pct(y)       => ((close - y) / f_safeDenom(y)) * 100.0
vbarLen(_y)    => math.max(atrSR * 0.30, syminfo.mintick * 3)
f_validRes(_y) => _y > close
f_validSup(_y) => _y < close
f_left(_t) => _t - barMs * zoneLeftExt
f_right() => time + barMs * zoneRightExt
f_top(_y) => _y + vbarLen(_y)
f_bot(_y) => _y - vbarLen(_y)
f_zoneGap(_a, _b) =>
    float _aTop = f_top(_a)
    float _aBot = f_bot(_a)
    float _bTop = f_top(_b)
    float _bBot = f_bot(_b)
    _aBot > _bTop ? _aBot - _bTop : _bBot > _aTop ? _bBot - _aTop : 0.0
f_minGap(_a, _b) => math.max(math.max(math.abs(_a), math.abs(_b)) * (minZoneDist * 0.01), 0.0)
f_zonesTouch(_a, _b) => f_zoneGap(_a, _b) <= syminfo.mintick
f_zonesNear(_a, _b) => minZoneDist > 0 and f_zoneGap(_a, _b) <= f_minGap(_a, _b)
f_zonesTouchOrNear(_a, _b) => f_zonesTouch(_a, _b) or f_zonesNear(_a, _b)

f_cap(x) =>
    capForce ? math.min(x, capForceMax) : x

f_forceRes(_y) =>
    float top = _y + vbarLen(_y)
    float bot = _y - vbarLen(_y)
    float h   = math.max(top - bot, syminfo.mintick)
    float f   = 0.0

    if close <= bot
        f := 0.0
    else if close >= top
        f := 100.0 + ((close - top) / h) * 100.0
    else
        f := ((close - bot) / h) * 100.0

    f_cap(f)

f_forceSup(_y) =>
    float top = _y + vbarLen(_y)
    float bot = _y - vbarLen(_y)
    float h   = math.max(top - bot, syminfo.mintick)
    float f   = 0.0

    if close >= top
        f := 0.0
    else if close <= bot
        f := 100.0 + ((bot - close) / h) * 100.0
    else
        f := ((top - close) / h) * 100.0

    f_cap(f)

f_labelTextRes(_y) =>
    string txt = "Resistance " + str.tostring(f_pct(_y), "#.##") + "%"
    if showForcePct
        txt := txt + " | S " + str.tostring(f_forceRes(_y), "#.0") + "%"
    txt

f_labelTextSup(_y) =>
    string txt = "Support " + str.tostring(f_pct(_y), "#.##") + "%"
    if showForcePct
        txt := txt + " | S " + str.tostring(f_forceSup(_y), "#.0") + "%"
    txt

var line[]  resLines      = array.new<line>()
var box[]   resBoxes      = array.new<box>()
var label[] resLabels     = array.new<label>()

var line[]  supLines      = array.new<line>()
var box[]   supBoxes      = array.new<box>()
var label[] supLabels     = array.new<label>()

f_deleteRes(_i) =>
    line.delete(array.get(resLines, _i))
    box.delete(array.get(resBoxes, _i))
    label _lb = array.get(resLabels, _i)
    if not na(_lb)
        label.delete(_lb)
    array.remove(resLines, _i)
    array.remove(resBoxes, _i)
    array.remove(resLabels, _i)

f_deleteSup(_i) =>
    line.delete(array.get(supLines, _i))
    box.delete(array.get(supBoxes, _i))
    label _lb = array.get(supLabels, _i)
    if not na(_lb)
        label.delete(_lb)
    array.remove(supLines, _i)
    array.remove(supBoxes, _i)
    array.remove(supLabels, _i)

f_updateResObj(_i, _level, _left) =>
    int _right = f_right()
    line _ln = array.get(resLines, _i)
    line.set_x1(_ln, _left)
    line.set_y1(_ln, _level)
    line.set_x2(_ln, _right)
    line.set_y2(_ln, _level)
    box _rect = array.get(resBoxes, _i)
    box.set_left(_rect, _left)
    box.set_right(_rect, _right)
    box.set_top(_rect, _level + vbarLen(_level))
    box.set_bottom(_rect, _level - vbarLen(_level))
    label _lb = array.get(resLabels, _i)
    if showSRLabels and not na(_lb)
        int _mid = int(math.round((_left + _right) / 2.0))
        label.set_x(_lb, _mid)
        label.set_y(_lb, _level)
        label.set_text(_lb, f_labelTextRes(_level))
    if not showSRLabels and not na(_lb)
        label.set_text(_lb, "")

f_updateSupObj(_i, _level, _left) =>
    int _right = f_right()
    line _ln = array.get(supLines, _i)
    line.set_x1(_ln, _left)
    line.set_y1(_ln, _level)
    line.set_x2(_ln, _right)
    line.set_y2(_ln, _level)
    box _rect = array.get(supBoxes, _i)
    box.set_left(_rect, _left)
    box.set_right(_rect, _right)
    box.set_top(_rect, _level + vbarLen(_level))
    box.set_bottom(_rect, _level - vbarLen(_level))
    label _lb = array.get(supLabels, _i)
    if showSRLabels and not na(_lb)
        int _mid = int(math.round((_left + _right) / 2.0))
        label.set_x(_lb, _mid)
        label.set_y(_lb, _level)
   

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

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

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

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

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

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

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