Metadata-Version: 2.4
Name: tca-channels
Version: 0.1.0
Summary: Transmission Channel Analysis (TCA) for SVAR / SVARMA / LP / DSGE models, with beautiful plots and tables. Import as `import tca`.
Author-email: Dr Merwan Roudane <merwanroudane920@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Dr Merwan Roudane <merwanroudane920@gmail.com>
        
        The TCA framework implemented here is due to Wegner, Lieb, Smeekes & Wilms
        (2024), "Transmission Channel Analysis in Dynamic Models", arXiv:2405.18987.
        The original MATLAB reference toolbox is by Enrico Wegner.
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/merwanroudane/tca
Project-URL: Source, https://github.com/merwanroudane/tca
Project-URL: Issues, https://github.com/merwanroudane/tca/issues
Keywords: transmission channel analysis,TCA,SVAR,DSGE,impulse response,macroeconometrics,causal inference,policy evaluation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23
Requires-Dist: scipy>=1.10
Requires-Dist: pandas>=1.5
Requires-Dist: matplotlib>=3.6
Provides-Extra: rich
Requires-Dist: rich>=13.0; extra == "rich"
Provides-Extra: networkx
Requires-Dist: networkx>=3.0; extra == "networkx"
Provides-Extra: all
Requires-Dist: rich>=13.0; extra == "all"
Requires-Dist: networkx>=3.0; extra == "all"
Requires-Dist: statsmodels>=0.14; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Dynamic: license-file

# TCA — Transmission Channel Analysis in Python

**TCA** is a Python library for **Transmission Channel Analysis** of
structural macro-econometric models. It is a careful Python port of the
MATLAB reference toolbox accompanying

> Wegner, Lieb, Smeekes & Wilms (2024). *Transmission Channel Analysis in
> Dynamic Models.* arXiv:2405.18987.

with first-class plotting and reporting helpers.

- **Author:** Dr Merwan Roudane — <merwanroudane920@gmail.com>
- **GitHub:** <https://github.com/merwanroudane/tca>

---

## What is TCA?

For a structural shock $\varepsilon_{i,t}$ and a target variable
$y_{j,t+h}$, the impulse response function (IRF) measures the **total**
dynamic causal effect of the shock. TCA decomposes that total effect into
**effects flowing through user-defined transmission channels**, where a
channel is defined either:

- **graphically**, as a subset of paths in the DAG induced by the
  systems-form representation $x = Bx + \Omega \varepsilon$, or
- **via potential outcomes**, as an assignment vector that turns some
  intermediate dependencies on or off.

TCA is fully compatible with traditional impulse-response analysis: it
needs only the structural identification of the shock of interest plus a
*transmission ordering* (a permutation of the variables encoded in the
**transmission matrix** $T$).

---

## Installation

```bash
pip install tca-channels
# Optional pretty terminals + DAG layouts:
pip install "tca-channels[all]"
```

Editable install for development:

```bash
git clone https://github.com/merwanroudane/tca
cd tca
pip install -e .[dev]
```

The distribution name on PyPI is **`tca-channels`**, but the Python package is imported as `tca`:

```python
import tca
from tca.models import SVAR
```

Pure-Python dependencies: `numpy`, `scipy`, `pandas`, `matplotlib`.
Optional: `rich` (coloured tables), `networkx` (alternative DAG layout),
`statsmodels` (alternative VAR estimators).

---

## Library map

| Module                  | What lives there                                                              |
|-------------------------|-------------------------------------------------------------------------------|
| `tca.q`                 | `Q` Boolean condition algebra; `make_condition`, `make_condition_y`           |
| `tca.transmission`      | `transmission`, `transmission_BOmega`, `transmission_irfs`, `through`, `not_through` |
| `tca.systems`           | `make_B`, `make_Omega`, `make_systems_form`, `to_transmission_irfs`           |
| `tca.models`            | `VAR`, `SVAR`, `LP`, `DSGE`, `Recursive`, `ExternalInstrument`, `InternalInstrument`  |
| `tca.viz`               | `plot_decomposition`, `plot_compare_decompositions`, `plot_irf_grid`, `plot_dag`, `plot_heatmap` |
| `tca.tables`            | `decomposition_table`, `channel_share_table`, `render_rich`, `style_dataframe` |

---

## Quick start

