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? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.