Hello
I’d like to build an indicator that is calculated only on close values of a fixed spcific daily time window. For example RSI of the last 100 hourly bars at close, but the 100 hourly bars that must be taken into account are those inside the time window 9:00-22:00 of each day despite the market is open from 00:00-23:00. I mean that i need to filter out from the computation all the bars that are outside my desired time window
I tried to customize the graph intrady times displayed but it affects only the graph.
The only way I thought to achieve this is to register each close on a custom array and then calculate my indicator, but it would be very complicate.Does anybody know an easy way to achieve this?
Thanks a lot
You are correct, customising the chart display times has zero effect on indicator calculations. And you are also correct that the only reliable way to achieve a time-filtered RSI in ProBuilder is to maintain your own array of closes — there is no built-in shortcut. The good news is that we can build a user defined custom series with arrays and therefore apply the RSI calculation on it.
The approach is:
- Use OpenHour to detect whether the current bar falls inside your desired window.
- When it does, store close into $fc[idx] and increment idx. This builds a compact series that contains only the in-window closes, numbered sequentially, with no gaps from excluded bars.
- Implement the RSI by hand (Wilder’s method) over that filtered series. This is necessary because the built-in RSI[] function always works on the full bar series and cannot skip bars.
- On the very first bar where you have enough data (idx = RsiPeriod + 1), compute the seed averages with a loop. On every subsequent bar, apply Wilder’s smoothing formula.
You can change WindowStart, WindowEnd, and RsiPeriod freely to adapt it to any window or period.
// Parameters
RsiPeriod = 14 // RSI look-back period (number of filtered bars)
WindowStart = 9 // Session start hour (>=)
WindowEnd = 22 // Session end hour (<)
// Time filter
inWindow = (OpenHour >= WindowStart) AND (OpenHour < WindowEnd)
// Fill the filtered-close array
// idx is a persistent counter of how many in-window bars we have seen so far
if inWindow then
$fc[idx] = close
idx = idx + 1
endif
// RSI calculation on the filtered series
// We need at least RsiPeriod+1 values to produce a meaningful result
myRSI = UNDEFINED
if idx > RsiPeriod then
// Seed: first Wilder average over the initial RsiPeriod bars
// (computed once when idx reaches RsiPeriod+1 exactly)
if idx = RsiPeriod + 1 then
sumGain = 0
sumLoss = 0
i = 1
while i <= RsiPeriod do
diff = $fc[idx - 1 - RsiPeriod + i] - $fc[idx - 1 - RsiPeriod + i - 1]
if diff > 0 then
sumGain = sumGain + diff
else
sumLoss = sumLoss + ABS(diff)
endif
i = i + 1
wend
avgGain = sumGain / RsiPeriod
avgLoss = sumLoss / RsiPeriod
else
// Subsequent bars: Wilder smoothing
diff = $fc[idx - 1] - $fc[idx - 2]
if diff > 0 then
myGain = diff
myLoss = 0
else
myGain = 0
myLoss = ABS(diff)
endif
avgGain = (avgGain * (RsiPeriod - 1) + myGain) / RsiPeriod
avgLoss = (avgLoss * (RsiPeriod - 1) + myLoss) / RsiPeriod
endif
if avgLoss = 0 then
myRSI = 100
else
RS = avgGain / avgLoss
myRSI = 100 - (100 / (1 + RS))
endif
endif
// Display
if NOT inWindow then
myRSI = UNDEFINED
endif
RETURN myRSI STYLE(LINE, 2) COLOURED(255, 165, 0) AS "RSI (filtered)"