@backtest-kit/cli 6.14.0 → 6.15.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 CHANGED
@@ -41,6 +41,7 @@ Point the CLI at your strategy file, choose a mode, and it handles exchange conn
41
41
  | **Telegram** | `--telegram` | Trade notifications with price charts |
42
42
  | **PineScript** | `--pine` | Run a local `.pine` indicator against exchange data |
43
43
  | **Candle Dump** | `--dump` | Fetch and save raw OHLCV candles to a file |
44
+ | **Flush** | `--flush` | Delete report/log/markdown/agent folders from strategy dump dir |
44
45
  | **Init Project** | `--init` | Scaffold a new backtest-kit project |
45
46
 
46
47
  ## 🚀 Installation
@@ -144,6 +145,7 @@ npm start -- --symbol BTCUSDT --ui
144
145
  | `--telegram` | boolean | Enable Telegram notifications (default: `false`) |
145
146
  | `--verbose` | boolean | Log each candle fetch (default: `false`) |
146
147
  | `--noCache` | boolean | Skip candle cache warming before backtest (default: `false`) |
148
+ | `--noFlush` | boolean | Skip removing report/log/markdown/agent folders before backtest run (default: `false`) |
147
149
  | `--symbol` | string | Trading pair (default: `"BTCUSDT"`) |
148
150
  | `--strategy` | string | Strategy name (default: first registered) |
149
151
  | `--exchange` | string | Exchange name (default: first registered) |
@@ -178,7 +180,7 @@ Runs the strategy against historical candle data using a registered `FrameSchema
178
180
  npm run backtest
179
181
  ```
180
182
 
181
- Before running, the CLI warms the candle cache for every interval in `--cacheInterval`. On the next run, cached data is used directly — no API calls needed. Pass `--noCache` to skip this step entirely.
183
+ Before running, the CLI removes the `report`, `log`, `markdown`, and `agent` folders from the strategy's `dump/` directory, then warms the candle cache for every interval in `--cacheInterval`. On the next run, cached data is used directly — no API calls needed. Pass `--noCache` to skip cache warming, `--noFlush` to keep existing output folders.
182
184
 
183
185
  ### Paper Trading
184
186
 
@@ -228,7 +230,7 @@ Runs the same historical period against multiple strategy files and prints a ran
228
230
  npm run walker
229
231
  ```
230
232
 
231
- Each positional argument is a separate strategy entry point. All files are loaded without changing `process.cwd()` — `.env` is read from the working directory only. After loading, `addWalkerSchema` is called automatically using the exchange and frame registered by the strategy files.
233
+ Each positional argument is a separate strategy entry point. Before loading them, the CLI removes the `report`, `log`, `markdown`, and `agent` folders from each entry point's `dump/` directory. Pass `--noFlush` to keep existing output. All files are loaded without changing `process.cwd()` — `.env` is read from the working directory only. After loading, `addWalkerSchema` is called automatically using the exchange and frame registered by the strategy files.
232
234
 
233
235
  If no frame is registered, the CLI falls back to the last 31 days from `Date.now()` with a console warning.
234
236
 
@@ -240,6 +242,7 @@ If no frame is registered, the CLI falls back to the last 31 days from `Date.now
240
242
  | `--symbol` | string | Trading pair (default: `"BTCUSDT"`) |
241
243
  | `--cacheInterval` | string | Intervals to pre-cache (default: `"1m, 15m, 30m, 4h"`) |
242
244
  | `--noCache` | boolean | Skip candle cache warming (default: `false`) |
245
+ | `--noFlush` | boolean | Skip removing report/log/markdown/agent folders before walker run (default: `false`) |
243
246
  | `--verbose` | boolean | Log each candle fetch and strategy progress (default: `false`) |
244
247
  | `--output` | string | Output file base name (default: `walker_{SYMBOL}_{TIMESTAMP}`) |
245
248
  | `--json` | boolean | Save results as JSON to `./dump/<output>.json` |
@@ -828,6 +831,57 @@ Or add it to `package.json`:
828
831
  npx @backtest-kit/cli --dump --symbol BTCUSDT --timeframe 15m --limit 500 --jsonl