```python
import numpy as np, pandas as pd
from tca.models import SVAR, Recursive
from tca import transmission, through, not_through
from tca.systems import make_systems_form, to_transmission_irfs
from tca.viz import plot_decomposition, plot_dag
from tca.tables import decomposition_table, render_rich

# 1) Estimate a structural VAR (recursive / Cholesky identification).
data = pd.DataFrame(np.random.RandomState(0).randn(200, 3),
                    columns=["x", "pi", "i"])
m = SVAR(data, p=2, identification=Recursive()).fit()

# 2) Choose a transmission ordering (here: x -> pi -> i).
order = m.define_order(["x", "pi", "i"])

# 3) Build channels:
direct   = m.not_through("pi", horizons=[0], order=["x", "pi", "i"])
indirect = m.through    ("pi", horizons=[0], order=["x", "pi", "i"])

# 4) Compute total IRFs and channel decompositions.
H = 12
irfs    = m.irfs(H)                                # structural IRFs
B, Om   = make_systems_form(m.Phi0, m.var.coeff_lags(), [], order, H)

eff_dir = transmission(from_=1, arr1=B, arr2=Om, q=direct,   method="BOmega", order=order)
eff_ind = transmission(from_=1, arr1=B, arr2=Om, q=indirect, method="BOmega", order=order)

# 5) Pretty table + decomposition plot.
df = decomposition_table(idx_outcome=3, irfs_total=irfs,
                         channel_effects=[eff_dir, eff_ind],
                         channel_names=["Direct", "Indirect (via π)"])
render_rich(df, title="Demand shock → interest rate")

plot_decomposition(idx_outcome=3, irfs_total=irfs,
                   channel_effects=[eff_dir, eff_ind],
                   channel_names=["Direct", "Indirect (via π)"],
                   ylabel="Response of i").show()
```

---

## API at a glance

### Boolean conditions

```python
from tca import Q, make_condition

# Atomic variables follow systems-form ordering: x1 = first variable at horizon 0.
q = (Q(1) | Q(2)) & ~Q(3)
q = make_condition("(x1 | x2) & !x3")
```

### Channel builders

```python
from tca import through, not_through

order = [1, 2, 3]
contemporaneous = through(1, [0], order)            # paths through x_{1,0}
no_inflation    = not_through(2, range(0, 13), order)
combined        = through([1, 2], [0, 1], order)    # joint condition
```

### Engine

```python
from tca import transmission

# Systems-form method.
eff = transmission(from_=1, arr1=B, arr2=Omega, q=q, method="BOmega", order=order)

# IRF method (works with local projections).
eff = transmission(from_=1, arr1=irfs_T, arr2=ortho_T, q=q, method="irf", order=order)
```

`eff` is a 3-D array of shape `(K, 1, H+1)` when `order` is supplied.

### Models

```python
from tca.models import VAR, SVAR, LP, DSGE, Recursive, ExternalInstrument

VAR(data, p=4).fit_and_select(max_p=8, ic="aic")
SVAR(data, p=4, identification=Recursive()).fit()
SVAR(data, p=4, identification=ExternalInstrument(z, normalize_to=2)).fit()
LP(data, shock=z, max_horizon=20, n_lags=4).fit()

# DSGE: provide a *linearised* model in VARMA form, an ABCD state-space
# (Morris 2016 conversion is built in), or pre-extracted Dynare structs.
DSGE.from_varma(Phi0, As=[A1], Psis=[])
DSGE.from_state_space(A, B, C, D, Sigma_e=Sigma_e)
DSGE.from_dynare(M_, options_, oo_)
```

---

## Visualisations

`tca.viz` provides four chart families:

- `plot_decomposition` — stacked-bar decomposition of an IRF.
- `plot_compare_decompositions` — side-by-side comparison of two decompositions.
- `plot_irf_grid` — IRF panel with optional confidence bands.
- `plot_heatmap` — heatmap of `B` / `Omega` / `Phi`.
- `plot_dag` — DAG of the systems form across horizons.

A consistent `TCA_PALETTE` and `set_style()` helper keep plots
publication-ready.

---

## Tables

```python
from tca.tables import decomposition_table, channel_share_table, render_rich, style_dataframe

df = decomposition_table(2, irfs_total, [eff_dir, eff_ind], ["Direct", "Indirect"])
render_rich(df, title="Demand shock → inflation")        # coloured terminal table
style_dataframe(df, cmap="RdBu_r")                       # notebook / HTML / LaTeX
```

`render_rich` requires the optional `rich` dependency and falls back to
plain text otherwise.

---

## Citing

If you use this library, please cite both the original framework and this
implementation:

```bibtex
@article{wegner2024tca,
  title  = {Transmission Channel Analysis in Dynamic Models},
  author = {Wegner, Enrico and Lieb, Lenard and Smeekes, Stephan and Wilms, Ines},
  journal= {arXiv preprint arXiv:2405.18987},
  year   = {2024}
}

@misc{roudane2026tcapy,
  title  = {tca: Transmission Channel Analysis in Python},
  author = {Roudane, Merwan},
  year   = {2026},
  url    = {https://github.com/merwanroudane/tca}
}
```

---

## License

MIT — see [LICENSE](./LICENSE).
