Metadata-Version: 2.5
Name: sophostechne-quant
Version: 1.0.0
Summary: Evolve, test and optimise trading strategies.
Project-URL: Repository, https://github.com/sophostechne/quant
Project-URL: Issues, https://github.com/sophostechne/quant/issues
Author: Sophos Techne
License-Expression: MIT
License-File: LICENSE
Keywords: backtesting,evolutionary,quantitative,strategy,trading
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: <3.15,>=3.12
Requires-Dist: nautilus-trader>=1.230
Requires-Dist: pandas>=2.0
Description-Content-Type: text/markdown

# quant

Evolve, test and optimise trading strategies.

The engine behind the [Quant Workbench](https://github.com/sophostechne/quant-vsce) extension,
usable on its own from the command line. Everything it reports is JSON on stdout, with
diagnostics on stderr, so it composes with whatever you already run.

## Install

```sh
pip install sophostechne-quant
```

The distribution is `sophostechne-quant`; the import package and the command are both `quant`.
It pulls in [NautilusTrader](https://github.com/nautechsystems/nautilus_trader) and pandas, so
the install is not small.

## The idea

A backtest that reports only a return is a sales pitch. Three questions have to be answered
together, and `evaluate` always answers all three — there is no flag to omit the awkward two:

- **Did it make money?** Net return, drawdown, profit factor, win rate, time in drawdown.
- **Was the drawdown real?** A Monte Carlo resample of the strategy's own trades, so the
  observed drawdown can be placed in the distribution of drawdowns it could have had.
- **Was any of it better than chance?** A noise floor of random strategies on the same bars.
  A strategy that does not beat its noise floor did not find an edge, whatever it returned.

## Use

```sh
quant evaluate --strategy my.strategy --product BTC-USD --timeframe 6h --bars 2000
```

Searching emits NDJSON — one object per generation, then a `done` object carrying the
survivors. Every survivor is scored twice: on the bars it was fitted to, and on a held-out tail
the search never saw. The gap between the two is the entire result.

```sh
quant evolve --population 250 --generations 20 --survivors 5 --holdout 0.3
```

Walk-forward tests the *method* rather than any one strategy. The whole search re-runs in every
training window and its winner is applied, untouched, to the window after.

```sh
quant walkforward --train-bars 1200 --test-bars 400
```

Costs are charged on every path: `--fee` (default 0.001) and `--slippage` (default 0.0005).
`--seed` makes a run reproducible, and `--regimes` conditions the search on market regime.

## Output

One JSON object per line, always with an `ok` field on terminal results. Failures are reported
as JSON too, so a caller parsing the stream never has to strip a traceback out of it:

```json
{"ok": false, "type": "error", "error": "FileNotFoundError: my.strategy"}
```

## Development

```sh
uv sync
uv run pytest
```

## License

MIT
