backtest-kit 1.5.3 β 1.5.5
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 +97 -8
- package/build/index.cjs +909 -234
- package/build/index.mjs +910 -235
- package/package.json +2 -2
- package/types.d.ts +69 -0
package/README.md
CHANGED
|
@@ -227,12 +227,13 @@ Backtest.background("BTCUSDT", {
|
|
|
227
227
|
|
|
228
228
|
- π€ **Mode Switching**: Seamlessly switch between backtest and live modes with identical strategy code. π
|
|
229
229
|
- π **Crash Recovery**: Atomic persistence ensures state recovery after crashesβno duplicate signals. ποΈ
|
|
230
|
-
- π **Graceful Shutdown**: Stop backtests, live trading, and walkers programmatically with `
|
|
230
|
+
- π **Graceful Shutdown**: Stop backtests, live trading, and walkers programmatically with `stop()` methods. Current signals complete normally, no forced closures. βΉοΈ
|
|
231
|
+
- π **Task Monitoring**: Track all running instances with `list()` methods. Monitor task statuses: `ready`, `pending`, `fulfilled`, `rejected`. π
|
|
231
232
|
- π οΈ **Custom Validators**: Define validation rules with strategy-level throttling and price logic checks. π§
|
|
232
233
|
- π‘οΈ **Signal Lifecycle**: Type-safe state machine prevents invalid state transitions. π
|
|
233
234
|
- π¦ **Dependency Inversion**: Lazy-load components at runtime for modular, scalable designs. π§©
|
|
234
235
|
- π **Schema Reflection**: Runtime introspection with `listExchanges()`, `listStrategies()`, `listFrames()`. π
|
|
235
|
-
- π¬ **Data Validation**: Automatic detection and rejection of incomplete candles from Binance API with anomaly checks.
|
|
236
|
+
- π¬ **Data Validation**: Automatic detection and rejection of incomplete candles from Binance API with anomaly checks. β
|
|
236
237
|
|
|
237
238
|
---
|
|
238
239
|
|
|
@@ -252,6 +253,7 @@ Backtest.background("BTCUSDT", {
|
|
|
252
253
|
- π **`addFrame`**: Configure timeframes for backtesting. π
|
|
253
254
|
- π **`Backtest` / `Live`**: Run strategies in backtest or live mode (generator or background). β‘
|
|
254
255
|
- π **`Backtest.stop()` / `Live.stop()` / `Walker.stop()`**: Gracefully stop running strategiesβcurrent signals complete, no forced exits. βΉοΈ
|
|
256
|
+
- π **`Backtest.list()` / `Live.list()` / `Walker.list()`**: Monitor all running instances with status tracking (`ready`, `pending`, `fulfilled`, `rejected`). π
|
|
255
257
|
- π
**`Schedule`**: Track scheduled signals and cancellation rate for limit orders. π
|
|
256
258
|
- π **`Partial`**: Access partial profit/loss statistics and reports for risk management. Track signals reaching milestone levels (10%, 20%, 30%, etc.). πΉ
|
|
257
259
|
- π― **`Constant`**: Kelly Criterion-based constants for optimal take profit (TP_LEVEL1-3) and stop loss (SL_LEVEL1-2) levels. π
|
|
@@ -1356,9 +1358,43 @@ listenPartialProfit(({ symbol, signal, price, level, backtest }) => {
|
|
|
1356
1358
|
|
|
1357
1359
|
---
|
|
1358
1360
|
|
|
1359
|
-
### 11. Graceful Shutdown
|
|
1361
|
+
### 11. Graceful Shutdown and Task Monitoring
|
|
1360
1362
|
|
|
1361
|
-
The framework provides graceful shutdown mechanisms for all execution modes: backtests, live trading, and walkers. This ensures clean termination without forced signal closures.
|
|
1363
|
+
The framework provides graceful shutdown mechanisms and task monitoring for all execution modes: backtests, live trading, and walkers. This ensures clean termination without forced signal closures and visibility into running tasks.
|
|
1364
|
+
|
|
1365
|
+
#### Task Status Monitoring
|
|
1366
|
+
|
|
1367
|
+
Use `list()` method to monitor all running instances and their statuses:
|
|
1368
|
+
|
|
1369
|
+
```typescript
|
|
1370
|
+
// Get list of all backtest instances
|
|
1371
|
+
const backtests = await Backtest.list();
|
|
1372
|
+
console.log(backtests);
|
|
1373
|
+
// [
|
|
1374
|
+
// { symbol: "BTCUSDT", strategyName: "strategy-1", status: "pending" },
|
|
1375
|
+
// { symbol: "ETHUSDT", strategyName: "strategy-2", status: "fulfilled" }
|
|
1376
|
+
// ]
|
|
1377
|
+
|
|
1378
|
+
// Get list of all live trading instances
|
|
1379
|
+
const liveInstances = await Live.list();
|
|
1380
|
+
console.log(liveInstances);
|
|
1381
|
+
// [
|
|
1382
|
+
// { symbol: "BTCUSDT", strategyName: "my-strategy", status: "pending" }
|
|
1383
|
+
// ]
|
|
1384
|
+
|
|
1385
|
+
// Get list of all walker instances
|
|
1386
|
+
const walkers = await Walker.list();
|
|
1387
|
+
console.log(walkers);
|
|
1388
|
+
// [
|
|
1389
|
+
// { symbol: "BTCUSDT", walkerName: "btc-walker", status: "fulfilled" }
|
|
1390
|
+
// ]
|
|
1391
|
+
```
|
|
1392
|
+
|
|
1393
|
+
**Task Statuses:**
|
|
1394
|
+
- `ready` - Task created but not yet started
|
|
1395
|
+
- `pending` - Task is currently running
|
|
1396
|
+
- `fulfilled` - Task completed successfully
|
|
1397
|
+
- `rejected` - Task failed with an error
|
|
1362
1398
|
|
|
1363
1399
|
#### How Graceful Shutdown Works
|
|
1364
1400
|
|
|
@@ -1369,6 +1405,7 @@ When you call `Backtest.stop()`, `Live.stop()`, or `Walker.stop()`:
|
|
|
1369
1405
|
3. **Callbacks Fire** - All lifecycle callbacks (`onClose`, etc.) execute as expected
|
|
1370
1406
|
4. **Events Emitted** - Completion events (`listenDoneBacktest`, `listenDoneLive`, `listenWalkerComplete`) fire
|
|
1371
1407
|
5. **State Persisted** - In live mode, final state is saved to disk
|
|
1408
|
+
6. **Status Updated** - Task status transitions from `pending` to `fulfilled`
|
|
1372
1409
|
|
|
1373
1410
|
#### Backtest Shutdown
|
|
1374
1411
|
|
|
@@ -1442,11 +1479,17 @@ Walker.background("BTCUSDT", {
|
|
|
1442
1479
|
walkerName: "btc-walker"
|
|
1443
1480
|
});
|
|
1444
1481
|
|
|
1482
|
+
// Monitor walker status
|
|
1483
|
+
const walkers = await Walker.list();
|
|
1484
|
+
console.log(walkers.find(w => w.walkerName === "btc-walker"));
|
|
1485
|
+
// { symbol: "BTCUSDT", walkerName: "btc-walker", status: "pending" }
|
|
1486
|
+
|
|
1445
1487
|
// Or stop walker manually after some condition
|
|
1446
1488
|
await Walker.stop("BTCUSDT", "btc-walker");
|
|
1447
1489
|
// - Current strategy completes execution
|
|
1448
1490
|
// - Remaining strategies (not yet started) won't run
|
|
1449
1491
|
// - listenWalkerComplete fires with partial results
|
|
1492
|
+
// - Status changes to "fulfilled"
|
|
1450
1493
|
|
|
1451
1494
|
listenWalkerComplete((results) => {
|
|
1452
1495
|
console.log("Walker stopped early:", results.bestStrategy);
|
|
@@ -1469,6 +1512,31 @@ await Walker.stop("BTCUSDT", "walker-A");
|
|
|
1469
1512
|
// - walker-B continues unaffected
|
|
1470
1513
|
```
|
|
1471
1514
|
|
|
1515
|
+
#### Monitoring Multiple Instances
|
|
1516
|
+
|
|
1517
|
+
Track multiple running instances across different symbols:
|
|
1518
|
+
|
|
1519
|
+
```typescript
|
|
1520
|
+
// Start multiple backtests
|
|
1521
|
+
Backtest.background("BTCUSDT", { strategyName: "strategy-1", ... });
|
|
1522
|
+
Backtest.background("ETHUSDT", { strategyName: "strategy-2", ... });
|
|
1523
|
+
Backtest.background("SOLUSDT", { strategyName: "strategy-3", ... });
|
|
1524
|
+
|
|
1525
|
+
// Monitor all running backtests
|
|
1526
|
+
const allBacktests = await Backtest.list();
|
|
1527
|
+
console.log(`Running: ${allBacktests.filter(b => b.status === "pending").length}`);
|
|
1528
|
+
console.log(`Completed: ${allBacktests.filter(b => b.status === "fulfilled").length}`);
|
|
1529
|
+
console.log(`Failed: ${allBacktests.filter(b => b.status === "rejected").length}`);
|
|
1530
|
+
|
|
1531
|
+
// Stop specific instance
|
|
1532
|
+
await Backtest.stop("ETHUSDT", "strategy-2");
|
|
1533
|
+
|
|
1534
|
+
// Verify status change
|
|
1535
|
+
const updated = await Backtest.list();
|
|
1536
|
+
const eth = updated.find(b => b.symbol === "ETHUSDT");
|
|
1537
|
+
console.log(eth.status); // "fulfilled"
|
|
1538
|
+
```
|
|
1539
|
+
|
|
1472
1540
|
#### Use Cases
|
|
1473
1541
|
|
|
1474
1542
|
1. **Backtest Early Exit** - Stop backtest when strategy performs poorly (e.g., drawdown > 10%)
|
|
@@ -1476,25 +1544,46 @@ await Walker.stop("BTCUSDT", "walker-A");
|
|
|
1476
1544
|
3. **Walker Optimization** - Skip remaining strategies when first one is excellent
|
|
1477
1545
|
4. **Resource Management** - Stop long-running backtests to free up resources
|
|
1478
1546
|
5. **Conditional Termination** - Stop based on external events (API limits, market conditions)
|
|
1547
|
+
6. **Task Monitoring Dashboard** - Build real-time monitoring UI with `list()` method
|
|
1548
|
+
7. **Health Checks** - Monitor task statuses for alerting and automation
|
|
1479
1549
|
|
|
1480
1550
|
#### Best Practices
|
|
1481
1551
|
|
|
1482
1552
|
1. **Always await stop()** - Ensure graceful shutdown completes before exiting process
|
|
1483
1553
|
2. **Use listenDone events** - Track completion with `listenDoneBacktest`, `listenDoneLive`, `listenWalkerComplete`
|
|
1484
|
-
3. **
|
|
1485
|
-
4. **
|
|
1486
|
-
5. **
|
|
1554
|
+
3. **Monitor task status** - Use `list()` method to track running instances and their states
|
|
1555
|
+
4. **Don't force-kill** - Let signals complete naturally instead of process.exit()
|
|
1556
|
+
5. **Save reports** - Call `dump()` methods before stopping to preserve results
|
|
1557
|
+
6. **Test shutdown paths** - Write tests that verify graceful shutdown behavior
|
|
1558
|
+
7. **Handle rejected status** - Check for `rejected` status and handle errors appropriately
|
|
1487
1559
|
|
|
1488
1560
|
```typescript
|
|
1489
|
-
// GOOD - Graceful shutdown with cleanup
|
|
1561
|
+
// GOOD - Graceful shutdown with cleanup and monitoring
|
|
1562
|
+
const instances = await Backtest.list();
|
|
1563
|
+
console.log(`Running instances: ${instances.filter(i => i.status === "pending").length}`);
|
|
1564
|
+
|
|
1490
1565
|
await Backtest.stop("BTCUSDT", "my-strategy");
|
|
1491
1566
|
await Backtest.dump("my-strategy"); // Save report
|
|
1567
|
+
|
|
1568
|
+
// Verify status change
|
|
1569
|
+
const updated = await Backtest.list();
|
|
1570
|
+
const stopped = updated.find(i => i.symbol === "BTCUSDT");
|
|
1571
|
+
console.log(`Status: ${stopped.status}`); // "fulfilled"
|
|
1492
1572
|
console.log("Shutdown complete");
|
|
1493
1573
|
|
|
1494
1574
|
// BAD - Forced exit without cleanup
|
|
1495
1575
|
process.exit(0); // Signals may not complete, callbacks may not fire
|
|
1496
1576
|
```
|
|
1497
1577
|
|
|
1578
|
+
#### Live Trading Considerations
|
|
1579
|
+
|
|
1580
|
+
**Important:** Live mode operates on real-time data with actual minute intervals. When testing graceful shutdown in live mode:
|
|
1581
|
+
|
|
1582
|
+
- Expect longer wait times (minimum 1 minute per candle)
|
|
1583
|
+
- Use backtest mode for quick iteration and testing
|
|
1584
|
+
- Live mode is designed for production trading, not rapid testing
|
|
1585
|
+
- Status transitions may take longer due to real-time constraints
|
|
1586
|
+
|
|
1498
1587
|
---
|
|
1499
1588
|
|
|
1500
1589
|
### 12. Scheduled Signal Persistence
|