829
832
  ```
830
833
 
834
+ ## 🗑️ Flushing Strategy Output (`--flush`)
835
+
836
+ `@backtest-kit/cli` can delete generated output folders from one or more strategy dump directories without touching cached candle data.
837
+
838
+ ### CLI Flags
839
+
840
+ | Flag | Type | Description |
841
+ |------|------|-------------|
842
+ | `--flush` | boolean | Enable flush mode |
843
+
844
+ **Positional arguments (required):** one or more strategy entry point files. For each entry point the CLI resolves its directory and removes the following subdirectories from `<entry-dir>/dump/`:
845
+
846
+ | Folder | Contents |
847
+ |--------|----------|
848
+ | `report` | Backtest report files (`.jsonl`) |
849
+ | `log` | Run logs (`log.jsonl`) |
850
+ | `markdown` | Exported Markdown reports |
851
+ | `agent` | Agent outline files |
852
+
853
+ Candle cache (`dump/data/`) and AI forecast outlines (`dump/outline/`) are **not** removed.
854
+
855
+ ### Usage
856
+
857
+ Flush a single strategy:
858
+
859
+ ```bash
860
+ npx @backtest-kit/cli --flush ./content/feb_2026.strategy/modules/backtest.module.ts
861
+ ```
862
+
863
+ Flush multiple strategies at once:
864
+
865
+ ```bash
866
+ npx @backtest-kit/cli --flush \
867
+ ./content/feb_2026.strategy/modules/backtest.module.ts \
868
+ ./content/mar_2026.strategy/modules/backtest.module.ts
869
+ ```
870
+
871
+ Or add it to `package.json`:
872
+
873
+ ```json
874
+ {
875
+ "scripts": {
876
+ "flush": "npx @backtest-kit/cli --flush ./content/feb_2026.strategy/modules/backtest.module.ts"
877
+ }
878
+ }
879
+ ```
880
+
881
+ ```bash
882
+ npm run flush
883
+ ```
884
+
831
885
  ## 🗂️ Scaffolding a New Project (`--init`)
832
886
 
833
887
  `@backtest-kit/cli` can bootstrap a ready-to-use project directory with a pre-configured layout, example strategy files, and all documentation fetched automatically.
@@ -985,6 +1039,7 @@ await run(mode, args);
985
1039
  | `frame` | `string` | Frame name (default: first registered) |
986
1040
  | `cacheInterval` | `CandleInterval[]` | Intervals to pre-cache (default: `["1m","15m","30m","1h","4h"]`) |
987
1041
  | `noCache` | `boolean` | Skip candle cache warming (default: `false`) |
1042
+ | `noFlush` | `boolean` | Skip removing report/log/markdown/agent folders before the run (default: `false`) |
988
1043
  | `verbose` | `boolean` | Log each candle fetch (default: `false`) |
989
1044
 
990
1045
  **Paper** and **Live** (`mode: "paper"` / `mode: "live"`):
package/build/index.cjs CHANGED
@@ -473,6 +473,10 @@ const getArgs = functoolsKit.singleshot(() => {
473
473
  type: "boolean",
474
474
  default: false,
475
475
  },
476
+ noFlush: {
477
+ type: "boolean",
478
+ default: false,
479
+ },
476
480
  cacheInterval: {
477
481
  type: "string",
478
482
  default: "1m, 15m, 30m, 4h",
@@ -486,6 +490,10 @@ const getArgs = functoolsKit.singleshot(() => {
486
490
  type: "boolean",
487
491
  default: false,
488
492
  },
493
+ flush: {
494
+ type: "boolean",
495
+ default: false,
496
+ },
489
497
  timeframe: {
490
498
  type: "string",
491
499
  default: "",
@@ -2461,14 +2469,27 @@ const cli = {
2461
2469
  };
2462
2470
  init();
2463
2471
 
2472
+ const NOTIFICATION_CONFIG = {
2473
+ signal: true,
2474
+ risk: true,
2475
+ info: true,
2476
+ breakeven: true,
2477
+ common_error: true,
2478
+ critical_error: true,
2479
+ validation_error: true,
2480
+ partial_loss: false,
2481
+ partial_profit: false,
2482
+ signal_sync: false,
2483
+ strategy_commit: true,
2484
+ };
2464
2485
  class SetupUtils {
2465
2486
  constructor() {
2466
2487
  this.enable = functoolsKit.singleshot(() => {
2467
2488
  cli.loggerService.debug("SetupUtils enable");
2489
+ BacktestKit.Notification.enable(NOTIFICATION_CONFIG);
2468
2490
  {
2469
2491
  BacktestKit.Recent.enable();
2470
2492
  BacktestKit.Storage.enable();
2471
- BacktestKit.Notification.enable();
2472
2493
  }
2473
2494
  {
2474
2495
  BacktestKit.Markdown.enable();
@@ -2590,14 +2611,14 @@ BacktestKit.setConfig({
2590
2611
  CC_WALKER_MARKDOWN_TOP_N: 10,
2591
2612
  });
2592
2613
 
2593
- const MODES = ["backtest", "walker", "paper", "live", "pine", "dump", "init", "help", "version"];
2614
+ const MODES = ["backtest", "walker", "paper", "live", "pine", "dump", "flush", "init", "help", "version"];
2594
2615
  const ENTRY_PATH$1 = "./node_modules/@backtest-kit/cli/build/index.mjs";
2595
2616
  const HELP_TEXT$1 = `
