sima
# sima — simultaneous VARMA on the ATSW ladder
**sima** is the MCP assistant for systems of time series: VARMA models by exact
maximum likelihood, built on the univariate models of each series, and, when
the series are cointegrated, the VARMA-VEC in levels. The engines are
[drvarma](https://pypi.org/project/drvarma/), whose ladder mode takes fue's
univariate files as input, and [drvec](https://pypi.org/project/drvec/), the
port of drvec C (Mauricio's VARMA-VEC by exact maximum likelihood), which takes
the same files. This package is the assistant: the protocol the model walks,
the evidence at each node, and the menu of decisions.
It is the third rung of the ATSW ladder:
art (one series) → mtram (transfer networks) → sima (systems)
You arrive at sima with several univariate models (`.pre` files from art or
fue), or from mtram when its network identification found a **cycle**: two
series that feed each other, which no transfer network can hold. sima takes
the same files.
## Install
```sh
pip install sima-tseries # from univariate models (.pre / .inp files); brings drvec
pip install "sima-tseries[raw]" # also from raw data: adds art-tseries, pandas, openpyxl
```
The raw entry (`load_data`, `characterize`, `build_univariate`, `write_specs`)
uses art's engine, so it needs the `raw` extra; so do the worked examples that
start from the data (`lutkepohl_poskitt`, `tiao_box`).
Register the server in your MCP client (the command is `sima`, stdio). The
binary wheels of drvarma carry the compiled likelihood the ladder needs. If
they are missing, drvarma warns and runs about 250 times slower. drvec's
wheels carry drvec C 0.13, which runs the long bootstraps (the rank test, the
IRF bands) 6-12 times faster than the port; the engine used is written in
every result.
## The protocol
| node | tool | what it answers |
|---|---|---|
| N0r–N0c | `load_data`, `characterize` | raw data: the table, and each series' λ, d and seasonality (art's engine) |
| N0u / N0v | `build_univariate` / `write_specs` | route U (the univariate models first) or route V (the vector first) |
| N0 | `load_pre` | the univariate models, the common window |
| N1 | `run_gate` | does the joint model reproduce the univariate ones? (it stops the analysis if not) |
| N1b | `canonical_analysis` | Box and Tiao's canonical analysis of the levels |
| N1c / C0 | `prepare_vec` | the cointegration question (two or more series with d = 1), the model's purpose, the VEC's specification and its checks |
| C1 | `rank_test`, `plot_rank_bootstrap` | the cointegration rank, by **parametric bootstrap** (a job); at small n, the rank at the neighbouring orders (`sweep` over p) |
| C2 | `estimate_vec` | the adopted VEC: the roles (normalisation), α, β, Π |
| C3–C4 | `test_restriction`, `add_exogenous` | restrictions on α, β and Γ by LR (who corrects; no feedback in the short run, the conditional model and the hand-over to mtram); exogenous inputs |
| C5 | `long_run` | θ, two half-lives, Gonzalo and Ng's permanent and transitory shocks |
| C6–C7 | `irf_bands`, `sweep` | the level responses' bootstrap bands; robustness (jobs) |
| C8 | `evaluate` | the yardstick for the VEC: a veto to forecast, a caveat for a long-run claim |
| — | `job_status`, `job_result`, `job_cancel`, `jobs` | the long jobs: detached, cached by content, they outlive the conversation |
| N2 | `identify_cross`, `identify_matrices`, `identify_echelon` | the cross dynamics: residual CCFs, Jenkins and Alavi's matrices, the Kronecker indices of the echelon form |
| N3–N4 | `estimate`, `check_residuals`, `simplify`, `structure` | a candidate and its LR, the checking, Tiao and Box's simplification, is it really simultaneous? |
| N4b | `study_estimation` | a fit on the MA invertibility wall |
| N5 | `evaluate`, `forecast_uncertainty` | **the yardstick**: does it forecast better than the univariates? |
| N6 | `forecast`, `impulse_response`, `variance_decomposition`, `reorder` | use of the chosen model (on a VEC: the levels; `reorder` refuses) |
| — | `plot_*` | the figures |
| — | `examples`, `load_example` | the worked examples |
| — | `record_decision`, `export_guion` | the record of the analysis |
| — | `split_inp` | out of drvarma's deprecated multivariate `.inp` |
The rules that shape everything:
- **The univariate model is the yardstick.** A VARMA that does not forecast
better than the univariate models out of sample has no reason to exist,
however significant its cross terms are in sample. For a VEC the comparison
is always made and reported: a veto when the model is to forecast, a caveat
beside a long-run claim (the purpose is recorded at N1c).
- **No cointegration claim without a finished bootstrap.** The rank is the
parametric bootstrap's; the asymptotic table is orientation only. A rank
adopted on theory is written in the guion as such.
- **Evidence and a menu, not a verdict.** The tools show the evidence and the
options with their arguments for and against. The analyst decides in the
guided lane, and the model decides, in writing, in the autonomous lane.
See [`docs/DESIGN.md`](https://github.com/davidesg/sima-python/blob/main/docs/DESIGN.md) and the generated tool reference
[`docs/TOOLS.md`](https://github.com/davidesg/sima-python/blob/main/docs/TOOLS.md).
## User manual
* [Jenkins and Alavi's method](https://github.com/davidesg/sima-python/blob/main/docs/MANUAL-jenkins-alavi.md): the method of
Jenkins and Alavi (1981), how sima implements it tool by tool, and their
muskrat-mink example worked through from art's univariate models — runnable
in [`examples/jenkins_alavi/`](https://github.com/davidesg/sima-python/tree/main/examples/jenkins_alavi/).
* [Tiao and Box's method](https://github.com/davidesg/sima-python/blob/main/docs/STUDY-tiao-box.md): the vector first, Tiao
and Box (1981) and Box and Tiao (1977): the stepwise M(l), the canonical
analysis of the levels, the structure and the simplification. Their gas
furnace is runnable in [`examples/tiao_box/`](https://github.com/davidesg/sima-python/tree/main/examples/tiao_box/), and the
flour prices in [`examples/flour_prices/`](https://github.com/davidesg/sima-python/tree/main/examples/flour_prices/).
* [Cointegrated systems](https://github.com/davidesg/sima-python/blob/main/docs/MANUAL-vec.md): the
cointegration question at N1c, the rank by parametric bootstrap, the VEC,
who corrects and the conditional model, the long run and the yardstick
(the study behind it: [`docs/STUDY-vec.md`](https://github.com/davidesg/sima-python/blob/main/docs/STUDY-vec.md); the plan:
[`docs/PLAN-vec.md`](https://github.com/davidesg/sima-python/blob/main/docs/PLAN-vec.md)).
Worked in [`examples/flour_prices/`](https://github.com/davidesg/sima-python/tree/main/examples/flour_prices/) (the flagship: where
the ladder's analysis leads into the rank), [`examples/jenkins_alavi/`](https://github.com/davidesg/sima-python/tree/main/examples/jenkins_alavi/)
(the mixed case) and [`examples/lutkepohl_e1/`](https://github.com/davidesg/sima-python/tree/main/examples/lutkepohl_e1/) (Lütkepohl's
E1: one relation, who corrects, an ill-defined fit declared) and
[`examples/johansen_juselius/`](https://github.com/davidesg/sima-python/tree/main/examples/johansen_juselius/) (the Danish money
demand: the bootstrap against the asymptotic table at n = 55) and
[`examples/martin_manjon_treadway/`](https://github.com/davidesg/sima-python/tree/main/examples/martin_manjon_treadway/)
(Martín Manjón and Treadway's two interest-rate trends, taken further than
the paper: the rank by bootstrap on 1985–2008, the Fed's target as the one
that corrects, no feedback and the conditional model). Each ships its
bootstraps' cache, so the tutorial's jobs return at once.
* [The echelon form](https://github.com/davidesg/sima-python/blob/main/docs/MANUAL-echelon.md): Lütkepohl and Poskitt's (1996)
identified VARMA: the Kronecker indices from the data (`identify_echelon`),
the fit (`estimate(indices=...)`), and their flour prices worked through,
runnable in [`examples/lutkepohl_poskitt/`](https://github.com/davidesg/sima-python/tree/main/examples/lutkepohl_poskitt/).
Each worked example runs node by node in a conversation with
`load_example(<name>)` (`examples` lists them).
## Licence
GPL-2.0-or-later. Authors: A.B. Treadway, J.A. Mauricio and D.E. Guerrero
(the engine); D.E. Guerrero (the assistant).
TDQS
Scored across 44 tools
The staged workflow gives most tools distinct roles, but several near-parallel tools are easy to confuse: load_data/load_pre/split_inp for entry, estimate/estimate_vec for model class, identify_cross/matrices/echelon for identification, and evaluate/forecast_uncertainty for comparison. The long, high-context descriptions help, but selection still depends on knowing the analyst's current route and model state.
Names are consistently snake_case with recognizable prefixes such as load_, plot_, identify_, and job_. The grammar varies between verb-only, noun-only, and verb_noun forms, but the convention remains readable and predictable overall.
Forty-four tools is very heavy for a single MCP server, even one modeling a full econometric workflow. Many tools map to legitimate stages, but the surface is large enough to overwhelm selection and orchestration without a higher-level workflow wrapper.
The surface covers the major lifecycle: raw/univariate entry, gating, identification, estimation, VEC analysis, forecasting, diagnostics, plotting, jobs, decisions, and export. Minor gaps remain around explicit session/model-state inspection and standalone handling of some implicitly parameterized actions such as set/adopt.