Time-of-Day Volatility Curve
Market volatility is not uniform throughout the trading day. Sessions open and close with higher activity; mid-day can be quieter. This indicator calculates the average volatility at each hour and plots the typical volatility pattern for the hour currently trading. Traders use this to understand when the market is usually most volatile, informing decisions about entry/exit timing and position sizing during different market sessions.
//@version=6
indicator("Time-of-Day Volatility Curve", shorty="ToD Vol", overlay=false, max_bars_back=5000)
// === INPUTS ===
volLen = input.int(14, "Volatility Lookback Period", minval=1, maxval=100)
method = input.string("ATR", "Volatility Method", options=["ATR", "StDev"])
showCurrent = input.bool(true, "Show Current Volatility")
showPattern = input.bool(true, "Show Time-of-Day Average")
// === CALCULATE VOLATILITY ===
// Volatility measure for this bar
volatility = method == "ATR" ? ta.atr(volLen) : ta.stdev(close, volLen)
// Which hour of the day is this bar (0-23)?
barHour = hour(time)
// === PERSISTENT STORAGE ===
// Track cumulative volatility and bar count for each of 24 hours
var float[] hourlySum = array.new<float>(24, 0.0)
var int[] hourlyCount = array.new<int>(24, 0)
// Add current bar's volatility to its hour bucket
currentSum = array.get(hourlySum, barHour)
currentCount = array.get(hourlyCount, barHour)
array.set(hourlySum, barHour, currentSum + volatility)
array.set(hourlyCount, barHour, currentCount + 1)
// === COMPUTE AVERAGES ===
// Average volatility for the current hour (across all days in history)
barCount = array.get(hourlyCount, barHour)
hourlyAverage = barCount > 0 ? array.get(hourlySum, barHour) / barCount : 0.0
// === PLOTS ===
if showCurrent
plot(volatility, "Current Volatility", color.new(color.gray, 70), linewidth=1)
if showPattern
plot(hourlyAverage, "Typical Volatility (This Hour)", color.new(color.blue, 0), linewidth=2)
hline(0, color=color.gray, linestyle=hline.style_dotted, linewidth=1)
How the code works
The indicator maintains two arrays with 24 slots, one for each hour of the day. Each time a bar closes, the code calculates its volatility using either Average True Range (ATR, which captures gaps and limits) or standard deviation of the close price. It then adds that volatility to the cumulative total for that bar's hour and increments the count. On the next day, when bars from the same hour appear, their volatility is added to the existing total. By dividing the cumulative sum by the count, the indicator computes a rolling average volatility specific to each hour. As the chart accumulates data across trading days, the average becomes more representative of typical conditions at that time. The blue line shows the typical volatility for the current hour; the gray line (optional) shows realized volatility for comparison.
Reading it on a chart
The indicator plots two series: a blue line showing the historical average volatility for the current hour, and a gray line (if enabled) showing the volatility realized in the present bar. Traders look for patterns: if the blue line is consistently higher during morning hours, that hour tends to be volatile. Mid-day often shows a dip in the blue line. Approaching major news or the final trading hour typically pushes the curve upward. When current volatility (gray) exceeds the typical level (blue), it signals conditions are more dynamic than usual for that time. Conversely, when current volatility is far below the blue line, the market is quieter than its typical pattern.
The indicator is useful for confirming whether price swings are normal for the time of day or noteworthy. A trader who avoids choppy markets might wait until the curve shows lower volatility before entering; a trader seeking breakouts might target high-volatility hours.
Limitations
The indicator has several blind spots. First, it does not distinguish between market structure, opening auctions, closing auctions, option expiry hours and pre-market/post-market sessions all create structural changes in volatility that seasonal patterns alone do not capture. Second, it does not account for the trader's own time zone or the market's time zone; "hour 9" means 09:00 in the exchange's local time, not the trader's, creating confusion across regions. Third, the accumulation is global across all historical data in the chart. If market volatility has increased secularly over years (due to higher frequency trading, regulatory changes or broader macro shifts), older bars distort the pattern. The curve does not adapt to regime changes.
Fourth, the count per hour grows without limit as more days are added to the chart, but the marginal value of 200-bar-old data is questionable. Early bars in the sample may have been from different sessions, different instruments or different trading conditions, yet they carry equal weight. Fifth, holidays, half-days and special sessions are not excluded; a half-day Friday morning volatility mixes with full-day Wednesdays, skewing the typical pattern. Sixth, ATR is influenced by gaps, which are correlated with overnight and opening hours but not with actual intraday trading intensity; for a pure intraday view, standard deviation of the close or intrabar ranges may be preferable. Finally, seasonality in volatility is real but complex; the indicator shows only the hour of day, not day of week, week of month, or proximity to known data releases, a richer model would need those layers.
Key definitions
Volatility: a measure of how much price fluctuates over a given period, typically expressed as a percentage change or absolute price range. Higher volatility means sharper, faster moves.
ATR (Average True Range): a technical indicator that measures the average of the true range (the greatest of the high-low spread, the gap up from the prior close, or the gap down) over a lookback period, smoothed by a moving average. ATR captures both intrabar swings and gaps.
Standard Deviation: a statistical measure of how far prices deviate from their average; in this context, it measures the scatter of recent close prices around their mean.
Time-of-Day Effect: an empirical regularity in which market volatility, volume, bid-ask spreads and price discovery efficiency vary predictably by hour of the trading day.
Intraday Pattern: a recurring, predictable behavior within a single trading day (as opposed to day-to-day or seasonal patterns).
Realized Volatility: the volatility observed in the current or recent bars, as opposed to implied volatility or historical average.
References
- Nasdaq, "Market Hours," Nasdaq.com. Accessed 2025. https://www.nasdaq.com/about/market-hours
- CME Group, "Globex Trading Hours," CME Group. Accessed 2025. https://www.cmegroup.com/
- Goodhart, C. A., & O'Hara, M. (1997), "High frequency data in financial markets: Issues and applications," Journal of Empirical Finance, 4(2), 73-114. Https://doi.org/10.1016/S0927-5398(97)00007-8
- Wood, R. A., McInish, T. H., & Ord, J. K. (1985), "An investigation of transactions data for NYSE stocks," Journal of Finance, 40(3), 723-739. Https://doi.org/10.1111/j.1540-6261.1985.tb04992.x
- Almgren, R. (2012), "Algorithmic Trading and Market Microstructure," Algorithmic Trading Review, New York. (Practitioner reference on intraday volatility structure.)
- Wikipedia, "Volatility (finance)," Wikimedia Foundation. Accessed 2025. https://en.wikipedia.org/wiki/Volatility_(finance)
Educational research on historical data only. Not investment advice, not a signal, and never a performance promise. Past results do not predict future performance. Every reference is link-verified before publication and every paper is re-audited weekly against the library's editorial standard.
Last reviewed by the PropLedger research pipeline: 2026-09-27. Educational research on historical data, not financial advice.
Keep reading
Turn-of-Month Countdown
Free open-source Pine Script indicator: turn-of-month countdown and shading. Full code and a plain-English walkthrough.
Keltner Channels vs Bollinger Bands Overlay
Free open-source Pine Script indicator: Keltner channel vs Bollinger band overlay. Full code and a plain-English walkthrough.
Session Open Anchored Move Measure
Free open-source Pine Script indicator: session open anchored move measure (points and ATR multiples). Full code and a plain-English walkthrough.