Range Breakout Verdict Engine
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «range breakout verdict engine.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Индикатор «Range Breakout Verdict Engine» (RBVE) автоматически обнаруживает ценовые диапазоны на графике и запускает последовательный статистический тест при пробитии границ диапазона закрытием бара. В основе теста лежит метод последовательного отношения правдоподобия (SPRT), параметры которого обучаются на реальных breakout-событиях текущего графика. Индикатор выносит вердикты ACCEPTED (продолжение) или DEVIATION (отклонение) при достижении достаточной доказательной базы.
Пользователь может задать допустимые уровни ошибок (с conservative, balanced и aggressive вариантами), количество баров для тестирования и параметры обучения. Если данных для обучения недостаточно, система переходит в режим LEARNING и не выдаёт окончательных вердиктов. Все решения фиксируются на закрытых барах и не пересматриваются.
Визуализация включает рамки диапазонов, метки вердиктов на графике и информационную панель с текущим состоянием теста, счётчиком доказательств и историей вердиктов. Индикатор поддерживает три условия оповещений: бычий вердикт, медвежий вердикт и начало тестирования пробития.
Настройки программы
| Настройка | Описание |
|---|---|
| rngLen | Количество баров в окне для определения диапазона. Диапазон формируется по максимуму и минимуму предыдущих N закрытых баров. |
| cmpMax | Максимальное сжатие: отношение высоты диапазона к высоте контекстного окна в 4 раза длиннее. Чем ниже значение, тем только более плотные консолидации принимаются как диапазон. |
| errIn | Уровень допустимых ошибок: conservative (α = β = 5%), balanced (α = β = 10%) или aggressive (α = β = 20%). Определяет допустимую частоту ложных вердиктов. Более низкие значения требуют больше доказательств. |
| maxK | Максимальное количество закрытых баров после бара пробития, которые тест может использовать для накопления доказательств. Если граница не достигнута, тест завершается как SKIP. |
| advOn | Включает расширенные правила обучения. При выключении используются значения по умолчанию: 1.0× для yardstick, 0.25× для глубины отказа, 30-барный горизонт и 5 проб на класс. |
| yardIn | Порог принятия (в кратных значениях от высоты диапазона): пробитие считается подтверждённым для обучения, если закрытие достигает этого расстояния за границей диапазона. |
| failIn | Глубина отказа (в кратных значениях от высоты диапазона): цена закрытия на этом расстоянии внутри диапазона классифицирует пробитие как неудачное для обучения. |
| horIn | Горизонт результата в барах: пробития, не разрешённые ни в одну сторону в пределах этого количества баров, отбрасываются из обучения. |
| nMinIn | Минимальное количество разрешённых пробитий каждого класса (ACCEPTED и FAILED), необходимое для выдачи вердиктов. До достижения этого порога панель показывает режим LEARNING. |
| showBox | Отображать ли рамки диапазонов на графике. Рамки рисуются пунктирной линией при формировании и сплошной при активном тесте. |
| bullCol | Цвет отрисовки для бычьих (восходящих) вердиктов и отметок на графике. |
| bearCol | Цвет отрисовки для медвежьих (нисходящих) вердиктов и отметок на графике. |
| showDash | Отображать ли информационную панель в правом верхнем углу графика с текущим состоянием, доказательствами и историей вердиктов. |
| tsIn | Размер таблицы информационной панели: Tiny, Small или Normal. |
Поиск по коду файла
indicator("Range Breakout Verdict Engine", shorttitle = "RBVE", overlay = true, max_boxes_count = 12, max_lines_count = 6, max_labels_count = 40)
enum ErrRate
conservative = "Conservative (α = β = 5%)"
balanced = "Balanced (α = β = 10%)"
aggressive = "Aggressive (α = β = 20%)"
enum TSize
tiny = "Tiny"
small = "Small"
normal = "Normal"
const string G_R = "Range Detection"
const string G_T = "Sequential Test"
const string G_L = "Learning Rules"
const string G_V = "Visuals"
int rngLen = input.int(20, "Range Length", minval = 8, maxval = 100, group = G_R, tooltip = "Bars in the candidate range window. The range is the high/low of the previous N closed bars.")
float cmpMax = input.float(0.50, "Max Compression", minval = 0.20, maxval = 0.90, step = 0.05, group = G_R, tooltip = "Range height ÷ height of the 4× longer context window. Lower values accept only tighter consolidations.")
ErrRate errIn = input.enum(ErrRate.balanced, "Error Rates", group = G_T, tooltip = "α = tolerated rate of ACCEPTED verdicts on breakouts that fail. β = tolerated rate of DEVIATION verdicts on breakouts that hold. Lower rates need more evidence, so verdicts arrive later and more tests end in SKIP.")
int maxK = input.int(8, "Max Test Bars", minval = 2, maxval = 30, group = G_T, tooltip = "Closed bars after the breakout bar that the test may use. If the evidence never crosses a bound, the test ends as SKIP.")
bool advOn = input.bool(false, "Custom Learning Rules", group = G_L, tooltip = "Off = defaults (1.0× yardstick, 0.25× failure depth, 30-bar horizon, 5 trials per class).")
float yardIn = input.float(1.0, "Acceptance Yardstick (× range height)", minval = 0.3, maxval = 3.0, step = 0.1, group = G_L, active = advOn, tooltip = "A breakout is labelled ACCEPTED for learning when a close reaches this distance beyond the broken boundary.")
float failIn = input.float(0.25, "Failure Depth (× range height)", minval = 0.05, maxval = 1.0, step = 0.05, group = G_L, active = advOn, tooltip = "A breakout is labelled FAILED for learning when a close returns this far back inside the range.")
int horIn = input.int(30, "Outcome Horizon (bars)", minval = 5, maxval = 200, group = G_L, active = advOn, tooltip = "Breakouts that resolve neither way within this many bars are discarded from learning.")
int nMinIn = input.int(5, "Min Trials per Class", minval = 2, maxval = 50, group = G_L, active = advOn, tooltip = "Resolved ACCEPTED and FAILED breakouts required before verdicts are issued. Until then the dashboard shows LEARNING.")
bool showBox = input.bool(true, "Show Range Boxes", group = G_V)
color bullCol = input.color(#22C3A6, "Bullish", group = G_V, inline = "pal")
color bearCol = input.color(#F0506E, "Bearish", group = G_V, inline = "pal")
bool showDash = input.bool(true, "Show Dashboard", group = G_V)
TSize tsIn = input.enum(TSize.small, "Table Size", group = G_V, active = showDash)
float yardE = advOn ? yardIn : 1.0
float failE = advOn ? failIn : 0.25
int nMinE = advOn ? nMinIn : 5
int horE = math.max(advOn ? horIn : 30, maxK + 1)
float alphaE = errIn == ErrRate.conservative ? 0.05 : errIn == ErrRate.balanced ? 0.10 : 0.20
float betaE = alphaE
float upperA = math.log((1.0 - betaE) / alphaE)
float lowerB = math.log(betaE / (1.0 - alphaE))
string tblSz = tsIn == TSize.tiny ? size.tiny : tsIn == TSize.small ? size.small : size.normal
color neutral = color.new(chart.fg_color, 55)
const int NB = 6
f_bin(float x) =>
x < -0.25 ? 0 : x < 0.0 ? 1 : x < 0.15 ? 2 : x < 0.35 ? 3 : x < 0.70 ? 4 : 5
f_lr(int b, array<int> ca, array<int> cf, int nA, int nF) =>
float pa = (ca.get(b) + 1.0) / (nA + NB)
float pf = (cf.get(b) + 1.0) / (nF + NB)
math.log(pa / pf)
f_pct(int num, int den) =>
den > 0 ? str.tostring(math.round(100.0 * num / den)) + "%" : "—"
float hiW = ta.highest(high, rngLen)
float loW = ta.lowest(low, rngLen)
float hiC = ta.highest(high, rngLen * 4)
float loC = ta.lowest(low, rngLen * 4)
var int state = 0
var float rTop = na
var float rBot = na
var int rFormed = na
var box curBox = na
var array<box> boxHist = array.new<box>()
var int tDir = 0
var float tBound = na
var float tH = na
var int tBar = na
var int tK = -1
var float llr = 0.0
var int vK = -1 // test bar on which the verdict was issued
var int verdict = 0 // 0 pending, 1 ACCEPTED, -1 DEVIATION, 2 SKIP, 3 LEARNING (no verdict)
var array<int> obs = array.new<int>()
var array<int> cntA = array.new<int>(NB, 0)
var array<int> cntF = array.new<int>(NB, 0)
var int nObsA = 0
var int nObsF = 0
var int nTrA = 0
var int nTrF = 0
var int nUnres = 0
var int accV = 0
var int accHit = 0
var int devV = 0
var int devHit = 0
var int lastV = 0
var int lastVDir = 0
var int lastVBar = na
var line yLine = na
var array<label> labs = array.new<label>()
bool bullSig = false
bool bearSig = false
bool testStart = false
var table wm = table.new(position.bottom_right, 1, 1)
if barstate.isfirst
table.cell(wm, 0, 0, "Telegram @free_fx_pro", text_color = color.new(color.gray, 70), text_size = size.large)
if barstate.isconfirmed
if state == 0
float wH = hiW[1] - loW[1]
float cH = hiC[1] - loC[1]
if not na(wH) and not na(cH) and cH > 0 and wH > syminfo.mintick * 2 and wH <= cmpMax * cH and close <= hiW[1] and close >= loW[1]
rTop := hiW[1]
rBot := loW[1]
rFormed := bar_index
state := 1
if showBox
curBox := box.new(bar_index - rngLen, rTop, bar_index, rBot, border_color = neutral, border_width = 1, border_style = line.style_dashed, bgcolor = color.new(chart.fg_color, 94))
boxHist.push(curBox)
if boxHist.size() > 4
box.delete(boxHist.shift())
else if state == 1
if close > rTop or close < rBot
tDir := close > rTop ? 1 : -1
tBound := tDir == 1 ? rTop : rBot
tH := rTop - rBot
tBar := bar_index
tK := -1
llr := 0.0
vK := -1
obs.clear()
verdict := nTrA >= nMinE and nTrF >= nMinE ? 0 : 3
state := 2
testStart := true
if showBox and not na(curBox)
box.set_right(curBox, bar_index)
if not na(yLine)
line.delete(yLine)
float yLvl = tBound + tDir * yardE * tH
yLine := line.new(bar_index, yLvl, bar_index + maxK, yLvl, color = neutral, style = line.style_dotted, width = 1)
else if bar_index - rFormed > 2 * rngLen
state := 0
if not na(curBox)
box.delete(curBox)
if boxHist.size() > 0
boxHist.pop()
curBox := na
else if showBox and not na(curBox)
box.set_right(curBox, bar_index)
if state == 2
tK += 1
float x = tDir * (close - tBound) / tH
int b = f_bin(x)
if tK <= maxK
obs.push(b)
if verdict == 0
llr += f_lr(b, cntA, cntF, nObsA, nObsF)
if llr >= upperA
verdict := 1
else if llr <= lowerB
verdict := -1
else if tK == maxK
verdict := 2
if verdict == 1 or verdict =Показано первые 50% кода (символов: 10796)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.