The indicator detects and plots Fair Value Gaps across multiple timeframes on the price chart, including 15 minutes, 1 hour, 4 hours, daily, weekly, and monthly.
1Copy the scriptPress Copy script above, or the copy button on the code below.
2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.
Source Code
1,339 lines of Pine Script v6 from indicator.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.
indicator.pine
// ========================================
// NXOG - New X Opening Gaps + FVG Multi-TF
// NWOG: Sex (close) → Seg (open) - Semanal
// NDOG: Dia Ant (close) → Dia Atual (open) - Diário
// NMOG: Mês Ant (close) → Mês Atual (open) - Mensal
// FVG: Fair Value Gap com filtro de sobreposição NXOG
// ========================================
//@version=6
indicator('NXOG + FVG', overlay = true, max_boxes_count = 500, max_labels_count = 200)
// ========== CONFIGURAÇÕES GERAIS ==========
var g_general = 'Configurações Gerais'
showLabels = input.bool(true, 'Texto dentro da BOX', group = g_general)
boxTransparency = input.int(85, 'Transparência dos Boxes', minval = 0, maxval = 100, group = g_general)
var g_mitig = 'Mitigação'
mitig_pct_threshold = input.int(50, 'Mitigando em X %', minval = 1, maxval = 100, group = g_mitig)
mitig_use_close = input.bool(false, 'Usar o corpo ao invés do pavio', group = g_mitig)
deleteAllMitigatedNXOG = input.bool(false, 'Remover TODOS Gaps (NXOG) mitigados', group = g_mitig)
deleteAllMitigatedFVG = input.bool(true, 'Remover TODOS FVGs mitigados', group = g_mitig)
// Configuração Hardcoded
nxog_min_gap = 0.01 // % mínimo do gap
// ========== NDOG ==========
var g_ndog = 'NDOG (Diário)'
enable_ndog = input.bool(true, 'Mostrar NDOG', tooltip = 'New Day Opening Gap (Ontem → Hoje)', group = g_ndog)
deleteFilledNDOG = input.bool(false, 'Remover NDOGs mitigados', group = g_ndog)
max_ndog = input.int(5, 'Máx NDOG', minval = 1, maxval = 10, group = g_ndog)
color_ndog_up = input.color(color.new(color.lime, 75), 'Cor Alta', group = g_ndog)
color_ndog_dn = input.color(color.new(color.lime, 75), 'Cor Baixa', group = g_ndog)
// ========== NWOG ==========
var g_nwog = 'NWOG (Semanal)'
enable_nwog = input.bool(true, 'Mostrar NWOG', tooltip = 'New Week Opening Gap (Sex → Seg)', group = g_nwog)
deleteFilledNWOG = input.bool(false, 'Remover NWOGs mitigados', group = g_nwog)
max_nwog = input.int(3, 'Máx NWOG', minval = 1, maxval = 10, group = g_nwog)
color_nwog_up = input.color(color.new(color.teal, 75), 'Cor Alta', group = g_nwog)
color_nwog_dn = input.color(color.new(color.teal, 75), 'Cor Baixa', group = g_nwog)
// ========== NMOG ==========
var g_nmog = 'NMOG (Mensal)'
enable_nmog = input.bool(true, 'Mostrar NMOG', tooltip = 'New Month Opening Gap (Mês Ant. → Novo)', group = g_nmog)
deleteFilledNMOG = input.bool(false, 'Remover NMOGs mitigados', group = g_nmog)
max_nmog = input.int(3, 'Máx NMOG', minval = 1, maxval = 10, group = g_nmog)
color_nmog_up = input.color(color.new(color.maroon, 75), 'Cor Alta', group = g_nmog)
color_nmog_dn = input.color(color.new(color.maroon, 75), 'Cor Baixa', group = g_nmog)
// ========== FVG 15M ==========
var g_tf15m = 'FVG 15M'
enable_15m = input.bool(true, 'FVG 15M', group = g_tf15m)
deleteFilled15m = input.bool(true, 'Remover FVGs mitigados', group = g_tf15m)
max_fvg_15m = input.int(8, 'Máx FVGs', minval = 1, maxval = 20, group = g_tf15m)
color_up_15m = input.color(color.new(color.blue, 85), 'Cor FVG Alta', group = g_tf15m)
color_dn_15m = input.color(color.new(color.blue, 85), 'Cor FVG Baixa', group = g_tf15m)
// ========== FVG 1H ==========
var g_tf1h = 'FVG 1H'
enable_1h = input.bool(true, 'FVG 1H', group = g_tf1h)
deleteFilled1h = input.bool(true, 'Remover FVGs mitigados', group = g_tf1h)
max_fvg_1h = input.int(6, 'Máx FVGs', minval = 1, maxval = 15, group = g_tf1h)
color_up_1h = input.color(color.new(color.orange, 85), 'Cor FVG Alta', group = g_tf1h)
color_dn_1h = input.color(color.new(color.orange, 85), 'Cor FVG Baixa', group = g_tf1h)
// ========== FVG 4H ==========
var g_tf4h = 'FVG 4H'
enable_4h = input.bool(true, 'FVG 4H', group = g_tf4h)
deleteFilled4h = input.bool(true, 'Remover FVGs mitigados', group = g_tf4h)
max_fvg_4h = input.int(5, 'Máx FVGs', minval = 1, maxval = 12, group = g_tf4h)
color_up_4h = input.color(color.new(color.purple, 85), 'Cor FVG Alta', group = g_tf4h)
color_dn_4h = input.color(color.new(color.purple, 85), 'Cor FVG Baixa', group = g_tf4h)
// ========== FVG 1D ==========
var g_tf1d = 'FVG 1D'
enable_1d = input.bool(true, 'FVG 1D', group = g_tf1d)
deleteFilled1d = input.bool(true, 'Remover FVGs mitigados', group = g_tf1d)
max_fvg_1d = input.int(4, 'Máx FVGs', minval = 1, maxval = 10, group = g_tf1d)
color_up_1d = input.color(color.new(color.yellow, 85), 'Cor FVG Alta', group = g_tf1d)
color_dn_1d = input.color(color.new(color.yellow, 85), 'Cor FVG Baixa', group = g_tf1d)
// ========== FVG 1W ==========
var g_tf1w = 'FVG 1W'
enable_1w = input.bool(true, 'FVG 1W', group = g_tf1w)
deleteFilled1w = input.bool(true, 'Remover FVGs mitigados', group = g_tf1w)
max_fvg_1w = input.int(3, 'Máx FVGs', minval = 1, maxval = 8, group = g_tf1w)
color_up_1w = input.color(color.new(color.fuchsia, 85), 'Cor FVG Alta', group = g_tf1w)
color_dn_1w = input.color(color.new(color.fuchsia, 85), 'Cor FVG Baixa', group = g_tf1w)
// ========== FVG 1M ==========
var g_tf1mo = 'FVG 1M'
enable_1mo = input.bool(true, 'FVG 1M', group = g_tf1mo)
deleteFilled1mo = input.bool(true, 'Remover FVGs mitigados', group = g_tf1mo)
max_fvg_1mo = input.int(2, 'Máx FVGs', minval = 1, maxval = 5, group = g_tf1mo)
color_up_1mo = input.color(color.new(color.navy, 85), 'Cor FVG Alta', group = g_tf1mo)
color_dn_1mo = input.color(color.new(color.navy, 85), 'Cor FVG Baixa', group = g_tf1mo)
// ========== ESTRUTURA DE DADOS ==========
type GapData
float top
float bottom
int start_time
int bar_index_start
box gap_box
bool hasRealBodyGap
// ========== ARRAYS NXOG ==========
var array<GapData> nwog_up_arr = array.new<GapData>(0)
var array<GapData> nwog_dn_arr = array.new<GapData>(0)
var array<GapData> ndog_up_arr = array.new<GapData>(0)
var array<GapData> ndog_dn_arr = array.new<GapData>(0)
var array<GapData> nmog_up_arr = array.new<GapData>(0)
var array<GapData> nmog_dn_arr = array.new<GapData>(0)
// ========== ARRAYS TIMESTAMPS JÁ PLOTADOS (evita duplicação após remoção) ==========
var array<int> plotted_nwog_times = array.new<int>(0)
var array<int> plotted_ndog_times = array.new<int>(0)
var array<int> plotted_nmog_times = array.new<int>(0)
// ========== ARRAYS FVG ==========
var array<GapData> fvgs_up_15m = array.new<GapData>(0)
var array<GapData> fvgs_dn_15m = array.new<GapData>(0)
var array<GapData> fvgs_up_1h = array.new<GapData>(0)
var array<GapData> fvgs_dn_1h = array.new<GapData>(0)
var array<GapData> fvgs_up_4h = array.new<GapData>(0)
var array<GapData> fvgs_dn_4h = array.new<GapData>(0)
var array<GapData> fvgs_up_1d = array.new<GapData>(0)
var array<GapData> fvgs_dn_1d = array.new<GapData>(0)
var array<GapData> fvgs_up_1w = array.new<GapData>(0)
var array<GapData> fvgs_dn_1w = array.new<GapData>(0)
var array<GapData> fvgs_up_1mo = array.new<GapData>(0)
var array<GapData> fvgs_dn_1mo = array.new<GapData>(0)
// ========== FUNÇÃO NWOG ==========
detectNWOG() =>
isDayChange = ta.change(dayofmonth) != 0
prevDayOfWeek = dayofweek[1]
wasFriday = prevDayOfWeek == dayofweek.friday
isFirstBarAfterWeekend = isDayChange and wasFriday
var float persistedNwogTop = na
var float persistedNwogBottom = na
var int persistedNwogTime = na
var bool persistedNwogBullish = false
var bool persistedNwogHasRealBodyGap = false
var int lastFridayTime = na
fridayOpen = open[1]
fridayClose = close[1]
fridayTime = time[1]
if isFirstBarAfterWeekend and not na(fridayClose) and not na(fridayOpen)
mondayOpen = open
mondayClose = close
mondayHigh = high
mondayLow = low
gapSize = math.abs(mondayOpen - fridayClose)
minGap = close * nxog_min_gap / 100
// Vácuo: o candle de segunda (incluindo wicks) está completamente fora do corpo de sexta
bodyGapUp = mondayLow > math.max(fridayOpen, fridayClose)
bodyGapDn = mondayHigh < math.min(fridayOpen, fridayClose)
hasRealBodyGap = bodyGapUp or bodyGapDn
isNewFriday = na(lastFridayTime) or fridayTime > lastFridayTime
if gapSize >= minGap and isNewFriday
persistedNwogTop := math.max(fridayClose, mondayOpen)
persistedNwogBottom := math.min(fridayClose, mondayOpen)
persistedNwogTime := fridayTime
persistedNwogBullish := mondayOpen > fridayClose
persistedNwogHasRealBodyGap := hasRealBodyGap
lastFridayTime := fridayTime
hasNWOG = not na(persistedNwogTop) and not na(persistedNwogBottom)
[persistedNwogTop, persistedNwogBottom, persistedNwogTime, persistedNwogBullish, hasNWOG, persistedNwogHasRealBodyGap]
// ========== FUNÇÃO NDOG ==========
detectNDOG() =>
isWeekChange = ta.change(weekofyear) != 0
isDayChange = ta.change(dayofmonth) != 0
currentDayOfWeek = dayofweek
prevDayOfWeek = dayofweek[1]
isMonday = currentDayOfWeek == dayofweek.monday
isSunday = currentDayOfWeek == dayofweek.sunday
wasFriday = prevDayOfWeek == dayofweek.friday
wasSaturday = prevDayOfWeek == dayofweek.saturday
wasSunday = prevDayOfWeek == dayofweek.sunday
isWeekendGap = wasFriday or isWeekChange or (isSunday and not wasSaturday) or (isMonday and wasSunday)
var float persistedNdogTop = na
var float persistedNdogBottom = na
var int persistedNdogTime = na
var bool persistedNdogBullish = false
var bool persistedNdogHasRealBodyGap = false
var bool persistedHasNDOG = false
var bool persistedHasNWOG_masked = false
var int persistedNdogDay = na
prevDayOpen = open[1]
prevDayClose = close[1]
currentDay = dayofmonth
gapAlreadyDetectedToday = not na(persistedNdogDay) and persistedNdogDay == currentDay
if timeframe.isdaily and isWeekendGap and not na(prevDayClose) and not na(prevDayOpen) and not gapAlreadyDetectedToday
currDayOpen = open
currDayClose = close
currDayHigh = high
currDayLow = low
persistedNdogTop := math.max(prevDayClose, currDayOpen)
persistedNdogBottom := math.min(prevDayClose, currDayOpen)
persistedNdogTime := time[1]
persistedNdogBullish := currDayOpen > prevDayClose
// Vácuo: o candle atual (incluindo wicks) está completamente fora do corpo do dia anterior
bodyGapUp = currDayLow > math.max(prevDayOpen, prevDayClose)
bodyGapDn = currDayHigh < math.min(prevDayOpen, prevDayClose)
persistedNdogHasRealBodyGap := bodyGapUp or bodyGapDn
persistedHasNWOG_masked := true
persistedHasNDOG := false
persistedNdogDay := currentDay
else if not isWeekendGap and not na(prevDayClose) and not na(prevDayOpen) and not gapAlreadyDetectedToday
currDayOpen = open
currDayClose = close
currDayHigh = high
currDayLow = low
gapSize = math.abs(currDayOpen - prevDayClose)
minGap = close * nxog_min_gap / 100
if gapSize >= minGap
persistedNdogTop := math.max(prevDayClose, currDayOpen)
persistedNdogBottom := math.min(prevDayClose, currDayOpen)
persistedNdogTime := time
persistedNdogBullish := currDayOpen > prevDayClose
// Vácuo: o candle atual (incluindo wicks) está completamente fora do corpo do dia anterior
bodyGapUp = currDayLow > math.max(prevDayOpen, prevDayClose)
bodyGapDn = currDayHigh < math.min(prevDayOpen, prevDayClose)
persistedNdogHasRealBodyGap := bodyGapUp or bodyGapDn
persistedHasNDOG := true
persistedNdogDay := currentDay
[persistedNdogTop, persistedNdogBottom, persistedNdogTime, persistedNdogBullish, persistedHasNDOG, persistedHasNWOG_masked, persistedNdogHasRealBodyGap]
// ========== FUNÇÃO NMOG ==========
detectNMOG() =>
isMonthChange = ta.change(month) != 0
var float persistedNmogTop = na
var float persistedNmogBottom = na
var int persistedNmogTime = na
var bool persistedNmogBullish = false
var bool persistedNmogHasRealBodyGap = false
var int lastMonthTime = na
lastMonthOpen = open[1]
lastMonthClose = close[1]
lastMonthTimeVal = time[1]
if isMonthChange and not na(lastMonthClose) and not na(lastMonthOpen)
newMonthOpen = open
newMonthClose = close
newMonthHigh = high
newMonthLow = low
gapSize = math.abs(newMonthOpen - lastMonthClose)
minGap = close * nxog_min_gap / 100
// Vácuo: o candle do novo mês (incluindo wicks) está completamente fora do corpo do mês anterior
bodyGapUp = newMonthLow > math.max(lastMonthOpen, lastMonthClose)
bodyGapDn = newMonthHigh < math.min(lastMonthOpen, lastMonthClose)
hasRealBodyGap = bodyGapUp or bodyGapDn
isNewMonth = na(lastMonthTime) or lastMonthTimeVal > lastMonthTime
if gapSize >= minGap and isNewMonth
persistedNmogTop := math.max(lastMonthClose, newMonthOpen)
persistedNmogBottom := math.min(lastMonthClose, newMonthOpen)
persistedNmogTime := lastMonthTimeVal
persistedNmogBullish := newMonthOpen > lastMonthClose
persistedNmogHasRealBodyGap := hasRealBodyGap
lastMonthTime := lastMonthTimeVal
hasNMOG = not na(persistedNmogTop) and not na(persistedNmogBottom)
[persistedNmogTop, persistedNmogBottom, persistedNmogTime, persistedNmogBullish, hasNMOG, persistedNmogHasRealBodyGap]
// ========== FUNÇÃO FVG ==========
// Nota: O filtro de session break foi removido aqui.
// A função fvgOverlapsNxog() controla se bloqueia FVGs baseado em:
// - Sobreposição de preço
// - Sobreposição de tempo
// - hasRealBodyGap == true (vácuo real)
// FVGs em cenário de sobreposição (sem vácuo) são permitidos.
detectFVG() =>
// Verificar se há gap de tempo entre os candles (indica gap de sessão sem candle intermediário)
// Tempo esperado entre candle[2] e candle atual = 2 períodos do timeframe
tfSeconds = timeframe.in_seconds(timeframe.period)
expectedTimeGap = tfSeconds * 2 * 1000 // em milissegundos
actualTimeGap = time - time[2]
// Se o gap de tempo é maior que 3x o esperado, há gap de sessão (sem candle intermediário real)
hasSessionGap = actualTimeGap > (expectedTimeGap * 1.5)
// Também verificar se o candle do meio [1] realmente tocou na região do gap
// FVG UP: gap entre high[2] e low - verificar se candle[1] tocou essa região
// FVG DN: gap entre low[2] e high - verificar se candle[1] tocou essa região
fvg_up_raw = high[2] < low and barstate.isconfirmed and not hasSessionGap
fvg_dn_raw = low[2] > high and barstate.isconfirmed and not hasSessionGap
up_top = fvg_up_raw ? low : na
up_bottom = fvg_up_raw ? high[2] : na
up_time = fvg_up_raw ? time[1] : na
dn_top = fvg_dn_raw ? low[2] : na
dn_bottom = fvg_dn_raw ? high : na
dn_time = fvg_dn_raw ? time[1] : na
[up_top, up_bottom, up_time, dn_top, dn_bottom, dn_time, fvg_up_raw, fvg_dn_raw]
// ========== HELPERS ==========
getChartRank() =>
r = 99999
if timeframe.isminutes
r := timeframe.multiplier
else if timeframe.isdaily
r := 10000
else if timeframe.isweekly
r := 20000
else if timeframe.ismonthly
r := 30000
r
tfLabelToRank(tfLabel) =>
r = 0
if tfLabel == '15m'
r := 15
else if tfLabel == '1H'
r := 60
else if tfLabel == '4H'
r := 240
else if tfLabel == '1D'
r := 10000
else if tfLabel == '1W'
r := 20000
else
r := 30000
r
tfLabelToSeconds(tfLabel) =>
seconds = timeframe.in_seconds(timeframe.period)
if tfLabel == '15m'
seconds := timeframe.in_seconds('15')
else if tfLabel == '1H'
seconds := timeframe.in_seconds('60')
else if tfLabel == '4H'
seconds := timeframe.in_seconds('240')
else if tfLabel == '1D'
seconds := timeframe.in_seconds('1D')
else if tfLabel == '1W'
seconds := timeframe.in_seconds('1W')
else if tfLabel == '1MÊS'
seconds := timeframe.in_seconds('1M')
seconds
canShowGapInCurrentTF(gapType) =>
bool show = false
currentTfRank = getChartRank()
if gapType == "NDOG"
show := currentTfRank <= 10000 and not timeframe.isweekly and not timeframe.ismonthly
else if gapType == "NWOG"
show := currentTfRank <= 20000 and not timeframe.ismonthly
else if gapType == "NMOG"
show := true
show
getBarIndexFromTime(targetTime, _currentTimeframe) =>
idx = bar_index
if not na(targetTime) and targetTime > 0
timeDiffMs = time - targetTime
tfSec = timeframe.in_seconds(timeframe.period)
barsBack = tfSec > 0 ? int(math.round(timeDiffMs / (tfSec * 1000))) : 0
barsBack := math.min(math.max(barsBack, 0), 500)
idx := bar_index - barsBack
idx := idx < 0 ? 0 : idx
idx
gap_fill_pct(isUp, top, bottom, srcHigh, srcLow, srcClose, useClose) =>
gap = math.max(top - bottom, syminfo.mintick)
pLow = useClose ? srcClose : srcLow
pHigh = useClose ? srcClose : srcHigh
float pct = na
if isUp
if pLow >= top
pct := 0.0
else if pLow <= bottom
pct := 100.0
else
pct := (top - pLow) / gap * 100.0
else
if pHigh <= bottom
pct := 0.0
else if pHigh >= top
pct := 100.0
else
pct := (pHigh - bottom) / gap * 100.0
pct
gapExistsInAny(gapTime, top, bottom) =>
exists = false
if array.size(nwog_up_arr) > 0
for i = 0 to array.size(nwog_up_arr) - 1 by 1
existing = array.get(nwog_up_arr, i)
if existing.start_time == gapTime or (math.abs(existing.top - top) < syminfo.mintick and math.abs(existing.bottom - bottom) < syminfo.mintick)
exists := true
break
if not exists and array.size(nwog_dn_arr) > 0
for i = 0 to array.size(nwog_dn_arr) - 1 by 1
existing = array.get(nwog_dn_arr, i)
if existing.start_time == gapTime or (math.abs(existing.top - top) < syminfo.mintick and math.abs(existing.bottom - bottom) < syminfo.mintick)
exists := true
break
if not exists and array.size(ndog_up_arr) > 0
for i = 0 to array.size(ndog_up_arr) - 1 by 1
existing = array.get(ndog_up_arr, i)
if existing.start_time == gapTime or (math.abs(existing.top - top) < syminfo.mintick and math.abs(existing.bottom - bottom) < syminfo.mintick)
exists := true
break
if not exists and array.size(ndog_dn_arr) > 0
for i = 0 to array.size(ndog_dn_arr) - 1 by 1
existing = array.get(ndog_dn_arr, i)
if existing.start_time == gapTime or (math.abs(existing.top - top) < syminfo.mintick and math.abs(existing.bottom - bottom) < syminfo.mintick)
exists := true
break
if not exists and array.size(nmog_up_arr) > 0
for i = 0 to array.size(nmog_up_arr) - 1 by 1
existing = array.get(nmog_up_arr, i)
if existing.start_time == gapTime or (math.abs(existing.top - top) < syminfo.mintick and math.abs(existing.bottom - bottom) < syminfo.mintick)
exists := true
break
if not exists and array.size(nmog_dn_arr) > 0
for i = 0 to array.size(nmog_dn_arr) - 1 by 1
existing = array.get(nmog_dn_arr, i)
if existing.start_time == gapTime or (math.abs(existing.top - top) < syminfo.mintick and math.abs(existing.bottom - bottom) < syminfo.mintick)
exists := true
break
exists
fvgExists(fvgArray, fvgTime) =>
exists = false
if array.size(fvgArray) > 0
for i = 0 to array.size(fvgArray) - 1 by 1
existingFVG = array.get(fvgArray, i)
if existingFVG.start_time == fvgTime
exists := true
break
exists
// Verifica se FVG sobrepõe NXOG com vácuo real
// Retorna true APENAS quando há: sobreposição de preço + janela temporal + hasRealBodyGap
fvgOverlapsNxog(fvgTop, fvgBottom, fvgTime, tfLabel) =>
overlaps = false
tfSeconds = tfLabelToSeconds(tfLabel)
float timeToleranceMs = tfSeconds * 1000.0
// NWOG UP
if not overlaps and array.size(nwog_up_arr) > 0
for i = 0 to array.size(nwog_up_arr) - 1 by 1
gap = array.get(nwog_up_arr, i)
priceOverlap = math.min(fvgTop, gap.top) > math.max(fvgBottom, gap.bottom)
timeOverlap = not na(fvgTime) and not na(gap.start_time) and fvgTime >= gap.start_time and (fvgTime - gap.start_time) <= timeToleranceMs
hasGapVacuum = gap.hasRealBodyGap == true
if priceOverlap and timeOverlap and hasGapVacuum
overlaps := true
break
// NWOG DN
if not overlaps and array.size(nwog_dn_arr) > 0
for i = 0 to array.size(nwog_dn_arr) - 1 by 1
gap = array.get(nwog_dn_arr, i)
priceOverlap = math.min(fvgTop, gap.top) > math.max(fvgBottom, gap.bottom)
timeOverlap = not na(fvgTime) and not na(gap.start_time) and fvgTime >= gap.start_time and (fvgTime - gap.start_time) <= timeToleranceMs
hasGapVacuum = gap.hasRealBodyGap == true
if priceOverlap and timeOverlap and hasGapVacuum
overlaps := true
break
// NDOG UP
if not overlaps and array.size(ndog_up_arr) > 0
for i = 0 to array.size(ndog_up_arr) - 1 by 1
gap = array.get(ndog_up_arr, i)
priceOverlap = math.min(fvgTop, gap.top) > math.max(fvgBottom, gap.bottom)
timeOverlap = not na(fvgTime) and not na(gap.start_time) and fvgTime >= gap.start_time and (fvgTime - gap.start_time) <= timeToleranceMs
hasGapVacuum = gap.hasRealBodyGap == true
if priceOverlap and timeOverlap and hasGapVacuum
overlaps := true
break
// NDOG DN
if not overlaps and array.size(ndog_dn_arr) > 0
for i = 0 to array.size(ndog_dn_arr) - 1 by 1
gap = array.get(ndog_dn_arr, i)
priceOverlap = math.min(fvgTop, gap.top) > math.max(fvgBottom, gap.bottom)
timeOverlap = not na(fvgTime) and not na(gap.start_time) and fvgTime >= gap.start_time and (fvgTime - gap.start_time) <= timeToleranceMs
hasGapVacuum = gap.hasRealBodyGap == true
if priceOverlap and timeOverlap and hasGapVacuum
overlaps := true
break
// NMOG UP
if not overlaps and array.size(nmog_up_arr) > 0
for i = 0 to array.size(nmog_up_arr) - 1 by 1
gap = array.get(nmog_up_arr, i)
priceOverlap = math.min(fvgTop, gap.top) > math.max(fvgBottom, gap.bottom)
timeOverlap = not na(fvgTime) and not na(gap.start_time) and fvgTime >= gap.start_time and (fvgTime - gap.start_time) <= timeToleranceMs
hasGapVacuum = gap.hasRealBodyGap == true
if priceOverlap and timeOverlap and hasGapVacuum
overlaps := true
break
// NMOG DN
if not overlaps and array.size(nmog_dn_arr) > 0
for i = 0 to array.size(nmog_dn_arr) - 1 by 1
gap = array.get(nmog_dn_arr, i)
priceOverlap = math.min(fvgTop, gap.top) > math.max(fvgBottom, gap.bottom)
timeOverlap = not na(fvgTime) and not na(gap.start_time) and fvgTime >= gap.start_time and (fvgTime - gap.start_time) <= timeToleranceMs
hasGapVacuum = gap.hasRealBodyGap == true
if priceOverlap and timeOverlap and hasGapVacuum
overlaps := true
break
overlaps
// Verifica se FVG sobrepõe o NXOG atual (ainda não adicionado aos arrays)
// Recebe os dados final* diretamente para verificar antes de serem adicionados aos arrays
fvgOverlapsCurrentNxog(fvgTop, fvgBottom, fvgTime, tfLabel,
nwogTop, nwogBottom, nwogTime, hasNwog, nwogHasRealBodyGap,
ndogTop, ndogBottom, ndogTime, hasNdog, ndogHasRealBodyGap,
nmogTop, nmogBottom, nmogTime, hasNmog, nmogHasRealBodyGap) =>
overlaps = false
tfSeconds = tfLabelToSeconds(tfLabel)
float timeToleranceMs = tfSeconds * 1000.0
// Verificar contra NWOG atual
if hasNwog and not na(nwogTop) and not na(nwogBottom) and nwogHasRealBodyGap
priceOverlap = math.min(fvgTop, nwogTop) > math.max(fvgBottom, nwogBottom)
timeOverlap = not na(fvgTime) and not na(nwogTime) and fvgTime >= nwogTime and (fvgTime - nwogTime) <= timeToleranceMs
if priceOverlap and timeOverlap
overlaps := true
// Verificar contra NDOG atual
if not overlaps and hasNdog and not na(ndogTop) and not na(ndogBottom) and ndogHasRealBodyGap
priceOverlap = math.min(fvgTop, ndogTop) > math.max(fvgBottom, ndogBottom)
timeOverlap = not na(fvgTime) and not na(ndogTime) and fvgTime >= ndogTime and (fvgTime - ndogTime) <= timeToleranceMs
if priceOverlap and timeOverlap
overlaps := true
// Verificar contra NMOG atual
if not overlaps and hasNmog and not na(nmogTop) and not na(nmogBottom) and nmogHasRealBodyGap
priceOverlap = math.min(fvgTop, nmogTop) > math.max(fvgBottom, nmogBottom)
timeOverlap = not na(fvgTime) and not na(nmogTime) and fvgTime >= nmogTime and (fvgTime - nmogTime) <= timeToleranceMs
if priceOverlap and timeOverlap
overlaps := true
overlaps
// ========== REQUEST.SECURITY - NXOG ==========
[nwog_top_4h, nwog_bottom_4h, nwog_time_4h, nwog_bullish_4h, has_nwog_4h, nwog_has_real_body_gap_4h] = request.security(syminfo.tickerid, '240', detectNWOG(), lookahead = barmerge.lookahead_off)
[ndog_top_4h, ndog_bottom_4h, ndog_time_4h, ndog_bullish_4h, has_ndog_4h, has_nwog_masked_4h, ndog_has_real_body_gap_4h] = request.security(syminfo.tickerid, '240', detectNDOG(), lookahead = barmerge.lookahead_off)
[nmog_top_4h, nmog_bottom_4h, nmog_time_4h, nmog_bullish_4h, has_nmog_4h, nmog_has_real_body_gap_4h] = request.security(syminfo.tickerid, '240', detectNMOG(), lookahead = barmerge.lookahead_off)
[nmog_top_1h, nmog_bottom_1h, nmog_time_1h, nmog_bullish_1h, has_nmog_1h, nmog_has_real_body_gap_1h] = request.security(syminfo.tickerid, '60', detectNMOG(), lookahead = barmerge.lookahead_off)
// ========== REQUEST.SECURITY - FVG ==========
[up_top_15m, up_bottom_15m, up_time_15m, dn_top_15m, dn_bottom_15m, dn_time_15m, signal_up_15m, signal_dn_15m] = request.security(syminfo.tickerid, '15', detectFVG(), lookahead = barmerge.lookahead_off)
[up_top_1h, up_bottom_1h, up_time_1h, dn_top_1h, dn_bottom_1h, dn_time_1h, signal_up_1h, signal_dn_1h] = request.security(syminfo.tickerid, '60', detectFVG(), lookahead = barmerge.lookahead_off)
[up_top_4h, up_bottom_4h, up_time_4h, dn_top_4h, dn_bottom_4h, dn_time_4h, signal_up_4h, signal_dn_4h] = request.security(syminfo.tickerid, '240', detectFVG(), lookahead = barmerge.lookahead_off)
[up_top_1d, up_bottom_1d, up_time_1d, dn_top_1d, dn_bottom_1d, dn_time_1d, signal_up_1d, signal_dn_1d] = request.security(syminfo.tickerid, '1D', detectFVG(), lookahead = barmerge.lookahead_off)
[up_top_1w, up_bottom_1w, up_time_1w, dn_top_1w, dn_bottom_1w, dn_time_1w, signal_up_1w, signal_dn_1w] = request.security(syminfo.tickerid, '1W', detectFVG(), lookahead = barmerge.lookahead_off)
[up_top_1mo, up_bottom_1mo, up_time_1mo, dn_top_1mo, dn_bottom_1mo, dn_time_1mo, signal_up_1mo, signal_dn_1mo] = request.security(syminfo.tickerid, '1M', detectFVG(), lookahead = barmerge.lookahead_off)
// ========== PROCESSAMENTO NXOG ==========
is4HorHigher = (timeframe.isminutes and timeframe.multiplier >= 240) or timeframe.isdaily or timeframe.isweekly or timeframe.ismonthly
isHigherTF = timeframe.isdaily or timeframe.isweekly or timeframe.ismonthly
var float finalNwogTop = na
var float finalNwogBottom = na
var int finalNwogTime = na
var bool finalNwogBullish = false
var bool finalHasNWOG = false
var bool finalNwogHasRealBodyGap = false
var float finalNdogTop = na
var float finalNdogBottom = na
var int finalNdogTime = na
var bool finalNdogBullish = false
var bool finalHasNDOG = false
var bool finalNdogHasRealBodyGap = false
var float finalNmogTop = na
var float finalNmogBottom = na
var int finalNmogTime = na
var bool finalNmogBullish = false
var bool finalHasNMOG = false
var bool finalNmogHasRealBodyGap = false
var bool hasNWOG_masked = false
if isHigherTF
hasNWOG_masked := has_nwog_masked_4h
finalHasNWOG := has_nwog_4h or has_nwog_masked_4h
if has_nwog_masked_4h
finalNwogTop := ndog_top_4h
finalNwogBottom := ndog_bottom_4h
finalNwogTime := ndog_time_4h
finalNwogBullish := ndog_bullish_4h
finalNwogHasRealBodyGap := ndog_has_real_body_gap_4h
else if has_nwog_4h
finalNwogTop := nwog_top_4h
finalNwogBottom := nwog_bottom_4h
finalNwogTime := nwog_time_4h
finalNwogBullish := nwog_bullish_4h
finalNwogHasRealBodyGap := nwog_has_real_body_gap_4h
else
[nwogTopLocal, nwogBottomLocal, nwogTimeLocal, nwogBullishLocal, hasNWOGLocal, nwogHasRealBodyGapLocal] = detectNWOG()
[ndogTopLocal, ndogBottomLocal, ndogTimeLocal, ndogBullishLocal, hasNDOGLocal, hasNWOG_maskedLocal, ndogHasRealBodyGapLocal] = detectNDOG()
hasNWOG_masked := hasNWOG_maskedLocal
finalHasNWOG := hasNWOGLocal or hasNWOG_maskedLocal
finalNwogTop := hasNWOG_maskedLocal ? ndogTopLocal : nwogTopLocal
finalNwogBottom := hasNWOG_maskedLocal ? ndogBottomLocal : nwogBottomLocal
finalNwogTime := hasNWOG_maskedLocal ? ndogTimeLocal : nwogTimeLocal
finalNwogBullish := hasNWOG_maskedLocal ? ndogBullishLocal : nwogBullishLocal
finalNwogHasRealBodyGap := hasNWOG_maskedLocal ? ndogHasRealBodyGapLocal : nwogHasRealBodyGapLocal
// NDOG: Sempre usa 4H para detecção consistente
finalHasNDOG := has_ndog_4h and not has_nwog_masked_4h
if finalHasNDOG
finalNdogTop := ndog_top_4h
finalNdogBottom := ndog_bottom_4h
finalNdogTime := ndog_time_4h
finalNdogBullish := ndog_bullish_4h
finalNdogHasRealBodyGap := ndog_has_real_body_gap_4h
[nmog_top, nmog_bottom, nmog_time, nmog_bullish, has_nmog, nmog_has_real_body_gap] = detectNMOG()
// ========== PROCESSAR NMOG ==========
if enable_nmog and canShowGapInCurrentTF("NMOG")
bool use1HData = is4HorHigher or (timeframe.isminutes and timeframe.multiplier == 60)
finalNmogTop := use1HData ? nmog_top_1h : nmog_top
finalNmogBottom := use1HData ? nmog_bottom_1h : nmog_bottom
finalNmogTime := use1HData ? nmog_time_1h : nmog_time
finalNmogBullish := use1HData ? nmog_bullish_1h : nmog_bullish
finalHasNMOG := use1HData ? has_nmog_1h : has_nmog
finalNmogHasRealBodyGap := use1HData ? nmog_has_real_body_gap_1h : nmog_has_real_body_gap
if finalHasNMOG and not na(finalNmogTop) and not na(finalNmogBottom)
gapArr = finalNmogBullish ? nmog_up_arr : nmog_dn_arr
gapColor = finalNmogBullish ? color_nmog_up : color_nmog_dn
if not gapExistsInAny(finalNmogTime, finalNmogTop, finalNmogBottom) and not array.includes(plotted_nmog_times, finalNmogTime)
startBarIndex = bar_index - 1
isYearChange = month(finalNmogTime) == 12
if timeframe.isdaily
if isYearChange
startBarIndex := getBarIndexFromTime(finalNmogTime, timeframe.period)
else
startBarIndex := getBarIndexFromTime(finalNmogTime, timeframe.period) + 1
else if timeframe.ismonthly
startBarIndex := getBarIndexFromTime(finalNmogTime, timeframe.period) - 1
else if timeframe.isweekly and isYearChange
startBarIndex := bar_index
newBox = box.new(startBarIndex, finalNmogTop, bar_index + 20, finalNmogBottom,
bgcolor = color.new(gapColor, boxTransparency),
border_color = color.new(gapColor, 50),
border_width = 1,
border_style = line.style_dashed,
text = showLabels ? 'NMOG ' + (finalNmogBullish ? '↑' : '↓') : na,
text_color = color.new(gapColor, 30),
text_size = size.small,
text_halign = text.align_center,
text_valign = text.align_center)
newGap = GapData.new(top = finalNmogTop, bottom = finalNmogBottom, start_time = finalNmogTime, bar_index_start = startBarIndex, gap_box = newBox, hasRealBodyGap = finalNmogHasRealBodyGap)
array.push(gapArr, newGap)
array.push(plotted_nmog_times, finalNmogTime)
// ========== PROCESSAR NWOG ==========
if enable_nwog and finalHasNWOG and not na(finalNwogTop) and not na(finalNwogBottom) and canShowGapInCurrentTF("NWOG")
gapArr = finalNwogBullish ? nwog_up_arr : nwog_dn_arr
gapColor = finalNwogBullish ? color_nwog_up : color_nwog_dn
if not gapExistsInAny(finalNwogTime, finalNwogTop, finalNwogBottom) and not array.includes(plotted_nwog_times, finalNwogTime)
startBarIndex = bar_index - 1
if timeframe.isweekly
startBarIndex := getBarIndexFromTime(finalNwogTime, timeframe.period) - 1
else if timeframe.isdaily
startBarIndex := getBarIndexFromTime(finalNwogTime, timeframe.period) + 1
newBox = box.new(startBarIndex, finalNwogTop, bar_index + 20, finalNwogBottom,
bgcolor = color.new(gapColor, boxTransparency),
border_color = color.new(gapColor, 50),
border_width = 1,
border_style = line.style_dashed,
text = showLabels ? 'NWOG ' + (finalNwogBullish ? '↑' : '↓') : na,
text_color = color.new(gapColor, 30),
text_size = size.small,
text_halign = text.align_center,
text_valign = text.align_center)
newGap = GapData.new(top = finalNwogTop, bottom = finalNwogBottom, start_time = finalNwogTime, bar_index_start = startBarIndex, gap_box = newBox, hasRealBodyGap = finalNwogHasRealBodyGap)
array.push(gapArr, newGap)
array.push(plotted_nwog_times, finalNwogTime)
// ========== PROCESSAR NDOG ==========
if enable_ndog and finalHasNDOG and not na(finalNdogTop) and not na(finalNdogBottom) and canShowGapInCurrentTF("NDOG")
gapArr = finalNdogBullish ? ndog_up_arr : ndog_dn_arr
gapColor = finalNdogBullish ? color_ndog_up : color_ndog_dn
if not gapExistsInAny(finalNdogTime, finalNdogTop, finalNdogBottom) and not array.includes(plotted_ndog_times, finalNdogTime)
// Sempre usar timestamp para calcular posição correta
startBarIndex = getBarIndexFromTime(finalNdogTime, timeframe.period) - 1
newBox = box.new(startBarIndex, finalNdogTop, bar_index + 20, finalNdogBottom,
bgcolor = color.new(gapColor, boxTransparency),
border_color = color.new(gapColor, 50),
border_width = 1,
border_style = line.style_dashed,
text = showLabels ? 'NDOG ' + (finalNdogBullish ? '↑' : '↓') : na,
text_color = color.new(gapColor, 30),
text_size = size.small,
text_halign = text.align_center,
text_valign = text.align_center)
newGap = GapData.new(top = finalNdogTop, bottom = finalNdogBottom, start_time = finalNdogTime, bar_index_start = startBarIndex, gap_box = newBox, hasRealBodyGap = finalNdogHasRealBodyGap)
array.push(gapArr, newGap)
array.push(plotted_ndog_times, finalNdogTime)
// ========== PROCESSAR FVG ==========
processFVGTimeframe(signalUp, upTop, upBottom, upTime, signalDn, dnTop, dnBottom, dnTime, fvgArrayUp, fvgArrayDn, maxFvgs, colorUp, colorDn, tfLabel, enabled, deleteFilled) =>
targetRank = tfLabelToRank(tfLabel)
chartRank = getChartRank()
showThisTF = targetRank >= chartRank
if enabled and barstate.isconfirmed and showThisTF
if signalUp and not na(upTop) and not na(upBottom) and not na(upTime)
overlapsArrays = fvgOverlapsNxog(upTop, upBottom, upTime, tfLabel)
overlapsCurrent = fvgOverlapsCurrentNxog(upTop, upBottom, upTime, tfLabel,
finalNwogTop, finalNwogBottom, finalNwogTime, finalHasNWOG, finalNwogHasRealBodyGap,
finalNdogTop, finalNdogBottom, finalNdogTime, finalHasNDOG, finalNdogHasRealBodyGap,
finalNmogTop, finalNmogBottom, finalNmogTime, finalHasNMOG, finalNmogHasRealBodyGap)
if not fvgExists(fvgArrayUp, upTime) and not overlapsArrays and not overlapsCurrent
startBarIndex = getBarIndexFromTime(upTime, tfLabel) - 1
newBox = box.new(startBarIndex, upTop, bar_index + 20, upBottom, bgcolor = color.new(colorUp, boxTransparency), border_color = color.new(colorUp, 50), border_width = 1, text = showLabels ? tfLabel + ' ↑' : na, text_color = color.new(colorUp, 30), text_size = size.small)
newFVG = GapData.new(top = upTop, bottom = upBottom, start_time = upTime, bar_index_start = startBarIndex, gap_box = newBox, hasRealBodyGap = false)
array.push(fvgArrayUp, newFVG)
if signalDn and not na(dnTop) and not na(dnBottom) and not na(dnTime)
overlapsArrays = fvgOverlapsNxog(dnTop, dnBottom, dnTime, tfLabel)
overlapsCurrent = fvgOverlapsCurrentNxog(dnTop, dnBottom, dnTime, tfLabel,
finalNwogTop, finalNwogBottom, finalNwogTime, finalHasNWOG, finalNwogHasRealBodyGap,
finalNdogTop, finalNdogBottom, finalNdogTime, finalHasNDOG, finalNdogHasRealBodyGap,
finalNmogTop, finalNmogBottom, finalNmogTime, finalHasNMOG, finalNmogHasRealBodyGap)
if not fvgExists(fvgArrayDn, dnTime) and not overlapsArrays and not overlapsCurrent
startBarIndex = getBarIndexFromTime(dnTime, tfLabel) - 1
newBox = box.new(startBarIndex, dnTop, bar_index + 20, dnBottom, bgcolor = color.new(colorDn, boxTransparency), border_color = color.new(colorDn, 50), border_width = 1, text = showLabels ? tfLabel + ' ↓' : na, text_color = color.new(colorDn, 30), text_size = size.small)
newFVG = GapData.new(top = dnTop, bottom = dnBottom, start_time = dnTime, bar_index_start = startBarIndex, gap_box = newBox, hasRealBodyGap = false)
array.push(fvgArrayDn, newFVG)
if barstate.isconfirmed
processFVGTimeframe(signal_up_15m, up_top_15m, up_bottom_15m, up_time_15m, signal_dn_15m, dn_top_15m, dn_bottom_15m, dn_time_15m, fvgs_up_15m, fvgs_dn_15m, max_fvg_15m, color_up_15m, color_dn_15m, '15m', enable_15m, deleteFilled15m or deleteAllMitigatedFVG)
processFVGTimeframe(signal_up_1h, up_top_1h, up_bottom_1h, up_time_1h, signal_dn_1h, dn_top_1h, dn_bottom_1h, dn_time_1h, fvgs_up_1h, fvgs_dn_1h, max_fvg_1h, color_up_1h, color_dn_1h, '1H', enable_1h, deleteFilled1h or deleteAllMitigatedFVG)
processFVGTimeframe(signal_up_4h, up_top_4h, up_bottom_4h, up_time_4h, signal_dn_4h, dn_top_4h, dn_bottom_4h, dn_time_4h, fvgs_up_4h, fvgs_dn_4h, max_fvg_4h, color_up_4h, color_dn_4h, '4H', enable_4h, deleteFilled4h or deleteAllMitigatedFVG)
processFVGTimeframe(signal_up_1d, up_top_1d, up_bottom_1d, up_time_1d, signal_dn_1d, dn_top_1d, dn_bottom_1d, dn_time_1d, fvgs_up_1d, fvgs_dn_1d, max_fvg_1d, color_up_1d, color_dn_1d, '1D', enable_1d, deleteFilled1d or deleteAllMitigatedFVG)
processFVGTimeframe(signal_up_1w, up_top_1w, up_bottom_1w, up_time_1w, signal_dn_1w, dn_top_1w, dn_bottom_1w, dn_time_1w, fvgs_up_1w, fvgs_dn_1w, max_fvg_1w, color_up_1w, color_dn_1w, '1W', enable_1w, deleteFilled1w or deleteAllMitigatedFVG)
processFVGTimeframe(signal_up_1mo, up_top_1mo, up_bottom_1mo, up_time_1mo, signal_dn_1mo, dn_top_1mo, dn_bottom_1mo, dn_time_1mo, fvgs_up_1mo, fvgs_dn_1mo, max_fvg_1mo, color_up_1mo, color_dn_1mo, '1MÊS', enable_1mo, deleteFilled1mo or deleteAllMitigatedFVG)
// ========== ESTENDER E GERENCIAR GAPS ==========
extendGap(gapArray, maxSize, deleteIfMitigated, isUp) =>
if array.size(gapArray) > 0
for i = array.size(gapArray) - 1 to 0 by 1
gapData = array.get(gapArray, i)
currentBox = gapData.gap_box
box.set_right(currentBox, bar_index + 5)
isMitigated = false
if deleteIfMitigated
pct = gap_fill_pct(isUp, gapData.top, gapData.bottom, high, low, close, mitig_use_close)
if pct >= mitig_pct_threshold
isMitigated := true
if isMitigated
box.delete(currentBox)
array.remove(gapArray, i)
while array.size(gapArray) > maxSize
oldGap = array.shift(gapArray)
box.delete(oldGap.gap_box)
// NXOG
extendGap(nwog_up_arr, max_nwog, deleteFilledNWOG or deleteAllMitigatedNXOG, true)
extendGap(nwog_dn_arr, max_nwog, deleteFilledNWOG or deleteAllMitigatedNXOG, false)
extendGap(ndog_up_arr, max_ndog, deleteFilledNDOG or deleteAllMitigatedNXOG, true)
extendGap(ndog_dn_arr, max_ndog, deleteFilledNDOG or deleteAllMitigatedNXOG, false)
extendGap(nmog_up_arr, max_nmog, deleteFilledNMOG or deleteAllMitigatedNXOG, true)
extendGap(nmog_dn_arr, max_nmog, deleteFilledNMOG or deleteAllMitigatedNXOG, false)
// FVG
extendGap(fvgs_up_15m, max_fvg_15m, deleteFilled15m or deleteAllMitigatedFVG, true)
extendGap(fvgs_dn_15m, max_fvg_15m, deleteFilled15m or deleteAllMitigatedFVG, false)
extendGap(fvgs_up_1h, max_fvg_1h, deleteFilled1h or deleteAllMitigatedFVG, true)
extendGap(fvgs_dn_1h, max_fvg_1h, deleteFilled1h or deleteAllMitigatedFVG, false)
extendGap(fvgs_up_4h, max_fvg_4h, deleteFilled4h or deleteAllMitigatedFVG, true)
extendGap(fvgs_dn_4h, max_fvg_4h, deleteFilled4h or deleteAllMitigatedFVG, false)
extendGap(fvgs_up_1d, max_fvg_1d, deleteFilled1d or deleteAllMitigatedFVG, true)
extendGap(fvgs_dn_1d, max_fvg_1d, deleteFilled1d or deleteAllMitigatedFVG, false)
extendGap(fvgs_up_1w, max_fvg_1w, deleteFilled1w or deleteAllMitigatedFVG, true)
extendGap(fvgs_dn_1w, max_fvg_1w, deleteFilled1w or deleteAllMitigatedFVG, false)
extendGap(fvgs_up_1mo, max_fvg_1mo, deleteFilled1mo or deleteAllMitigatedFVG, true)
extendGap(fvgs_dn_1mo, max_fvg_1mo, deleteFilled1mo or deleteAllMitigatedFVG, false)
// ========== ALERTAS ==========
alertcondition(finalHasNWOG, 'NWOG', 'New Week Opening Gap detectado')
alertcondition(finalHasNDOG, 'NDOG', 'New Day Opening Gap detectado')
alertcondition(has_nmog or has_nmog_1h, 'NMOG', 'New Month Opening Gap detectado')
alertcondition(signal_up_15m or signal_dn_15m, 'FVG 15m', 'Novo FVG detectado no 15m')
alertcondition(signal_up_1h or signal_dn_1h, 'FVG 1H', 'Novo FVG detectado no 1H')
alertcondition(signal_up_4h or signal_dn_4h, 'FVG 4H', 'Novo FVG detectado no 4H')
alertcondition(signal_up_1d or signal_dn_1d, 'FVG 1D', 'Novo FVG detectado no 1D')
alertcondition(signal_up_1w or signal_dn_1w, 'FVG 1W', 'Novo FVG detectado no 1W')
alertcondition(signal_up_1mo or signal_dn_1mo, 'FVG 1MÊS', 'Novo FVG detectado no 1MÊS')
// ========================================
// SESSÕES / KILLZONES
// ========================================
timeZone = 'America/New_York'
var g_KZ_General = 'Sessões — Geral'
show_kz = input.bool(true, 'Mostrar Caixas', inline = 'VIS', group = g_KZ_General)
show_kz_text = input.bool(true, 'Mostrar Texto', inline = 'VIS', group = g_KZ_General)
max_sessions_per_type = input.int(2, 'Histórico (caixas passadas)', minval = 0, maxval = 50, group = g_KZ_General)
boxTransparencySessions = input.int(85, 'Transparência Box', minval = 0, maxval = 100, group = g_KZ_General)
textTransparencySessions = input.int(20, 'Transparência Texto', minval = 0, maxval = 100, group = g_KZ_General)
var g_KZ_Asia = 'Sessões — Asia'
use_asia = input.bool(true, '', inline = 'ASIA', group = g_KZ_Asia)
as_txt = input.string('Asia', '', inline = 'ASIA', group = g_KZ_Asia)
asia = input.session('2000-0000', '', inline = 'ASIA', group = g_KZ_Asia)
as_color = input.color(color.blue, '', inline = 'ASIA', group = g_KZ_Asia)
var g_KZ_London = 'Sessões — London'
use_london = input.bool(true, '', inline = 'LONDON', group = g_KZ_London)
lo_txt = input.string('London', '', inline = 'LONDON', group = g_KZ_London)
london = input.session('0200-0500', '', inline = 'LONDON', group = g_KZ_London)
lo_color = input.color(color.red, '', inline = 'LONDON', group = g_KZ_London)
var g_KZ_NY = 'Sessões — New York'
use_nyam = input.bool(true, '', inline = 'NYAM', group = g_KZ_NY)
na_txt = input.string('NY AM', '', inline = 'NYAM', group = g_KZ_NY)
nyam = input.session('0930-1100', '', inline = 'NYAM', group = g_KZ_NY)
na_color = input.color(#089981, '', inline = 'NYAM', group = g_KZ_NY)
use_nylu = input.bool(true, '', inline = 'NYLU', group = g_KZ_NY)
nl_txt = input.string('NY Lunch', '', inline = 'NYLU', group = g_KZ_NY)
nylu = input.session('1200-1300', '', inline = 'NYLU', group = g_KZ_NY)
nl_color = input.color(color.yellow, '', inline = 'NYLU', group = g_KZ_NY)
use_nypm = input.bool(true, '', inline = 'NYPM', group = g_KZ_NY)
np_txt = input.string('NY PM', '', inline = 'NYPM', group = g_KZ_NY)
nypm = input.session('1330-1600', '', inline = 'NYPM', group = g_KZ_NY)
np_color = input.color(color.purple, '', inline = 'NYPM', group = g_KZ_NY)
var array<box> asia_boxes = array.new<box>(0)
var array<line> asia_hi = array.new<line>(0)
var array<line> asia_lo = array.new<line>(0)
var array<box> lon_boxes = array.new<box>(0)
var array<line> lon_hi = array.new<line>(0)
var array<line> lon_lo = array.new<line>(0)
var array<box> nyam_boxes = array.new<box>(0)
var array<line> nyam_hi = array.new<line>(0)
var array<line> nyam_lo = array.new<line>(0)
var array<box> nylu_boxes = array.new<box>(0)
var array<line> nylu_hi = array.new<line>(0)
var array<line> nylu_lo = array.new<line>(0)
var array<box> nypm_boxes = array.new<box>(0)
var array<line> nypm_hi = array.new<line>(0)
var array<line> nypm_lo = array.new<line>(0)
get_box_color(color c) =>
color.new(c, boxTransparencySessions)
get_text_color(color c) =>
color.new(c, textTransparencySessions)
prune(boxes, his, los, limit) =>
while array.size(boxes) > limit
b = array.shift(boxes)
if not na(b)
box.delete(b)
keep = array.size(boxes)
while array.size(his) > keep
lh = array.shift(his)
if not na(lh)
line.delete(lh)
while array.size(los) > keep
ll = array.shift(los)
if not na(ll)
line.delete(ll)
processSession(sessionRange, sessionColor, sessionText, enabled) =>
box retBox = na
line retHi = na
line retLo = na
if enabled
inSession = not na(time(timeframe.period, sessionRange, timeZone))
isFirstBar = inSession and not inSession[1]
isLastBar = not inSession and inSession[1]
var float sessionHigh = na
var float sessionLow = na
var int sessionStartTime = na
var int sessionHighTime = na
var int sessionLowTime = na
var box sessionBox = na
if isFirstBar
sessionStartTime := time
sessionHigh := high
sessionLow := low
sessionHighTime := time
sessionLowTime := time
_boxColor = get_box_color(sessionColor)
_textColor = get_text_color(sessionColor)
sessionBox := box.new(left = sessionStartTime, top = sessionHigh, right = sessionStartTime, bottom = sessionLow,
xloc = xloc.bar_time,
bgcolor = show_kz ? _boxColor : na, border_color = show_kz ? _boxColor : na,
border_width = 0,
text = show_kz and show_kz_text ? sessionText : na,
text_color = _textColor, text_size = size.large)
else if inSession
if high > sessionHigh
sessionHigh := high
sessionHighTime := time
if low < sessionLow
sessionLow := low
sessionLowTime := time
if not na(sessionBox)
box.set_top(sessionBox, sessionHigh)
box.set_bottom(sessionBox, sessionLow)
box.set_right(sessionBox, time)
if isLastBar and show_kz
if sessionHighTime != time[1]
retHi := line.new(sessionHighTime, sessionHigh, time[1], sessionHigh,
xloc = xloc.bar_time, color = color.new(sessionColor, 0), width = 2, style = line.style_solid)
if sessionLowTime != time[1]
retLo := line.new(sessionLowTime, sessionLow, time[1], sessionLow,
xloc = xloc.bar_time, color = color.new(sessionColor, 0), width = 2, style = line.style_solid)
retBox := sessionBox
[retBox, retHi, retLo]
showSessions = timeframe.in_seconds() <= 3600
[asia_box, asia_ln_hi, asia_ln_lo] = processSession(asia, as_color, as_txt, use_asia and showSessions)
if not na(asia_box)
array.push(asia_boxes, asia_box)
array.push(asia_hi, asia_ln_hi)
array.push(asia_lo, asia_ln_lo)
prune(asia_boxes, asia_hi, asia_lo, max_sessions_per_type)
[lon_box, lon_ln_hi, lon_ln_lo] = processSession(london, lo_color, lo_txt, use_london and showSessions)
if not na(lon_box)
array.push(lon_boxes, lon_box)
array.push(lon_hi, lon_ln_hi)
array.push(lon_lo, lon_ln_lo)
prune(lon_boxes, lon_hi, lon_lo, max_sessions_per_type)
[nyam_box, nyam_ln_hi, nyam_ln_lo] = processSession(nyam, na_color, na_txt, use_nyam and showSessions)
if not na(nyam_box)
array.push(nyam_boxes, nyam_box)
array.push(nyam_hi, nyam_ln_hi)
array.push(nyam_lo, nyam_ln_lo)
prune(nyam_boxes, nyam_hi, nyam_lo, max_sessions_per_type)
[nylu_box, nylu_ln_hi, nylu_ln_lo] = processSession(nylu, nl_color, nl_txt, use_nylu and showSessions)
if not na(nylu_box)
array.push(nylu_boxes, nylu_box)
array.push(nylu_hi, nylu_ln_hi)
array.push(nylu_lo, nylu_ln_lo)
prune(nylu_boxes, nylu_hi, nylu_lo, max_sessions_per_type)
[nypm_box, nypm_ln_hi, nypm_ln_lo] = processSession(nypm, np_color, np_txt, use_nypm and showSessions)
if not na(nypm_box)
array.push(nypm_boxes, nypm_box)
array.push(nypm_hi, nypm_ln_hi)
array.push(nypm_lo, nypm_ln_lo)
prune(nypm_boxes, nypm_hi, nypm_lo, max_sessions_per_type)
// ========================================
// TF COUNTDOWN
// ========================================
var tfd_grpLayout = 'TF Countdown — Layout'
tfd_posChoice = input.string('Top Right', 'Posição', options = ['Top Left', 'Top Right', 'Bottom Left', 'Bottom Right'], group = tfd_grpLayout)
tfd_showFooter = true
tfd_footerText = 'Tavares'
tfd_panelBg = color.black
tfd_upColor = color.rgb(46, 204, 113)
tfd_dnColor = color.rgb(239, 83, 80)
tfd_accentCol = color.white
tfd_useTrendCols = true
tfd_labelsBlack = true
var tfd_const_hdr_size = size.small
var tfd_const_row_size = size.normal
var tfd_const_ftr_size = size.normal
tfd_posTbl = tfd_posChoice == 'Top Left' ? position.top_left :
tfd_posChoice == 'Top Right' ? position.top_right :
tfd_posChoice == 'Bottom Left' ? position.bottom_left : position.bottom_right
tfd_pad_label(txt) => ' ' + txt + ' '
tfd_pad_timer(txt) => ' ' + txt + ' '
tfd_zz(n) =>
n < 10 ? '0' + str.tostring(n) : str.tostring(n)
tfd_fmt_hhmmss(hh, mm, ss) =>
tfd_zz(hh) + ':' + tfd_zz(mm) + ':' + tfd_zz(ss)
tfd_fmt_mmss(mm, ss) =>
tfd_zz(mm) + ':' + tfd_zz(ss)
tfd_fmt_by_tf(tf, ms) =>
s = math.max(0, int(ms / 1000))
hh = int(math.floor(s / 3600))
mm = int(math.floor(s % 3600 / 60))
ss = s % 60
forceHH = tf == '240' or tf == 'D'
(forceHH or hh > 0) ? tfd_fmt_hhmmss(hh, mm, ss) : tfd_fmt_mmss(mm, ss)
tfd_pretty_tf(tf) =>
tf == '3' ? '3M' :
tf == '5' ? '5M' :
tf == '15' ? '15M' :
tf == '60' ? '1H' :
tf == '240' ? '4H' :
tf == 'D' ? '1D' : tf
tfd_tf_dir_closed(tf) =>
request.security(syminfo.tickerid, tf, close >= open, barmerge.gaps_off, barmerge.lookahead_off)
tfd_up_3 = tfd_tf_dir_closed('3')
tfd_up_5 = tfd_tf_dir_closed('5')
tfd_up_15 = tfd_tf_dir_closed('15')
tfd_up_60 = tfd_tf_dir_closed('60')
tfd_up_240 = tfd_tf_dir_closed('240')
tfd_up_D = tfd_tf_dir_closed('D')
tfd_getUp(tf) =>
tf == '3' ? tfd_up_3 :
tf == '5' ? tfd_up_5 :
tf == '15' ? tfd_up_15 :
tf == '60' ? tfd_up_60 :
tf == '240' ? tfd_up_240 :
tf == 'D' ? tfd_up_D : false
tfd_tf_ms(tf) =>
tf == '3' ? 3 * 60 * 1000 :
tf == '5' ? 5 * 60 * 1000 :
tf == '15' ? 15 * 60 * 1000 :
tf == '60' ? 60 * 60 * 1000 :
tf == '240' ? 240 * 60 * 1000 :
tf == 'D' ? 24 * 60 * 60 * 1000 : 60 * 1000
tfd_calc_next_close_math(tfMinutes) =>
currentTime = timenow
currentHour = hour(currentTime)
currentMinute = minute(currentTime)
currentSecond = second(currentTime)
totalMinutesFromMidnight = currentHour * 60 + currentMinute
periodsFromMidnight = math.floor(totalMinutesFromMidnight / tfMinutes)
nextCloseMinutes = (periodsFromMidnight + 1) * tfMinutes
nextCloseHour = math.floor(nextCloseMinutes / 60)
nextCloseMinute = nextCloseMinutes % 60
if nextCloseHour >= 24
nextCloseHour := nextCloseHour - 24
nextCloseTime = timestamp(year(currentTime), month(currentTime), dayofmonth(currentTime), nextCloseHour, nextCloseMinute, 0)
if nextCloseTime <= currentTime
nextCloseTime := nextCloseTime + 24 * 60 * 60 * 1000
math.max(0, nextCloseTime - currentTime)
tfd_tc3_on = request.security(syminfo.tickerid, '3', time_close, barmerge.gaps_off, barmerge.lookahead_on)
tfd_tc5_on = request.security(syminfo.tickerid, '5', time_close, barmerge.gaps_off, barmerge.lookahead_on)
tfd_tc15_on = request.security(syminfo.tickerid, '15', time_close, barmerge.gaps_off, barmerge.lookahead_on)
tfd_tc60_on = request.security(syminfo.tickerid, '60', time_close, barmerge.gaps_off, barmerge.lookahead_on)
tfd_tc240_on = request.security(syminfo.tickerid, '240', time_close, barmerge.gaps_off, barmerge.lookahead_on)
tfd_tcD_on = request.security(syminfo.tickerid, 'D', time_close, barmerge.gaps_off, barmerge.lookahead_on)
tfd_tc3_off = request.security(syminfo.tickerid, '3', time_close, barmerge.gaps_off, barmerge.lookahead_off)
tfd_tc5_off = request.security(syminfo.tickerid, '5', time_close, barmerge.gaps_off, barmerge.lookahead_off)
tfd_tc15_off = request.security(syminfo.tickerid, '15', time_close, barmerge.gaps_off, barmerge.lookahead_off)
tfd_tc60_off = request.security(syminfo.tickerid, '60', time_close, barmerge.gaps_off, barmerge.lookahead_off)
tfd_tc240_off = request.security(syminfo.tickerid, '240', time_close, barmerge.gaps_off, barmerge.lookahead_off)
tfd_tcD_off = request.security(syminfo.tickerid, 'D', time_close, barmerge.gaps_off, barmerge.lookahead_off)
tfd_get_tc_on(tf) =>
tf == '3' ? tfd_tc3_on :
tf == '5' ? tfd_tc5_on :
tf == '15' ? tfd_tc15_on :
tf == '60' ? tfd_tc60_on :
tf == '240' ? tfd_tc240_on :
tf == 'D' ? tfd_tcD_on : na
tfd_get_tc_off(tf) =>
tf == '3' ? tfd_tc3_off :
tf == '5' ? tfd_tc5_off :
tf == '15' ? tfd_tc15_off :
tf == '60' ? tfd_tc60_off :
tf == '240' ? tfd_tc240_off :
tf == 'D' ? tfd_tcD_off : na
tfd_remain_security(tf) =>
msPer = tfd_tf_ms(tf)
tc_on = tfd_get_tc_on(tf)
tc_off = tfd_get_tc_off(tf)
tc = na(tc_on) ? (na(tc_off) ? na : tc_off + msPer) : tc_on
na(tc) ? 0 : math.max(0, tc - timenow)
tfd_remain(tf) =>
currentTfMinutes = timeframe.in_seconds(timeframe.period) / 60
tfMinutes = tf == '3' ? 3 : tf == '5' ? 5 : tf == '15' ? 15 : tf == '60' ? 60 : tf == '240' ? 240 : tf == 'D' ? 1440 : 1
if tfMinutes < currentTfMinutes
tfd_calc_next_close_math(tfMinutes)
else
tfd_remain_security(tf)
var array<string> tfd_labels = array.new_string()
var array<string> tfd_tfs = array.new_string()
array.clear(tfd_labels)
array.clear(tfd_tfs)
array.push(tfd_labels, 'M3')
array.push(tfd_tfs, '3')
array.push(tfd_labels, 'M5')
array.push(tfd_tfs, '5')
array.push(tfd_labels, 'M15')
array.push(tfd_tfs, '15')
array.push(tfd_labels, 'H1')
array.push(tfd_tfs, '60')
array.push(tfd_labels, 'H4')
array.push(tfd_tfs, '240')
array.push(tfd_labels, 'D')
array.push(tfd_tfs, 'D')
tfd_tfCount = math.min(array.size(tfd_labels), array.size(tfd_tfs))
tfd_activeRows = 1 + tfd_tfCount + (tfd_showFooter ? 1 : 0)
var table tfd_tbl = na
var int tfd_prevRows = 0
if na(tfd_tbl) or tfd_activeRows != tfd_prevRows or barstate.isfirst
if not na(tfd_tbl)
table.delete(tfd_tbl)
tfd_tbl := table.new(tfd_posTbl, 2, tfd_activeRows, border_width = 1, frame_color = color.black, border_color = color.black)
tfd_prevRows := tfd_activeRows
table.merge_cells(tfd_tbl, 0, 0, 1, 0)
tfd_headerTxt = syminfo.ticker + ' • ' + tfd_pretty_tf(timeframe.period)
table.cell(tfd_tbl, 0, 0, tfd_pad_label(tfd_headerTxt),
text_color = tfd_accentCol, text_halign = text.align_center, text_valign = text.align_center,
bgcolor = tfd_panelBg, text_size = tfd_const_hdr_size)
tfd_draw_row(row, labelTxt, tfStr) =>
remainMs = tfd_remain(tfStr)
dirUp = tfd_getUp(tfStr)
boxCol = tfd_useTrendCols ? (dirUp ? tfd_upColor : tfd_dnColor) : color.new(color.white, 85)
lblCol = tfd_labelsBlack ? color.black : (labelTxt == 'H4' or labelTxt == 'D' ? color.black : color.white)
table.cell(tfd_tbl, 0, row, tfd_pad_label(labelTxt),
text_color = lblCol, bgcolor = boxCol,
text_halign = text.align_center, text_valign = text.align_center, text_size = tfd_const_row_size)
timerTxt = tfd_fmt_by_tf(tfStr, remainMs)
table.cell(tfd_tbl, 1, row, tfd_pad_timer(timerTxt),
text_color = color.black, bgcolor = na,
text_halign = text.align_center, text_valign = text.align_center, text_size = tfd_const_row_size)
for i = 0 to tfd_tfCount - 1
tfd_draw_row(i + 1, array.get(tfd_labels, i), array.get(tfd_tfs, i))
if tfd_showFooter
tfd_footerRow = tfd_activeRows - 1
table.merge_cells(tfd_tbl, 0, tfd_footerRow, 1, tfd_footerRow)
table.cell(tfd_tbl, 0, tfd_footerRow, tfd_pad_label(tfd_footerText),
text_color = color.white, bgcolor = tfd_panelBg,
text_halign = text.align_center, text_valign = text.align_center, text_size = tfd_const_ftr_size)
// ========================================
// LINHA DA MEIA-NOITE
// ========================================
var g_midnight = 'Linha da Meia-Noite'
showLine = input.bool(true, "Mostrar Linha", group = g_midnight)
lineColor = color.gray
lineWidth = 1
onlyIntraday = true
midnightWindow = "0000-0001:1234567"
endHour = 17
tz = "America/New_York"
is_newbar(sess, _tz) =>
t = time("D", sess, _tz)
(na(t[1]) and not na(t)) or (t[1] < t)
is_end_time() =>
current_hour = hour(time, tz)
current_hour >= endHour
is_intraday = not timeframe.isdaily and not timeframe.isweekly and not timeframe.ismonthly
canPlot = showLine and (not onlyIntraday or is_intraday)
var line currentMidnightLine = na
var float currentMidnightPrice = na
var int midnightBarIndex = na
var bool lineActive = false
isMidnightBar = is_newbar(midnightWindow, tz)
if isMidnightBar and canPlot
currentMidnightPrice := open
midnightBarIndex := bar_index
lineActive := true
if not na(currentMidnightLine)
line.delete(currentMidnightLine)
currentMidnightLine := line.new(
x1=bar_index,
y1=open,
x2=bar_index,
y2=open,
color=lineColor,
width=lineWidth,
style=line.style_solid
)
if not na(currentMidnightLine) and lineActive and canPlot
if is_end_time()
line.set_x2(currentMidnightLine, bar_index)
line.set_y2(currentMidnightLine, currentMidnightPrice)
lineActive := false
else
line.set_x2(currentMidnightLine, bar_index)
line.set_y2(currentMidnightLine, currentMidnightPrice)
plot(lineActive and canPlot and not na(currentMidnightPrice) ? currentMidnightPrice : na,
title="Midnight Level",
color=color.new(lineColor, 30),
linewidth=1,
style=plot.style_linebr)
plotshape(
isMidnightBar and canPlot ? open : na,
style=shape.circle,
location=location.absolute,
color=color.new(lineColor, 0),
size=size.small,
title="Início - Meia-Noite"
)
// ========================================
// SEPARADOR DE DIAS (LINHA VERTICAL + NOME)
// ========================================
var g_day_sep = 'Separador de Dias'
enable_day_sep = input.bool(true, 'Mostrar Separador', group = g_day_sep)
day_sep_color = input.color(color.new(color.gray, 30), 'Cor', group = g_day_sep)
day_sep_crypto = input.bool(false, 'Mercado 24/7 (Crypto)', tooltip = 'Ativar para BTC, ETH e outros que não fecham fim de semana', group = g_day_sep)
daySep_isIntraday = not timeframe.isdaily and not timeframe.isweekly and not timeframe.ismonthly
daySep_canShow = enable_day_sep and daySep_isIntraday
var array<line> daySep_lines = array.new<line>(0)
var int daySep_maxHistory = 10
daySep_pruneHistory() =>
while array.size(daySep_lines) > daySep_maxHistory
oldLine = array.shift(daySep_lines)
if not na(oldLine)
line.delete(oldLine)
if isMidnightBar and daySep_canShow and barstate.isconfirmed
newLine = line.new(
x1 = bar_index,
y1 = low,
x2 = bar_index,
y2 = high,
color = day_sep_color,
width = 2,
style = line.style_dashed,
extend = extend.both
)
array.push(daySep_lines, newLine)
daySep_pruneHistory()
daySep_hour = hour(time, tz)
daySep_minute = minute(time, tz)
daySep_is12am = daySep_hour == 12 and daySep_minute == 0
plotchar(daySep_canShow and daySep_is12am and dayofweek == dayofweek.sunday and day_sep_crypto ? true : false,
text='Sunday', char = ".", color=day_sep_color, location=location.top, offset=0)
plotchar(daySep_canShow and daySep_is12am and dayofweek == dayofweek.monday ? true : false,
text='Monday', char = ".", color=day_sep_color, location=location.top, offset=0)
plotchar(daySep_canShow and daySep_is12am and dayofweek == dayofweek.tuesday ? true : false,
text='Tuesday', char = ".", color=day_sep_color, location=location.top, offset=0)
plotchar(daySep_canShow and daySep_is12am and dayofweek == dayofweek.wednesday ? true : false,
text='Wednesday', char = ".", color=day_sep_color, location=location.top, offset=0)
plotchar(daySep_canShow and daySep_is12am and dayofweek == dayofweek.thursday ? true : false,
text='Thursday', char = ".", color=day_sep_color, location=location.top, offset=0)
plotchar(daySep_canShow and daySep_is12am and dayofweek == dayofweek.friday ? true : false,
text='Friday', char = ".", color=day_sep_color, location=location.top, offset=0)
plotchar(daySep_canShow and daySep_is12am and dayofweek == dayofweek.saturday and day_sep_crypto ? true : false,
text='Saturday', char = ".", color=day_sep_color, location=location.top, offset=0)
Overview
NXOG + FVG identifies institutional opening gaps such as NDOG, NWOG, and NMOG with colored boxes and labels. Killzones for major trading sessions are visualized with customizable boxes, high-low lines, and colors. Mitigation filters automatically remove gaps based on percentage thresholds, using body or wick for calculations, with options to delete all mitigated gaps. Boxes have adjustable transparency and optional text labels. The script draws elements directly on the main price chart.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Texto dentro da BOX
bool
true
showLabels
Transparência dos Boxes
int
85
boxTransparency
Mitigando em X %
int
50
mitig_pct_threshold
Usar o corpo ao invés do pavio
bool
false
mitig_use_close
Remover TODOS Gaps (NXOG) mitigados
bool
false
deleteAllMitigatedNXOG
Remover TODOS FVGs mitigados
bool
true
deleteAllMitigatedFVG
Mostrar NDOG
bool
true
enable_ndog
Remover NDOGs mitigados
bool
false
deleteFilledNDOG
Máx NDOG
int
5
max_ndog
Cor Alta
color
color.new(color.lime, 75)
color_ndog_up
Cor Baixa
color
color.new(color.lime, 75)
color_ndog_dn
Mostrar NWOG
bool
true
enable_nwog
Show all 40 settings
Setting
Type
Default
Variable
Remover NWOGs mitigados
bool
false
deleteFilledNWOG
Máx NWOG
int
3
max_nwog
Cor Alta
color
color.new(color.teal, 75)
color_nwog_up
Cor Baixa
color
color.new(color.teal, 75)
color_nwog_dn
Mostrar NMOG
bool
true
enable_nmog
Remover NMOGs mitigados
bool
false
deleteFilledNMOG
Máx NMOG
int
3
max_nmog
Cor Alta
color
color.new(color.maroon, 75)
color_nmog_up
Cor Baixa
color
color.new(color.maroon, 75)
color_nmog_dn
FVG 15M
bool
true
enable_15m
Remover FVGs mitigados
bool
true
deleteFilled15m
Máx FVGs
int
8
max_fvg_15m
Cor FVG Alta
color
color.new(color.blue, 85)
color_up_15m
Cor FVG Baixa
color
color.new(color.blue, 85)
color_dn_15m
FVG 1H
bool
true
enable_1h
Remover FVGs mitigados
bool
true
deleteFilled1h
Máx FVGs
int
6
max_fvg_1h
Cor FVG Alta
color
color.new(color.orange, 85)
color_up_1h
Cor FVG Baixa
color
color.new(color.orange, 85)
color_dn_1h
FVG 4H
bool
true
enable_4h
Remover FVGs mitigados
bool
true
deleteFilled4h
Máx FVGs
int
5
max_fvg_4h
Cor FVG Alta
color
color.new(color.purple, 85)
color_up_4h
Cor FVG Baixa
color
color.new(color.purple, 85)
color_dn_4h
FVG 1D
bool
true
enable_1d
Remover FVGs mitigados
bool
true
deleteFilled1d
Máx FVGs
int
4
max_fvg_1d
Cor FVG Alta
color
color.new(color.yellow, 85)
color_up_1d
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.
The Golden Bullet Strategy is an overlay signal indicator based on Smart Money Concepts and time-based liquidity models. It identifies liquidity sweeps of a designated reference session range during a specified hunt window. It then confirms Market Structure Sh
Indicatorv6SMC / ICT / price actionSessions & time
This indicator overlays options gamma-exposure levels, session VWAP bands, and intraday market structure tools directly on the price chart. It provides three modular components: strike walls with standard deviation bands and opening ranges, a gamma regime engi
This indicator detects and draws the first Fair Value Gap (FVG) that forms in each hourly session based on a selected lower timeframe, with specialized handling for Regular Trading Hours (RTH) confluence windows. It draws FVG range boxes, midpoint lines, hourl
This indicator combines six trading tools into a single chart overlay to optimize indicator limits. It calculates Bollinger Bands, projects weekend price boundaries, plots market structure elements like order blocks, breaker blocks, and MSB lines, marks New Yo
This indicator highlights Inner Circle Trader (ICT) killzones and key session pivot points directly on the price chart. It projects shaded boxes for specific trading sessions, including Asia, London, NY AM, NY Lunch, and NY PM, to help traders identify high-li
Indicatorv5SMC / ICT / price actionSessions & time
Bandz Session Ranges + ORG + Opening Prices plots trading session ranges, killzones, opening RTH gaps, standard deviation projections, and key opening prices directly on the price chart. It calculates gap ranges based on prior regular trading hours close sourc