ACD Duration Models

Autoregressive Conditional Duration for inter-event timing analysis

Trade arrivals cluster: fast trades follow fast trades, quiet periods follow quiet periods. The Autoregressive Conditional Duration (ACD) model captures this pattern, letting you detect when trade intensity is abnormally high or low. Unusual acceleration in trade arrivals often signals informed trading activity.

API

python
acd = hz.AcdModel(
    omega=0.1,    # baseline duration component
    alpha=0.2,    # reaction to last duration surprise
    beta=0.7,     # persistence of expected duration
)

# Feed trade-to-trade durations (seconds between consecutive trades)
expected_duration = acd.update(duration)
# Returns: float -- the model's expected duration for the next trade

print(acd.expected_duration())   # current conditional expectation
print(acd.residual())            # last duration / expected_duration

Parameters

The ACD model follows the structure E[d_i] = omega + alpha * d_{i-1} + beta * E[d_{i-1}]:

ParameterRoleConstraint
omegaUnconditional baseline> 0
alphaSensitivity to last observed duration>= 0
betaPersistence of the expected duration>= 0
alpha + betaMust be less than 1 for stationaritySum under 1

Higher beta means the expected duration changes slowly. Higher alpha means it reacts sharply to the most recent trade.

Detecting informed trading

When trades arrive much faster than the model expects, someone may be acting on private information:

python
acd = hz.AcdModel(omega=0.5, alpha=0.15, beta=0.75)

for i in range(1, len(trade_times)):
    duration = trade_times[i] - trade_times[i - 1]
    expected = acd.update(duration)
    residual = duration / expected

    if residual < 0.3:
        # Trade arrived 3x faster than expected
        print(f"Abnormally fast trade at {trade_times[i]}")
        # Consider: widen spreads, reduce offered size, flag for review

Trade intensity as a feature

Use the ACD residual as a feature in your strategy — it measures whether the market is “hot” or “cold” relative to its own history:

python
acd = hz.AcdModel(omega=0.5, alpha=0.2, beta=0.7)

# In your strategy loop:
def on_trade(self, trade):
    duration = trade.timestamp - self.last_trade_time
    self.last_trade_time = trade.timestamp

    expected = self.acd.update(duration)
    intensity = expected / max(duration, 0.001)  # > 1 means faster than expected

    if intensity > 3.0:
        # Market is unusually active -- tighten quotes, reduce edge target
        pass
    elif intensity < 0.3:
        # Market is quiet -- widen quotes, increase edge target
        pass

When to use

  • Market making: adjust quote width and size based on trade intensity.
  • Informed trading detection: abnormally fast trade clusters suggest someone knows something.
  • Event monitoring: prediction markets often see trade acceleration before public information release.
  • Execution timing: submit orders during quiet periods (low intensity) for better fills.

Next