backtest-kit 1.4.12 → 1.4.14
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/build/index.cjs +130 -100
- package/build/index.mjs +130 -100
- package/package.json +1 -1
- package/types.d.ts +80 -64
package/build/index.cjs
CHANGED
|
@@ -10464,6 +10464,11 @@ const columns = [
|
|
|
10464
10464
|
label: "Symbol",
|
|
10465
10465
|
format: (data) => data.symbol,
|
|
10466
10466
|
},
|
|
10467
|
+
{
|
|
10468
|
+
key: "strategyName",
|
|
10469
|
+
label: "Strategy",
|
|
10470
|
+
format: (data) => data.strategyName,
|
|
10471
|
+
},
|
|
10467
10472
|
{
|
|
10468
10473
|
key: "signalId",
|
|
10469
10474
|
label: "Signal ID",
|
|
@@ -10498,7 +10503,7 @@ const columns = [
|
|
|
10498
10503
|
/** Maximum number of events to store in partial reports */
|
|
10499
10504
|
const MAX_EVENTS = 250;
|
|
10500
10505
|
/**
|
|
10501
|
-
* Storage class for accumulating partial profit/loss events per symbol.
|
|
10506
|
+
* Storage class for accumulating partial profit/loss events per symbol-strategy pair.
|
|
10502
10507
|
* Maintains a chronological list of profit and loss level events.
|
|
10503
10508
|
*/
|
|
10504
10509
|
class ReportStorage {
|
|
@@ -10509,17 +10514,17 @@ class ReportStorage {
|
|
|
10509
10514
|
/**
|
|
10510
10515
|
* Adds a profit event to the storage.
|
|
10511
10516
|
*
|
|
10512
|
-
* @param symbol - Trading pair symbol
|
|
10513
10517
|
* @param data - Signal row data
|
|
10514
10518
|
* @param currentPrice - Current market price
|
|
10515
10519
|
* @param level - Profit level reached
|
|
10516
10520
|
* @param backtest - True if backtest mode
|
|
10517
10521
|
*/
|
|
10518
|
-
addProfitEvent(
|
|
10522
|
+
addProfitEvent(data, currentPrice, level, backtest, timestamp) {
|
|
10519
10523
|
this._eventList.push({
|
|
10520
10524
|
timestamp,
|
|
10521
10525
|
action: "profit",
|
|
10522
|
-
symbol,
|
|
10526
|
+
symbol: data.symbol,
|
|
10527
|
+
strategyName: data.strategyName,
|
|
10523
10528
|
signalId: data.id,
|
|
10524
10529
|
position: data.position,
|
|
10525
10530
|
currentPrice,
|
|
@@ -10534,17 +10539,17 @@ class ReportStorage {
|
|
|
10534
10539
|
/**
|
|
10535
10540
|
* Adds a loss event to the storage.
|
|
10536
10541
|
*
|
|
10537
|
-
* @param symbol - Trading pair symbol
|
|
10538
10542
|
* @param data - Signal row data
|
|
10539
10543
|
* @param currentPrice - Current market price
|
|
10540
10544
|
* @param level - Loss level reached
|
|
10541
10545
|
* @param backtest - True if backtest mode
|
|
10542
10546
|
*/
|
|
10543
|
-
addLossEvent(
|
|
10547
|
+
addLossEvent(data, currentPrice, level, backtest, timestamp) {
|
|
10544
10548
|
this._eventList.push({
|
|
10545
10549
|
timestamp,
|
|
10546
10550
|
action: "loss",
|
|
10547
|
-
symbol,
|
|
10551
|
+
symbol: data.symbol,
|
|
10552
|
+
strategyName: data.strategyName,
|
|
10548
10553
|
signalId: data.id,
|
|
10549
10554
|
position: data.position,
|
|
10550
10555
|
currentPrice,
|
|
@@ -10580,35 +10585,37 @@ class ReportStorage {
|
|
|
10580
10585
|
};
|
|
10581
10586
|
}
|
|
10582
10587
|
/**
|
|
10583
|
-
* Generates markdown report with all partial events for a symbol (View).
|
|
10588
|
+
* Generates markdown report with all partial events for a symbol-strategy pair (View).
|
|
10584
10589
|
*
|
|
10585
10590
|
* @param symbol - Trading pair symbol
|
|
10591
|
+
* @param strategyName - Strategy name
|
|
10586
10592
|
* @returns Markdown formatted report with all events
|
|
10587
10593
|
*/
|
|
10588
|
-
async getReport(symbol) {
|
|
10594
|
+
async getReport(symbol, strategyName) {
|
|
10589
10595
|
const stats = await this.getData();
|
|
10590
10596
|
if (stats.totalEvents === 0) {
|
|
10591
|
-
return functoolsKit.str.newline(`# Partial Profit/Loss Report: ${symbol}`, "", "No partial profit/loss events recorded yet.");
|
|
10597
|
+
return functoolsKit.str.newline(`# Partial Profit/Loss Report: ${symbol}:${strategyName}`, "", "No partial profit/loss events recorded yet.");
|
|
10592
10598
|
}
|
|
10593
10599
|
const header = columns.map((col) => col.label);
|
|
10594
10600
|
const separator = columns.map(() => "---");
|
|
10595
10601
|
const rows = this._eventList.map((event) => columns.map((col) => col.format(event)));
|
|
10596
10602
|
const tableData = [header, separator, ...rows];
|
|
10597
10603
|
const table = functoolsKit.str.newline(tableData.map((row) => `| ${row.join(" | ")} |`));
|
|
10598
|
-
return functoolsKit.str.newline(`# Partial Profit/Loss Report: ${symbol}`, "", table, "", `**Total events:** ${stats.totalEvents}`, `**Profit events:** ${stats.totalProfit}`, `**Loss events:** ${stats.totalLoss}`);
|
|
10604
|
+
return functoolsKit.str.newline(`# Partial Profit/Loss Report: ${symbol}:${strategyName}`, "", table, "", `**Total events:** ${stats.totalEvents}`, `**Profit events:** ${stats.totalProfit}`, `**Loss events:** ${stats.totalLoss}`);
|
|
10599
10605
|
}
|
|
10600
10606
|
/**
|
|
10601
|
-
* Saves symbol report to disk.
|
|
10607
|
+
* Saves symbol-strategy report to disk.
|
|
10602
10608
|
*
|
|
10603
10609
|
* @param symbol - Trading pair symbol
|
|
10610
|
+
* @param strategyName - Strategy name
|
|
10604
10611
|
* @param path - Directory path to save report (default: "./dump/partial")
|
|
10605
10612
|
*/
|
|
10606
|
-
async dump(symbol, path$1 = "./dump/partial") {
|
|
10607
|
-
const markdown = await this.getReport(symbol);
|
|
10613
|
+
async dump(symbol, strategyName, path$1 = "./dump/partial") {
|
|
10614
|
+
const markdown = await this.getReport(symbol, strategyName);
|
|
10608
10615
|
try {
|
|
10609
10616
|
const dir = path.join(process.cwd(), path$1);
|
|
10610
10617
|
await fs.mkdir(dir, { recursive: true });
|
|
10611
|
-
const filename = `${symbol}.md`;
|
|
10618
|
+
const filename = `${symbol}_${strategyName}.md`;
|
|
10612
10619
|
const filepath = path.join(dir, filename);
|
|
10613
10620
|
await fs.writeFile(filepath, markdown, "utf-8");
|
|
10614
10621
|
console.log(`Partial profit/loss report saved: ${filepath}`);
|
|
@@ -10623,10 +10630,10 @@ class ReportStorage {
|
|
|
10623
10630
|
*
|
|
10624
10631
|
* Features:
|
|
10625
10632
|
* - Listens to partial profit and loss events via partialProfitSubject/partialLossSubject
|
|
10626
|
-
* - Accumulates all events (profit, loss) per symbol
|
|
10633
|
+
* - Accumulates all events (profit, loss) per symbol-strategy pair
|
|
10627
10634
|
* - Generates markdown tables with detailed event information
|
|
10628
10635
|
* - Provides statistics (total profit/loss events)
|
|
10629
|
-
* - Saves reports to disk in dump/partial/{symbol}.md
|
|
10636
|
+
* - Saves reports to disk in dump/partial/{symbol}_{strategyName}.md
|
|
10630
10637
|
*
|
|
10631
10638
|
* @example
|
|
10632
10639
|
* ```typescript
|
|
@@ -10636,7 +10643,7 @@ class ReportStorage {
|
|
|
10636
10643
|
* // No manual callback setup needed
|
|
10637
10644
|
*
|
|
10638
10645
|
* // Later: generate and save report
|
|
10639
|
-
* await service.dump("BTCUSDT");
|
|
10646
|
+
* await service.dump("BTCUSDT", "my-strategy");
|
|
10640
10647
|
* ```
|
|
10641
10648
|
*/
|
|
10642
10649
|
class PartialMarkdownService {
|
|
@@ -10644,10 +10651,10 @@ class PartialMarkdownService {
|
|
|
10644
10651
|
/** Logger service for debug output */
|
|
10645
10652
|
this.loggerService = inject(TYPES.loggerService);
|
|
10646
10653
|
/**
|
|
10647
|
-
* Memoized function to get or create ReportStorage for a symbol.
|
|
10648
|
-
* Each symbol gets its own isolated storage instance.
|
|
10654
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy pair.
|
|
10655
|
+
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
10649
10656
|
*/
|
|
10650
|
-
this.getStorage = functoolsKit.memoize(([symbol]) =>
|
|
10657
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName]) => JSON.stringify([symbol, strategyName]), () => new ReportStorage());
|
|
10651
10658
|
/**
|
|
10652
10659
|
* Processes profit events and accumulates them.
|
|
10653
10660
|
* Should be called from partialProfitSubject subscription.
|
|
@@ -10664,8 +10671,8 @@ class PartialMarkdownService {
|
|
|
10664
10671
|
this.loggerService.log("partialMarkdownService tickProfit", {
|
|
10665
10672
|
data,
|
|
10666
10673
|
});
|
|
10667
|
-
const storage = this.getStorage(data.symbol);
|
|
10668
|
-
storage.addProfitEvent(data.
|
|
10674
|
+
const storage = this.getStorage(data.symbol, data.data.strategyName);
|
|
10675
|
+
storage.addProfitEvent(data.data, data.currentPrice, data.level, data.backtest, data.timestamp);
|
|
10669
10676
|
};
|
|
10670
10677
|
/**
|
|
10671
10678
|
* Processes loss events and accumulates them.
|
|
@@ -10683,101 +10690,113 @@ class PartialMarkdownService {
|
|
|
10683
10690
|
this.loggerService.log("partialMarkdownService tickLoss", {
|
|
10684
10691
|
data,
|
|
10685
10692
|
});
|
|
10686
|
-
const storage = this.getStorage(data.symbol);
|
|
10687
|
-
storage.addLossEvent(data.
|
|
10693
|
+
const storage = this.getStorage(data.symbol, data.data.strategyName);
|
|
10694
|
+
storage.addLossEvent(data.data, data.currentPrice, data.level, data.backtest, data.timestamp);
|
|
10688
10695
|
};
|
|
10689
10696
|
/**
|
|
10690
|
-
* Gets statistical data from all partial profit/loss events for a symbol.
|
|
10697
|
+
* Gets statistical data from all partial profit/loss events for a symbol-strategy pair.
|
|
10691
10698
|
* Delegates to ReportStorage.getData().
|
|
10692
10699
|
*
|
|
10693
10700
|
* @param symbol - Trading pair symbol to get data for
|
|
10701
|
+
* @param strategyName - Strategy name to get data for
|
|
10694
10702
|
* @returns Statistical data object with all metrics
|
|
10695
10703
|
*
|
|
10696
10704
|
* @example
|
|
10697
10705
|
* ```typescript
|
|
10698
10706
|
* const service = new PartialMarkdownService();
|
|
10699
|
-
* const stats = await service.getData("BTCUSDT");
|
|
10707
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
10700
10708
|
* console.log(stats.totalProfit, stats.totalLoss);
|
|
10701
10709
|
* ```
|
|
10702
10710
|
*/
|
|
10703
|
-
this.getData = async (symbol) => {
|
|
10711
|
+
this.getData = async (symbol, strategyName) => {
|
|
10704
10712
|
this.loggerService.log("partialMarkdownService getData", {
|
|
10705
10713
|
symbol,
|
|
10714
|
+
strategyName,
|
|
10706
10715
|
});
|
|
10707
|
-
const storage = this.getStorage(symbol);
|
|
10716
|
+
const storage = this.getStorage(symbol, strategyName);
|
|
10708
10717
|
return storage.getData();
|
|
10709
10718
|
};
|
|
10710
10719
|
/**
|
|
10711
|
-
* Generates markdown report with all partial events for a symbol.
|
|
10720
|
+
* Generates markdown report with all partial events for a symbol-strategy pair.
|
|
10712
10721
|
* Delegates to ReportStorage.getReport().
|
|
10713
10722
|
*
|
|
10714
10723
|
* @param symbol - Trading pair symbol to generate report for
|
|
10724
|
+
* @param strategyName - Strategy name to generate report for
|
|
10715
10725
|
* @returns Markdown formatted report string with table of all events
|
|
10716
10726
|
*
|
|
10717
10727
|
* @example
|
|
10718
10728
|
* ```typescript
|
|
10719
10729
|
* const service = new PartialMarkdownService();
|
|
10720
|
-
* const markdown = await service.getReport("BTCUSDT");
|
|
10730
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
10721
10731
|
* console.log(markdown);
|
|
10722
10732
|
* ```
|
|
10723
10733
|
*/
|
|
10724
|
-
this.getReport = async (symbol) => {
|
|
10734
|
+
this.getReport = async (symbol, strategyName) => {
|
|
10725
10735
|
this.loggerService.log("partialMarkdownService getReport", {
|
|
10726
10736
|
symbol,
|
|
10737
|
+
strategyName,
|
|
10727
10738
|
});
|
|
10728
|
-
const storage = this.getStorage(symbol);
|
|
10729
|
-
return storage.getReport(symbol);
|
|
10739
|
+
const storage = this.getStorage(symbol, strategyName);
|
|
10740
|
+
return storage.getReport(symbol, strategyName);
|
|
10730
10741
|
};
|
|
10731
10742
|
/**
|
|
10732
|
-
* Saves symbol report to disk.
|
|
10743
|
+
* Saves symbol-strategy report to disk.
|
|
10733
10744
|
* Creates directory if it doesn't exist.
|
|
10734
10745
|
* Delegates to ReportStorage.dump().
|
|
10735
10746
|
*
|
|
10736
10747
|
* @param symbol - Trading pair symbol to save report for
|
|
10748
|
+
* @param strategyName - Strategy name to save report for
|
|
10737
10749
|
* @param path - Directory path to save report (default: "./dump/partial")
|
|
10738
10750
|
*
|
|
10739
10751
|
* @example
|
|
10740
10752
|
* ```typescript
|
|
10741
10753
|
* const service = new PartialMarkdownService();
|
|
10742
10754
|
*
|
|
10743
|
-
* // Save to default path: ./dump/partial/
|
|
10744
|
-
* await service.dump("BTCUSDT");
|
|
10755
|
+
* // Save to default path: ./dump/partial/BTCUSDT_my-strategy.md
|
|
10756
|
+
* await service.dump("BTCUSDT", "my-strategy");
|
|
10745
10757
|
*
|
|
10746
|
-
* // Save to custom path: ./custom/path/
|
|
10747
|
-
* await service.dump("BTCUSDT", "./custom/path");
|
|
10758
|
+
* // Save to custom path: ./custom/path/BTCUSDT_my-strategy.md
|
|
10759
|
+
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
10748
10760
|
* ```
|
|
10749
10761
|
*/
|
|
10750
|
-
this.dump = async (symbol, path = "./dump/partial") => {
|
|
10762
|
+
this.dump = async (symbol, strategyName, path = "./dump/partial") => {
|
|
10751
10763
|
this.loggerService.log("partialMarkdownService dump", {
|
|
10752
10764
|
symbol,
|
|
10765
|
+
strategyName,
|
|
10753
10766
|
path,
|
|
10754
10767
|
});
|
|
10755
|
-
const storage = this.getStorage(symbol);
|
|
10756
|
-
await storage.dump(symbol, path);
|
|
10768
|
+
const storage = this.getStorage(symbol, strategyName);
|
|
10769
|
+
await storage.dump(symbol, strategyName, path);
|
|
10757
10770
|
};
|
|
10758
10771
|
/**
|
|
10759
10772
|
* Clears accumulated event data from storage.
|
|
10760
|
-
* If
|
|
10761
|
-
* If
|
|
10773
|
+
* If ctx is provided, clears only that specific symbol-strategy pair's data.
|
|
10774
|
+
* If nothing is provided, clears all data.
|
|
10762
10775
|
*
|
|
10763
|
-
* @param
|
|
10776
|
+
* @param ctx - Optional context with symbol and strategyName
|
|
10764
10777
|
*
|
|
10765
10778
|
* @example
|
|
10766
10779
|
* ```typescript
|
|
10767
10780
|
* const service = new PartialMarkdownService();
|
|
10768
10781
|
*
|
|
10769
|
-
* // Clear specific symbol
|
|
10770
|
-
* await service.clear("BTCUSDT");
|
|
10782
|
+
* // Clear specific symbol-strategy pair
|
|
10783
|
+
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
10771
10784
|
*
|
|
10772
|
-
* // Clear all
|
|
10785
|
+
* // Clear all data
|
|
10773
10786
|
* await service.clear();
|
|
10774
10787
|
* ```
|
|
10775
10788
|
*/
|
|
10776
|
-
this.clear = async (
|
|
10789
|
+
this.clear = async (ctx) => {
|
|
10777
10790
|
this.loggerService.log("partialMarkdownService clear", {
|
|
10778
|
-
|
|
10791
|
+
ctx,
|
|
10779
10792
|
});
|
|
10780
|
-
|
|
10793
|
+
if (ctx) {
|
|
10794
|
+
const key = JSON.stringify([ctx.symbol, ctx.strategyName]);
|
|
10795
|
+
this.getStorage.clear(key);
|
|
10796
|
+
}
|
|
10797
|
+
else {
|
|
10798
|
+
this.getStorage.clear();
|
|
10799
|
+
}
|
|
10781
10800
|
};
|
|
10782
10801
|
/**
|
|
10783
10802
|
* Initializes the service by subscribing to partial profit/loss events.
|
|
@@ -13079,24 +13098,26 @@ class BacktestUtils {
|
|
|
13079
13098
|
/**
|
|
13080
13099
|
* Saves strategy report to disk.
|
|
13081
13100
|
*
|
|
13101
|
+
* @param symbol - Trading pair symbol
|
|
13082
13102
|
* @param strategyName - Strategy name to save report for
|
|
13083
13103
|
* @param path - Optional directory path to save report (default: "./dump/backtest")
|
|
13084
13104
|
*
|
|
13085
13105
|
* @example
|
|
13086
13106
|
* ```typescript
|
|
13087
13107
|
* // Save to default path: ./dump/backtest/my-strategy.md
|
|
13088
|
-
* await Backtest.dump("my-strategy");
|
|
13108
|
+
* await Backtest.dump("BTCUSDT", "my-strategy");
|
|
13089
13109
|
*
|
|
13090
13110
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
13091
|
-
* await Backtest.dump("my-strategy", "./custom/path");
|
|
13111
|
+
* await Backtest.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
13092
13112
|
* ```
|
|
13093
13113
|
*/
|
|
13094
|
-
this.dump = async (strategyName, path) => {
|
|
13114
|
+
this.dump = async (symbol, strategyName, path) => {
|
|
13095
13115
|
backtest$1.loggerService.info(BACKTEST_METHOD_NAME_DUMP, {
|
|
13116
|
+
symbol,
|
|
13096
13117
|
strategyName,
|
|
13097
13118
|
path,
|
|
13098
13119
|
});
|
|
13099
|
-
await backtest$1.backtestMarkdownService.dump(strategyName, path);
|
|
13120
|
+
await backtest$1.backtestMarkdownService.dump(symbol, strategyName, path);
|
|
13100
13121
|
};
|
|
13101
13122
|
}
|
|
13102
13123
|
}
|
|
@@ -13292,24 +13313,26 @@ class LiveUtils {
|
|
|
13292
13313
|
/**
|
|
13293
13314
|
* Saves strategy report to disk.
|
|
13294
13315
|
*
|
|
13316
|
+
* @param symbol - Trading pair symbol
|
|
13295
13317
|
* @param strategyName - Strategy name to save report for
|
|
13296
13318
|
* @param path - Optional directory path to save report (default: "./dump/live")
|
|
13297
13319
|
*
|
|
13298
13320
|
* @example
|
|
13299
13321
|
* ```typescript
|
|
13300
13322
|
* // Save to default path: ./dump/live/my-strategy.md
|
|
13301
|
-
* await Live.dump("my-strategy");
|
|
13323
|
+
* await Live.dump("BTCUSDT", "my-strategy");
|
|
13302
13324
|
*
|
|
13303
13325
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
13304
|
-
* await Live.dump("my-strategy", "./custom/path");
|
|
13326
|
+
* await Live.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
13305
13327
|
* ```
|
|
13306
13328
|
*/
|
|
13307
|
-
this.dump = async (strategyName, path) => {
|
|
13329
|
+
this.dump = async (symbol, strategyName, path) => {
|
|
13308
13330
|
backtest$1.loggerService.info(LIVE_METHOD_NAME_DUMP, {
|
|
13331
|
+
symbol,
|
|
13309
13332
|
strategyName,
|
|
13310
13333
|
path,
|
|
13311
13334
|
});
|
|
13312
|
-
await backtest$1.liveMarkdownService.dump(strategyName, path);
|
|
13335
|
+
await backtest$1.liveMarkdownService.dump(symbol, strategyName, path);
|
|
13313
13336
|
};
|
|
13314
13337
|
}
|
|
13315
13338
|
}
|
|
@@ -13403,24 +13426,26 @@ class ScheduleUtils {
|
|
|
13403
13426
|
/**
|
|
13404
13427
|
* Saves strategy report to disk.
|
|
13405
13428
|
*
|
|
13429
|
+
* @param symbol - Trading pair symbol
|
|
13406
13430
|
* @param strategyName - Strategy name to save report for
|
|
13407
13431
|
* @param path - Optional directory path to save report (default: "./dump/schedule")
|
|
13408
13432
|
*
|
|
13409
13433
|
* @example
|
|
13410
13434
|
* ```typescript
|
|
13411
13435
|
* // Save to default path: ./dump/schedule/my-strategy.md
|
|
13412
|
-
* await Schedule.dump("my-strategy");
|
|
13436
|
+
* await Schedule.dump("BTCUSDT", "my-strategy");
|
|
13413
13437
|
*
|
|
13414
13438
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
13415
|
-
* await Schedule.dump("my-strategy", "./custom/path");
|
|
13439
|
+
* await Schedule.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
13416
13440
|
* ```
|
|
13417
13441
|
*/
|
|
13418
|
-
this.dump = async (strategyName, path) => {
|
|
13442
|
+
this.dump = async (symbol, strategyName, path) => {
|
|
13419
13443
|
backtest$1.loggerService.info(SCHEDULE_METHOD_NAME_DUMP, {
|
|
13444
|
+
symbol,
|
|
13420
13445
|
strategyName,
|
|
13421
13446
|
path,
|
|
13422
13447
|
});
|
|
13423
|
-
await backtest$1.scheduleMarkdownService.dump(strategyName, path);
|
|
13448
|
+
await backtest$1.scheduleMarkdownService.dump(symbol, strategyName, path);
|
|
13424
13449
|
};
|
|
13425
13450
|
}
|
|
13426
13451
|
}
|
|
@@ -13532,20 +13557,21 @@ class Performance {
|
|
|
13532
13557
|
* Creates directory if it doesn't exist.
|
|
13533
13558
|
* Default path: ./dump/performance/{strategyName}.md
|
|
13534
13559
|
*
|
|
13560
|
+
* @param symbol - Trading pair symbol
|
|
13535
13561
|
* @param strategyName - Strategy name to save report for
|
|
13536
13562
|
* @param path - Optional custom directory path
|
|
13537
13563
|
*
|
|
13538
13564
|
* @example
|
|
13539
13565
|
* ```typescript
|
|
13540
13566
|
* // Save to default path: ./dump/performance/my-strategy.md
|
|
13541
|
-
* await Performance.dump("my-strategy");
|
|
13567
|
+
* await Performance.dump("BTCUSDT", "my-strategy");
|
|
13542
13568
|
*
|
|
13543
13569
|
* // Save to custom path: ./reports/perf/my-strategy.md
|
|
13544
|
-
* await Performance.dump("my-strategy", "./reports/perf");
|
|
13570
|
+
* await Performance.dump("BTCUSDT", "my-strategy", "./reports/perf");
|
|
13545
13571
|
* ```
|
|
13546
13572
|
*/
|
|
13547
|
-
static async dump(strategyName, path = "./dump/performance") {
|
|
13548
|
-
return backtest$1.performanceMarkdownService.dump(strategyName, path);
|
|
13573
|
+
static async dump(symbol, strategyName, path = "./dump/performance") {
|
|
13574
|
+
return backtest$1.performanceMarkdownService.dump(symbol, strategyName, path);
|
|
13549
13575
|
}
|
|
13550
13576
|
}
|
|
13551
13577
|
|
|
@@ -14140,26 +14166,26 @@ const PARTIAL_METHOD_NAME_DUMP = "PartialUtils.dump";
|
|
|
14140
14166
|
*
|
|
14141
14167
|
* Data source:
|
|
14142
14168
|
* - PartialMarkdownService listens to partialProfitSubject/partialLossSubject
|
|
14143
|
-
* - Accumulates events in ReportStorage (max 250 events per symbol)
|
|
14144
|
-
* - Events include: timestamp, action, symbol, signalId, position, level, price, mode
|
|
14169
|
+
* - Accumulates events in ReportStorage (max 250 events per symbol-strategy pair)
|
|
14170
|
+
* - Events include: timestamp, action, symbol, strategyName, signalId, position, level, price, mode
|
|
14145
14171
|
*
|
|
14146
14172
|
* @example
|
|
14147
14173
|
* ```typescript
|
|
14148
14174
|
* import { Partial } from "./classes/Partial";
|
|
14149
14175
|
*
|
|
14150
|
-
* // Get statistical data for BTCUSDT
|
|
14151
|
-
* const stats = await Partial.getData("BTCUSDT");
|
|
14176
|
+
* // Get statistical data for BTCUSDT:my-strategy
|
|
14177
|
+
* const stats = await Partial.getData("BTCUSDT", "my-strategy");
|
|
14152
14178
|
* console.log(`Total events: ${stats.totalEvents}`);
|
|
14153
14179
|
* console.log(`Profit events: ${stats.totalProfit}`);
|
|
14154
14180
|
* console.log(`Loss events: ${stats.totalLoss}`);
|
|
14155
14181
|
*
|
|
14156
14182
|
* // Generate markdown report
|
|
14157
|
-
* const markdown = await Partial.getReport("BTCUSDT");
|
|
14183
|
+
* const markdown = await Partial.getReport("BTCUSDT", "my-strategy");
|
|
14158
14184
|
* console.log(markdown); // Formatted table with all events
|
|
14159
14185
|
*
|
|
14160
14186
|
* // Export report to file
|
|
14161
|
-
* await Partial.dump("BTCUSDT"); // Saves to ./dump/partial/
|
|
14162
|
-
* await Partial.dump("BTCUSDT", "./custom/path"); // Custom directory
|
|
14187
|
+
* await Partial.dump("BTCUSDT", "my-strategy"); // Saves to ./dump/partial/BTCUSDT_my-strategy.md
|
|
14188
|
+
* await Partial.dump("BTCUSDT", "my-strategy", "./custom/path"); // Custom directory
|
|
14163
14189
|
* ```
|
|
14164
14190
|
*/
|
|
14165
14191
|
class PartialUtils {
|
|
@@ -14171,11 +14197,12 @@ class PartialUtils {
|
|
|
14171
14197
|
* Returns aggregated metrics calculated from all profit and loss events.
|
|
14172
14198
|
*
|
|
14173
14199
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
14200
|
+
* @param strategyName - Strategy name (e.g., "my-strategy")
|
|
14174
14201
|
* @returns Promise resolving to PartialStatistics object with counts and event list
|
|
14175
14202
|
*
|
|
14176
14203
|
* @example
|
|
14177
14204
|
* ```typescript
|
|
14178
|
-
* const stats = await Partial.getData("BTCUSDT");
|
|
14205
|
+
* const stats = await Partial.getData("BTCUSDT", "my-strategy");
|
|
14179
14206
|
*
|
|
14180
14207
|
* console.log(`Total events: ${stats.totalEvents}`);
|
|
14181
14208
|
* console.log(`Profit events: ${stats.totalProfit} (${(stats.totalProfit / stats.totalEvents * 100).toFixed(1)}%)`);
|
|
@@ -14187,16 +14214,17 @@ class PartialUtils {
|
|
|
14187
14214
|
* }
|
|
14188
14215
|
* ```
|
|
14189
14216
|
*/
|
|
14190
|
-
this.getData = async (symbol) => {
|
|
14191
|
-
backtest$1.loggerService.info(PARTIAL_METHOD_NAME_GET_DATA, { symbol });
|
|
14192
|
-
return await backtest$1.partialMarkdownService.getData(symbol);
|
|
14217
|
+
this.getData = async (symbol, strategyName) => {
|
|
14218
|
+
backtest$1.loggerService.info(PARTIAL_METHOD_NAME_GET_DATA, { symbol, strategyName });
|
|
14219
|
+
return await backtest$1.partialMarkdownService.getData(symbol, strategyName);
|
|
14193
14220
|
};
|
|
14194
14221
|
/**
|
|
14195
|
-
* Generates markdown report with all partial profit/loss events for a symbol.
|
|
14222
|
+
* Generates markdown report with all partial profit/loss events for a symbol-strategy pair.
|
|
14196
14223
|
*
|
|
14197
14224
|
* Creates formatted table containing:
|
|
14198
14225
|
* - Action (PROFIT/LOSS)
|
|
14199
14226
|
* - Symbol
|
|
14227
|
+
* - Strategy
|
|
14200
14228
|
* - Signal ID
|
|
14201
14229
|
* - Position (LONG/SHORT)
|
|
14202
14230
|
* - Level % (+10%, -20%, etc)
|
|
@@ -14207,35 +14235,36 @@ class PartialUtils {
|
|
|
14207
14235
|
* Also includes summary statistics at the end.
|
|
14208
14236
|
*
|
|
14209
14237
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
14238
|
+
* @param strategyName - Strategy name (e.g., "my-strategy")
|
|
14210
14239
|
* @returns Promise resolving to markdown formatted report string
|
|
14211
14240
|
*
|
|
14212
14241
|
* @example
|
|
14213
14242
|
* ```typescript
|
|
14214
|
-
* const markdown = await Partial.getReport("BTCUSDT");
|
|
14243
|
+
* const markdown = await Partial.getReport("BTCUSDT", "my-strategy");
|
|
14215
14244
|
* console.log(markdown);
|
|
14216
14245
|
*
|
|
14217
14246
|
* // Output:
|
|
14218
|
-
* // # Partial Profit/Loss Report: BTCUSDT
|
|
14247
|
+
* // # Partial Profit/Loss Report: BTCUSDT:my-strategy
|
|
14219
14248
|
* //
|
|
14220
|
-
* // | Action | Symbol | Signal ID | Position | Level % | Current Price | Timestamp | Mode |
|
|
14221
|
-
* // | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
14222
|
-
* // | PROFIT | BTCUSDT | abc123 | LONG | +10% | 51500.00000000 USD | 2024-01-15T10:30:00.000Z | Backtest |
|
|
14223
|
-
* // | LOSS | BTCUSDT | abc123 | LONG | -10% | 49000.00000000 USD | 2024-01-15T11:00:00.000Z | Backtest |
|
|
14249
|
+
* // | Action | Symbol | Strategy | Signal ID | Position | Level % | Current Price | Timestamp | Mode |
|
|
14250
|
+
* // | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
14251
|
+
* // | PROFIT | BTCUSDT | my-strategy | abc123 | LONG | +10% | 51500.00000000 USD | 2024-01-15T10:30:00.000Z | Backtest |
|
|
14252
|
+
* // | LOSS | BTCUSDT | my-strategy | abc123 | LONG | -10% | 49000.00000000 USD | 2024-01-15T11:00:00.000Z | Backtest |
|
|
14224
14253
|
* //
|
|
14225
14254
|
* // **Total events:** 2
|
|
14226
14255
|
* // **Profit events:** 1
|
|
14227
14256
|
* // **Loss events:** 1
|
|
14228
14257
|
* ```
|
|
14229
14258
|
*/
|
|
14230
|
-
this.getReport = async (symbol) => {
|
|
14231
|
-
backtest$1.loggerService.info(PARTIAL_METHOD_NAME_GET_REPORT, { symbol });
|
|
14232
|
-
return await backtest$1.partialMarkdownService.getReport(symbol);
|
|
14259
|
+
this.getReport = async (symbol, strategyName) => {
|
|
14260
|
+
backtest$1.loggerService.info(PARTIAL_METHOD_NAME_GET_REPORT, { symbol, strategyName });
|
|
14261
|
+
return await backtest$1.partialMarkdownService.getReport(symbol, strategyName);
|
|
14233
14262
|
};
|
|
14234
14263
|
/**
|
|
14235
14264
|
* Generates and saves markdown report to file.
|
|
14236
14265
|
*
|
|
14237
14266
|
* Creates directory if it doesn't exist.
|
|
14238
|
-
* Filename format: {symbol}.md (e.g., "
|
|
14267
|
+
* Filename format: {symbol}_{strategyName}.md (e.g., "BTCUSDT_my-strategy.md")
|
|
14239
14268
|
*
|
|
14240
14269
|
* Delegates to PartialMarkdownService.dump() which:
|
|
14241
14270
|
* 1. Generates markdown report via getReport()
|
|
@@ -14244,26 +14273,27 @@ class PartialUtils {
|
|
|
14244
14273
|
* 4. Logs success/failure to console
|
|
14245
14274
|
*
|
|
14246
14275
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
14276
|
+
* @param strategyName - Strategy name (e.g., "my-strategy")
|
|
14247
14277
|
* @param path - Output directory path (default: "./dump/partial")
|
|
14248
14278
|
* @returns Promise that resolves when file is written
|
|
14249
14279
|
*
|
|
14250
14280
|
* @example
|
|
14251
14281
|
* ```typescript
|
|
14252
|
-
* // Save to default path: ./dump/partial/
|
|
14253
|
-
* await Partial.dump("BTCUSDT");
|
|
14282
|
+
* // Save to default path: ./dump/partial/BTCUSDT_my-strategy.md
|
|
14283
|
+
* await Partial.dump("BTCUSDT", "my-strategy");
|
|
14254
14284
|
*
|
|
14255
|
-
* // Save to custom path: ./reports/partial/
|
|
14256
|
-
* await Partial.dump("BTCUSDT", "./reports/partial");
|
|
14285
|
+
* // Save to custom path: ./reports/partial/BTCUSDT_my-strategy.md
|
|
14286
|
+
* await Partial.dump("BTCUSDT", "my-strategy", "./reports/partial");
|
|
14257
14287
|
*
|
|
14258
14288
|
* // After multiple symbols backtested, export all reports
|
|
14259
14289
|
* for (const symbol of ["BTCUSDT", "ETHUSDT", "BNBUSDT"]) {
|
|
14260
|
-
* await Partial.dump(symbol, "./backtest-results");
|
|
14290
|
+
* await Partial.dump(symbol, "my-strategy", "./backtest-results");
|
|
14261
14291
|
* }
|
|
14262
14292
|
* ```
|
|
14263
14293
|
*/
|
|
14264
|
-
this.dump = async (symbol, path) => {
|
|
14265
|
-
backtest$1.loggerService.info(PARTIAL_METHOD_NAME_DUMP, { symbol, path });
|
|
14266
|
-
await backtest$1.partialMarkdownService.dump(symbol, path);
|
|
14294
|
+
this.dump = async (symbol, strategyName, path) => {
|
|
14295
|
+
backtest$1.loggerService.info(PARTIAL_METHOD_NAME_DUMP, { symbol, strategyName, path });
|
|
14296
|
+
await backtest$1.partialMarkdownService.dump(symbol, strategyName, path);
|
|
14267
14297
|
};
|
|
14268
14298
|
}
|
|
14269
14299
|
}
|
|
@@ -14276,9 +14306,9 @@ class PartialUtils {
|
|
|
14276
14306
|
* import { Partial } from "backtest-kit";
|
|
14277
14307
|
*
|
|
14278
14308
|
* // Usage same as PartialUtils methods
|
|
14279
|
-
* const stats = await Partial.getData("BTCUSDT");
|
|
14280
|
-
* const report = await Partial.getReport("BTCUSDT");
|
|
14281
|
-
* await Partial.dump("BTCUSDT");
|
|
14309
|
+
* const stats = await Partial.getData("BTCUSDT", "my-strategy");
|
|
14310
|
+
* const report = await Partial.getReport("BTCUSDT", "my-strategy");
|
|
14311
|
+
* await Partial.dump("BTCUSDT", "my-strategy");
|
|
14282
14312
|
* ```
|
|
14283
14313
|
*/
|
|
14284
14314
|
const Partial = new PartialUtils();
|