DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Trending

  • Resume the Evaluation, Not the Entire Batch: Build a Checkpoint-Aware AI Job Controller With Temporal
  • Building High-Performance Time-Series Applications With Java and QuestDB
  • Designing a Role-Aware Runtime for AI Avatar Systems
  • MCP vs REST/HTTP API vs Kafka: The Architect's Guide to Agentic AI Integration
  1. DZone
  2. Data Engineering
  3. Data
  4. The Sqrt(t) Volatility Band Is Wrong in Both Directions; Here's What to Compute Instead

The Sqrt(t) Volatility Band Is Wrong in Both Directions; Here's What to Compute Instead

Sigma*sqrt(t) misprices volatility bands for fat-tailed series, and the error flips sign with horizon. Here is what to compute instead.

By 
Alex Malinowski user avatar
Alex Malinowski
·
Oct. 08, 26 · Analysis
Likes (0)
Comment
Save
Tweet
Share
97 Views

Join the DZone community and get the full member experience.

Join For Free

If you have ever drawn a forecast band around a price series, you have probably reached for the same formula everyone reaches for: take a volatility estimate, multiply by the square root of the horizon, and call the result your interval. sigma * sqrt(t) is the closed-form move; it is one line of code, and for fat-tailed financial series it is wrong in a way that is worth understanding precisely, because the error does not even keep the same sign as you change the horizon.

This is a short engineering write-up on what breaks, how we measured it, and the handful of things you actually have to compute to build an honest, reproductible interval. 

What Sqrt(t) Assumes, and Why Crypto Violates It

The sigma * sqrt(t) scaling falls out of assuming i.i.d. Gaussian log-returns: variance adds linearly in time, so standard deviation scales with the root of time, and a fixed multiple of it gives a fixed-probability band. Two assumptions are doing all the work — normality and independence — and daily crypto returns honor neither. Realized kurtosis on daily BTC log-returns sits near 16 against the Gaussian's 3. Returns are close to uncorrelated, but their magnitudes are strongly autocorrelated (volatility clustering), so the independence the formula needs is not there either.

We measured the damage against the full Binance history rather than a recent window — 3,261 daily bars for BTC back to 2017. The quantity of interest is the ratio of an empirically measured 80% band to the sigma * rt(t) band at each horizon:

Shell
 
horizon    empirical80 / sqrt-t band   (BTC)
 1 day               ~0.80
 7 days              ~0.88
30 days              ~1.00


Read that carefully: at one day the parametric band is too wide (0.80), and by thirty days it is about right (1.00). The error changes sign with the horizon, so there is no single scale factor you can bake in to fix it. The reason the short-horizon band is too wide despite fat tails is that the kurtosis lives in the extreme tails, not in the 10th–90th-percentile shoulders — so the 80% interval is actually narrower than Gaussian while the 99% interval is much wider. Fat tails and a narrow 80% band coexist, which is exactly the kind of thing a parametric shortcut hides from you.

Compute the Empirical Band Instead

The fix is to stop parameterizing and read the interval straight off the empirical distribution of realized h-day log-returns:

Python
 
import numpy as np

def empirical_band(prices, horizon, lo=0.10, hi=0.90):
    p = np.asarray(prices, dtype=float)
    # overlapping h-day log-returns
    r = np.log(p[horizon:] / p[:-horizon])
    q_lo, q_hi = np.quantile(r, [lo, hi])
    spot = p[-1]
    return spot * np.exp(q_lo), spot * np.exp(q_hi)


That is the whole idea, and it already beats the parametric band because it makes no distributional assumption. But there is a trap in the line that builds r.

The Overlapping-Windows Trap

Those h-day returns overlap: consecutive 30-day windows share 29 days of data. Overlapping samples are heavily autocorrelated, so if you report len(r) as your sample size, you are overstating your evidence by roughly the horizon. For BTC's 30-day band, ~3,231 overlapping windows correspond to only about 107 independent months. Quantile estimates from overlapping windows are still usable, but their uncertainty is far larger than the raw count implies, and you must report the independent count, not the overlapping one:

Python
 
def independent_count(n_bars, horizon):
    return max(1, (n_bars - horizon) // horizon)


We print band from N independent windows directly on every chart for this reason. A band from 107 independent months is a different epistemic object than one implying 3,231 samples, and collapsing the two is how backtests quietly manufacture confidence.

Evaluate With Coverage, in Both Directions

The metric for an interval forecast is coverage, and the failure is symmetric. A claimed 50% band should contain the outcome about half the time across many out-of-sample days. If it contains 90%, the band is padded — a failure that a one-sided "were we inside?" check will never catch, because padding always looks safe. So score both the 50% core and the 80% band against their targets, over many days, and treat over-coverage as a miss.

Make It Reproducible and Tamper-Evident

The last piece is provenance, and it is pure engineering. We serialize each forecast object, hash it with SHA-256, and anchor the hash to the Bitcoin blockchain via OpenTimestamps before publishing. One gotcha worth flagging because it cost us a real bug: hash the exact bytes you publish. We were writing the JSON with a trailing newline but hashing the object without it, so a reader running shasum on the published file got a different digest — which reads as fraud even though nothing was wrong. Write the file, hash the file, timestamp the file; byte-for-byte, no re-serialization in between.

None of this is an edge, and the write-up would be dishonest if it implied one. An empirical band lowers the cost of being wrong about volatility; it does not tell you direction. No method reliably beats a liquid market, and anyone promising that is selling something. What the empirical quantile buys you is a band whose width means what it says — and a pipeline where any reader can recompute the number and check the timestamp themselves.

The live version, scored in public with the misses kept, is at neuportal.ai/experiment.

Educational content — not financial advice.

BAND (application)

Opinions expressed by DZone contributors are their own.

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook