Skip to main content
Pro Feature. Requires a Pro or Ultra subscription. Get started at api.mathematicalcompany.com
What is this? ACD models predict how long until the next trade or event. Just like GARCH models volatility clustering (big moves follow big moves), ACD captures duration clustering (fast trades follow fast trades). Use it to detect unusual trading activity - if a trade arrives much sooner than expected, someone might have information.

ACD Duration Models

Horizon implements Autoregressive Conditional Duration (ACD) models from Engle and Russell (1998) for modeling the time between market events. ACD models capture the clustering of trade arrivals and provide real-time estimates of expected duration, surprise, and hazard rate. All computation runs in Rust via PyO3.

ACD(1,1) Model

Autoregressive conditional duration with GARCH-like dynamics for inter-event times.

Surprise Detection

Quantify how unexpected a trade arrival is relative to the fitted duration process.

Hazard Rate

Instantaneous probability of an event occurring given elapsed time since the last event.

Pipeline Integration

hz.duration_monitor() injects live duration state into your strategy context each cycle.

Why Duration Models?

Trade arrivals in prediction markets are not uniformly distributed. Activity clusters around news events, resolution deadlines, and whale entries. The ACD model captures this clustering by modeling the conditional expected duration between events as an autoregressive process: psi_i = omega + alpha * x_(i-1) + beta * psi_(i-1) where x_i is the observed duration and psi_i is the conditional expected duration. Short durations predict more short durations (clustering), and the model mean-reverts to omega / (1 - alpha - beta).
ACD models are the duration-domain analogue of GARCH models for volatility. Just as GARCH captures volatility clustering, ACD captures trade-arrival clustering. Together they provide a complete picture of market microstructure dynamics.

API

hz.AcdModel

Create an ACD(1,1) model with specified parameters.
Stationarity requires alpha + beta < 1. If this condition is violated, a ValueError is raised.

AcdModel Methods

update(event_time)

Feed a new event time into the model. Updates the internal state with the observed inter-event duration.
Returns an AcdState object.

expected_duration()

Return the current conditional expected duration (psi_i) given the model state.
Returns float.

surprise(duration)

Compute the surprise of an observed duration: x_i / psi_i. Values greater than 1.0 indicate the event arrived later than expected; values less than 1.0 indicate it arrived sooner.
Returns float.

hazard_rate(elapsed)

Estimate the instantaneous hazard rate given the time elapsed since the last event. Under the exponential ACD assumption, h(t) = 1 / psi_i (constant hazard), but the model adjusts for clustering effects.
Returns float.

AcdState Type

Returned by AcdModel.update().

Fitting from Data

hz.fit_acd

Estimate ACD(1,1) parameters from a series of event times using maximum likelihood.
Returns a fitted AcdModel.

hz.acd_log_likelihood

Compute the log-likelihood of an ACD(1,1) model given observed event times. Useful for model comparison and diagnostics.
Returns float: the log-likelihood value.

Pipeline Integration

hz.duration_monitor

Pipeline function that tracks inter-event durations in real time and injects ACD state into ctx.params["acd"].
The ctx.params["acd"] dict contains:

Mathematical Background

The ACD(1,1) model specifies the conditional expected duration as:psi_i = omega + alpha * x_(i-1) + beta * psi_(i-1)The unconditional mean duration is E[x] = omega / (1 - alpha - beta), which requires alpha + beta < 1 for stationarity.The standardized durations epsilon_i = x_i / psi_i are i.i.d. with unit mean under the model. Departures from this (surprise values far from 1.0) indicate model misspecification or regime changes.
Under the exponential ACD assumption, the log-likelihood is:L = sum(-log(psi_i) - x_i / psi_i)fit_acd maximizes this over (omega, alpha, beta) subject to omega > 0, alpha >= 0, beta >= 0, alpha + beta < 1. The optimizer uses bounded L-BFGS-B internally.
The hazard rate h(t) = f(t) / S(t) gives the instantaneous probability of an event at time t, conditional on no event having occurred since the last one. Under exponential ACD, the hazard is constant at 1/psi_i between events. A rising hazard over elapsed time suggests the next event is overdue.