Skip to main content

cfad — Characteristic Function Anomaly Detector

License: MIT CI PyPI version

cfad is research software for studying distributional change in financial return series with empirical characteristic functions (ECFs). It turns rolling ECF discrepancies into shape-sensitive anomaly scores, supports sequential Page-CUSUM monitoring, and includes model-comparison, goodness-of-fit, backtesting, bootstrap, sensitivity, notebook, dashboard, and benchmark workflows for reproducible experimentation.

The project is aimed at methodological research and validation rather than turnkey production trading signals. Its benchmarks explicitly preserve negative results and document where the current ECF score does, and does not, outperform simpler distributional summaries.

For each rolling window, CFAD compares the empirical characteristic function with the Gaussian characteristic function fitted to that window's sample mean and variance. The normalized real-frequency discrepancy is the anomaly score:

$$ D_t = \left[ \frac{1}{\xi_{\max}-\xi_{\min}} \int_{\xi_{\min}}^{\xi_{\max}} \left| \widehat\varphi_t(\xi)

\varphi_{\mathcal N(\widehat\mu_t,\widehat\sigma_t^2)}(\xi) \right|^2 ,d\xi \right]^{1/2}. $$

Because location and scale are fitted within each window, the score is aimed at higher-order shape changes such as tail and skewness changes. A two-sided Page-CUSUM then converts the score sequence into sequential alarms.

Scientific scope. The finite-sample ECF $\widehat\varphi_n(z)=n^{-1}\sum_j e^{izx_j}$ is a finite sum of entire functions and is itself entire. Therefore its exact closed-contour integral is zero. CFAD does not infer population-CF branch cuts or poles from an empirical contour residue. Complex contour integration remains available as a diagnostic helper for parametric characteristic functions evaluated at complex arguments, but it is not the empirical anomaly statistic.


Status

The repository is currently a research/development project. Version 0.2.2 is the first verified public release available both as a GitHub Release and on PyPI. PyPI publication uses GitHub Actions OpenID Connect (OIDC) trusted publishing rather than a long-lived API token.

Current validation boundary

Two frozen validation programmes have now tested the corrected method rather than the retired contour-residue interpretation.

The v2 sequential benchmark showed that Monte Carlo calibration can control the Gaussian-null false-alarm rate, but the Gaussian-reference score was not robust to a stable Student-t in-control law and had weak first-alarm power once false alarms were controlled. The v3 score-level ablation then removed CUSUM and separated frequency scaling from reference-law choice. Standardizing each window corrected the legacy score's sensitivity to pure variance changes, and a frozen empirical in-control ECF produced strong null-law stability. However, the empirical-reference score achieved AUC 0.646 for a Gaussian-to-Student-t shape change and 0.783 for a Gaussian-to-skew change, for an average of 0.715 versus 0.738 for a simple kurtosis-distance comparator.

Accordingly, the current evidence does not establish that CFAD is a validated sequential detector or that its ECF score outperforms simpler moment summaries. The negative v2 and v3 results are retained as reproducible evidence in benchmarks/ and are treated as design constraints rather than tuned away.

Installation

From PyPI:

python -m pip install cfad

For development from the default branch:

git clone https://github.com/DiogoRibeiro7/cfad
cd cfad
git switch main
python -m pip install -e ".[dev]" --no-build-isolation

The package includes optional Cython acceleration for rolling ECF evaluation and CUSUM updates. The statistical score itself is implemented once in NumPy, so installing the extensions changes performance rather than the definition of the statistic.

Quick start

import numpy as np
from cfad import detect

rng = np.random.default_rng(42)
returns = np.concatenate(
    [
        rng.normal(0.0, 0.01, 300),
        rng.standard_t(df=3.0, size=150) * 0.01 / np.sqrt(3.0),
    ]
)

report = detect(
    returns,
    window=60,
    xi_range=(-10.0, 10.0),
    step=1,
    calibration_frac=0.4,
    k=0.5,
    h=5.0,
)
print(report.summary())

For market data, fetch the series explicitly with the provider of your choice, then pass returns to detect. Keeping data acquisition outside the core example makes the detector reproducible without relying on network access.

Detection pipeline

returns
  │
  ├─ rolling ECF on a real-frequency grid
  │
  ├─ fitted Gaussian CF in each window
  │
  ├─ normalized ECF L2 shape distance D_t
  │
  ├─ calibration of score mean/std on an in-control prefix
  │
  └─ two-sided Page-CUSUM → alarms

Parametric CF models

CFAD also implements characteristic-function models for descriptive model comparison and goodness-of-fit work:

Model Main use
GaussianCF location/scale baseline
NIGCF semi-heavy tails and skewness
CGMYCF jump/tail-shape modelling
LevyStableCF power-law tail modelling

compare_models() compares fitted models by real-frequency ECF discrepancy and AIC. A better-fitting non-Gaussian model is evidence of distributional fit, not a direct empirical test for complex singularities.

Utilities

The repository includes:

  • rolling_gof, cf_distance, and epps_pulley_test for ECF goodness of fit;
  • WalkForwardBacktest for temporal evaluation;
  • bootstrap and score-stability diagnostics;
  • window_sensitivity, frequency_sensitivity, and threshold sensitivity;
  • multivariate and market-oriented helpers;
  • a Streamlit dashboard under apps/;
  • reproducible notebooks and benchmark scripts.

Reproducibility