2596
2617
  Example:
2597
2618
 
2598
2619
  node ${ENTRY_PATH$1} --help
2599
2620
  `.trimStart();
2600
- const main$b = async () => {
2621
+ const main$c = async () => {
2601
2622
  if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
2602
2623
  return;
2603
2624
  }
@@ -2605,19 +2626,48 @@ const main$b = async () => {
2605
2626
  if (MODES.some((mode) => values[mode])) {
2606
2627
  return;
2607
2628
  }
2608
- process.stdout.write(`@backtest-kit/cli ${"6.14.0"}\n`);
2629
+ process.stdout.write(`@backtest-kit/cli ${"6.15.0"}\n`);
2609
2630
  process.stdout.write("\n");
2610
2631
  process.stdout.write(`Run with --help to see available commands.\n`);
2611
2632
  process.stdout.write("\n");
2612
2633
  process.stdout.write(HELP_TEXT$1);
2613
2634
  process.exit(0);
2614
2635
  };
2615
- main$b();
2636
+ main$c();
2616
2637
 
2617
2638
  const notifyShutdown = functoolsKit.singleshot(async () => {
2618
2639
  console.log("Graceful shutdown initiated. Press Ctrl+C again to force quit.");
2619
2640
  });
2620
2641
 
2642
+ const FLUSH_DIRS = ["report", "log", "markdown", "agent"];
2643
+ const flush = async (entryPoint) => {
2644
+ const moduleRoot = path.dirname(path.resolve(process.cwd(), entryPoint));
2645
+ const dumpDir = path.join(moduleRoot, "dump");
2646
+ for (const dir of FLUSH_DIRS) {
2647
+ const target = path.join(dumpDir, dir);
2648
+ await fs$1.rm(target, { recursive: true, force: true });
2649
+ console.log(`Removed: ${target}`);
2650
+ }
2651
+ };
2652
+ const main$b = async () => {
2653
+ if (!getEntry((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))) {
2654
+ return;
2655
+ }
2656
+ const { values } = getArgs();
2657
+ if (!values.flush) {
2658
+ return;
2659
+ }
2660
+ const entryPoints = getPositionals();
2661
+ if (!entryPoints.length) {
2662
+ throw new Error("Entry point is required");
2663
+ }
2664
+ for (const entryPoint of entryPoints) {
2665
+ await flush(entryPoint);
2666
+ }
2667
+ process.exit(0);
2668
+ };
2669
+ main$b();
2670
+
2621
2671
  const BEFORE_EXIT_FN$5 = functoolsKit.singleshot(async () => {
2622
2672
  process.off("SIGINT", BEFORE_EXIT_FN$5);
2623
2673
  const [running = null] = await BacktestKit.Backtest.list();
@@ -2646,6 +2696,10 @@ const main$a = async () => {
2646
2696
  if (!values.backtest) {
2647
2697
  return;
2648
2698
  }
2699
+ if (!values.noFlush) {
2700
+ const [entryPoint = null] = getPositionals();
2701
+ entryPoint && await flush(entryPoint);
2702
+ }
2649
2703
  await cli.backtestMainService.connect();
2650
2704
  listenGracefulShutdown$5();
2651
2705
  };
@@ -2675,6 +2729,11 @@ const main$9 = async () => {
2675
2729
  if (!values.walker) {
2676
2730
  return;
2677
2731
  }
2732
+ if (!values.noFlush) {
2733
+ for (const entryPoint of getPositionals()) {
2734
+ await flush(entryPoint);
2735
+ }
2736
+ }
2678
2737
  listenGracefulShutdown$4();
2679
2738
  await cli.walkerMainService.connect();
2680
2739
  };
@@ -3060,6 +3119,7 @@ Modes:
3060
3119
  --live <entry> Live trading with real orders
3061
3120
  --pine <entry> Execute a local .pine indicator file
3062
3121
  --dump Fetch and save raw OHLCV candles
3122
+ --flush <entry...> Delete report/log/markdown/agent folders from strategy dump dir
3063
3123
  --init Scaffold a new project in the current directory
3064
3124
  --help Print this help message
3065
3125
 
@@ -3071,6 +3131,7 @@ Backtest flags:
3071
3131
  --frame <string> Frame name from addFrameSchema (default: first registered)
3072
3132
  --cacheInterval <string> Comma-separated intervals to pre-cache (default: "1m, 15m, 30m, 4h")
3073
3133
  --noCache Skip candle cache warming before the run
3134
+ --noFlush Skip removing report/log/markdown/agent folders before backtest run
3074
3135
  --verbose Log every candle fetch to stdout
3075
3136
  --ui Start web dashboard at http://localhost:60050
3076
3137
  --telegram Send trade notifications to Telegram
@@ -3080,6 +3141,7 @@ Walker flags (--walker):
3080
3141
  --symbol <string> Trading pair (default: BTCUSDT)
3081
3142
  --cacheInterval <string> Comma-separated intervals to pre-cache (default: "1m, 15m, 30m, 4h")
3082
3143
  --noCache Skip candle cache warming before the run
3144
+ --noFlush Skip removing report/log/markdown/agent folders before walker run
3083
3145
  --verbose Log every candle fetch to stdout
3084
3146
  --output <string> Output file base name (default: walker_{SYMBOL}_{TIMESTAMP})
3085
3147
  --json Save results as JSON to ./dump/<output>.json
@@ -3129,6 +3191,13 @@ Candle dump flags (--dump):
3129
3191
 
3130
3192
  Module file ./modules/dump.module is loaded automatically if it exists.
3131
3193
 
3194
+ Flush flags (--flush):
3195
+
3196
+ One or more positional entry points. For each entry point the following
3197
+ subdirectories are removed from <entry-dir>/dump/:
3198
+
3199
+ report log markdown agent
3200
+
3132
3201
  Init flags (--init):
3133
3202
 
3134
3203
  --output <string> Target directory name (default: backtest-kit-project)
@@ -3144,6 +3213,8 @@ Module hooks (loaded automatically by each mode):
3144
3213
  modules/pine.module --pine Exchange schema for PineScript runs
3145
3214
  modules/dump.module --dump Exchange schema for candle dumps
3146
3215
 
3216
+ --flush has no associated module. It only removes dump subdirectories.
3217
+
3147
3218
  Extensions .ts, .mjs, .cjs are tried automatically. Missing module = soft warning.
3148
3219
 
3149
3220
  Environment variables:
@@ -3156,13 +3227,15 @@ Environment variables:
3156
3227
  Examples:
3157
3228
 
3158
3229
  node ${ENTRY_PATH} --backtest ./content/feb_2026.strategy.ts
3159
- node ${ENTRY_PATH} --backtest --symbol BTCUSDT --noCache --ui ./content/feb_2026.strategy.ts
3230
+ node ${ENTRY_PATH} --backtest --symbol BTCUSDT --noCache --noFlush --ui ./content/feb_2026.strategy.ts
3160
3231
  node ${ENTRY_PATH} --walker ./content/feb_2026_v1.strategy.ts ./content/feb_2026_v2.strategy.ts ./content/feb_2026_v3.strategy.ts
3161
- node ${ENTRY_PATH} --walker --symbol BTCUSDT --noCache --markdown ./content/feb_2026_v1.ts ./content/feb_2026_v2.ts
3232
+ node ${ENTRY_PATH} --walker --symbol BTCUSDT --noCache --noFlush --markdown ./content/feb_2026_v1.ts ./content/feb_2026_v2.ts
3162
3233
  node ${ENTRY_PATH} --paper --symbol ETHUSDT ./content/feb_2026.strategy.ts
3163
3234
  node ${ENTRY_PATH} --live --ui --telegram ./content/feb_2026.strategy.ts
3164
3235
  node ${ENTRY_PATH} --pine ./math/feb_2026.pine --timeframe 15m --limit 500 --jsonl
3165
3236
  node ${ENTRY_PATH} --dump --symbol BTCUSDT --timeframe 15m --limit 500 --jsonl
3237
+ node ${ENTRY_PATH} --flush ./content/feb_2026.strategy/feb_2026.strategy.ts
3238
+ node ${ENTRY_PATH} --flush ./content/feb_2026.strategy/feb_2026.strategy.ts ./content/feb_2026.strategy/feb_2026.test.ts
3166
3239
  node ${ENTRY_PATH} --init --output my-trading-bot
3167
3240
  `.trimStart();
