Metadata-Version: 2.5
Name: praxis-358063
Version: 0.1.0
Summary: Praxis reproduction of paper 358063 (dynamic momentum learning, Levy & Lopes 2021). Historical statistics only; see README.md and run.py.
Project-URL: Audit, https://market-graphs.com/praxis/papers/358063
Project-URL: Paper, https://arxiv.org/abs/2106.08420
Project-URL: Praxis, https://market-graphs.com/praxis
License: PRAXIS REPRODUCTION LICENCE — public release
        
        Licensor   MarketGraphs (Aleksei Fedotenkov, United Kingdom) · https://market-graphs.com/praxis
        Package    praxis-358063 — our reproduction of paper 358063 (Levy & Lopes 2021, arXiv 2106.08420)
        
        1. Grant. A perpetual, non-exclusive, non-transferable licence to use this
           reproduction internally: to read, run, modify and extend it, and to use it
           and its outputs in your own research and trading, including live trading,
           within your organisation.
        
        2. No redistribution. The files, in whole or in part, modified or not, may not
           be republished, sold, sublicensed, hosted, or built into a product or
           service for others. Results and conclusions are yours to share; the files
           are not. One organisation per licence.
        
        3. Ownership. The code and text remain the copyright of MarketGraphs. No price
           data ships in this package; data the code fetches stays under its source's
           own terms (Yahoo Finance: personal use).
        
        4. No advice. This is a historical reproduction of a published result. Nothing
           in it is investment advice, a signal, or a recommendation.
        
        5. No warranty. Provided as is; the licensor is not liable for any loss arising
           from its use.
License-File: LICENSE
Keywords: momentum,praxis,quantitative-finance,reproduction,systematic-trading
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Requires-Dist: numpy<3,>=1.26
Requires-Dist: pandas<3,>=2.0
Requires-Dist: pyarrow<25,>=15
Requires-Dist: yfinance==0.2.65
Description-Content-Type: text/markdown

# Trend-Following Strategies via Dynamic Momentum Learning (2021) — Praxis reproduction

Bruno P. C. Levy & Hedibert F. Lopes, [arXiv 2106.08420](https://arxiv.org/abs/2106.08420).
**Verdict: OVERSTATED.** The report: https://market-graphs.com/praxis/papers/358063

**The claim.** Replace the naive time-series-momentum sign rule with a dynamic-logistic
classifier — 127 models, one per subset of momentum look-backs (1–12 months), reweighted
each month by predictive record (DMA/DMS) — and a diversified futures book goes from
Sharpe 0.81 to 1.23 net of costs.

**What we measured.** On the public panel the lift is +274bp/yr at t = 0.85, never
significant, and negative since publication (0.42 vs the naive rule's 0.60). The
mechanics replicate, including the 2009 momentum-crash escape almost to the number.

## Run it

Python 3.10 or newer. In a terminal, in this folder:

    python3 -m venv .venv
    source .venv/bin/activate          (Windows: .venv\Scripts\activate)
    pip install -r requirements.txt
    python run.py

It prints claimed vs measured as JSON, then checks every number against the report:
all match to the decimal, or it names the ones that moved. About a minute. Next time,
only the second and fourth lines.

    python run.py --frozen           the frozen panel, once rebuilt with scripts/freeze_fixtures.py
    python run.py --end 2020-09-30   the paper's own sample only
    python run.py --cost-scale 2     double the cost estimates

Any end date after 2026-06-30 is refused. This is a historical reproduction: it produces
no current signal, weight, position or order, connects to no broker, sends nothing anywhere.

**What this is, and is not.** This reproduces the strategy's published result, our C0–C1:
the paper rebuilt faithfully, with point-in-time signals, real costs and roll legs. The
C2–C7 gates (deflated Sharpe, multiple-testing, period robustness, generalisation,
capacity, post-publication decay, the factor-zoo comparison) run in our engine; their
results are on the report page, their code is not in this package.

## The data

One object, the **monthly close panel**: month-end closes of 39 futures, Yahoo
front-month continuous chains (`CL=F`, `GC=F`, `6E=F`, …), October 1997 to June 2026,
roll-unadjusted, NaN for gaps, a series ends when a contract dies (lumber, 2023-05).

- `src/praxis_358063/data/public.py` — the Yahoo loader. `run.py` and the CLI fetch the chains on
  your machine; no price data ships in this package (Yahoo's terms allow personal use, not
  redistribution). A mutable source: numbers move as Yahoo revises and extends its series.
- `fixtures/MANIFEST.json` — the frozen panel the report ran on (rows, window, sha256), so a moved
  number can be told from a moved source. `scripts/freeze_fixtures.py` rebuilds that panel locally;
  `run.py --frozen` then lands on the report's numbers to the decimal.
- `src/praxis_358063/universe.py` — the 39 contracts, their tickers, asset class, rolls per year, costs.

The paper used Refinitiv: 56 contracts, roll-adjusted, 1980–2020. Free data covers 39 of
the 56 — the paper's full 25-commodity sleeve, plus US equity-index, Treasury and FX
futures — and front-month chains are not back-adjusted, so absolute Sharpe levels differ
from the paper's; the DMS-versus-naive comparison stays consistent on any one panel.

Your own data: implement `DataInterface` (one method, `src/praxis_358063/data/interface.py`),
run `check_adapter` from `data/conformance.py` against it, then pass it to `reproduce()`.
Expect the levels to move with roll treatment and coverage.

## The strategy (`src/praxis_358063/`)

- `dma.py` — the 127 dynamic-logistic models over momentum look-backs, DMA/DMS weighting.
- `tsmom.py` — sizing (1/N)·40%/σ, costs, the naive benchmark, Sharpe and vol scaling.
- `run.py` — `reproduce()`: DMS-TVP vs naive 12-month, the lift's t-stat, the commodity
  sleeve, the 2009 crash, the post-publication window.

Inherited from the published validation: one-way costs {commodity 3bp, equity/bond/FX 1bp}
plus roll legs; a contract enters 36 months after its data starts; the book trades only
months with ten or more eligible contracts; classifier state prior 100·I (the lift moves
+130 → +274bp/yr across priors 1, 10, 100: direction robust, size prior-sensitive).

## Tests

    pip install pytest        (inside the same .venv)
    pytest -q

The golden master re-runs the full filter on the frozen snapshot and pins the report's
numbers to the decimal. Unit checks cover look-ahead, the momentum matrix and the universe.
