Metadata-Version: 2.5
Name: camplet
Version: 1.0.0
Summary: CAMPLET seasonal adjustment: a transparent, adaptive method using arithmetic-progression updates.
Author: Abeln
Author-email: Herbert Kruitbosch <h.t.kruitbosch@rug.nl>
License: GPL-3.0-only
License-File: LICENSE
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Requires-Dist: pandas>=1.0
Provides-Extra: test
Requires-Dist: openpyxl; extra == 'test'
Requires-Dist: pytest; extra == 'test'
Requires-Dist: xlrd; extra == 'test'
Description-Content-Type: text/markdown

# camplet

A pure Python implementation of **CAMPLET**, a transparent, adaptive
seasonal adjustment method that corrects for seasonality and outliers via
arithmetic-progression updates, without model identification or
optimisation.

Ported from the original VBA macro (`D200603-CampletExcel-v4.2`,
`basCBFherzien.bas`) and validated against its own output (see
`tests/test_camplet.py`). A Java port for JDemetra+ v3 lives at
[jdplus-camplet](../jdplus-camplet); this package has no dependency on it or
on Java.

## Installation

```bash
pip install camplet  # once published; for now: pip install -e .
```

## Usage

```python
import pandas as pd
from camplet import camplet

idx = pd.date_range("2000-01-01", periods=144, freq="MS")
x = pd.Series(range(144), index=idx, dtype=float)

res = camplet(x)
print(res.accuracy)
print(res.to_frame().head())
```

`camplet()` is univariate: one series in, one result out. To adjust many
series, loop over them yourself (e.g. `df.groupby(...).apply(...)`) - the
same way you would with `statsmodels.tsa` decompositions.

The returned `CampletResult.data` has `raw`/`sa`/`seasonal` columns;
`.to_frame()` (diagnostics included by default) adds the per-period
adaptive-parameter trace that the original VBA tool wrote to its "Adj_"
worksheets (`ca`, `mu`, `pa`, `le`, `ti`, `expo_e`, `abs_pct_e`, `years`,
`weight`, `growth`).

## Input requirements

CAMPLET reads observations by position: the k-th value is taken to be the
period after the (k-1)-th. A skipped period therefore shifts every later
observation into the wrong season while still producing plausible-looking
output. To catch this, `camplet()`:

- **raises `ValueError`** if `x` contains `NaN`/`None`/`inf` (fill or trim
  the gaps first);
- **raises `ValueError`** if the Series' `DatetimeIndex`/`PeriodIndex` (or
  `dates`) has duplicated, out-of-order or irregularly spaced timestamps,
  e.g. a missing month;
- **warns** (`UserWarning`) if an explicit `periodicity` contradicts
  monthly or quarterly timestamps, e.g. `periodicity=4` on monthly data.

A plain list or array without timestamps can't be checked, so making sure
it has no gaps is up to you.
