@backtest-kit/cli 16.6.0 → 17.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -45
- package/build/index.cjs +152 -450
- package/build/index.mjs +156 -454
- package/docker/package.json +6 -6
- package/package.json +13 -13
- package/template/project/package.mustache +5 -5
package/README.md
CHANGED
|
@@ -104,8 +104,7 @@ Every invocation is **one mode** (a primary flag) + a positional strategy/entry
|
|
|
104
104
|
| **Candle Dump** | `--dump` | Fetch & save raw OHLCV candles to a file |
|
|
105
105
|
| **PnL Debug** | `--pnldebug` | Simulate per-minute PnL for a given entry price & direction |
|
|
106
106
|
| **Broker Debug** | `--brokerdebug` | Fire a single broker commit against the live adapter |
|
|
107
|
-
| **
|
|
108
|
-
| **Tune** | `--tune` | Walk-forward parameter search over a crowd-ideas feed: train on the head, one frozen shot on the tail |
|
|
107
|
+
| **Sweep** | `--sweep` | Grid sweep over a crowd-ideas feed: profit-before-stop corridor + raw author tracks, axes from a positional JSON config |
|
|
109
108
|
| **Flush** | `--flush` | Delete report/log/markdown/agent folders from a strategy dump dir |
|
|
110
109
|
| **Init** | `--init` | Scaffold a new project |
|
|
111
110
|
| **Docker** | `--docker` | Scaffold a self-contained Docker workspace |
|
|
@@ -273,7 +272,7 @@ Utilities that don't run a strategy. They share one convention, explained once h
|
|
|
273
272
|
> **The `<mode>.module` convention.** By default the CLI auto-registers CCXT Binance. To use a different exchange (custom API keys, rate limits, a non-spot market), drop a `modules/<mode>.module.ts` that calls `addExchangeSchema` from `backtest-kit`. The CLI loads it automatically before running, trying `.ts`/`.mjs`/`.cjs`; it's searched **next to the target file first, then in the project root**. `.env` is loaded root-first then the target-file dir (override), so API keys stay out of code.
|
|
274
273
|
|
|
275
274
|
<details>
|
|
276
|
-
<summary>The shared <code><mode>.module.ts</code> shape (pine / editor / dump / pnldebug / brokerdebug /
|
|
275
|
+
<summary>The shared <code><mode>.module.ts</code> shape (pine / editor / dump / pnldebug / brokerdebug / sweep)</summary>
|
|
277
276
|
|
|
278
277
|
```typescript
|
|
279
278
|
// modules/pine.module.ts (same shape for editor/dump/pnldebug.module; brokerdebug registers a Broker instead)
|
|
@@ -451,62 +450,32 @@ The CLI loads `./modules/brokerdebug.module`, fetches the last candle for `--sym
|
|
|
451
450
|
|
|
452
451
|
</details>
|
|
453
452
|
|
|
454
|
-
### 🎛️
|
|
453
|
+
### 🎛️ Sweep (`--sweep`)
|
|
455
454
|
|
|
456
|
-
A **
|
|
455
|
+
A **grid sweep** over a feed of crowd trading ideas: the grid axes come from a positional JSON config of the consumer — from a small feasibility probe to a full parameter search. Without a config the engine defaults apply. Authors are graded by ONE binary outcome — **profit-before-stop**: walking each point's own hold window candle by candle, an idea is a HIT when a fixation (the profit lock if lock > 0, OR the trailing arm level) fires BEFORE the hard stop, a MISS when the hard stop fires first, the window times out, or the candles run out. Prints a Markdown report with the corridor share, the ranking winners, and the **raw author tracks** (ideas/hits/hitRate per grading rule) — the engine grades every author but bans none; who to trust is userspace.
|
|
457
456
|
|
|
458
457
|
```bash
|
|
459
|
-
npx @backtest-kit/cli --
|
|
460
|
-
# →
|
|
458
|
+
npx @backtest-kit/cli --sweep --symbol BTCUSDT ./assets/tv-ideas.normalized.jsonl
|
|
459
|
+
# → engine-default grid; add a config to shape the sweep:
|
|
460
|
+
npx @backtest-kit/cli --sweep --symbol BTCUSDT ./assets/tv-ideas.normalized.jsonl ./assets/probe.config.json
|
|
461
461
|
```
|
|
462
462
|
|
|
463
463
|
<details>
|
|
464
|
-
<summary>
|
|
464
|
+
<summary>Sweep flags, input format & behavior</summary>
|
|
465
465
|
|
|
466
466
|
| Flag | Type | Description |
|
|
467
467
|
|------|------|-------------|
|
|
468
|
-
| `--
|
|
468
|
+
| `--sweep` | boolean | Enable the grid sweep |
|
|
469
469
|
| `--symbol` | string | Trading pair to simulate (default `"BTCUSDT"`) |
|
|
470
470
|
| `--exchange` | string | Exchange (default: first registered, falls back to CCXT Binance) |
|
|
471
|
-
| `--output` | string | Output base name (default `
|
|
472
|
-
| `--json` | boolean | Save the full `
|
|
471
|
+
| `--output` | string | Output base name (default `sweep_{SYMBOL}_{TIMESTAMP}`) |
|
|
472
|
+
| `--json` | boolean | Save the full `ISweepResult` to `./dump/<output>.json` |
|
|
473
473
|
| `--markdown` | boolean | Save the summary report to `./dump/<output>.md` |
|
|
474
|
-
| `--verbose` | boolean | Log every
|
|
474
|
+
| `--verbose` | boolean | Log every sweep lifecycle callback to the console |
|
|
475
475
|
|
|
476
|
-
**
|
|
476
|
+
**Positionals:** path to an ideas `.jsonl` file (required) — one idea per line, exact shape `{ "id": number, "ts": number, "symbol": string, "direction": "LONG"|"SHORT"|"NEUTRAL", "author": string }` — and an **optional config `.json`** with the shape `{ "gridAxes"?: ISweepGridAxes, "reportOrder"?: "sharpe"|"sortino"|"pnl"|"recovery" }`. Both files are validated **before any work starts** — a structure mismatch (including an unknown config key) aborts the run with an error naming the field. No config → an empty object → the engine defaults. Ideas of other symbols are filtered out by the engine, so one shared feed serves any `--symbol`.
|
|
477
477
|
|
|
478
|
-
Under the hood:
|
|
479
|
-
|
|
480
|
-
</details>
|
|
481
|
-
|
|
482
|
-
### 🔧 Tune (`--tune`)
|
|
483
|
-
|
|
484
|
-
The **parameter search** counterpart of the `--simulator` probe: a walk-forward sweep of the full grid with the profit-harvesting machinery ON — profit lock, trailing take, weighted consensus, Wilson-bound ban, both author-hit metrics (close/reach). Honesty is structural: training sees only the head of the feed (`--split` of its time range, default 70%), then the sharpe winner is frozen — point and raw author track record — and fired **exactly once** on the tail via `Simulator.test`. Nothing is trained on the tail; authors unseen in training are banned by default.
|
|
485
|
-
|
|
486
|
-
```bash
|
|
487
|
-
npx @backtest-kit/cli --tune --symbol BTCUSDT ./assets/tv-ideas.normalized.jsonl
|
|
488
|
-
# → train winners + one out-of-sample shot; add --json / --markdown to save into ./dump/
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
<details>
|
|
492
|
-
<summary>Tune flags, input format & behavior</summary>
|
|
493
|
-
|
|
494
|
-
| Flag | Type | Description |
|
|
495
|
-
|------|------|-------------|
|
|
496
|
-
| `--tune` | boolean | Enable the walk-forward parameter search |
|
|
497
|
-
| `--symbol` | string | Trading pair to tune (default `"BTCUSDT"`) |
|
|
498
|
-
| `--exchange` | string | Exchange (default: first registered, falls back to CCXT Binance) |
|
|
499
|
-
| `--split` | string | Train share of the feed time range, 0..1 (default `0.7`) |
|
|
500
|
-
| `--output` | string | Output base name (default `tune_{SYMBOL}_{TIMESTAMP}`) |
|
|
501
|
-
| `--json` | boolean | Save `{ trainSplit, train, test }` to `./dump/<output>.json` |
|
|
502
|
-
| `--markdown` | boolean | Save the walk-forward report to `./dump/<output>.md` |
|
|
503
|
-
| `--verbose` | boolean | Log simulator lifecycle callbacks to the console |
|
|
504
|
-
|
|
505
|
-
**Positional (required):** path to an ideas `.jsonl` file — same shape and validation as `--simulator`.
|
|
506
|
-
|
|
507
|
-
The report carries the train winners of all four ranking criteria (full point labels including lock, Wilson bound and the author-hit metric), the out-of-sample result of the frozen sharpe winner with its trade list, and the **frozen author track record** — the raw `author/ideas/hits` numbers to hardcode for production `Simulator.test`: banned flags and vote weights are re-derived from them under the frozen point's rule, and an author absent from the list is banned by default. Exchange via `tune.module` (see convention above).
|
|
508
|
-
|
|
509
|
-
A train-on-train winner is a ceiling, never a promise: the out-of-sample section is the honest number, and the final arbiter for any point picked here is a real engine backtest (`Backtest.run`).
|
|
478
|
+
Under the hood: one candle pass per idea to the grid's longest hold (lazy chunked fetch through the exchange, persist cache first), flood dedupe (one idea per author per direction per 8h), EVERY author traded (the engine grades every author on the raw per-author track **inside each point's own hold window** and bans none — userspace filters on the continuous `hitRate`), production slot semantics (one open position per author), time-based Sharpe/Sortino over daily equity buckets. The result is a single report bucket — `result.reports.reports` (grid point reports, sorted by `reportOrder`), `result.reports.best` (the four ranking winners), and `result.reports.tracks` (author tracks). Each track line is self-contained (`{holdMinutes, profitLockPercent, hardStopPercent, trailingTakePercent, author, ideas, hits, hitRate}`) for grep/jq without a join. With `--verbose` every lifecycle callback (`onIdeas`, `onProfiles`, `onAuthorsTrained`, `onGridPoint`, `onRanking`, `onDone`) is logged to the console as it fires, so long runs show progress. Exchange via `sweep.module` (see convention above).
|
|
510
479
|
|
|
511
480
|
</details>
|
|
512
481
|
|