⌘Ctrlk
  1. Competitions
  2. Competitions

ADIA Lab Structural Break Challenge: Real Time Edition

Monitor time series in real time and detect when their behaviour changes.

Overview

Detecting structural changes in time series data in real time is a critical task across various scientific and engineering domains. In this competition, you monitor a stream of univariate time series data one observation at a time and, after each new observation, report how confident you are that a structural break has already occurred somewhere in the online segment up to and including the current step.

Problem Statement

The task of this competition is to monitor a univariate time series in real time and, at each new observation, quantify whether a permanent structural break has already occurred somewhere up to that point.

Each series is comprised of a long historical segment (1,000 to 5,000 observations, with no break), and an online segment (10 to 1,000 observations, possibly with a structural break).

The observations in this online segment are revealed one at a time: after each of them, your detection algorithm must output a score between 0 and 1, reflecting cumulative confidence that a structural break has already occurred - 0 if absolutely confident no break has occurred, 1 if absolutely confident a break has already occurred.

The training data (with known structural break locations) combines a large collection of synthetic and real-world time series exhibiting a wide variety of break types - including changes in mean, variance, distributional shape, and dependence structure.

Submissions are evaluated on an independent test set using the Time-Stratified AUC (TS-AUC): at each online time step, a standard AUC is computed cross-sectionally across all series, and the weighted average over time steps is the final score.

Differences from the 2025 Edition

If you participated in the 2025 edition, the core concept is the same, but the mechanics are fundamentally different:

Data delivery

Both segments given at once

Online segment arrives one step at a time

Break location

Always at the known boundary

Unknown -- anywhere in the online segment

Output

One score per series

One score per time step

This edition mirrors a realistic monitoring scenario: you watch a stream of data and, after each new observation, you report how confident you are that the process has already changed.

Competition Timeline

  • Start Date: May 6th, 2026 at 4:00 p.m. UTC

  • Quota Refresh: every Wednesday at 4:00 p.m. UTC

  • End Date: September 17th, 2026 at 4:00 p.m. UTC (Thursday)

  • Final Evaluation: End of October, 2026

What is a Structural Break?

A structural break occurs when the statistical behaviour of a time series changes permanently at some point in time. Before the break, the data follows one process; from the break onwards, it follows a different one.

The figure below shows a simple example: the series has a constant mean before the break and a different mean after it. The dashed line marks the break time.

Example: a time series with a structural break. The dashed line marks the break.
Example: a time series with a structural break.

Structural breaks appear in many domains:

  • Climatology: shifts in weather patterns that may signal climate anomalies or long-term change.

  • Industry: changes in machinery sensor readings that anticipate equipment failures or maintenance needs.

  • Healthcare: sudden changes in physiological signals that may indicate critical health events.

  • Finance: shifts in market or strategy behaviour relevant to risk management and portfolio decisions.

Dataset

The dataset contains a large and diverse collection of univariate time series exhibiting many different kinds of structural breaks -- changes in mean, variance, distribution shape, correlation structure, and more. All series are pre-processed into a common z-scored format.

Each series is split into two parts, a historical segment and an online segment.

Time series structure: historical segment (blue), online segment before the break (green), online segment after the break (red). The dashed vertical lines mark the start of the online segment and the break position.
Time series structure

Historical segment

The historical segment is a long reference sequence provided to you in full at the start, typically between 1,000 and 5,000 observations. It represents the behaviour of the series before any potential break.

Online segment

The online segment follows the historical segment and is revealed to you one observation at a time, typically between 10 and 1,000 observations long.

After you submit your score for the current observation, the next one is released. There is no way to look ahead.

Each series contains at most one structural break, and the historical segment is always break-free.

Any break, if present, falls somewhere within the online segment:

  • With probability 0.5, a break occurs at some unknown point within the online segment. You must infer its position from the data.

  • With probability 0.5, no break occurs during the online segment at all.

Break position

For the training set only, the break position tau is a 0-indexed position within the online segment at which the break occurs, or None if no break occurs.

Data Size

The dataset is divided into multiple parts:

Public training set

Local & Cloud

10,000

Public (reduced) test set

Local

100

Public test set

Cloud

10,000

Private test set

Cloud

10,000

True values are only available for the training set (both locally and in the cloud) and the reduced test set (only locally).

Scoring

The competition uses a single metric: Time-Stratified AUC (TS-AUC).

At each online time step ttt, the metric computes a standard AUC cross-sectionally across all series alive at that step:

  • A series is positive at step ttt, if the break has already occurred by that step (ideal score = 1).

  • A series is negative at step ttt, otherwise (ideal score = 0).

The TS-AUC is the weighted average of these per-step AUCs, with weight w(t)=npos(t)⋅nneg(t)w(t) = n_\text{pos}(t) \cdot n_\text{neg}(t)w(t)=npos​(t)⋅nneg​(t) (the number of positive-negative pairs at step ttt):

TS-AUC=∑tw(t) AUC(t)∑tw(t)\text{TS-AUC} = \frac{\sum_t w(t)\,\text{AUC}(t)}{\sum_t w(t)}TS-AUC=∑t​w(t)∑t​w(t)AUC(t)​
  • 0.5: equivalent to random guessing. To score above 0.5, a predictor must use the content of the series: at every fixed ttt, the metric compares series against each other, so a score that does not depend on the series cannot discriminate.

  • 1.0: perfect detection.

Code Submission

This is a code competition where participants are required to submit their Python code (files or notebooks) directly to the Crunch Hub.

Your submission should:

  1. Process and analyze the data;

  2. Output a score between 0 and 1 for each time series steps in the test set, representing the likelihood of a structural break;

  3. Your code must produce deterministic output, or it will be ineligible for any rewards;

