Breaker Block Detector
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator breaker block detector for tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Breaker Block Detector — это индикатор для TradingView (Pine Script v6), который отображает на графике так называемые «breaker blocks» — зоны порядка (Order Block), сформированные вблизи свинг-пивотов. Индикатор определяет, были ли эти зоны пробиты ценой, и оценивает качество пробития по шкале A/B/C на основе отношения размера движения к ATR.
Для каждой свежей зоны индикатор рисует прямоугольник (box) и подписывает меткой с указанием направления и градации. Зоны, которые были повторно протестированы ценой, могут перемещаться в архив тестированных (при соответствующей настройке) или удаляться. Также индикатор отслеживает инвалидацию зон при пробитии в противоположном направлении.
В правом верхнем углу отображается дашборд с информацией о количестве свежих зон, ближайших зонах выше и ниже, числе протестированных зон и последнем событии. Индикатор поддерживает четыре условия оповещений: формирование бычьего/медвежьего брейкера, общее событие формирования и ретест зоны.
Пользователь может настраивать параметры обнаружения (длину свинга, окно поиска, подтверждение пробития), отображение (цвета, метки, маркеры, дашборд), а также ограничения по количеству активных зон и минимальному смещению для признака значимой пробитости.
Настройки программы
| Настройка | Описание |
|---|---|
| swingLen | Длина свинга — Длина свинга (количество баров) для определения свинг-пивотов высока и низа. |
| obWindow | Окно поиска OB — Количество баров надвигаться от пивота для поиска свечи порядка (Order Block). |
| pendExpiry | Срок действия ожидающих OB — Количество баров, по истечении которых неподтверждённые ожидающиеся зоны удаляются. |
| zoneSrc | Источник зоны — Источник данных для построения зоны: тело свечи (Body) или полная свеча (Full Candle). |
| breakConf | Подтверждение пробития — Режим подтверждения пробития зоны: по цене закрытия (Close) или по экстремуму свечи (Wick). |
| dirBreak | Направленное пробитие свечей — Включает/отключает фильтр направления: при активном значении пробитие считается только в совпадении с направлением свечи. |
| minDispATR | Минимальное смещение (ATR) — Минимальное отношение смещения цены к ATR, при котором пробитие считается значимым. |
| atrLen | Длина ATR — Длина периода для расчёта ATR (средний истинный диапазон), используемого при оценке пробития зон. |
| maxZoneATR | Максимальная высота зоны (ATR) — Максимальная допустимая высота зоны в единицах ATR. Зоны, превышающие этот порог, отклоняются. |
| showBull | Показать бычьи брейкеры — Включает или отключает отображение бычьих брейкер-зон. |
| showBear | Показать медвежьи брейкеры — Включает или отключает отображение медвежьих брейкер-зон. |
| maxZones | Макс. активных зон на сторону — Максимальное количество одновременно отображаемых активных зон на каждую сторону (бычью и медвежью). |
| showTested | Показать протестированные зоны — Включает или отключает отображение протестированных (retest) зон. При отключении они удаляются после повторного касания. |
| showMarkers | Показать маркеры-триггеры — Включает или отключает маркеры-триггеры в месте пробития зоны. |
| showLabels | Показать метки — Включает или отключает текстовые метки на графике для каждой брейкер-зоны. |
| showDash | Показать дашборд — Включает или отключает отображение информационного дашборда в правом верхнем углу графика. |
| gradeA_ATR | Порог градации A — Пороговое значение отношения смещения к ATR для присвоения градации A. |
| gradeB_ATR | Порог градации B — Пороговое значение отношения смещения к ATR для присвоения градации B. |
| bullCol | Цвет бычьего брейкера — Цвет отображения бычьих брейкер-зон на графике. |
| bearCol | Цвет медвежьего брейкера — Цвет отображения медвежьих брейкер-зон на графике. |
| testedCol | Цвет протестированной зоны — Цвет отображения зон, которые были повторно протестированы ценой. |
Поиск по коду файла
indicator("Breaker Block Detector", shorttitle="Breakers [EA]", overlay=true, max_boxes_count=200, max_labels_count=200)
grp1 = "Detection"
swingLen = input.int(5, "Swing Length", minval=2, maxval=20, group=grp1)
obWindow = input.int(5, "OB Search Window", minval=1, maxval=20, group=grp1, tooltip="Candles to search back from pivot for OB candle.")
pendExpiry = input.int(150, "Pending OB Expiry (bars)", minval=50, maxval=500, group=grp1)
zoneSrc = input.string("Body", "Zone Source", options=["Body", "Full Candle"], group=grp1)
breakConf = input.string("Close", "Break Confirmation", options=["Close", "Wick"], group=grp1)
dirBreak = input.bool(true, "Directional Break Candle", group=grp1)
minDispATR = input.float(1.0, "Min Break Displacement ATR", minval=0.3, maxval=3.0, step=0.05, group=grp1)
atrLen = input.int(14, "ATR Length", minval=5, maxval=50, group=grp1)
maxZoneATR = input.float(2.0, "Max Zone Height ATR", minval=0.5, maxval=10.0, step=0.25, group=grp1, tooltip="Reject oversized zones.")
grp2 = "Display"
showBull = input.bool(true, "Show Bullish Breakers", group=grp2)
showBear = input.bool(true, "Show Bearish Breakers", group=grp2)
maxZones = input.int(5, "Max Active Zones Per Side", minval=3, maxval=20, group=grp2)
showTested = input.bool(false, "Show Tested Zones", group=grp2, tooltip="OFF: tested zones removed. ON: tested zones fade gray as visual archive.")
showMarkers = input.bool(false, "Show Trigger Markers", group=grp2)
showLabels = input.bool(true, "Show Labels", group=grp2)
showDash = input.bool(true, "Show Dashboard", group=grp2)
grp3 = "Grading"
gradeA_ATR = input.float(1.75, "A Grade (ATR)", minval=1.0, maxval=5.0, step=0.05, group=grp3)
gradeB_ATR = input.float(1.25, "B Grade (ATR)", minval=0.5, maxval=3.0, step=0.05, group=grp3)
grp4 = "Style"
bullCol = input.color(color.new(#00D9A3, 25), "Bullish Breaker", group=grp4)
bearCol = input.color(color.new(#F59E0B, 25), "Bearish Breaker", group=grp4)
testedCol = input.color(color.new(#6B7280, 60), "Tested Zone", group=grp4)
atr = ta.atr(atrLen)
ph = ta.pivothigh(high, swingLen, swingLen)
pl = ta.pivotlow(low, swingLen, swingLen)
f_findBearOB(int pivotOffset) =>
float obTop = na
float obBot = na
int obBar = na
for i = pivotOffset to pivotOffset + obWindow - 1
if i < bar_index and close[i] < open[i]
obTop := zoneSrc == "Body" ? open[i] : high[i]
obBot := zoneSrc == "Body" ? close[i] : low[i]
obBar := bar_index - i
break
[obTop, obBot, obBar]
f_findBullOB(int pivotOffset) =>
float obTop = na
float obBot = na
int obBar = na
for i = pivotOffset to pivotOffset + obWindow - 1
if i < bar_index and close[i] > open[i]
obTop := zoneSrc == "Body" ? close[i] : high[i]
obBot := zoneSrc == "Body" ? open[i] : low[i]
obBar := bar_index - i
break
[obTop, obBot, obBar]
f_scanBreakBull(float obTop, int fromOffset) =>
int breakBar = na
float ratio = na
for i = fromOffset to 0
float c = close[i]
float o = open[i]
float bd = math.abs(c - o)
float a = atr[i]
bool broke = breakConf == "Close" ? c > obTop : high[i] > obTop
bool dirOK = not dirBreak or (c > o)
bool hasDisp = not na(a) and a > 0 and bd >= minDispATR * a
if broke and dirOK and hasDisp
breakBar := bar_index - i
ratio := a > 0 ? bd / a : 0.0
break
[breakBar, ratio]
f_scanBreakBear(float obBot, int fromOffset) =>
int breakBar = na
float ratio = na
for i = fromOffset to 0
float c = close[i]
float o = open[i]
float bd = math.abs(c - o)
float a = atr[i]
bool broke = breakConf == "Close" ? c < obBot : low[i] < obBot
bool dirOK = not dirBreak or (c < o)
bool hasDisp = not na(a) and a > 0 and bd >= minDispATR * a
if broke and dirOK and hasDisp
breakBar := bar_index - i
ratio := a > 0 ? bd / a : 0.0
break
[breakBar, ratio]
f_postBreakState(float zTop, float zBot, bool isBull, int breakBarIdx) =>
int state = 0
int eventBar = na
int offset = bar_index - breakBarIdx - 1
if offset > 0
for i = offset to 1
int thisBar = bar_index - i
float c = close[i]
float h = high[i]
float l = low[i]
if isBull and c < zBot
state := -1
eventBar := thisBar
break
if not isBull and c > zTop
state := -1
eventBar := thisBar
break
if state == 0 and l <= zTop and h >= zBot
state := 1
eventBar := thisBar
break
[state, eventBar]
f_gradeRatio(float r) =>
r >= gradeA_ATR ? "A" : r >= gradeB_ATR ? "B" : "C"
var float[] pendTop = array.new_float()
var float[] pendBot = array.new_float()
var int[] pendBorn = array.new_int()
var bool[] pendIsBull = array.new_bool()
var int[] pendObBar = array.new_int()
var box[] brkBox = array.new_box()
var label[] brkLbl = array.new_label()
var float[] brkTop = array.new_float()
var float[] brkBot = array.new_float()
var bool[] brkIsBull = array.new_bool()
var string[] brkGrade = array.new_string()
var int[] brkBorn = array.new_int()
var box[] tstBox = array.new_box()
f_delFresh(int i) =>
box.delete(array.get(brkBox, i))
lb = array.get(brkLbl, i)
if not na(lb)
label.delete(lb)
array.remove(brkBox, i)
array.remove(brkLbl, i)
array.remove(brkTop, i)
array.remove(brkBot, i)
array.remove(brkIsBull, i)
array.remove(brkGrade, i)
array.remove(brkBorn, i)
f_archiveFresh(int i) =>
bx = array.get(brkBox, i)
box.set_bgcolor(bx, testedCol)
box.set_border_color(bx, color.new(#6B7280, 40))
box.set_extend(bx, extend.none)
box.set_right(bx, bar_index)
array.push(tstBox, bx)
lb = array.get(brkLbl, i)
if not na(lb)
label.delete(lb)
array.remove(brkBox, i)
array.remove(brkLbl, i)
array.remove(brkTop, i)
array.remove(brkBot, i)
array.remove(brkIsBull, i)
array.remove(brkGrade, i)
array.remove(brkBorn, i)
f_brkColor(bool isBull, string grade) =>
color baseCol = isBull ? bullCol : bearCol
int transp = grade == "A" ? 20 : grade == "B" ? 45 : 70
color.new(baseCol, transp)
f_borderColor(bool isBull) =>
isBull ? color.new(#00D9A3, 5) : color.new(#F59E0B, 5)
var bool evtBullBrk = false
var bool evtBearBrk = false
var bool evtRetest = false
var string lastEvent = "—"
evtBullBrk := false
evtBearBrk := false
evtRetest := false
f_createBreaker(float pT, float pB, bool pBull, int obSourceBar, int breakBarIdx, string grade, int initState, int eventBar) =>
float newMid = (pT + pB) / 2
bool rejected = false
float zoneHeight = math.abs(pT - pB)
if not na(atr) and atr > 0 and zoneHeight > maxZoneATR * atr
rejected := true
if not rejected and array.size(brkTop) > 0
for j = array.size(brkTop) - 1 to 0
if j < array.size(brkTop) and array.get(brkIsBull, j) == pBull
float existMid = (array.get(brkTop, j) + array.get(brkBot, j)) / 2
if not na(atr) and math.abs(newMid - existMid) < atr * 0.50
string existGrade = array.get(brkGrade, j)
bool newBetter = (grade == "A" and existGrade != "A") or (grade == "B" and existGrade == "C")
if newBetter
f_delFresh(j)
else
rejected := true
break
if not rejected
bool showThis = (pBull and showBull) or (not pBull and showBear)
if showThis
if initState == 1
if showTested
int boxRight = not na(eventBar) ? eventBar : bar_index
box tbx = box.new(obSourceBar, pT, boxRight, pB, bgcolor=testedCol, border_color=color.new(#6B7280, 40), border_width=1)
array.push(tstBox, tbx)
else
color fc = f_brkColor(pBull, grade)
color bc = f_borderColor(pBull)
box bx = box.new(obSourceBar, pT, bar_index + 1, pB, bgcolor=fc, border_color=bc, border_width=1, extend=extend.right)
label lb = na
if showLabels
string side = pBull ? "Bull" : "Bear"
string txt = side + " BRK " + grade
float labelY = pBull ? pT : pB
lb := label.new(bar_index, labelY, txt, style=pBull ? label.style_label_down : label.style_label_up, color=color.new(pBull ? #00D9A3 : #F59E0B, 70), textcolor=color.white, size=size.tiny)
if showMarkers
string mTxt = "◆ " + grade
int mOffset = bar_index - breakBarIdx
float mY = pBull ? low[mOffset] - nz(atr, 0) * 0.15 : high[mOffset] + nz(atr, 0) * 0.15
label.new(breakBarIdx, mY, mTxt, style=pBull ? label.style_label_up : label.style_label_down, color=color.new(color.black, 100), textcolor=pBull ? #00D9A3 : #F59E0B, size=size.tiny)
array.push(brkBox, bx)
array.push(brkLbl, lb)
array.push(brkTop, pT)
array.push(brkBot, pB)
array.push(brkIsBull, pBull)
array.push(brkGrade, grade)
array.push(brkBorn, bar_index)
rejected
if not na(pl)
[obT, obB, obBr] = f_findBearOB(swingLen)
if not na(obT) and not na(obB) and not Показано первые 50% кода (символов: 13646)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.