Next-Hour Volatility Forecast

Forecast next-hour realized volatility from trailing returns

Pro

The dataset contains, for each of ten anonymous tokens, trailing one-minute log returns and trading volume observed at hourly forecast points. The task is to forecast each token's realized volatility over the following hour, computed from one-minute returns.

Training and test data are split chronologically with an embargo gap between them.

Prediction target

Realized volatility over the next hour

σ  =  k=1Mrk2,rk=ln ⁣(pkpk1)\sigma \;=\; \sqrt{\sum_{k=1}^{M} r_k^{2}}, \qquad r_k = \ln\!\left(\dfrac{p_k}{p_{k-1}}\right)

where r_1 ... r_M are the token's one-minute log returns over the next hour (about 60 of them) and p_k are its one-minute prices.

Scoring

Submissions are graded against the hidden holdout by root mean squared error in log space, lower is better:

RMSElog  =  1Ni=1N(lny^ilnyi)2\mathrm{RMSE}_{\log} \;=\; \sqrt{\dfrac{1}{N}\sum_{i=1}^{N}\left(\ln \hat{y}_i - \ln y_i\right)^2}

ŷᵢ is your predicted volatility and yᵢ the realized volatility for each of the N scored rows. Log space makes the error a ratio, so being off by a given factor costs the same whether volatility is high or low.

Data files

train.csv.gz and test.csv.gz. The test set has 21,432 rows; your submission must cover every test id exactly once.

Data dictionary

ColumnDescription
idOpaque row id. Your submission joins on this; row order does not matter.
window_startInteger minutes since the start of the data. The forecast is made at this moment; lag features end here.
window_endwindow_start + 60. The target is the realized volatility over this window. Group across time however you like; validate forward in time.
assetStable anonymous token id (0-9). The same asset keeps the same id across all rows.
lag_mA trailing one-minute log return of the token: lag_m covers the minute ending m minutes before window_start, so lag_m = ln( price at (window_start - (m-1) min) / price at (window_start - m min) ). The offsets m present in the header are dense for recent minutes and sparser further back; lag_1 is the most recent minute.
volume_mThe token's trading volume during the same minute that lag_m covers (base-asset volume of that one-minute bar), at the same offsets m as the return lags. Volume and volatility move together, so this is a useful predictor.
targetRealized volatility over the next hour, computed from 1-minute returns (train only).

Rules

  • 5 scored submissions per day (UTC).
  • Your submission is scored on a public split (shown to you) and a private split (used for ranking). Your leaderboard entry is the private score of your best public submission.
  • The board is always open. No deadlines, all-time rankings.
  • Target windows never overlap for the same asset, and the test range is strictly later than training with an embargo gap between them.

Getting started

import pandas as pd

train = pd.read_csv('train.csv.gz')
test = pd.read_csv('test.csv.gz')
lags = [c for c in train.columns if c.startswith('lag_')]
# Baseline: root mean of recent squared returns as the vol proxy
test['prediction'] = (test[lags[:12]] ** 2).mean(axis=1) ** 0.5
test[['id', 'prediction']].to_csv('submission.csv', index=False)