The main scientific validation target is not "does an alarm fire on one famous market event?" but how the detector behaves under controlled null and alternative data-generating processes. The benchmark layer reports false-positive behaviour, power/discrimination under prespecified shape changes, specificity to location/scale changes, and comparison against simpler baselines.

Frozen failed experiments are part of the evidence record. In particular, benchmarks/v2_failed_calibration_record.json records the failed sequential screen and benchmarks/v3_failed_score_validation_record.json records the failed score-level screen. Those failures are not retroactively reclassified after parameter or method changes.

Documentation and paper

The manuscript is a draft companion to the software. Citation metadata should only advertise a journal DOI after an actual accepted/published record exists.

Author

Diogo Ribeiro
Faculty of Media Arts and Design, Technical University of Porto
ORCID: 0009-0001-2022-7072

License

MIT

Metadata

Release files for cfad 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cfad 0.2.3
File Size Uploaded
cfad-0.2.3.tar.gz 224.6 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for cfad 0.2.3
File
cfad-0.2.3-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
cfad-0.2.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.5+ x86-64, Linux glibc 2.28+ x86-64 Details
cfad-0.2.3-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
cfad-0.2.3-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
cfad-0.2.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64, Linux glibc 2.5+ x86-64 Details
cfad-0.2.3-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
cfad-0.2.3-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
cfad-0.2.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64, Linux glibc 2.5+ x86-64 Details
cfad-0.2.3-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details

Total release size: 3.4 MB

Release files / cfad-0.2.3.tar.gz

Download URL cfad-0.2.3.tar.gz
Size 224.6 kB
Tags Source
SHA-256 checksum
How to use checksums
dfb765e5bc4c19f2329ad7320f0d5777f733dbece872802d0be5fc1fa6494156
BLAKE2b-256 checksum
How to use checksums
950f0a292e4cd7bcf4ed45b6806046fb6f8a17d9ed5f4e7608e1f3da99b41ba4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp312-cp312-win_amd64.whl

Download URL cfad-0.2.3-cp312-cp312-win_amd64.whl
Size 279.7 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
4eea88a087a507a16db63aa3721e61bdec13cc306511965d6c682d22d55b089b
BLAKE2b-256 checksum
How to use checksums
706a7f03158745330db7a79d7c9748ff88e495f976fd1dcc1db6f4ae80da0f2e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL cfad-0.2.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 541.9 kB
Tags CPython 3.12 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64
SHA-256 checksum
How to use checksums
bf0404527ca454a12c42872adfde96eaed11e226c4aab8da7afa0304e2a67b6f
BLAKE2b-256 checksum
How to use checksums
4aa4aa0a5121073bbab3c944721fedf1734686c63e3f9cad483141d0a8f2f531
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp312-cp312-macosx_11_0_arm64.whl

Download URL cfad-0.2.3-cp312-cp312-macosx_11_0_arm64.whl
Size 279.4 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
69271c7816724d9ed8cfb39cf9cce272e554cb18c332ed92b8a4e6c255b79b01
BLAKE2b-256 checksum
How to use checksums
0d81c141f72dfc59908283bb00a89dde72862d4424fe21123930e59eda4685ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp311-cp311-win_amd64.whl

Download URL cfad-0.2.3-cp311-cp311-win_amd64.whl
Size 276.7 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
fd609f201e5c1eb03e77453cff07a946c23b186cf52d7fb2334eff863c6d5522
BLAKE2b-256 checksum
How to use checksums
d23c8004d69d90dfdebf642b48a2974129bcedd04b2c41f7f0cc1af47c1c633e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL cfad-0.2.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 505.2 kB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64
SHA-256 checksum
How to use checksums
1b6d64ae97f2639236c11c7e7c2b3cdfd04e8c7788c586cdd3be03289362db64
BLAKE2b-256 checksum
How to use checksums
f72d4ebc49c2225309b2953b36e48516732dcab79a8a91267bdf06665d00eea0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp311-cp311-macosx_11_0_arm64.whl

Download URL cfad-0.2.3-cp311-cp311-macosx_11_0_arm64.whl
Size 276.7 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0cc7ae12cb9b204ed5583cbbe9ba98e569f674a3b7744c32f43fcecc9ff50b1e
BLAKE2b-256 checksum
How to use checksums
63203284e199c06bf52b329ed9139222a187dfe632dbc88ae5b62decee555a78
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp310-cp310-win_amd64.whl

Download URL cfad-0.2.3-cp310-cp310-win_amd64.whl
Size 277.7 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
ec170d9cae519f8779131346b4aee5dd92afa8a8bd30f2fbba525fa9a292893c
BLAKE2b-256 checksum
How to use checksums
c17ed27a16a167629d47fad4aa58a353f26fb719de943dd58d6b546175880783
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL cfad-0.2.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 499.9 kB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64
SHA-256 checksum
How to use checksums
d46b0ba631497141cd533bc7542df8ccd7eada8b7ac8ca94e47e68e4ed24df94
BLAKE2b-256 checksum
How to use checksums
edef8ee7809a2104f194eb8903cdf19d845afd28c5514541889151f72a04fe52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / cfad-0.2.3-cp310-cp310-macosx_11_0_arm64.whl

Download URL cfad-0.2.3-cp310-cp310-macosx_11_0_arm64.whl
Size 278.1 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
49ccbed221def626c9246e94b69d6aca1059838ef41c9fe304df51e6e92a1935
BLAKE2b-256 checksum
How to use checksums
1729b48c86a67d3c3233f1e2b6f0207f7f0dd0177f40747602299dcb7e4c448a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.3 This release

10 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page