Buenas!
El primer punto es posible pero computacionalmente hablando no. Tiene demasiados bucles.
Respecto al segundo punto, se puede poner hora de chequeo, eso sí, sería necesario poner un mensaje de advertencia para que el timeframe utilizado sea menor del diario.
defparam drawonlastbaronly = true
// ----------------------------------------------
// === TIMEFRAME CHECK ===
// ----------------------------------------------
dailyOrHigher = 0
if GetTimeFrame >= 86400 then
dailyOrHigher = 1
drawtext("This indicator requires an intraday timeframe. Please switch to a timeframe below Daily.", barindex, close) coloured(255, 0, 0)
endif
// ----------------------------------------------
// === SESSION PARAMETERS ===
// ----------------------------------------------
// Enter times in HHMM format (e.g. 800 = 08:00, 1600 = 16:00)
// Asian: startHHMM=2200, endHHMM=800
// European: startHHMM=800, endHHMM=1530
// US: startHHMM=1530, endHHMM=2200
startHHMM = 800
endHHMM = 1600
cnum = 40 // Number of rows (channels)
pctVA = 70 // Value Area Volume %
showPOC = 1 // Show POC label (1=yes, 0=no)
showVAHL = 1 // Show VAH/VAL labels (1=yes, 0=no)
pocExtend = 50 // POC/VAH/VAL line extension in bars
maxScanBars = 500 // Max bars to scan backwards
// ----------------------------------------------
// === COLOR SETTINGS (RGB + Alpha) ===
// ----------------------------------------------
// POC line (red)
pocR = 255
pocG = 0
pocB = 0
// VAH/VAL lines (grey)
vaLineR = 128
vaLineG = 128
vaLineB = 128
// Value Area Up volume (blue, 70% opaque)
vaUpR = 33
vaUpG = 150
vaUpB = 243
vaUpA = 178
// Value Area Down volume (orange, 70% opaque)
vaDnR = 255
vaDnG = 152
vaDnB = 0
vaDnA = 178
// Up Volume outside VA (blue, 25% opaque)
upVolR = 33
upVolG = 150
upVolB = 243
upVolA = 64
// Down Volume outside VA (orange, 25% opaque)
dnVolR = 255
dnVolG = 152
dnVolB = 0
dnVolA = 64
// ----------------------------------------------
// === ATR for label offset ===
// ----------------------------------------------
atr = averagetruerange[14]
// Convert HHMM to HHMMSS for time comparison
startT = startHHMM * 100
endT = endHHMM * 100
// ----------------------------------------------
// MAIN CALCULATION (intraday only, last bar only)
// ----------------------------------------------
if dailyOrHigher = 0 and islastbarupdate then
// =============================================
// Phase 1: Find session bar range
// Scans backwards from current bar.
// endOff = offset of NEWEST bar in session
// startOff = offset of OLDEST bar in session
// =============================================
endOff = -1
startOff = -1
scanDone = 0
for i = 0 to maxScanBars
if scanDone = 0 then
bt = time[i]
// Determine if bar is inside session
inSess = 0
if startT <= endT then
// Normal session (no midnight crossing)
if bt >= startT and bt <= endT then
inSess = 1
endif
else
// Midnight-crossing session (e.g. 22:00 to 08:00)
if bt >= startT or bt <= endT then
inSess = 1
endif
endif
if endOff < 0 then
// Still looking for first session bar
if inSess = 1 then
endOff = i
startOff = i
endif
else
// Already found session
if inSess = 1 then
startOff = i
else
scanDone = 1
endif
endif
endif
next
// =============================================
// Phase 2: Calculate Volume Profile
// =============================================
if endOff >= 0 and startOff >= endOff then
sessionBars = startOff - endOff + 1
// --- Find highest/lowest in session ---
topPrice = high[endOff]
botPrice = low[endOff]
for i = endOff + 1 to startOff do
if high[i] > topPrice then
topPrice = high[i]
endif
if low[i] < botPrice then
botPrice = low[i]
endif
next
gap = (topPrice - botPrice) / 500
stepSize = (topPrice - botPrice) / cnum
// --- Store channel levels ---
for x = 0 to cnum do
$levels[x] = botPrice + stepSize * x
next
// --- Initialize volume arrays ---
// $vol[0..cnum-1] = up (green) volume
// $vol[cnum..2*cnum-1] = down (red) volume
for x = 0 to cnum * 2 - 1 do
$vol[x] = 0
next
// --- Distribute volume across channels ---
for b = endOff to startOff do
bTop = max(close[b], open[b])
bBot = min(close[b], open[b])
if close[b] >= open[b] then
isGreen = 1
else
isGreen = 0
endif
tw = high[b] - bTop
bw = bBot - low[b]
bd = bTop - bBot
denom = 2 * tw + 2 * bw + bd
if denom > 0 then
bdVol = bd * volume[b] / denom
twVol = 2 * tw * volume[b] / denom
bwVol = 2 * bw * volume[b] / denom
else
bdVol = 0
twVol = 0
bwVol = 0
endif
for x = 0 to cnum - 1 do
lLo = $levels[x]
lHi = $levels[x + 1]
// Body overlap
if bd > 0 then
bdOvlp = max(0, min(lHi, bTop) - max(lLo, bBot))
bdC = bdOvlp * bdVol / bd
else
bdC = 0
endif
// Top wick overlap
if tw > 0 then
twOvlp = max(0, min(lHi, high[b]) - max(lLo, bTop))
twC = twOvlp * twVol / tw
else
twC = 0
endif
// Bottom wick overlap
if bw > 0 then
bwOvlp = max(0, min(lHi, bBot) - max(lLo, low[b]))
bwC = bwOvlp * bwVol / bw
else
bwC = 0
endif
// Accumulate up volume (green body + half wicks)
if isGreen = 1 then
$vol[x] = $vol[x] + bdC + twC / 2 + bwC / 2
else
$vol[x] = $vol[x] + twC / 2 + bwC / 2
endif
// Accumulate down volume (red body + half wicks)
if isGreen = 1 then
$vol[x + cnum] = $vol[x + cnum] + twC / 2 + bwC / 2
else
$vol[x + cnum] = $vol[x + cnum] + bdC + twC / 2 + bwC / 2
endif
next
next
// --- Find POC and totals ---
maxVol = 0
pocIdx = 0
totalSum = 0
for x = 0 to cnum - 1 do
$totals[x] = $vol[x] + $vol[x + cnum]
totalSum = totalSum + $totals[x]
if $totals[x] > maxVol then
maxVol = $totals[x]
pocIdx = x
endif
next
// --- Calculate Value Area ---
vaTotal = $totals[pocIdx]
vaThreshold = totalSum * pctVA / 100
vaUp = pocIdx
vaDown = pocIdx
vaDone = 0
for x = 0 to cnum - 1 do
if vaDone = 0 then
if vaTotal >= vaThreshold then
vaDone = 1
else
if vaUp < cnum - 1 then
upperV = $totals[vaUp + 1]
else
upperV = 0
endif
if vaDown > 0 then
lowerV = $totals[vaDown - 1]
else
lowerV = 0
endif
if upperV = 0 and lowerV = 0 then
vaDone = 1
else
if upperV >= lowerV then
vaTotal = vaTotal + upperV
vaUp = vaUp + 1
else
vaTotal = vaTotal + lowerV
vaDown = vaDown - 1
endif
endif
endif
endif
next
// --- Scale volumes for display width ---
if maxVol > 0 then
for x = 0 to cnum * 2 - 1 do
$vol[x] = $vol[x] * sessionBars / (3 * maxVol)
next
endif
// --- Draw volume profile rectangles ---
startX = barindex - startOff
for x = 0 to cnum - 1 do
upW = round($vol[x])
dnW = round($vol[x + cnum])
y1 = $levels[x + 1] - gap
y2 = $levels[x] + gap
if x >= vaDown and x <= vaUp then
// Inside Value Area
if upW > 0 then
drawrectangle(startX, y1, startX + upW, y2) coloured(vaUpR, vaUpG, vaUpB, 0) fillcolor(vaUpR, vaUpG, vaUpB, vaUpA)
endif
if dnW > 0 then
drawrectangle(startX + upW, y1, startX + upW + dnW, y2) coloured(vaDnR, vaDnG, vaDnB, 0) fillcolor(vaDnR, vaDnG, vaDnB, vaDnA)
endif
else
// Outside Value Area
if upW > 0 then
drawrectangle(startX, y1, startX + upW, y2) coloured(upVolR, upVolG, upVolB, 0) fillcolor(upVolR, upVolG, upVolB, upVolA)
endif
if dnW > 0 then
drawrectangle(startX + upW, y1, startX + upW + dnW, y2) coloured(dnVolR, dnVolG, dnVolB, 0) fillcolor(dnVolR, dnVolG, dnVolB, dnVolA)
endif
endif
next
// --- Draw POC line + label ---
pocLevel = ($levels[pocIdx] + $levels[pocIdx + 1]) / 2
drawsegment(startX, pocLevel, barindex + pocExtend, pocLevel) coloured(pocR, pocG, pocB) style(line, 2)
if showPOC = 1 then
drawtext("POC: #pocLevel#", barindex + 15, pocLevel + 0.25 * atr) coloured(pocR, pocG, pocB)
endif
// --- Draw VAH line + label ---
vahLevel = $levels[vaUp + 1]
drawsegment(startX, vahLevel, barindex + pocExtend, vahLevel) coloured(vaLineR, vaLineG, vaLineB) style(dottedline, 1)
if showVAHL = 1 then
drawtext("VAH: #vahLevel#", barindex + 15, vahLevel + 0.25 * atr) coloured(vaLineR, vaLineG, vaLineB)
endif
// --- Draw VAL line + label ---
valLevel = $levels[vaDown]
drawsegment(startX, valLevel, barindex + pocExtend, valLevel) coloured(vaLineR, vaLineG, vaLineB) style(dottedline, 1)
if showVAHL = 1 then
drawtext("VAL: #valLevel#", barindex + 15, valLevel - 0.25 * atr) coloured(vaLineR, vaLineG, vaLineB)
endif
endif
endif
// ----------------------------------------------
RETURN