Skip to main content

Pure-Python multivariate Hawkes process simulation and MLE (exponential kernels), no C++ deps

Project description

phawkes

Pure-Python multivariate Hawkes processes with exponential kernels — simulation, MLE, and systemic-risk metrics. No C++ dependencies.

Why this exists

There is already an excellent Hawkes library: tick from École Polytechnique. We recommend it whenever it works for you.

However, as of Python 3.13, tick 0.8.0.1 builds but its Base metaclass breaks on instantiation of any learner class ('HawkesExpKern' object has no settable attribute 'events'). This is a known incompatibility with CPython 3.13's stricter descriptor protocol. The simulator side of tick still works; only the fitters fail.

phawkes fills the gap with a minimal, tested, pure-numpy + scipy implementation of the exponential-kernel multivariate Hawkes MLE. It is deliberately small — if you need sum-of-exponentials kernels, L1 / trace-norm regularization, EM for semi-parametric kernels, or GPU Riemannian fits, tick on Python ≤ 3.12 is still the better tool.

Install

pip install phawkes

Requires Python ≥ 3.9, numpy ≥ 1.23, scipy ≥ 1.10.

Quickstart

import numpy as np
from phawkes import HawkesExpSim, HawkesExpMLE, branching_ratio

true_mu = np.array([0.3, 0.2])
true_alpha = np.array([[0.2, 0.1], [0.3, 0.15]])
beta = 1.0

# simulate a realization on [0, 4000]
sim = HawkesExpSim(baseline=true_mu, adjacency=true_alpha, decay=beta, seed=7)
events = sim.simulate(end_time=4000.0)

# fit by MLE
learner = HawkesExpMLE(decay=beta).fit(events, end_time=4000.0)
print(learner.baseline_)        # ~ true_mu
print(learner.adjacency_)       # ~ true_alpha
print(learner.branching_ratio())  # spectral radius of fitted alpha

The math (1-minute version)

A multivariate exponential-kernel Hawkes process with shared decay β has conditional intensity

$$ \lambda_i(t) = \mu_i + \sum_j \sum_{t_j^k < t} \alpha_{ij}, \beta, e^{-\beta (t - t_j^k)} $$

  • μᵢ ≥ 0 is the baseline (background) rate on dim i
  • αᵢⱼ ≥ 0 is the branching coefficient from dim j to dim i
  • β > 0 controls how fast past events' excitation decays

Stability (finite expected event count per unit time) requires the spectral radius of α — the branching ratio λ_max(α) — to be strictly less than 1. As it approaches 1, a single shock can cascade through many downstream events; this is the quantitative signature of near-critical contagion in finance and epidemics.

Log-likelihood on the window [0, T]:

$$ \ell = \sum_i \left[\sum_k \log \lambda_i(t_i^k)\right] - \sum_i \int_0^T \lambda_i(t), dt $$

For exponential kernels the integral is closed-form, and the sum of log-intensities admits Ogata's 1981 recursion for O(N) total evaluation. phawkes.HawkesExpMLE implements this, parameterises μ = exp(log_μ) and α = exp(log_α) for strict positivity, optimises by L-BFGS-B with analytic gradients, and optionally ridges log_α.

Per-regime fitting

Pooling Hawkes events across different market regimes creates spurious criticality — the MLE interprets regime shifts as endogenous self-excitation and inflates the branching ratio. fit_per_regime slices event streams by labelled time intervals and fits a separate MLE per label:

from phawkes import RegimeSegment, fit_per_regime

segments = [
    RegimeSegment(0.0,    500.0, "calm"),
    RegimeSegment(500.0,  700.0, "crisis"),
    RegimeSegment(700.0, 1000.0, "calm"),
]
fits = fit_per_regime(events, segments, decay=1.0)
fits["calm"].branching_ratio()     # e.g. 0.3
fits["crisis"].branching_ratio()   # e.g. 0.85 — near-critical

Roadmap

v0.1 (this release):

  • Exponential-kernel multivariate Hawkes MLE with shared decay
  • Ogata-thinning simulator
  • Per-regime convenience wrapper
  • Branching-ratio utility
  • Unit-tested against simulator ground truth on 2-dim and 5-dim problems

v0.2+ (planned):

  • Sum-of-exponentials kernels (richer temporal structure)
  • L1 / trace-norm regularization (Bacry et al. 2020, JMLR)
  • Per-edge decay βᵢⱼ (currently shared)
  • Cross-validation for choosing β
  • Benchmark parity with tick on Python 3.12

Authors

  • Pierre Samson (@darw007d) — idea, use-case, design decisions
  • Claude Opus (Anthropic) — implementation and tests

Originally motivated by the OMEGA Swarm hedge-fund project, where regime-stratified Hawkes calibration replaces a heuristic 5% per cycle edge-decay in a live contagion network. The library is deliberately agnostic of that use-case.

Contributing

Issues and PRs welcome. We care about:

  • Numerical correctness (every new fitter needs a simulator-recovery test)
  • Zero heavy dependencies (no C++, no tensorflow / torch)
  • Honest documentation — if something is slow or unstable, say so

Citations

If phawkes contributes to a published result, please cite the foundational references alongside this library:

  • Hawkes, A.G. (1971). Spectra of some self-exciting and mutually exciting point processes. Biometrika.
  • Ogata, Y. (1981). On Lewis' simulation method for point processes. IEEE Trans. Inform. Theory.
  • Laub, P.J., Taimre, T. & Pollett, P.K. (2015). Hawkes Processes. arXiv:1507.02822.
  • Bacry, E., Bompaire, M., Gaïffas, S. & Muzy, J.-F. (2020). Sparse and low-rank multivariate Hawkes processes. JMLR.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

phawkes-0.1.0.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

phawkes-0.1.0-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file phawkes-0.1.0.tar.gz.

File metadata

  • Download URL: phawkes-0.1.0.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for phawkes-0.1.0.tar.gz
Algorithm Hash digest
SHA256 58ba119d048b4217092cb3f4ebfa4da9fce580ed4b4fc177c2b4fcf3c5662f16
MD5 2afbf402031e814c6bf6cc5a84b1734e
BLAKE2b-256 dd7b28532427004d845172d3803156413bccb759f91b62d50a5b25e0310bce5b

See more details on using hashes here.

File details

Details for the file phawkes-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: phawkes-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for phawkes-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e9585b025a5020bd480075e252d4fc294ef7ab401922a47b25ef29751edb5337
MD5 03bde24034e5bd2fce72863b9ef8aab5
BLAKE2b-256 4a5e2b4f5979dc619c05c0e8620fa614ad9bf41524830255b5f355fc69d566ac

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page