FVG Displacement & Fill Scoring
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator_fvg_displacement_&_fill_scoring_for_tradingview.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Индикатор «FVG Displacement & Fill Scoring» предназначен для обнаружения и оценки ценовых разрывов (FVG — Fair Value Gaps) на графиках TradingView. Он рассчитывает составной балл смещения каждого разрыва на основе трёх взвешенных метрик: размера разрыва, диапазона свечи и соотношения тела свечи к диапазону, всё выражается в единицах ATR. Индикатор отслеживает жизненный цикл зон — от появления до заполнения или инвалидации — и визуализирует их в виде цветных прямоугольников с метками на графике.
Продукт предоставляет дашборд-панель с информацией о ближайших зонах спроса и предложения, режиме рынка (SMA на H4) и статистике разделения (квартильные бины балла смещения vs реакция цены). Дополнительно доступны условные оповещения TradingView при появлении новых зон и изменении состояния заполнения. Индикатор работает на подтверждённых барах без перерисовки и не генерирует торговые сигналы, входы или размеры позиций.
Настройки охватывают детекцию разрывов, весовые коэффициенты и нормализацию составного балла, измерение структурных проб и объёма, фильтрацию по сессии и таймфрейму режима, а также обширный набор параметров визуализации и производительности. Все данные о зонах хранятся в памяти с возможностью ограничения количества отслеживаемых зон.
Настройки программы
| Настройка | Описание |
|---|---|
| atrLen | Длина периода для расчёта ATR (средний истинный диапазон), используемого как базовая единица измерения размеров разрывов и свечных диапазонов. |
| minGapATR | Минимальный размер разрыва в единицах ATR для отслеживания. Значение 0 означает отслеживание всех корректных трёхсвечных разрывов. Повышение фильтрует микроразрывы. |
| detectBull | Включает или отключает обнаружение бычьих (demand) разрывов, где низкая свеча выше высокой свечи двумя барами ранее. |
| detectBear | Включает или отключает обнаружение медвежьих (supply) разрывов, где высокая свеча ниже низкой свечи двумя барами ранее. |
| wGap | Весовой коэффициент для размера разрыва в составеном балле смещения. |
| wRange | Весовой коэффициент для диапазона свечи в составеном балле смещения. |
| wBody | Весовой коэффициент для соотношения тела свечи к диапазону в составеном балле смещения. |
| gapNorm | Нормализующий коэффициент: значение размера разрыва в единицах ATR, которое соответствует полной подсчётной оценке 1.0 для метрики размера разрыва. |
| rngNorm | Нормализующий коэффициент: значение диапазона свечи в единицах ATR, которое соответствует полной подсчётной оценке 1.0 для метрики диапазона. |
| structProbe | Включает измерение пробоя структуры: проверяет, не пробил ли свеча смещения последний подтверждённый пивот (бычий: максимум, медвежий: минимум). Результат экспортируется и бинится, но не входит в составной балл. |
| pivLen | Количество баров для поиска назад и вперёд при определении ключевых пивотов, используемых в пробе структурного пробоя. |
| volProbe | Включает измерение соотношения объёма свечи смещения к среднему объёму. Результат экспортируется и бинится, но не входит в составной балл. |
| volAvgLen | Длина периода для расчёта среднего объёма, используемого в зондировании объёма. |
| halfPct | Порог половинного заполнения зоны в доле от размера разрыва. При достижении этого уровня заполнение зоны переходит в состояние «половинное». |
| reactBars | Количество баров после первой отметки тега, в течение которых измеряется благоприятное удаление цены от зоны. Это переменная результата для хранилища разделения. |
| regimeTF | Таймфрейм для определения режима рынка (H4 по умолчанию). Регим используется только как флаг для панели и хранилища, не как условие фильтрации. |
| regimeLen | Длина SMA для расчёта линии режима на указанном таймфрейме. |
| useSess | Включает фильтрацию обнаружения разрывов только внутри заданной торговой сессии. |
| sess | Временной интервал торговой сессии для фильтрации обнаружения разрывов (по умолчанию 0000-2400 — круглосуточно). |
| sessTZ | Часовой пояс торговой сессии, в котором задаётся фильтр. |
| showBoxes | Включает или отключает отображение прямоугольников зон разрывов на графике. |
| gradeOp | При включении прозрачность прямоугольников зон изменяется в зависимости от состояния заполнения (свежая — более плотная, заполненная — более прозрачная). |
| showLbl | Включает или отключает инлайн-метки (текстовые подписи) на активных зонах. |
| retailLbl | При включении метки зон отображаются в формате «DEMAND ZONE / SUPPLY ZONE · балл/100 · состояние». При отключении — в количественном формате «балл СОСТОЯНИЕ %заполнения». |
| showMid | Включает отображение пунктирной линии на уровне 50% заполнения (половинный порог) каждой активной зоны. |
| maxAge | Максимальный возраст зоны в баражах для отображения на графике. Зоны старше этого порога перестают рисоваться. Значение 0 означает без ограничений. Данные в хранилище при этом не затрагиваются. |
| showCall | Включает отображение стрелок-вызовов (callout) на свече смещения при обнаружении нового разрыва. |
| showPanel | Включает или отключает дашборд-панель в правом верхнем углу графика с информацией о зонах, режиме и ATR. |
| maxDraw | Максимальное количество прямоугольников зон, отображаемых на графике одновременно. Более старые зоны удаляются визуально. |
| maxLbl | Максимальное количество инлайн-меток, отображаемых одновременно. Присваиваются только наиболее высоко оценённым активным зонам. Мёртвые зоны (полностью заполненные или инвалидированные) не получают меток. |
| minLblScore | Минимальный составной балл для присвоения инлайн-метки зоне. Зоны с оценкой ниже этого порога не получают меток. Значение 0 отключает фильтр. |
| lblAnti | Режим обработки перекрывающихся меток: «Off» — без коррекции, «Nudge apart (vertical)» — раздвигает метки вертикально, «Cascade right (bars)» — сдвигает метки вправо по барам. |
| lblStagger | В режиме каскадного сдвига — количество баров, на которое каждое последующее перекрывающееся смещённое смещается вправо. |
| lblLeader | Включает отображение пунктирных соединительных линий от смещённой метки к правому краю соответствующей зоны. |
| lblOvlATR | Минимальное вертикальное расстояние между якорями меток, выраженное в единицах ATR. В режиме сдвига задаёт допустимое перекрытие. |
| showDead | При включении прямоугольники полностью заполненных или инвалидированных зон сохраняются на графике в приглушённом виде для обзора. При отключении они удаляются сразу после заполнения. |
| bullHex | Цвет для обозначения бычьих (demand) зон на графике. |
| bearHex | Цвет для обозначения медвежьих (supply) зон на графике. |
| maxZones | Жёсткий лимит количества отслеживаемых зон в памяти. Старые зоны за пределами лимита удаляются. Влияет на производительность при глубокой истории. |
| showStats | Включает или отключает таблицу квартильной статистики разделения в правом нижнем углу графика. |
| minN | Минимальное количество завершённых наблюдений в выборке для доверенной оценки квартильных статистик в таблице разделения. |
| sliceOpt | Фильтр выборки для хранилища разделения: «All» — все данные, «Regime-aligned» — только совпадающие с режимом, «Counter-regime» — противоположный режим, «Struct-broke» — пробитые пивоты, «No-struct» — без пробития. |
Поиск по коду файла
indicator("FVG Displacement & Fill Scoring", shorttitle="FVG DispFill", overlay=true, max_boxes_count=500, max_labels_count=500, max_lines_count=500)
grpDet = "Detection"
atrLen = input.int(14, "ATR length", minval=1, group=grpDet)
minGapATR = input.float(0.0,"Min gap size (× ATR) to track", minval=0.0, step=0.05, group=grpDet, tooltip="0 = track every valid 3-candle gap; the score does the ranking. Raise only to prune micro-gaps.")
detectBull = input.bool(true,"Detect bullish (demand) gaps", group=grpDet)
detectBear = input.bool(true,"Detect bearish (supply) gaps", group=grpDet)
grpScore = "Displacement score (composite, 0–100)"
wGap = input.float(1.0, "Weight — gap size (ATR)", minval=0.0, step=0.1, group=grpScore)
wRange = input.float(1.0, "Weight — candle range (ATR)", minval=0.0, step=0.1, group=grpScore)
wBody = input.float(1.0, "Weight — body / range ratio", minval=0.0, step=0.1, group=grpScore)
gapNorm = input.float(1.0, "Normalise — gap ATR = full at", minval=0.1, step=0.1, group=grpScore, tooltip="Gap size (in ATR) that maps to a full sub-score of 1.0.")
rngNorm = input.float(2.0, "Normalise — range ATR = full at", minval=0.1, step=0.1, group=grpScore, tooltip="Displacement-candle range (in ATR) that maps to a full sub-score of 1.0.")
grpProbe = "Measure-only probes (not in composite)"
structProbe = input.bool(true, "Structure-break probe (broke prior pivot)", group=grpProbe, tooltip="Did the displacement candle break the most recent confirmed pivot (bull: pivot high, bear: pivot low)? Exported and binned, kept out of the score until the harness earns it.")
pivLen = input.int(10, "Pivot lookback / lookforward", minval=2, group=grpProbe)
volProbe = input.bool(true, "Volume probe (disp vol vs avg)", group=grpProbe)
volAvgLen = input.int(20, "Volume average length", minval=2, group=grpProbe)
grpFill = "Fill lifecycle"
halfPct = input.float(0.5, "Half-fill threshold (fraction of gap)", minval=0.05, maxval=0.95, step=0.05, group=grpFill)
reactBars= input.int(20, "Reaction window (bars) after first tag", minval=1, group=grpFill, tooltip="Bars over which favorable excursion away from the zone is measured. This is the outcome variable for the separation harness.")
grpRegime= "Regime / context (flag only)"
regimeTF = input.timeframe("240", "Regime timeframe", group=grpRegime)
regimeLen= input.int(20, "Regime SMA length", minval=1, group=grpRegime)
grpSess = "Session filter (UTC)"
useSess = input.bool(false, "Only detect inside session", group=grpSess)
sess = input.session("0000-2400", "Session", group=grpSess)
sessTZ = input.string("UTC", "Session timezone", group=grpSess)
grpViz = "Visuals"
showBoxes= input.bool(true, "Draw gap boxes", group=grpViz)
gradeOp = input.bool(true, "Grade box opacity by fill state", group=grpViz)
showLbl = input.bool(true, "Inline zone label", group=grpViz)
retailLbl= input.bool(true, "Retail wording (Demand/Supply zone + strength)", group=grpViz, tooltip="On = 'DEMAND ZONE · 72/100 · Fresh' for published charts. Off = quant read 'score STATE fill%' for your own use.")
showMid = input.bool(true, "50% midline (half-fill threshold)", group=grpViz, tooltip="Dashed line at the half-fill level of each live zone. Drawn at halfPct, so it follows the half-fill threshold.")
maxAge = input.int(400, "Max zone age drawn (bars, 0 = unlimited)", minval=0, group=grpViz, tooltip="Display only. Zones older than this stop being drawn so ancient gaps don't paint wall-to-wall bands across the chart. Harness data is untouched.")
showCall = input.bool(true, "Callout arrow on displacement candle", group=grpViz)
showPanel= input.bool(true, "Dashboard panel", group=grpViz)
maxDraw = input.int(30, "Max gap boxes drawn (oldest retired)", minval=1, maxval=400, group=grpViz)
maxLbl = input.int(8, "Max inline labels (top score, live only)", minval=0, maxval=60, group=grpViz, tooltip="Only the highest-scoring LIVE zones get an inline label. Dead zones (full/invalidated) are never labelled. Stops the label wall in ranges.")
minLblScore = input.float(0.0, "Min score for inline label", minval=0.0, maxval=100.0, step=5, group=grpViz, tooltip="Zones scoring below this never get an inline label, even if a top-K slot is free. 0 = off. Display only — boxes and harness untouched.")
lblAnti = input.string("Nudge apart (vertical)", "Overlapping labels", options=["Off", "Nudge apart (vertical)", "Cascade right (bars)"], group=grpViz, tooltip="What to do when two labelled zones sit too close together. Nudge = keep labels at the zone edge and push them apart vertically by the minimum needed, split evenly up/down. Cascade = step each colliding label rightward instead. Display only.")
lblStagger = input.int(11, "Cascade step (bars)", minval=1, maxval=100, group=grpViz, tooltip="Cascade mode only — how many bars each subsequent colliding label steps right.")
lblLeader = input.bool(true, "Leader line (label → zone)", group=grpViz, tooltip="When anti-overlap moves a label away from its zone mid (nudge or cascade), draw a dotted connector from the label anchor back to the zone's right edge at its midpoint. Labels that were not displaced get no leader. Display only.")
lblOvlATR = input.float(0.8, "Label spacing (× ATR)", minval=0.1, maxval=10.0, step=0.1, group=grpViz, tooltip="Minimum vertical distance between label anchors, in ATRs. In nudge mode this is the gap enforced between labels; in cascade mode it is the collision tolerance. Raise if labels still touch at your zoom level, lower for tighter packing.")
showDead = input.bool(false, "Keep full / invalidated zone boxes", group=grpViz, tooltip="Off = retire a zone's box the moment it fills or invalidates (data stays in the harness). On = keep them faint for review.")
bullHex = input.color(#16CFA1, "Bull (demand) color", group=grpViz)
bearHex = input.color(#FF4D6E, "Bear (supply) color", group=grpViz)
grpPerf = "Performance"
maxZones = input.int(500, "Max zones held in memory (oldest dropped)", minval=50, maxval=2000, group=grpPerf, tooltip="Hard cap on the tracked-zone array — this is what bounds the per-bar loop. The oldest zones past the cap are dropped. Lower it if you hit 'Loop takes too long' on deep history.")
grpRes = "Research — separation harness"
showStats= input.bool(true, "Show quartile stats table", group=grpRes)
minN = input.int(20, "Min completed sample to trust bins", minval=4, group=grpRes)
sliceOpt = input.string("All", "Harness slice", options=["All", "Regime-aligned", "Counter-regime", "Struct-broke", "No-struct"], group=grpRes, tooltip="Filter the completed sample before binning. Regime slices use the H4 regime direction AT FIRST TAG (the decision moment), not at birth. Struct slices use the structure-break probe. Quartile thresholds are recomputed within the slice.")
colBull = bullHex
colBear = bearHex
colText = color.new(#e6e6e6, 0)
colDim = color.new(#9aa0a6, 0)
panelBg = color.new(#12161c, 10)
panelHdr = color.new(#1c232c, 0)
atr = ta.atr(atrLen)
regimeSMA = request.security(syminfo.tickerid, regimeTF, ta.sma(close, regimeLen), lookahead=barmerge.lookahead_off)
regimeDir = na(regimeSMA) ? 0 : (close > regimeSMA ? 1 : close < regimeSMA ? -1 : 0)
inSession = not useSess or not na(time(timeframe.period, sess, sessTZ))
var float lastPivotHigh = na
var float lastPivotLow = na
ph = ta.pivothigh(high, pivLen, pivLen)
pl = ta.pivotlow(low, pivLen, pivLen)
if not na(ph)
lastPivotHigh := ph
if not na(pl)
lastPivotLow := pl
volAvg = ta.sma(volume, volAvgLen)
S_FRESH = 0
S_TAG = 1
S_HALF = 2
S_FULL = 3
S_INVAL = 4
type FVG
int dir // +1 bull demand / -1 bear supply
float top // upper edge
float bot // lower edge
int birthBar // bar_index at birth
float dispScore // composite 0–100
bool structBroke // measure-only probe
float volRatio // measure-only probe
int state // fill state code
float fillDepth // 0..1 max penetration into the gap
float reactExc // favorable excursion (ATR-at-tag units) in reactBars after first tag
int tagBar // bar_index when first tagged (na → -1)
float atrTag // ATR frozen at first tag — excursion denominator for the whole window
int regimeTag // H4 regime direction at first tag (+1 / -1 / 0)
bool reactDone // reaction window complete
bool counted // pushed to harness sample
box bx
label lb
line ml // 50% (half-fill) midline
line ldr // dotted leader connecting a displaced label to its zone
var array<FVG> zones = array.new<FVG>()
var array<float> sampScore = array.new<float>()
var array<float> sampExc = array.new<float>()
var array<int> sampStruct= array.new<int>() // 1/0
var array<int> sampRegime= array.new<int>() // +1 aligned / -1 counter / 0 flat-unknown (at first tag)
clamp01(x) => math.max(0.0, math.min(1.0, x))
f_pushSample(FVG z) =>
array.push(sampScore, z.dispScore)
array.push(sampExc, z.reactExc)
array.push(sampStruct, z.structBroke ? 1 : 0)
array.push(sampRegime, z.regimeTag == 0 ? 0 : z.dir == z.regimeTag ? 1 : -1)
dispScoreOf(float gapATR, float rngATR, float bodyRatio) =>
gs = clamp01(gapATR / gapNorm)
rs = clamp01(rngATR / rngNorm)
bs = clamp01(bodyRatio)
wsum = wGap + wRange + wBody
wsum <= 0 ? 0.0 : 100.0 * (wGap*gs + wRange*rs + wBody*bs) / wsum
stateTransp(int st) =>
if not gradeOp
82
else
switch st
S_FRESH => 78
S_TAG => 84
S_HALF => 89
S_FULL => 93
=> 93
var float alBDir = 0.0
var float alBScore = 0.0
var float alBState = 0.0
var float alBStruct = 0.0
var float alBVol = 0.0
var float alBTop = 0.0
var float alBBot = 0.0
var float alBFill = 0.0
var float alCDir = 0.0
var float alCScore = 0.0
var float alCState = 0.0
var float alCStruct = 0.0
var float alCVol = 0.0
var float alCTop = 0.0
var float alCBot = 0.0
var float alCFill = 0.0
bornThisBar = false
changedThisBar = false
float chgBest = na // highest dispScore among state changes this bar
makeZone(int dir, float top, float bot) =>
dRange = high[1] - low[1]
dBody = math.abs(close[1] - open[1])
dBodyR = dRange > 0 ? dBody / dRange : 0.0
gapSz = top - bot
gapATR = atr > 0 ? gapSz / atr : 0.0
rngATR = atr > 0 ? dRange / atr : 0.0
score = dispScoreOf(gapATR, rngATR, dBodyR)
sBroke = false
if structProbe
sBroke := dir == 1 ? (not na(lastPivotHigh) and high[1] > lastPivotHigh) : (not na(lastPivotLow) and low[1] < lastPivotLow)
vRatio = volProbe and not na(volAvg) and volAvg > 0 ? volume[1] / volAvg : na
FVG.new(dir, top, bot, bar_index, score, sBroke, vRatio, S_FRESH, 0.0, 0.0, -1, na, 0, false, false, na, na, na, na)
if barstate.isconfirmed and inSession and bar_index > 2
if detectBull and low > high[2]
top = low
bot = high[2]
if (top - bot) >= minGapATR * atr
z = makeZone(1, top, bot)
array.push(zones, z)
bornThisBar := true
alBDir := z.dir
alBScore := z.dispScore
alBState := z.state
alBStruct := z.structBroke ? 1 : 0
alBVol := na(z.volRatio) ? -1.0 : z.volRatio
alBTop := z.top
alBBot := z.bot
alBFill := z.fillDepth
if detectBear and high < low[2]
top = low[2]
bot = high
if (top - bot) >= minGapATR * atr
z = makeZone(-1, top, bot)
array.push(zones, z)
bornThisBar := true
alBDir := z.dir
alBScore := z.dispScore
alBState := z.state
alBStruct := z.structBroke ? 1 : 0
alBVol := na(z.volRatio) ? -1.0 : z.volRatio
alBTop := z.top
alBBot := z.bot
alBFill := z.fillDepth
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)
if barstate.isconfirmed
n = array.size(zones)
if n > 0
for i = 0 to n - 1
z = array.get(zones, i)
span = z.top - z.bot
if span > 0 and z.state != S_INVAL
prevState = z.state
pen = 0.0
if z.dir == 1
if low < z.top
pen := clamp01((z.top - math.max(low, z.bot)) / span)
else
if high > z.bot
pen := clamp01((math.min(high, z.top) - z.bot) / span)
if pen > z.fillDepth
z.fillDepth := pen
invalidated = z.dir == 1 ? close < z.bot : close > z.top
newState = z.state
if invalidated
newState := S_INVAL
else if z.fillDepth >= 1.0
newState := S_FULL
else if z.fillDepth >= halfPct
newState := S_HALF
else if z.fillDepth > 0.0
newState := S_TAG
if newState != prevState
z.state := newState
if z.tagBar == -1 and newState >= S_TAG
z.tagBar := bar_index
z.atrTag := atr
z.regimeTag := regimeDir
if na(chgBest) or z.dispScore > chgBest
chgBest := z.dispScore
changedThisBar := true
alCDir := z.dir
alCScore := z.dispScore
alCState := z.state
alCStruct := z.structBroke ? 1 : 0
alCVol := na(z.volRatio) ? -1.0 : z.volRatio
alCTop := z.top
alCBot := z.bot
alCFill := z.fillDepth
if z.tagBar != -1 and not z.reactDone and bar_index > z.tagBar
if z.dir == 1
exc = z.atrTag > 0 ? (high - z.top) / z.atrTag : 0.0
if exc > z.reactExc
z.reactExc := exc
else
exc = z.atrTag > 0 ? (z.bot - low) / z.atrTag : 0.0
if exc > z.reactExc
z.reactExc := exc
if bar_index - z.tagBar >= reactBars
z.reactDone := true
if not z.counted
z.counted := true
f_pushSample(z)
if z.state == S_INVAL and z.tagBar != -1 and not z.counted
z.reactDone := true
z.counted := true
f_pushSample(z)
array.set(zones, i, z)
if barstate.isconfirmed and not showDead
pj = array.size(zones) - 1
while pj >= 0
zp = array.get(zones, pj)
if (zp.state == S_FULL or zp.state == S_INVAL) and zp.counted
if not na(zp.bx)
box.delete(zp.bx)
if not na(zp.lb)
label.delete(zp.lb)
if not na(zp.ml)
line.delete(zp.ml)
if not na(zp.ldr)
line.delete(zp.ldr)
array.remove(zones, pj)
pj -= 1
if barstate.isconfirmed
while array.size(zones) > maxZones
zd = array.get(zones, 0)
if not na(zd.bx)
box.delete(zd.bx)
if not na(zd.lb)
label.delete(zd.lb)
if not na(zd.ml)
line.delete(zd.ml)
if not na(zd.ldr)
line.delete(zd.ldr)
array.remove(zones, 0)
f_stateName(int st) =>
switch st
S_FRESH => "FRESH"
S_TAG => "TAGGED"
S_HALF => "HALF"
S_FULL => "FULL"
S_INVAL => "INVALID"
=> "?"
f_retailState(int st) =>
switch st
S_FRESH => "Fresh"
S_TAG => "Tested"
S_HALF => "Half-filled"
S_FULL => "Filled"
=> "Broken"
f_zoneText(int dir, float score, int st, float fill, bool sBroke) =>
if retailLbl
(dir == 1 ? "DEMAND ZONE" : "SUPPLY ZONE") + "\n" + str.tostring(math.round(score)) + "/100 · " + f_retailState(st)
else
str.tostring(math.round(score)) + " " + f_stateName(st) + " " + str.tostring(math.round(fill * 100)) + "%" + (sBroke ? " ⚡" : "")
if barstate.islast and (showBoxes or showLbl or showMid)
total = array.size(zones)
start = math.max(0, total - maxDraw)
if start > 0
for i = 0 to start - 1
zr = array.get(zones, i)
if not na(zr.bx)
box.delete(zr.bx)
zr.bx := na
if not na(zr.lb)
label.delete(zr.lb)
zr.lb := na
if not na(zr.ml)
line.delete(zr.ml)
zr.ml := na
if not na(zr.ldr)
line.delete(zr.ldr)
zr.ldr := na
array.set(zones, i, zr)
lblSet = array.new<int>()
if showLbl and maxLbl > 0 and total > 0
liveScores = array.new<float>()
for i = start to total - 1
zc = array.get(zones, i)
zcExp = maxAge > 0 and (bar_index - zc.birthBar) > maxAge
if zc.state != S_INVAL and zc.state != S_FULL and not zcExp and zc.dispScore >= minLblScore
array.push(liveScores, zc.dispScore)
nLive = array.size(liveScores)
if nLive > 0
float lblCut = -1.0 // <= all real scores → everyone eligible
if nLive > maxLbl
array.sort(liveScores, order.descending)
lblCut := array.get(liveScores, maxLbl - 1) // K-th highest score
int slots = maxLbl
for i = start to total - 1
zc = array.get(zones, i)
zcExp = maxAge > 0 and (bar_index - zc.birthBar) > maxAge
elig = zc.state != S_INVAL and zc.state != S_FULL and not zcExp and zc.dispScore >= minLblScore
if elig and zc.dispScore > lblCut and slots > 0
array.push(lblSet, i)
slots -= 1
ti = total - 1
while ti >= start and slots > 0
zc = array.get(zones, ti)
zcExp = maxAge > 0 and (bar_index - zc.birthBar) > maxAge
elig = zc.state != S_INVAL and zc.state != S_FULL and not zcExp and zc.dispScoreПоказано первые 50% кода (символов: 26455)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.