QuantScenarioBench/qsb-rough-bergomi
QuantScenarioBench — Rough Bergomi Benchmark Dataset This dataset is a representative benchmark sample generated by QuantScenarioBench, a JAX-native framework for reproducible stochastic market scenario generation. It contains 10,000 independent simulation paths under the Rough Bergomi model over 252 daily time steps (1 year horizon). Each path includes both the asset price trajectory (observation) and the instantaneous variance trajectory (latent state). Need a larger or… See the full description on the dataset page: https://huggingface.co/datasets/QuantScenarioBench/qsb-rough-bergomi.
QuantScenarioBench — Rough Bergomi Benchmark Dataset
This dataset is a representative benchmark sample generated by [QuantScenarioBench](https://github.com/tim-nish/QuantScenarioBench), a JAX-native framework for reproducible stochastic market scenario generation.
It contains 10,000 independent simulation paths under the Rough Bergomi model over 252 daily time steps (1 year horizon). Each path includes both the asset price trajectory (observation) and the instantaneous variance trajectory (latent state).
Need a larger or custom dataset? This file is a fixed benchmark sample. To generate datasets at any scale — more paths, different parameters, non-uniform time grids, or other market models — use the QuantScenarioBench library directly: ``python pip install quantscenariobench `` See the GitHub project for full documentation and examples.Model Description
The Rough Bergomi model (Bayer, Friz & Gatheral, 2016) is a non-Markovian stochastic volatility model that drives the variance process with a fractional Brownian motion (fBM) with Hurst exponent $H < \frac{1}{2}$. The roughness of the variance path ($H \approx 0.1$ empirically) captures the steep short-maturity implied-vol skew observed in equity markets and addresses a well-known shortcoming of Markovian models such as Heston.
The variance and asset price evolve as:
$$Vt = \xi0 \exp\!\left(\eta\,W^Ht - \tfrac{1}{2}\eta^2\,t^{2H}\right)$$ $$dSt = \mu\,St\,dt + \sqrt{Vt}\,St\,dW^St, \quad \text{Corr}(dW^St, dWt) = \rho$$
where $W^H_t$ is a Riemann–Liouville fractional Brownian motion, discretised via the Volterra representation:
$$W^H{ti} = \sum{j=0}^{i-1} (ti - tj)^{H - \frac{1}{2}} \,\Delta Wj$$
Because the variance is non-Markovian (each step depends on the full history of BM increments), the simulation pre-computes the full Volterra kernel matrix and applies it to each path via a single matrix–vector product.
Key properties:
- Rough volatility — variance paths with $H = 0.1$ are much rougher than Brownian motion ($H = 0.5$)
- Empirically calibrated — $H \approx 0.1$ is the canonical estimate from historical implied-vol data (Gatheral et al., 2018)
- Non-Markovian — past BM increments influence future variance; this is why diffrax is bypassed for variance simulation
- Leverage effect — negative $\rho$ links downward price moves to rising variance
Parameters used for this dataset
The risk-neutral setting (mu=0) and identical initial vol (xi0=0.04) to the other benchmark datasets make ATM option prices directly comparable across models.
Simulation Configuration
Column Schema
All QuantScenarioBench datasets share the same 12-column schema regardless of the market model used. This enables direct cross-model comparison by loading datasets with identical code.
Usage
from datasets import load_dataset
import numpy as np
ds = load_dataset("QuantScenarioBench/qsb-rough-bergomi", split="train")
# Each row is one simulated path
row = ds[0]
prices = np.array(row["observation"]) # shape (253,) — asset price
variances = np.array(row["latent_state"]) # shape (253,) — instantaneous variance
vols = np.sqrt(variances) # instantaneous vol
print(f"S0={prices[0]:.2f} S_T={prices[-1]:.2f} avg_vol={vols.mean():.3f}")
# Stack all paths
all_prices = np.stack([ds[i]["observation"] for i in range(len(ds))])
all_vars = np.stack([ds[i]["latent_state"] for i in range(len(ds))])
print(all_prices.shape) # (10000, 253)
print(all_vars.shape) # (10000, 253)Cross-model comparison
All three benchmark datasets share the same schema and time grid:
bs = load_dataset("QuantScenarioBench/qsb-black-scholes", split="train")
h = load_dataset("QuantScenarioBench/qsb-heston", split="train")
rb = load_dataset("QuantScenarioBench/qsb-rough-bergomi", split="train")
import numpy as np
for name, ds in [("BS", bs), ("Heston", h), ("rBergomi", rb)]:
terminals = np.array([ds[i]["observation"][-1] for i in range(len(ds))])
print(f"{name:10s} mean={terminals.mean():.2f} std={terminals.std():.2f}")Generate a custom dataset
from quantscenariobench.api import simulate
from quantscenariobench.export import export_parquet, publish_to_hub
from quantscenariobench.interface import TimeGrid
from quantscenariobench.models import RoughBergomi
import jax.numpy as jnp
model = RoughBergomi(H=0.05, eta=2.0, rho=-0.8, xi0=0.04, S0=100.0, mu=0.0)
tg = TimeGrid(jnp.linspace(0.0, 2.0, 505)) # 2-year horizon
scenario = simulate(model, tg, n_paths=100_000, seed=99)
export_parquet([scenario], "my_rb_dataset.parquet")
# or: publish_to_hub([scenario], "my-org/my-rb-dataset")Reproducibility
Simulation paths are bit-identical across runs on the same computational backend when using the same seed, library_version, and model parameters.
Cross-backend bit-identity is not guaranteed. JAX floating-point operations may produce different bit patterns across hardware backends (CPU, GPU, TPU) even with identical inputs. The seed, prng_key_info, and library_version columns document full provenance so that any differences can be traced to backend changes rather than parameter or code drift.
Related Datasets
All three datasets use the same time grid, seed, and initial spot for direct cross-model comparison.
Citation
If you use this dataset or QuantScenarioBench in your research, please cite the GitHub repository.
