diff --git a/README.md b/README.md new file mode 100644 index 0000000..617621e --- /dev/null +++ b/README.md @@ -0,0 +1,122 @@ +# aura + +**aura is a "game engine for traders."** It is a Rust framework — and a +playground — for authoring trading strategies as composable dataflow nodes, +backtesting them deterministically and massively in parallel, validating them +(sweep / Monte-Carlo / walk-forward), and freezing a validated strategy into a +standalone bot with a broker connection. Its differentiator is the **World**: a +program that constructs and orchestrates whole *families* of backtests, not the +single run. + +This README is a discoverability map of the shipped `aura` CLI — *what commands +exist and what they do*. It deliberately keeps per-flag detail light; the two +authoritative sources for exact syntax are always: + +- `aura --help` — the exhaustive flag grammar. +- The design ledger (`docs/design/INDEX.md`) and glossary (`docs/glossary.md`) + — the concepts and invariants behind the surface. + +## Build & run + +aura is a Cargo workspace. Build everything and you get one binary named `aura`: + +```sh +cargo build --workspace # binary at target/debug/aura +cargo build --workspace --release # optimized, at target/release/aura +``` + +Invoke it as `aura …` (examples below use the plain name). + +## Concepts in one breath + +- **Blueprint** — a serialized signal graph as data: a param-generic + `price → bias` node graph. A blueprint file (`blueprint.json`) is the unit a + downstream consumer loads and drives verbs over. +- **Open vs. closed** — a blueprint with unbound (free) numeric knobs is *open*; + one with every knob bound is *closed*. Different verbs want different states + (see each verb below). +- **Family** — the set of runs one verb produces over a blueprint (a sweep grid, + a Monte-Carlo seed set, a walk-forward window sequence). Families are persisted + in a content-addressed store and can be listed, ranked, and reproduced. +- **Axis** — one named, sweepable knob of a blueprint (e.g. `graph.fast.length`), + bound with a comma-separated value list. + +## Running & orchestrating a loaded blueprint + +These verbs all take the **blueprint file as their first positional argument** +and drive a family of runs over it. (Each verb also has a legacy built-in form +selected by `--strategy`/`--harness` instead of a `.json` path, for the +engine's own bundled example strategies — see `--help`.) + +| Command | Purpose | +|---|---| +| `aura run ` | Run one backtest of a **closed** blueprint and print its report. An open (free-knob) blueprint is refused with a clean error — bind it, or use `sweep`. | +| `aura sweep --list-axes` | **Discover** the blueprint's open, sweepable knobs. Prints each as `:`. Run this first to learn the axis names. | +| `aura sweep --axis = [--axis …]` | Run a **grid family** over the named axes and persist it. | +| `aura mc --seeds ` | Run a **Monte-Carlo family** of `n` seeded realizations. Wants a **closed** blueprint (the inverse of sweep). | +| `aura walkforward --axis = [--axis …]` | Run an **in-sample-refit walk-forward family** — rolling optimize + out-of-sample test across windows, stitched into one verdict + parameter stability. `--select` chooses the per-window objective. | +| `aura runs families` | List every persisted family (id, kind, member count). | +| `aura runs family [rank ]` | List one family's members, optionally ranked best-first by an R metric (e.g. `sqn_normalized`, `expectancy_r`). | +| `aura reproduce ` | Re-derive every member of a persisted family from the content-addressed store and check it is bit-identical (the C18/C1 determinism guarantee). | + +**Important contract — every open knob is mandatory.** On `sweep` and +`walkforward`, the knobs enumerated by `--list-axes` are *all* required: you must +supply an `--axis` for each open knob. There is no default value — pin a knob you +don't want to vary with a single-value axis (`--axis name=4`). Omitting one is a +clean error naming the missing knob, not a silent default. + +Use `aura --help` for the full data-window (`--real`/`--from`/`--to`), +naming (`--name`/`--trace`), and selection (`--select`) flags. + +## Authoring & introspecting topology + +A blueprint is authored declaratively from a **JSON op-list**: an ordered list +of by-identifier construction ops replayed against the standard node vocabulary. + +| Command | Purpose | +|---|---| +| `aura graph build` | Read an op-list document on **stdin**, build the blueprint, and print its canonical JSON to **stdout** (no trailing newline — it is the content-addressed artifact). | +| `aura graph introspect --vocabulary` | List every node type available to op-lists. | +| `aura graph introspect --node ` | Show one type's input ports, output fields, and param paths (with the bind-value form). | +| `aura graph introspect --unwired` | Read a *partial* op-list on stdin and list its still-open interior slots. | +| `aura graph introspect --content-id` | Read an op-list on stdin and print the SHA-256 content id of the blueprint it would build. | + +### Op-list shape + +Each element is one op, tagged by `"op"`. Node params are bound with the **typed +`Scalar` form** — a tagged, capitalized-kind object: `{"I64": 5}`, `{"F64": +1.5}`, `{"Bool": true}`. A worked example (an SMA-crossover → bias signal): + +```json +[ + {"op":"source","role":"price","kind":"F64"}, + {"op":"add","type":"SMA","name":"fast","bind":{"length":{"I64":2}}}, + {"op":"add","type":"SMA","name":"slow","bind":{"length":{"I64":4}}}, + {"op":"add","type":"Sub"}, + {"op":"add","type":"Bias"}, + {"op":"feed","role":"price","into":["fast.series","slow.series"]}, + {"op":"connect","from":"fast.value","to":"sub.lhs"}, + {"op":"connect","from":"slow.value","to":"sub.rhs"}, + {"op":"connect","from":"sub.value","to":"bias.signal"}, + {"op":"expose","from":"bias.bias","as":"bias"} +] +``` + +Piping this document into `aura graph build` emits a `blueprint.json` you can +then feed to `run` / `sweep` / `mc` / `walkforward` above: + +```sh +aura graph build < crossover.ops.json > crossover.bp.json +aura sweep crossover.bp.json --list-axes +``` + +The op kinds are `source`, `input`, `add`, `feed`, `connect`, and `expose`. See +`aura graph introspect --node ` for a type's exact ports and the op-script +grammar in the design ledger for the full semantics. + +## Where to go deeper + +- `aura --help` — exhaustive, always-current flag grammar. +- `docs/design/INDEX.md` — the design ledger: architecture, invariants, the World. +- `docs/glossary.md` — canonical terminology (blueprint, family, axis, sweep / + Monte-Carlo / walk-forward, R, content-id, …).