3168
3241
  const main$1 = async () => {
@@ -3173,7 +3246,7 @@ const main$1 = async () => {
3173
3246
  if (!values.help) {
3174
3247
  return;
3175
3248
  }
3176
- process.stdout.write(`@backtest-kit/cli ${"6.14.0"}\n\n`);
3249
+ process.stdout.write(`@backtest-kit/cli ${"6.15.0"}\n\n`);
3177
3250
  process.stdout.write(HELP_TEXT);
3178
3251
  process.exit(0);
3179
3252
  };
@@ -3187,7 +3260,7 @@ const main = async () => {
3187
3260
  if (!values.version) {
3188
3261
  return;
3189
3262
  }
3190
- process.stdout.write(`@backtest-kit/cli ${"6.14.0"}\n`);
3263
+ process.stdout.write(`@backtest-kit/cli ${"6.15.0"}\n`);
3191
3264
  process.exit(0);
3192
3265
  };
3193
3266
  main();
package/build/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import * as BacktestKit from 'backtest-kit';
3
- import { Log, listExchangeSchema, addExchangeSchema, roundTicks, listFrameSchema, addFrameSchema, listenDoneLive, listenDoneBacktest, shutdown, listenSignal, listStrategySchema, overrideExchangeSchema, Backtest, Session, Cache, Interval, alignToInterval, addWalkerSchema, overrideWalkerSchema, Walker, listenDoneWalker, Live, getCandles, checkCandles, warmCandles, listenRisk, listenStrategyCommit, listenSync, Recent, Storage, Notification, Markdown, Report, Dump, Memory, StorageLive, StorageBacktest, RecentLive, RecentBacktest, NotificationLive, NotificationBacktest, MarkdownWriter, ReportWriter, PersistSignalAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistPartialAdapter, PersistBreakevenAdapter, PersistCandleAdapter, PersistStorageAdapter, PersistNotificationAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistIntervalAdapter, PersistMemoryAdapter, PersistRecentAdapter, setConfig, Exchange } from 'backtest-kit';
3
+ import { Log, listExchangeSchema, addExchangeSchema, roundTicks, listFrameSchema, addFrameSchema, listenDoneLive, listenDoneBacktest, shutdown, listenSignal, listStrategySchema, overrideExchangeSchema, Backtest, Session, Cache, Interval, alignToInterval, addWalkerSchema, overrideWalkerSchema, Walker, listenDoneWalker, Live, getCandles, checkCandles, warmCandles, listenRisk, listenStrategyCommit, listenSync, Notification, Recent, Storage, Markdown, Report, Dump, Memory, StorageLive, StorageBacktest, RecentLive, RecentBacktest, NotificationLive, NotificationBacktest, MarkdownWriter, ReportWriter, PersistSignalAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistPartialAdapter, PersistBreakevenAdapter, PersistCandleAdapter, PersistStorageAdapter, PersistNotificationAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistIntervalAdapter, PersistMemoryAdapter, PersistRecentAdapter, setConfig, Exchange } from 'backtest-kit';
4
4
  import { getErrorMessage, errorData, singleshot, str, BehaviorSubject, compose, createAwaiter, execpool, queued, sleep, randomString, TIMEOUT_SYMBOL, typo, retry, trycatch, memoize } from 'functools-kit';
5
5
  import fs, { constants } from 'fs';
6
6
  import * as stackTrace from 'stack-trace';
7
- import path, { join, resolve, basename, extname, dirname } from 'path';
8
- import fs$1, { access, readFile, mkdir, writeFile, readdir, copyFile } from 'fs/promises';
7
+ import path, { join, resolve, dirname, basename, extname } from 'path';
8
+ import fs$1, { access, readFile, mkdir, writeFile, rm, readdir, copyFile } from 'fs/promises';
9
9
  import dotenv from 'dotenv';
10
10
  import { createActivator } from 'di-kit';
11
11
  import { fileURLToPath } from 'url';
@@ -448,6 +448,10 @@ const getArgs = singleshot(() => {
448
448
  type: "boolean",
449
449
  default: false,
450
450
  },
451
+ noFlush: {
452
+ type: "boolean",
453
+ default: false,
454
+ },
451
455
  cacheInterval: {
452
456
  type: "string",
453
457
  default: "1m, 15m, 30m, 4h",
@@ -461,6 +465,10 @@ const getArgs = singleshot(() => {
461
465
  type: "boolean",
462
466
  default: false,
463
467
  },
468
+ flush: {
469
+ type: "boolean",
470
+ default: false,
471
+ },
464
472
  timeframe: {
465
473
  type: "string",
466
474
  default: "",
@@ -2432,14 +2440,27 @@ const cli = {
2432
2440
  };
2433
2441
  init();
2434
2442
 
2443
+ const NOTIFICATION_CONFIG = {
2444
+ signal: true,
2445
+ risk: true,
2446
+ info: true,
2447
+ breakeven: true,
2448
+ common_error: true,
2449
+ critical_error: true,
2450
+ validation_error: true,
2451
+ partial_loss: false,
2452
+ partial_profit: false,
2453
+ signal_sync: false,
2454
+ strategy_commit: true,
2455
+ };
2435
2456
  class SetupUtils {
2436
2457
  constructor() {
2437
2458
  this.enable = singleshot(() => {
2438
2459
  cli.loggerService.debug("SetupUtils enable");
2460
+ Notification.enable(NOTIFICATION_CONFIG);
2439
2461
  {
2440
2462
  Recent.enable();
2441
2463
  Storage.enable();
2442
- Notification.enable();
2443
2464
  }
2444
2465
  {
2445
2466
  Markdown.enable();
@@ -2561,14 +2582,14 @@ setConfig({
2561
2582
  CC_WALKER_MARKDOWN_TOP_N: 10,
2562
2583
  });
2563
2584
 
2564
- const MODES = ["backtest", "walker", "paper", "live", "pine", "dump", "init", "help", "version"];
2585
+ const MODES = ["backtest", "walker", "paper", "live", "pine", "dump", "flush", "init", "help", "version"];
2565
2586
  const ENTRY_PATH$1 = "./node_modules/@backtest-kit/cli/build/index.mjs";
2566
2587
  const HELP_TEXT$1 = `
2567
2588
  Example:
2568
2589
 
2569
2590
  node ${ENTRY_PATH$1} --help
2570
2591
  `.trimStart();
2571
- const main$b = async () => {
2592
+ const main$c = async () => {
2572
2593
  if (!getEntry(import.meta.url)) {
2573
2594
  return;
2574
2595
  }
@@ -2576,19 +2597,48 @@ const main$b = async () => {
2576
2597
  if (MODES.some((mode) => values[mode])) {
2577
2598
  return;
2578
2599
  }
2579
- process.stdout.write(`@backtest-kit/cli ${"6.14.0"}\n`);
2600
+ process.stdout.write(`@backtest-kit/cli ${"6.15.0"}\n`);
2580
2601
  process.stdout.write("\n");
2581
2602
  process.stdout.write(`Run with --help to see available commands.\n`);
2582
2603
  process.stdout.write("\n");
2583
2604
  process.stdout.write(HELP_TEXT$1);
2584
2605
  process.exit(0);
2585
2606
  };
2586
- main$b();
2607
+ main$c();
2587
2608
 
2588
2609
  const notifyShutdown = singleshot(async () => {
2589
2610
  console.log("Graceful shutdown initiated. Press Ctrl+C again to force quit.");
2590
2611
  });
2591
2612
 
2613
+ const FLUSH_DIRS = ["report", "log", "markdown", "agent"];
2614
+ const flush = async (entryPoint) => {
2615
+ const moduleRoot = dirname(resolve(process.cwd(), entryPoint));
2616
+ const dumpDir = join(moduleRoot, "dump");
2617
+ for (const dir of FLUSH_DIRS) {
2618
+ const target = join(dumpDir, dir);
2619
+ await rm(target, { recursive: true, force: true });
2620
+ console.log(`Removed: ${target}`);
2621
+ }
2622
+ };
2623
+ const main$b = async () => {
2624
+ if (!getEntry(import.meta.url)) {
2625
+ return;
2626
+ }
2627
+ const { values } = getArgs();
2628
+ if (!values.flush) {
2629
+ return;
2630
+ }
2631
+ const entryPoints = getPositionals();
2632
+ if (!entryPoints.length) {
2633
+ throw new Error("Entry point is required");
2634
+ }
2635
+ for (const entryPoint of entryPoints) {
2636
+ await flush(entryPoint);
2637
+ }
2638
+ process.exit(0);
2639
+ };
2640
+ main$b();
2641
+
2592
2642
  const BEFORE_EXIT_FN$5 = singleshot(async () => {
2593
2643
  process.off("SIGINT", BEFORE_EXIT_FN$5);
2594
2644
  const [running = null] = await Backtest.list();
@@ -2617,6 +2667,10 @@ const main$a = async () => {
2617
2667
  if (!values.backtest) {
2618
2668
  return;
2619
2669
  }
2670
+ if (!values.noFlush) {
2671
+ const [entryPoint = null] = getPositionals();
2672
+ entryPoint && await flush(entryPoint);
2673
+ }
2620
2674
  await cli.backtestMainService.connect();
2621
2675
  listenGracefulShutdown$5();
2622
2676
  };
@@ -2646,6 +2700,11 @@ const main$9 = async () => {
2646
2700
  if (!values.walker) {
2647
2701
  return;
2648
2702
  }
2703
+ if (!values.noFlush) {
2704
+ for (const entryPoint of getPositionals()) {
2705
+ await flush(entryPoint);
2706
+ }
2707
+ }
2649
2708
  listenGracefulShutdown$4();
2650
2709
  await cli.walkerMainService.connect();
2651
2710
  };
@@ -3031,6 +3090,7 @@ Modes:
3031
3090
  --live <entry> Live trading with real orders
3032
3091
  --pine <entry> Execute a local .pine indicator file
3033
3092
  --dump Fetch and save raw OHLCV candles
3093
+ --flush <entry...> Delete report/log/markdown/agent folders from strategy dump dir
3034
3094
  --init Scaffold a new project in the current directory
3035
3095
  --help Print this help message
3036
3096
 
@@ -3042,6 +3102,7 @@ Backtest flags:
3042
3102
  --frame <string> Frame name from addFrameSchema (default: first registered)
3043
3103
  --cacheInterval <string> Comma-separated intervals to pre-cache (default: "1m, 15m, 30m, 4h")
3044
3104
  --noCache Skip candle cache warming before the run
3105
+ --noFlush Skip removing report/log/markdown/agent folders before backtest run
3045
3106
  --verbose Log every candle fetch to stdout
3046
3107
  --ui Start web dashboard at http://localhost:60050
3047
3108
  --telegram Send trade notifications to Telegram
@@ -3051,6 +3112,7 @@ Walker flags (--walker):
3051
3112
  --symbol <string> Trading pair (default: BTCUSDT)
3052
3113
  --cacheInterval <string> Comma-separated intervals to pre-cache (default: "1m, 15m, 30m, 4h")
3053
3114
  --noCache Skip candle cache warming before the run
3115
+ --noFlush Skip removing report/log/markdown/agent folders before walker run
3054
3116
  --verbose Log every candle fetch to stdout
3055
3117
  --output <string> Output file base name (default: walker_{SYMBOL}_{TIMESTAMP})
3056
3118
  --json Save results as JSON to ./dump/<output>.json
@@ -3100,6 +3162,13 @@ Candle dump flags (--dump):
3100
3162
 
3101
3163
  Module file ./modules/dump.module is loaded automatically if it exists.
3102
3164
 
3165
+ Flush flags (--flush):
3166
+
3167
+ One or more positional entry points. For each entry point the following
3168
+ subdirectories are removed from <entry-dir>/dump/:
3169
+
3170
+ report log markdown agent
3171
+
3103
3172
  Init flags (--init):
3104
3173
 
3105
3174
  --output <string> Target directory name (default: backtest-kit-project)
@@ -3115,6 +3184,8 @@ Module hooks (loaded automatically by each mode):
3115
3184
  modules/pine.module --pine Exchange schema for PineScript runs
3116
3185
  modules/dump.module --dump Exchange schema for candle dumps
3117
3186
 
3187
+ --flush has no associated module. It only removes dump subdirectories.
3188
+
3118
3189
  Extensions .ts, .mjs, .cjs are tried automatically. Missing module = soft warning.
3119
3190
 
3120
3191
  Environment variables:
@@ -3127,13 +3198,15 @@ Environment variables:
3127
3198
  Examples:
3128
3199
 
3129
3200
  node ${ENTRY_PATH} --backtest ./content/feb_2026.strategy.ts
3130
- node ${ENTRY_PATH} --backtest --symbol BTCUSDT --noCache --ui ./content/feb_2026.strategy.ts
3201
+ node ${ENTRY_PATH} --backtest --symbol BTCUSDT --noCache --noFlush --ui ./content/feb_2026.strategy.ts
3131
3202
  node ${ENTRY_PATH} --walker ./content/feb_2026_v1.strategy.ts ./content/feb_2026_v2.strategy.ts ./content/feb_2026_v3.strategy.ts
3132
- node ${ENTRY_PATH} --walker --symbol BTCUSDT --noCache --markdown ./content/feb_2026_v1.ts ./content/feb_2026_v2.ts
3203
+ node ${ENTRY_PATH} --walker --symbol BTCUSDT --noCache --noFlush --markdown ./content/feb_2026_v1.ts ./content/feb_2026_v2.ts
3133
3204
  node ${ENTRY_PATH} --paper --symbol ETHUSDT ./content/feb_2026.strategy.ts
3134
3205
  node ${ENTRY_PATH} --live --ui --telegram ./content/feb_2026.strategy.ts
3135
3206
  node ${ENTRY_PATH} --pine ./math/feb_2026.pine --timeframe 15m --limit 500 --jsonl
3136
3207
  node ${ENTRY_PATH} --dump --symbol BTCUSDT --timeframe 15m --limit 500 --jsonl
3208
+ node ${ENTRY_PATH} --flush ./content/feb_2026.strategy/feb_2026.strategy.ts
3209
+ node ${ENTRY_PATH} --flush ./content/feb_2026.strategy/feb_2026.strategy.ts ./content/feb_2026.strategy/feb_2026.test.ts
3137
3210
  node ${ENTRY_PATH} --init --output my-trading-bot
3138
3211
  `.trimStart();
3139
3212
  const main$1 = async () => {
@@ -3144,7 +3217,7 @@ const main$1 = async () => {
3144
3217
  if (!values.help) {
3145
3218
  return;
3146
3219
  }
3147
- process.stdout.write(`@backtest-kit/cli ${"6.14.0"}\n\n`);
3220
+ process.stdout.write(`@backtest-kit/cli ${"6.15.0"}\n\n`);
3148
3221
  process.stdout.write(HELP_TEXT);
3149
3222
  process.exit(0);
3150
3223
  };
@@ -3158,7 +3231,7 @@ const main = async () => {
3158
3231
  if (!values.version) {
3159
3232
  return;
3160
3233
  }
3161
- process.stdout.write(`@backtest-kit/cli ${"6.14.0"}\n`);
3234
+ process.stdout.write(`@backtest-kit/cli ${"6.15.0"}\n`);
3162
3235
  process.exit(0);
3163
3236
  };
3164
3237
  main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backtest-kit/cli",
3
- "version": "6.14.0",
3
+ "version": "6.15.0",
4
4
  "description": "Zero-boilerplate CLI runner for backtest-kit strategies. Run backtests, paper trading, and live bots with candle cache warming, web dashboard, and Telegram notifications — no setup code required.",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
@@ -61,11 +61,11 @@
61
61
  "devDependencies": {
62
62
  "@babel/plugin-transform-modules-umd": "7.27.1",
63
63
  "@babel/standalone": "7.29.1",
64
- "@backtest-kit/ui": "6.14.0",
65
- "@backtest-kit/graph": "6.14.0",
66
- "@backtest-kit/ollama": "6.14.0",
67
- "@backtest-kit/pinets": "6.14.0",
68
- "@backtest-kit/signals": "6.14.0",
64
+ "@backtest-kit/ui": "6.15.0",
65
+ "@backtest-kit/graph": "6.15.0",
66
+ "@backtest-kit/ollama": "6.15.0",
67
+ "@backtest-kit/pinets": "6.15.0",
68
+ "@backtest-kit/signals": "6.15.0",
69
69
  "@rollup/plugin-replace": "6.0.3",
70
70
  "@rollup/plugin-typescript": "11.1.6",
71
71
  "@types/image-size": "0.7.0",
@@ -73,7 +73,7 @@
73
73
  "@types/mustache": "4.2.6",
74
74
  "@types/node": "22.9.0",
75
75
  "@types/stack-trace": "0.0.33",
76
- "backtest-kit": "6.14.0",
76
+ "backtest-kit": "6.15.0",
77
77
  "glob": "11.0.1",
78
78
  "markdown-it": "14.1.1",
79
79
  "rimraf": "6.0.1",
@@ -88,12 +88,12 @@
88
88
  "peerDependencies": {
89
89
  "@babel/plugin-transform-modules-umd": "^7.27.1",
90
90
  "@babel/standalone": "^7.29.1",
91
- "@backtest-kit/ui": "^6.14.0",
92
- "@backtest-kit/graph": "^6.14.0",
93
- "@backtest-kit/ollama": "^6.14.0",
94
- "@backtest-kit/pinets": "^6.14.0",
95
- "@backtest-kit/signals": "^6.14.0",
96
- "backtest-kit": "^6.14.0",
91
+ "@backtest-kit/ui": "^6.15.0",
92
+ "@backtest-kit/graph": "^6.15.0",
93
+ "@backtest-kit/ollama": "^6.15.0",
94
+ "@backtest-kit/pinets": "^6.15.0",
95
+ "@backtest-kit/signals": "^6.15.0",
96
+ "backtest-kit": "^6.15.0",
97
97
  "markdown-it": "^14.1.1",
98
98
  "typescript": "^5.0.0"
99
99
  },
@@ -12,12 +12,12 @@
12
12
  "license": "ISC",
13
13
  "type": "commonjs",
14
14
  "dependencies": {
15
- "@backtest-kit/cli": "^6.14.0",
16
- "@backtest-kit/graph": "^6.14.0",
17
- "@backtest-kit/pinets": "^6.14.0",
18
- "@backtest-kit/ui": "^6.14.0",
15
+ "@backtest-kit/cli": "^6.15.0",
16
+ "@backtest-kit/graph": "^6.15.0",
17
+ "@backtest-kit/pinets": "^6.15.0",
18
+ "@backtest-kit/ui": "^6.15.0",
19
19
  "agent-swarm-kit": "^2.5.0",
20
- "backtest-kit": "^6.14.0",
20
+ "backtest-kit": "^6.15.0",
21
21
  "functools-kit": "^2.2.0",
22
22
  "garch": "^1.2.3",
23
23
  "get-moment-stamp": "^1.1.2",