Your submitted code will be executed on the platform and automatically scored against a portion of the test set. Shortly after submission, your score will appear on the public leaderboard of the competition.

Visual animation.

Interface

At each new online observation, produce a score between 0 and 1 representing your cumulative confidence that a structural break has already occurred somewhere in the online segment up to and including the current step:

  • 0: no break detected so far.

  • 1: a break has definitely already occurred.

You produce one score per time step, so for a series with an online segment of length T you output T scores.

There are a few constraints on the data that will stop your code if you try to ignore them:

  • You must provide your result before you can get the next point from x_online.

  • The online segment cannot be read twice.

  • You must yield at each point.

Rely on the testing tool to make sure your code is working as intended locally.

Requirements

Your solution must include two functions:

  • infer(): to returns predictions on the test set.

The execution time of your solution should not exceed the platform's time limits: 15 hours per week.

Your solution must be deterministic: when re-run on 10% of the data, the predicted values should be the same (within a tolerance of 1e-8).

What a good score sequence looks like

The ideal score is a step function: it stays at 0 as long as no break has occurred, then jumps to 1 as soon as the break happens. If there is no break, the ideal score is 0 throughout.

The figure below shows how your detection algorithm's score sequence (solid line) compares to the ideal sequence (dashed step). The shaded area between them reflects how early and how cleanly the break was detected.

Evaluation example: participant scores (solid) vs ideal step function (dashed). A good submission keeps the shaded area small.
Evaluation example

Computational note

With 10,000 series and up to 1,000 online steps each, solutions that recompute everything from scratch at every step may run into time budget constraints.

Incremental approaches, which are maintaining a compact running state and updating it with each new observation, are worth considering for efficiency, though any solution that fits within the time budget is acceptable.

Parallelism

Infering so many points can be slow. That is why we offer a parallel approach, but only at the time series level. Your model must still process each point separately.

Depending on your model's capacity, the dataset will be split into n equal parts. Your model will start n times in different processes (not threads), and each process will receive and fully process one part.

How to use it

To ensure optimal performance, your model must follow a few restrictions:

  • Because of the concurrency, your model should avoid writing any files.

  • Make sure the cloud environment can handle the RAM and CPU consumption of your model.

    • If you want 6 processes and your model consumes 4 GB of RAM, the runtime must have 4 * 6 = 12 GB of RAM plus some overhead.

    • The same applies to CPU cores. Overallocation can actually decrease performance.

You can enable parallel processing by simply specifying the number of workers you want via a global constant:

The @crunch/keep:on command is only required for notebook users to prevent the line from being commented out. Keep the constant in a dedicated cell, or add @crunch/keep:off after the assignation.

Known issues

  1. Exceptions and Crashes: When using multiple processes that all print to a single terminal, it is expected that lines will mix with each other. This makes errors harder to debug, as traces cannot be printed properly. We have made sure to report the first error trace, but subsequent errors will be ignored.

  2. CPU over-allocation: NumPy uses OpenBLAS behind the scenes to try to parallelize some computations which could potentially conflict with the parallelism mechanism. To help resolve this issue, we recommend using threadpoolctl at the correct location(s).

Methodology Suggestions

  • Statistical tests comparing the distribution of the historical segment to the online observations seen so far (t-tests, KS tests, CUSUM).

  • Change-point detection algorithms designed for online or streaming data.

  • Feature extraction summarising the online window incrementally, fed into a trained classifier.

  • Probabilistic and Bayesian models tracking the likelihood of a change sequentially.

  • Deep learning models trained to score (series, time step) pairs using the labeled training data.

  • Foundation models for time series pre-trained on large corpora, used as feature extractors or fine-tuned on the labeled training data.

Whatever approach you choose, the training set provides full supervision: the known break positions let you construct labeled (series, time step) pairs and apply standard binary classification training.

Prizes

All prizes are in USDC, a cryptocurrency with the same value as the US dollar.

1st place

$40,000

2nd place

$20,000

3rd place

$10,000

4th place

$5,000

5th place

$5,000

6th place

$5,000

7th place

$5,000

8th place

$3,500

9th place

$3,500

10th place

$3,000

FAQ

What data is used to compute the mean and standard deviation for standardizing each series?

Only the historical (reference) segment, not the online period or the full series.

Is standardization done separately for each series?

Yes, each series is standardized independently.

Are the normalization parameters (mean/std) updated once the online period starts?

No. They are fixed before the online stream begins and never updated afterward.

Are real and synthetic series normalized the same way?

Yes, Both go through the same standardization pipeline.

Is the reference window assumed to be free of structural breaks or irregularities?

Yes and no: there are no structural breaks by definition (the reference window defines what is "normal"), but there can be irregularities (jumps, etc.).

Can I use an AI assistant or LLM to help with the competition?

Yes, as long as you don't copy the full dataset into its context.

Last updated 11 days ago

Was this helpful?

Was this helpful?

def infer(
    datasets: Iterable[Tuple[List[float], Iterable[float]]],
    model_directory_path: str,
):
    """
    Load your trained model, then use the `yield` keyword to indicate that it is ready.
    Then iterate over the datasets and points to provide a result using `yield <prediction>`.

    Args:
        datasets: the data object to iterate.
        model_directory_path: the path to the directory where you model has been saved in the train function.
    """

    model = joblib.load(os.path.join(model_directory_path, 'model.joblib'))

    # Mark as ready
    yield

    for x_historical, x_online in datasets:
        for point in x_online:

            # Consume the point (float)
            result = model.consume(point)

            # Provide your result, one at a time
            yield result
# @crunch/keep:on
INFER_PARALLELISM = 4