nanobook 0.16.2

Deterministic Rust execution engine for trading backtests: limit-order book, portfolio simulation, metrics, risk checks, and Python bindings
Documentation
# Reference-parity golden fixture

This directory holds the input fixture and pre-computed reference
outputs that `tests/reference_parity.rs` compares nanobook's
implementation against. Every numeric claim in the README (RSI, ATR,
Sharpe, Sortino, CVaR, max drawdown, etc.) is pinned here.

## Files

- `requirements.txt` — pinned Python reference-library versions.
- `generate_golden.py` — seeded fixture generator. Run manually.
- `golden.json` — generated output. **Check in.** Read-only from CI.
- `README.md` — this file.

## Regeneration (manual only)

Regenerate only when `requirements.txt` is deliberately bumped or a
fixture parameter (seed, N) is changed with intent.

**System prerequisites.**

- macOS: `brew install ta-lib`
- Ubuntu: `apt-get install libta-lib-dev`

**Procedure.**

```bash
# From the repository root.
uv venv .parity-venv
source .parity-venv/bin/activate
uv pip install -r tests/parity/requirements.txt
python tests/parity/generate_golden.py
deactivate
rm -rf .parity-venv
```

The script prints the SHA-256 of the generated `golden.json` and the
exact reference-library versions used. Commit the updated JSON in the
same commit as the `requirements.txt` bump, alongside the Rust-side
tolerance adjustments if any are needed.

## Philosophy

This harness is the measurement substrate for every numerical fix in
nanobook. Each fix commit either:

- Adds a new test that compares a specific function to a known
  reference, or
- Turns a previously-failing test green (because the fix aligns
  nanobook with the reference).

**Never loosen tolerance to make a test pass.** If a 1e-6 test fails
with our current output differing from the reference by 1e-5, either
the reference convention is different (document it, pick a different
reference) or nanobook has a bug (fix it, don't hide it).

## Fixture structure

`golden.json` is nested:

```
{
  "_meta": { "seed": 42, "n": 500, "versions": { ... } },
  "inputs": {
    "returns":  [N floats],
    "close":    [N floats],
    "highs":    [N floats],
    "lows":     [N floats]
  },
  "scipy":      { ... },
  "talib":      { ... },
  "quantstats": { ... }
}
```

Any `null` value in an array represents a NaN / non-finite in the
reference output (e.g., TA-Lib's RSI is undefined for the first
`period` indices). The Rust side reads these as `None`.

## Drift policy

If a Rust test fails after a library bump:

1. Read `_meta.versions` in `golden.json` — what moved?
2. Run the upstream changelog / release notes for the bumped
   library.
3. If the reference library changed numerics deliberately (rare),
   update the Rust-side expected behavior explicitly in the same
   commit.
4. If the reference library has a bug, pin the previous version in
   `requirements.txt` and wait for a fix upstream.

Never silently regenerate `golden.json` without understanding the
delta.