backtest-kit 1.11.4 → 1.11.6

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 CHANGED
@@ -10960,6 +10960,7 @@ const DEFAULT_COLUMNS = Object.freeze({ ...COLUMN_CONFIG });
10960
10960
 
10961
10961
  var _a$1, _b$1, _c$1;
10962
10962
  const MARKDOWN_METHOD_NAME_ENABLE = "MarkdownUtils.enable";
10963
+ const MARKDOWN_METHOD_NAME_DISABLE = "MarkdownUtils.disable";
10963
10964
  const MARKDOWN_METHOD_NAME_USE_ADAPTER = "MarkdownAdapter.useMarkdownAdapter";
10964
10965
  const WAIT_FOR_INIT_SYMBOL$1 = Symbol("wait-for-init");
10965
10966
  const WRITE_SAFE_SYMBOL$1 = Symbol("write-safe");
@@ -11244,6 +11245,83 @@ class MarkdownUtils {
11244
11245
  }
11245
11246
  return functoolsKit.compose(...unList.map((un) => () => void un()));
11246
11247
  };
11248
+ /**
11249
+ * Disables markdown report services selectively.
11250
+ *
11251
+ * Unsubscribes from specified markdown services to stop report generation.
11252
+ * Use this method to stop markdown report generation for specific services while keeping others active.
11253
+ *
11254
+ * Each disabled service will:
11255
+ * - Stop listening to events immediately
11256
+ * - Stop accumulating data for reports
11257
+ * - Stop generating markdown files
11258
+ * - Free up event listener and memory resources
11259
+ *
11260
+ * Unlike enable(), this method does NOT return an unsubscribe function.
11261
+ * Services are unsubscribed immediately upon calling this method.
11262
+ *
11263
+ * @param config - Service configuration object specifying which services to disable. Defaults to disabling all services.
11264
+ * @param config.backtest - Disable backtest result reports with full trade history
11265
+ * @param config.breakeven - Disable breakeven event tracking
11266
+ * @param config.partial - Disable partial profit/loss event tracking
11267
+ * @param config.heat - Disable portfolio heatmap analysis
11268
+ * @param config.walker - Disable walker strategy comparison reports
11269
+ * @param config.performance - Disable performance bottleneck analysis
11270
+ * @param config.risk - Disable risk rejection tracking
11271
+ * @param config.schedule - Disable scheduled signal tracking
11272
+ * @param config.live - Disable live trading event reports
11273
+ *
11274
+ * @example
11275
+ * ```typescript
11276
+ * import { Markdown } from "backtest-kit";
11277
+ *
11278
+ * // Disable specific services
11279
+ * Markdown.disable({ backtest: true, walker: true });
11280
+ *
11281
+ * // Disable all services
11282
+ * Markdown.disable();
11283
+ * ```
11284
+ */
11285
+ this.disable = ({ backtest: bt$1 = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, schedule = false, walker = false, } = WILDCARD_TARGET$1) => {
11286
+ bt.loggerService.debug(MARKDOWN_METHOD_NAME_DISABLE, {
11287
+ backtest: bt$1,
11288
+ breakeven,
11289
+ heat,
11290
+ live,
11291
+ partial,
11292
+ performance,
11293
+ risk,
11294
+ schedule,
11295
+ walker,
11296
+ });
11297
+ if (bt$1) {
11298
+ bt.backtestMarkdownService.unsubscribe();
11299
+ }
11300
+ if (breakeven) {
11301
+ bt.breakevenMarkdownService.unsubscribe();
11302
+ }
11303
+ if (heat) {
11304
+ bt.heatMarkdownService.unsubscribe();
11305
+ }
11306
+ if (live) {
11307
+ bt.liveMarkdownService.unsubscribe();
11308
+ }
11309
+ if (partial) {
11310
+ bt.partialMarkdownService.unsubscribe();
11311
+ }
11312
+ if (performance) {
11313
+ bt.performanceMarkdownService.unsubscribe();
11314
+ }
11315
+ if (risk) {
11316
+ bt.riskMarkdownService.unsubscribe();
11317
+ }
11318
+ if (schedule) {
11319
+ bt.scheduleMarkdownService.unsubscribe();
11320
+ }
11321
+ if (walker) {
11322
+ bt.walkerMarkdownService.unsubscribe();
11323
+ }
11324
+ };
11247
11325
  }
11248
11326
  }
11249
11327
  /**
@@ -19147,6 +19225,7 @@ const REPORT_BASE_METHOD_NAME_WRITE = "ReportBase.write";
19147
19225
  const REPORT_UTILS_METHOD_NAME_USE_REPORT_ADAPTER = "ReportUtils.useReportAdapter";
19148
19226
  const REPORT_UTILS_METHOD_NAME_WRITE_DATA = "ReportUtils.writeReportData";
19149
19227
  const REPORT_UTILS_METHOD_NAME_ENABLE = "ReportUtils.enable";
19228
+ const REPORT_UTILS_METHOD_NAME_DISABLE = "ReportUtils.disable";
19150
19229
  const REPORT_UTILS_METHOD_NAME_USE_DUMMY = "ReportUtils.useDummy";
19151
19230
  const REPORT_UTILS_METHOD_NAME_USE_JSONL = "ReportUtils.useJsonl";
19152
19231
  const WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
@@ -19388,6 +19467,82 @@ class ReportUtils {
19388
19467
  }
19389
19468
  return functoolsKit.compose(...unList.map((un) => () => void un()));
19390
19469
  };
19470
+ /**
19471
+ * Disables report services selectively.
19472
+ *
19473
+ * Unsubscribes from specified report services to stop event logging.
19474
+ * Use this method to stop JSONL logging for specific services while keeping others active.
19475
+ *
19476
+ * Each disabled service will:
19477
+ * - Stop listening to events immediately
19478
+ * - Stop writing to JSONL files
19479
+ * - Free up event listener resources
19480
+ *
19481
+ * Unlike enable(), this method does NOT return an unsubscribe function.
19482
+ * Services are unsubscribed immediately upon calling this method.
19483
+ *
19484
+ * @param config - Service configuration object specifying which services to disable. Defaults to disabling all services.
19485
+ * @param config.backtest - Disable backtest closed signal logging
19486
+ * @param config.breakeven - Disable breakeven event logging
19487
+ * @param config.partial - Disable partial close event logging
19488
+ * @param config.heat - Disable heatmap data logging
19489
+ * @param config.walker - Disable walker iteration logging
19490
+ * @param config.performance - Disable performance metrics logging
19491
+ * @param config.risk - Disable risk rejection logging
19492
+ * @param config.schedule - Disable scheduled signal logging
19493
+ * @param config.live - Disable live trading event logging
19494
+ *
19495
+ * @example
19496
+ * ```typescript
19497
+ * import { Report } from "backtest-kit";
19498
+ *
19499
+ * // Disable specific services
19500
+ * Report.disable({ backtest: true, live: true });
19501
+ *
19502
+ * // Disable all services
19503
+ * Report.disable();
19504
+ * ```
19505
+ */
19506
+ this.disable = ({ backtest: bt$1 = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, schedule = false, walker = false, } = WILDCARD_TARGET) => {
19507
+ bt.loggerService.debug(REPORT_UTILS_METHOD_NAME_DISABLE, {
19508
+ backtest: bt$1,
19509
+ breakeven,
19510
+ heat,
19511
+ live,
19512
+ partial,
19513
+ performance,
19514
+ risk,
19515
+ schedule,
19516
+ walker,
19517
+ });
19518
+ if (bt$1) {
19519
+ bt.backtestReportService.unsubscribe();
19520
+ }
19521
+ if (breakeven) {
19522
+ bt.breakevenReportService.unsubscribe();
19523
+ }
19524
+ if (heat) {
19525
+ bt.heatReportService.unsubscribe();
19526
+ }
19527
+ if (live) {
19528
+ bt.liveReportService.unsubscribe();
19529
+ }
19530
+ if (partial) {
19531
+ bt.partialReportService.unsubscribe();
19532
+ }
19533
+ if (performance) {
19534
+ bt.performanceReportService.unsubscribe();
19535
+ }
19536
+ if (risk) {
19537
+ bt.riskReportService.unsubscribe();
19538
+ }
19539
+ if (schedule) {
19540
+ bt.scheduleReportService.unsubscribe();
19541
+ }
19542
+ if (walker) {
19543
+ bt.walkerReportService.unsubscribe();
19544
+ }
19545
+ };
19391
19546
  }
19392
19547
  }
19393
19548
  /**
@@ -19477,9 +19632,46 @@ const Report = new ReportAdapter();
19477
19632
  const BACKTEST_REPORT_METHOD_NAME_SUBSCRIBE = "BacktestReportService.subscribe";
19478
19633
  const BACKTEST_REPORT_METHOD_NAME_UNSUBSCRIBE = "BacktestReportService.unsubscribe";
19479
19634
  const BACKTEST_REPORT_METHOD_NAME_TICK = "BacktestReportService.tick";
19635
+ /**
19636
+ * Service for logging backtest strategy tick events to SQLite database.
19637
+ *
19638
+ * Captures all backtest signal lifecycle events (idle, opened, active, closed)
19639
+ * and stores them in the Report database for analysis and debugging.
19640
+ *
19641
+ * Features:
19642
+ * - Listens to backtest signal events via signalBacktestEmitter
19643
+ * - Logs all tick event types with full signal details
19644
+ * - Stores events in Report.writeData() for persistence
19645
+ * - Protected against multiple subscriptions using singleshot
19646
+ *
19647
+ * @example
19648
+ * ```typescript
19649
+ * import { BacktestReportService } from "backtest-kit";
19650
+ *
19651
+ * const reportService = new BacktestReportService();
19652
+ *
19653
+ * // Subscribe to backtest events
19654
+ * const unsubscribe = reportService.subscribe();
19655
+ *
19656
+ * // Run backtest...
19657
+ * // Events are automatically logged
19658
+ *
19659
+ * // Later: unsubscribe
19660
+ * await reportService.unsubscribe();
19661
+ * ```
19662
+ */
19480
19663
  class BacktestReportService {
19481
19664
  constructor() {
19665
+ /** Logger service for debug output */
19482
19666
  this.loggerService = inject(TYPES.loggerService);
19667
+ /**
19668
+ * Processes backtest tick events and logs them to the database.
19669
+ * Handles all event types: idle, opened, active, closed.
19670
+ *
19671
+ * @param data - Backtest tick result with signal lifecycle information
19672
+ *
19673
+ * @internal
19674
+ */
19483
19675
  this.tick = async (data) => {
19484
19676
  this.loggerService.log(BACKTEST_REPORT_METHOD_NAME_TICK, { data });
19485
19677
  const baseEvent = {
@@ -19570,6 +19762,21 @@ class BacktestReportService {
19570
19762
  }, { ...searchOptions, signalId: data.signal?.id });
19571
19763
  }
19572
19764
  };
19765
+ /**
19766
+ * Subscribes to backtest signal emitter to receive tick events.
19767
+ * Protected against multiple subscriptions.
19768
+ * Returns an unsubscribe function to stop receiving events.
19769
+ *
19770
+ * @returns Unsubscribe function to stop receiving backtest events
19771
+ *
19772
+ * @example
19773
+ * ```typescript
19774
+ * const service = new BacktestReportService();
19775
+ * const unsubscribe = service.subscribe();
19776
+ * // ... later
19777
+ * unsubscribe();
19778
+ * ```
19779
+ */
19573
19780
  this.subscribe = functoolsKit.singleshot(() => {
19574
19781
  this.loggerService.log(BACKTEST_REPORT_METHOD_NAME_SUBSCRIBE);
19575
19782
  const unsubscribe = signalBacktestEmitter.subscribe(this.tick);
@@ -19578,6 +19785,19 @@ class BacktestReportService {
19578
19785
  unsubscribe();
19579
19786
  };
19580
19787
  });
19788
+ /**
19789
+ * Unsubscribes from backtest signal emitter to stop receiving tick events.
19790
+ * Calls the unsubscribe function returned by subscribe().
19791
+ * If not subscribed, does nothing.
19792
+ *
19793
+ * @example
19794
+ * ```typescript
19795
+ * const service = new BacktestReportService();
19796
+ * service.subscribe();
19797
+ * // ... later
19798
+ * await service.unsubscribe();
19799
+ * ```
19800
+ */
19581
19801
  this.unsubscribe = async () => {
19582
19802
  this.loggerService.log(BACKTEST_REPORT_METHOD_NAME_UNSUBSCRIBE);
19583
19803
  if (this.subscribe.hasValue()) {
@@ -19591,9 +19811,46 @@ class BacktestReportService {
19591
19811
  const LIVE_REPORT_METHOD_NAME_SUBSCRIBE = "LiveReportService.subscribe";
19592
19812
  const LIVE_REPORT_METHOD_NAME_UNSUBSCRIBE = "LiveReportService.unsubscribe";
19593
19813
  const LIVE_REPORT_METHOD_NAME_TICK = "LiveReportService.tick";
19814
+ /**
19815
+ * Service for logging live trading strategy tick events to SQLite database.
19816
+ *
19817
+ * Captures all live trading signal lifecycle events (idle, opened, active, closed)
19818
+ * and stores them in the Report database for real-time monitoring and analysis.
19819
+ *
19820
+ * Features:
19821
+ * - Listens to live signal events via signalLiveEmitter
19822
+ * - Logs all tick event types with full signal details
19823
+ * - Stores events in Report.writeData() for persistence
19824
+ * - Protected against multiple subscriptions using singleshot
19825
+ *
19826
+ * @example
19827
+ * ```typescript
19828
+ * import { LiveReportService } from "backtest-kit";
19829
+ *
19830
+ * const reportService = new LiveReportService();
19831
+ *
19832
+ * // Subscribe to live trading events
19833
+ * const unsubscribe = reportService.subscribe();
19834
+ *
19835
+ * // Run live trading...
19836
+ * // Events are automatically logged
19837
+ *
19838
+ * // Later: unsubscribe
19839
+ * await reportService.unsubscribe();
19840
+ * ```
19841
+ */
19594
19842
  class LiveReportService {
19595
19843
  constructor() {
19844
+ /** Logger service for debug output */
19596
19845
  this.loggerService = inject(TYPES.loggerService);
19846
+ /**
19847
+ * Processes live trading tick events and logs them to the database.
19848
+ * Handles all event types: idle, opened, active, closed.
19849
+ *
19850
+ * @param data - Live trading tick result with signal lifecycle information
19851
+ *
19852
+ * @internal
19853
+ */
19597
19854
  this.tick = async (data) => {
19598
19855
  this.loggerService.log(LIVE_REPORT_METHOD_NAME_TICK, { data });
19599
19856
  const baseEvent = {
@@ -19684,6 +19941,21 @@ class LiveReportService {
19684
19941
  }, { ...searchOptions, signalId: data.signal?.id });
19685
19942
  }
19686
19943
  };
19944
+ /**
19945
+ * Subscribes to live signal emitter to receive tick events.
19946
+ * Protected against multiple subscriptions.
19947
+ * Returns an unsubscribe function to stop receiving events.
19948
+ *
19949
+ * @returns Unsubscribe function to stop receiving live trading events
19950
+ *
19951
+ * @example
19952
+ * ```typescript
19953
+ * const service = new LiveReportService();
19954
+ * const unsubscribe = service.subscribe();
19955
+ * // ... later
19956
+ * unsubscribe();
19957
+ * ```
19958
+ */
19687
19959
  this.subscribe = functoolsKit.singleshot(() => {
19688
19960
  this.loggerService.log(LIVE_REPORT_METHOD_NAME_SUBSCRIBE);
19689
19961
  const unsubscribe = signalLiveEmitter.subscribe(this.tick);
@@ -19692,6 +19964,19 @@ class LiveReportService {
19692
19964
  unsubscribe();
19693
19965
  };
19694
19966
  });
19967
+ /**
19968
+ * Unsubscribes from live signal emitter to stop receiving tick events.
19969
+ * Calls the unsubscribe function returned by subscribe().
19970
+ * If not subscribed, does nothing.
19971
+ *
19972
+ * @example
19973
+ * ```typescript
19974
+ * const service = new LiveReportService();
19975
+ * service.subscribe();
19976
+ * // ... later
19977
+ * await service.unsubscribe();
19978
+ * ```
19979
+ */
19695
19980
  this.unsubscribe = async () => {
19696
19981
  this.loggerService.log(LIVE_REPORT_METHOD_NAME_UNSUBSCRIBE);
19697
19982
  if (this.subscribe.hasValue()) {
@@ -19705,9 +19990,47 @@ class LiveReportService {
19705
19990
  const SCHEDULE_REPORT_METHOD_NAME_SUBSCRIBE = "ScheduleReportService.subscribe";
19706
19991
  const SCHEDULE_REPORT_METHOD_NAME_UNSUBSCRIBE = "ScheduleReportService.unsubscribe";
19707
19992
  const SCHEDULE_REPORT_METHOD_NAME_TICK = "ScheduleReportService.tick";
19993
+ /**
19994
+ * Service for logging scheduled signal events to SQLite database.
19995
+ *
19996
+ * Captures all scheduled signal lifecycle events (scheduled, opened, cancelled)
19997
+ * and stores them in the Report database for tracking delayed order execution.
19998
+ *
19999
+ * Features:
20000
+ * - Listens to signal events via signalEmitter
20001
+ * - Logs scheduled, opened (from scheduled), and cancelled events
20002
+ * - Calculates duration between scheduling and execution/cancellation
20003
+ * - Stores events in Report.writeData() for schedule tracking
20004
+ * - Protected against multiple subscriptions using singleshot
20005
+ *
20006
+ * @example
20007
+ * ```typescript
20008
+ * import { ScheduleReportService } from "backtest-kit";
20009
+ *
20010
+ * const reportService = new ScheduleReportService();
20011
+ *
20012
+ * // Subscribe to scheduled signal events
20013
+ * const unsubscribe = reportService.subscribe();
20014
+ *
20015
+ * // Run strategy with scheduled orders...
20016
+ * // Scheduled events are automatically logged
20017
+ *
20018
+ * // Later: unsubscribe
20019
+ * await reportService.unsubscribe();
20020
+ * ```
20021
+ */
19708
20022
  class ScheduleReportService {
19709
20023
  constructor() {
20024
+ /** Logger service for debug output */
19710
20025
  this.loggerService = inject(TYPES.loggerService);
20026
+ /**
20027
+ * Processes signal tick events and logs scheduled signal lifecycle to the database.
20028
+ * Handles scheduled, opened (from scheduled), and cancelled event types.
20029
+ *
20030
+ * @param data - Strategy tick result with signal lifecycle information
20031
+ *
20032
+ * @internal
20033
+ */
19711
20034
  this.tick = async (data) => {
19712
20035
  this.loggerService.log(SCHEDULE_REPORT_METHOD_NAME_TICK, { data });
19713
20036
  const baseEvent = {
@@ -19794,6 +20117,21 @@ class ScheduleReportService {
19794
20117
  }, searchOptions);
19795
20118
  }
19796
20119
  };
20120
+ /**
20121
+ * Subscribes to signal emitter to receive scheduled signal events.
20122
+ * Protected against multiple subscriptions.
20123
+ * Returns an unsubscribe function to stop receiving events.
20124
+ *
20125
+ * @returns Unsubscribe function to stop receiving scheduled signal events
20126
+ *
20127
+ * @example
20128
+ * ```typescript
20129
+ * const service = new ScheduleReportService();
20130
+ * const unsubscribe = service.subscribe();
20131
+ * // ... later
20132
+ * unsubscribe();
20133
+ * ```
20134
+ */
19797
20135
  this.subscribe = functoolsKit.singleshot(() => {
19798
20136
  this.loggerService.log(SCHEDULE_REPORT_METHOD_NAME_SUBSCRIBE);
19799
20137
  const unsubscribe = signalEmitter.subscribe(this.tick);
@@ -19802,6 +20140,19 @@ class ScheduleReportService {
19802
20140
  unsubscribe();
19803
20141
  };
19804
20142
  });
20143
+ /**
20144
+ * Unsubscribes from signal emitter to stop receiving events.
20145
+ * Calls the unsubscribe function returned by subscribe().
20146
+ * If not subscribed, does nothing.
20147
+ *
20148
+ * @example
20149
+ * ```typescript
20150
+ * const service = new ScheduleReportService();
20151
+ * service.subscribe();
20152
+ * // ... later
20153
+ * await service.unsubscribe();
20154
+ * ```
20155
+ */
19805
20156
  this.unsubscribe = async () => {
19806
20157
  this.loggerService.log(SCHEDULE_REPORT_METHOD_NAME_UNSUBSCRIBE);
19807
20158
  if (this.subscribe.hasValue()) {
@@ -19815,9 +20166,45 @@ class ScheduleReportService {
19815
20166
  const PERFORMANCE_REPORT_METHOD_NAME_SUBSCRIBE = "PerformanceReportService.subscribe";
19816
20167
  const PERFORMANCE_REPORT_METHOD_NAME_UNSUBSCRIBE = "PerformanceReportService.unsubscribe";
19817
20168
  const PERFORMANCE_REPORT_METHOD_NAME_TRACK = "PerformanceReportService.track";
20169
+ /**
20170
+ * Service for logging performance metrics to SQLite database.
20171
+ *
20172
+ * Captures all performance timing events from strategy execution
20173
+ * and stores them in the Report database for bottleneck analysis and optimization.
20174
+ *
20175
+ * Features:
20176
+ * - Listens to performance events via performanceEmitter
20177
+ * - Logs all timing metrics with duration and metadata
20178
+ * - Stores events in Report.writeData() for performance analysis
20179
+ * - Protected against multiple subscriptions using singleshot
20180
+ *
20181
+ * @example
20182
+ * ```typescript
20183
+ * import { PerformanceReportService } from "backtest-kit";
20184
+ *
20185
+ * const reportService = new PerformanceReportService();
20186
+ *
20187
+ * // Subscribe to performance events
20188
+ * const unsubscribe = reportService.subscribe();
20189
+ *
20190
+ * // Run strategy...
20191
+ * // Performance metrics are automatically logged
20192
+ *
20193
+ * // Later: unsubscribe
20194
+ * await reportService.unsubscribe();
20195
+ * ```
20196
+ */
19818
20197
  class PerformanceReportService {
19819
20198
  constructor() {
20199
+ /** Logger service for debug output */
19820
20200
  this.loggerService = inject(TYPES.loggerService);
20201
+ /**
20202
+ * Processes performance tracking events and logs them to the database.
20203
+ *
20204
+ * @param event - Performance contract with timing and metric information
20205
+ *
20206
+ * @internal
20207
+ */
19821
20208
  this.track = async (event) => {
19822
20209
  this.loggerService.log(PERFORMANCE_REPORT_METHOD_NAME_TRACK, { event });
19823
20210
  await Report.writeData("performance", {
@@ -19839,6 +20226,21 @@ class PerformanceReportService {
19839
20226
  walkerName: "",
19840
20227
  });
19841
20228
  };
20229
+ /**
20230
+ * Subscribes to performance emitter to receive timing events.
20231
+ * Protected against multiple subscriptions.
20232
+ * Returns an unsubscribe function to stop receiving events.
20233
+ *
20234
+ * @returns Unsubscribe function to stop receiving performance events
20235
+ *
20236
+ * @example
20237
+ * ```typescript
20238
+ * const service = new PerformanceReportService();
20239
+ * const unsubscribe = service.subscribe();
20240
+ * // ... later
20241
+ * unsubscribe();
20242
+ * ```
20243
+ */
19842
20244
  this.subscribe = functoolsKit.singleshot(() => {
19843
20245
  this.loggerService.log(PERFORMANCE_REPORT_METHOD_NAME_SUBSCRIBE);
19844
20246
  const unsubscribe = performanceEmitter.subscribe(this.track);
@@ -19847,6 +20249,19 @@ class PerformanceReportService {
19847
20249
  unsubscribe();
19848
20250
  };
19849
20251
  });
20252
+ /**
20253
+ * Unsubscribes from performance emitter to stop receiving events.
20254
+ * Calls the unsubscribe function returned by subscribe().
20255
+ * If not subscribed, does nothing.
20256
+ *
20257
+ * @example
20258
+ * ```typescript
20259
+ * const service = new PerformanceReportService();
20260
+ * service.subscribe();
20261
+ * // ... later
20262
+ * await service.unsubscribe();
20263
+ * ```
20264
+ */
19850
20265
  this.unsubscribe = async () => {
19851
20266
  this.loggerService.log(PERFORMANCE_REPORT_METHOD_NAME_UNSUBSCRIBE);
19852
20267
  if (this.subscribe.hasValue()) {
@@ -19860,9 +20275,46 @@ class PerformanceReportService {
19860
20275
  const WALKER_REPORT_METHOD_NAME_SUBSCRIBE = "WalkerReportService.subscribe";
19861
20276
  const WALKER_REPORT_METHOD_NAME_UNSUBSCRIBE = "WalkerReportService.unsubscribe";
19862
20277
  const WALKER_REPORT_METHOD_NAME_TICK = "WalkerReportService.tick";
20278
+ /**
20279
+ * Service for logging walker optimization progress to SQLite database.
20280
+ *
20281
+ * Captures walker strategy optimization results and stores them in the Report database
20282
+ * for tracking parameter optimization and comparing strategy performance.
20283
+ *
20284
+ * Features:
20285
+ * - Listens to walker events via walkerEmitter
20286
+ * - Logs each strategy test result with metrics and statistics
20287
+ * - Tracks best strategy and optimization progress
20288
+ * - Stores events in Report.writeData() for optimization analysis
20289
+ * - Protected against multiple subscriptions using singleshot
20290
+ *
20291
+ * @example
20292
+ * ```typescript
20293
+ * import { WalkerReportService } from "backtest-kit";
20294
+ *
20295
+ * const reportService = new WalkerReportService();
20296
+ *
20297
+ * // Subscribe to walker optimization events
20298
+ * const unsubscribe = reportService.subscribe();
20299
+ *
20300
+ * // Run walker optimization...
20301
+ * // Each strategy result is automatically logged
20302
+ *
20303
+ * // Later: unsubscribe
20304
+ * await reportService.unsubscribe();
20305
+ * ```
20306
+ */
19863
20307
  class WalkerReportService {
19864
20308
  constructor() {
20309
+ /** Logger service for debug output */
19865
20310
  this.loggerService = inject(TYPES.loggerService);
20311
+ /**
20312
+ * Processes walker optimization events and logs them to the database.
20313
+ *
20314
+ * @param data - Walker contract with strategy optimization results
20315
+ *
20316
+ * @internal
20317
+ */
19866
20318
  this.tick = async (data) => {
19867
20319
  this.loggerService.log(WALKER_REPORT_METHOD_NAME_TICK, { data });
19868
20320
  await Report.writeData("walker", {
@@ -19898,6 +20350,21 @@ class WalkerReportService {
19898
20350
  walkerName: data.walkerName,
19899
20351
  });
19900
20352
  };
20353
+ /**
20354
+ * Subscribes to walker emitter to receive optimization progress events.
20355
+ * Protected against multiple subscriptions.
20356
+ * Returns an unsubscribe function to stop receiving events.
20357
+ *
20358
+ * @returns Unsubscribe function to stop receiving walker optimization events
20359
+ *
20360
+ * @example
20361
+ * ```typescript
20362
+ * const service = new WalkerReportService();
20363
+ * const unsubscribe = service.subscribe();
20364
+ * // ... later
20365
+ * unsubscribe();
20366
+ * ```
20367
+ */
19901
20368
  this.subscribe = functoolsKit.singleshot(() => {
19902
20369
  this.loggerService.log(WALKER_REPORT_METHOD_NAME_SUBSCRIBE);
19903
20370
  const unsubscribe = walkerEmitter.subscribe(this.tick);
@@ -19906,6 +20373,19 @@ class WalkerReportService {
19906
20373
  unsubscribe();
19907
20374
  };
19908
20375
  });
20376
+ /**
20377
+ * Unsubscribes from walker emitter to stop receiving events.
20378
+ * Calls the unsubscribe function returned by subscribe().
20379
+ * If not subscribed, does nothing.
20380
+ *
20381
+ * @example
20382
+ * ```typescript
20383
+ * const service = new WalkerReportService();
20384
+ * service.subscribe();
20385
+ * // ... later
20386
+ * await service.unsubscribe();
20387
+ * ```
20388
+ */
19909
20389
  this.unsubscribe = async () => {
19910
20390
  this.loggerService.log(WALKER_REPORT_METHOD_NAME_UNSUBSCRIBE);
19911
20391
  if (this.subscribe.hasValue()) {
@@ -19919,9 +20399,46 @@ class WalkerReportService {
19919
20399
  const HEAT_REPORT_METHOD_NAME_SUBSCRIBE = "HeatReportService.subscribe";
19920
20400
  const HEAT_REPORT_METHOD_NAME_UNSUBSCRIBE = "HeatReportService.unsubscribe";
19921
20401
  const HEAT_REPORT_METHOD_NAME_TICK = "HeatReportService.tick";
20402
+ /**
20403
+ * Service for logging heatmap (closed signals) events to SQLite database.
20404
+ *
20405
+ * Captures closed signal events across all symbols for portfolio-wide
20406
+ * heatmap analysis and stores them in the Report database.
20407
+ *
20408
+ * Features:
20409
+ * - Listens to signal events via signalEmitter
20410
+ * - Logs only closed signals with PNL data
20411
+ * - Stores events in Report.writeData() for heatmap generation
20412
+ * - Protected against multiple subscriptions using singleshot
20413
+ *
20414
+ * @example
20415
+ * ```typescript
20416
+ * import { HeatReportService } from "backtest-kit";
20417
+ *
20418
+ * const reportService = new HeatReportService();
20419
+ *
20420
+ * // Subscribe to signal events
20421
+ * const unsubscribe = reportService.subscribe();
20422
+ *
20423
+ * // Run strategy...
20424
+ * // Closed signals are automatically logged
20425
+ *
20426
+ * // Later: unsubscribe
20427
+ * await reportService.unsubscribe();
20428
+ * ```
20429
+ */
19922
20430
  class HeatReportService {
19923
20431
  constructor() {
20432
+ /** Logger service for debug output */
19924
20433
  this.loggerService = inject(TYPES.loggerService);
20434
+ /**
20435
+ * Processes signal tick events and logs closed signals to the database.
20436
+ * Only processes closed signals - other actions are ignored.
20437
+ *
20438
+ * @param data - Strategy tick result with signal lifecycle information
20439
+ *
20440
+ * @internal
20441
+ */
19925
20442
  this.tick = async (data) => {
19926
20443
  this.loggerService.log(HEAT_REPORT_METHOD_NAME_TICK, { data });
19927
20444
  if (data.action !== "closed") {
@@ -19937,6 +20454,7 @@ class HeatReportService {
19937
20454
  backtest: data.backtest,
19938
20455
  signalId: data.signal?.id,
19939
20456
  position: data.signal?.position,
20457
+ note: data.signal?.note,
19940
20458
  pnl: data.pnl.pnlPercentage,
19941
20459
  closeReason: data.closeReason,
19942
20460
  openTime: data.signal?.pendingAt,
@@ -19950,6 +20468,21 @@ class HeatReportService {
19950
20468
  walkerName: "",
19951
20469
  });
19952
20470
  };
20471
+ /**
20472
+ * Subscribes to signal emitter to receive closed signal events.
20473
+ * Protected against multiple subscriptions.
20474
+ * Returns an unsubscribe function to stop receiving events.
20475
+ *
20476
+ * @returns Unsubscribe function to stop receiving signal events
20477
+ *
20478
+ * @example
20479
+ * ```typescript
20480
+ * const service = new HeatReportService();
20481
+ * const unsubscribe = service.subscribe();
20482
+ * // ... later
20483
+ * unsubscribe();
20484
+ * ```
20485
+ */
19953
20486
  this.subscribe = functoolsKit.singleshot(() => {
19954
20487
  this.loggerService.log(HEAT_REPORT_METHOD_NAME_SUBSCRIBE);
19955
20488
  const unsubscribe = signalEmitter.subscribe(this.tick);
@@ -19958,6 +20491,19 @@ class HeatReportService {
19958
20491
  unsubscribe();
19959
20492
  };
19960
20493
  });
20494
+ /**
20495
+ * Unsubscribes from signal emitter to stop receiving events.
20496
+ * Calls the unsubscribe function returned by subscribe().
20497
+ * If not subscribed, does nothing.
20498
+ *
20499
+ * @example
20500
+ * ```typescript
20501
+ * const service = new HeatReportService();
20502
+ * service.subscribe();
20503
+ * // ... later
20504
+ * await service.unsubscribe();
20505
+ * ```
20506
+ */
19961
20507
  this.unsubscribe = async () => {
19962
20508
  this.loggerService.log(HEAT_REPORT_METHOD_NAME_UNSUBSCRIBE);
19963
20509
  if (this.subscribe.hasValue()) {
@@ -19972,9 +20518,46 @@ const PARTIAL_REPORT_METHOD_NAME_SUBSCRIBE = "PartialReportService.subscribe";
19972
20518
  const PARTIAL_REPORT_METHOD_NAME_UNSUBSCRIBE = "PartialReportService.unsubscribe";
19973
20519
  const PARTIAL_REPORT_METHOD_NAME_TICK_PROFIT = "PartialReportService.tickProfit";
19974
20520
  const PARTIAL_REPORT_METHOD_NAME_TICK_LOSS = "PartialReportService.tickLoss";
20521
+ /**
20522
+ * Service for logging partial profit/loss events to SQLite database.
20523
+ *
20524
+ * Captures all partial position exit events (profit and loss levels)
20525
+ * and stores them in the Report database for tracking partial closures.
20526
+ *
20527
+ * Features:
20528
+ * - Listens to partial profit events via partialProfitSubject
20529
+ * - Listens to partial loss events via partialLossSubject
20530
+ * - Logs all partial exit events with level and price information
20531
+ * - Stores events in Report.writeData() for persistence
20532
+ * - Protected against multiple subscriptions using singleshot
20533
+ *
20534
+ * @example
20535
+ * ```typescript
20536
+ * import { PartialReportService } from "backtest-kit";
20537
+ *
20538
+ * const reportService = new PartialReportService();
20539
+ *
20540
+ * // Subscribe to partial events
20541
+ * const unsubscribe = reportService.subscribe();
20542
+ *
20543
+ * // Run strategy with partial exits...
20544
+ * // Partial events are automatically logged
20545
+ *
20546
+ * // Later: unsubscribe
20547
+ * await reportService.unsubscribe();
20548
+ * ```
20549
+ */
19975
20550
  class PartialReportService {
19976
20551
  constructor() {
20552
+ /** Logger service for debug output */
19977
20553
  this.loggerService = inject(TYPES.loggerService);
20554
+ /**
20555
+ * Processes partial profit events and logs them to the database.
20556
+ *
20557
+ * @param data - Partial profit event data with signal, level, and price information
20558
+ *
20559
+ * @internal
20560
+ */
19978
20561
  this.tickProfit = async (data) => {
19979
20562
  this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_TICK_PROFIT, { data });
19980
20563
  await Report.writeData("partial", {
@@ -20006,6 +20589,13 @@ class PartialReportService {
20006
20589
  walkerName: "",
20007
20590
  });
20008
20591
  };
20592
+ /**
20593
+ * Processes partial loss events and logs them to the database.
20594
+ *
20595
+ * @param data - Partial loss event data with signal, level, and price information
20596
+ *
20597
+ * @internal
20598
+ */
20009
20599
  this.tickLoss = async (data) => {
20010
20600
  this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_TICK_LOSS, { data });
20011
20601
  await Report.writeData("partial", {
@@ -20037,6 +20627,21 @@ class PartialReportService {
20037
20627
  walkerName: "",
20038
20628
  });
20039
20629
  };
20630
+ /**
20631
+ * Subscribes to partial profit/loss emitters to receive partial exit events.
20632
+ * Protected against multiple subscriptions.
20633
+ * Returns an unsubscribe function to stop receiving events.
20634
+ *
20635
+ * @returns Unsubscribe function to stop receiving partial events
20636
+ *
20637
+ * @example
20638
+ * ```typescript
20639
+ * const service = new PartialReportService();
20640
+ * const unsubscribe = service.subscribe();
20641
+ * // ... later
20642
+ * unsubscribe();
20643
+ * ```
20644
+ */
20040
20645
  this.subscribe = functoolsKit.singleshot(() => {
20041
20646
  this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_SUBSCRIBE);
20042
20647
  const unProfit = partialProfitSubject.subscribe(this.tickProfit);
@@ -20047,6 +20652,19 @@ class PartialReportService {
20047
20652
  unLoss();
20048
20653
  };
20049
20654
  });
20655
+ /**
20656
+ * Unsubscribes from partial profit/loss emitters to stop receiving events.
20657
+ * Calls the unsubscribe function returned by subscribe().
20658
+ * If not subscribed, does nothing.
20659
+ *
20660
+ * @example
20661
+ * ```typescript
20662
+ * const service = new PartialReportService();
20663
+ * service.subscribe();
20664
+ * // ... later
20665
+ * await service.unsubscribe();
20666
+ * ```
20667
+ */
20050
20668
  this.unsubscribe = async () => {
20051
20669
  this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_UNSUBSCRIBE);
20052
20670
  if (this.subscribe.hasValue()) {
@@ -20060,9 +20678,45 @@ class PartialReportService {
20060
20678
  const BREAKEVEN_REPORT_METHOD_NAME_SUBSCRIBE = "BreakevenReportService.subscribe";
20061
20679
  const BREAKEVEN_REPORT_METHOD_NAME_UNSUBSCRIBE = "BreakevenReportService.unsubscribe";
20062
20680
  const BREAKEVEN_REPORT_METHOD_NAME_TICK = "BreakevenReportService.tickBreakeven";
20681
+ /**
20682
+ * Service for logging breakeven events to SQLite database.
20683
+ *
20684
+ * Captures all breakeven events (when signal reaches breakeven point)
20685
+ * and stores them in the Report database for analysis and tracking.
20686
+ *
20687
+ * Features:
20688
+ * - Listens to breakeven events via breakevenSubject
20689
+ * - Logs all breakeven achievements with full signal details
20690
+ * - Stores events in Report.writeData() for persistence
20691
+ * - Protected against multiple subscriptions using singleshot
20692
+ *
20693
+ * @example
20694
+ * ```typescript
20695
+ * import { BreakevenReportService } from "backtest-kit";
20696
+ *
20697
+ * const reportService = new BreakevenReportService();
20698
+ *
20699
+ * // Subscribe to breakeven events
20700
+ * const unsubscribe = reportService.subscribe();
20701
+ *
20702
+ * // Run strategy...
20703
+ * // Breakeven events are automatically logged
20704
+ *
20705
+ * // Later: unsubscribe
20706
+ * await reportService.unsubscribe();
20707
+ * ```
20708
+ */
20063
20709
  class BreakevenReportService {
20064
20710
  constructor() {
20711
+ /** Logger service for debug output */
20065
20712
  this.loggerService = inject(TYPES.loggerService);
20713
+ /**
20714
+ * Processes breakeven events and logs them to the database.
20715
+ *
20716
+ * @param data - Breakeven event data with signal and price information
20717
+ *
20718
+ * @internal
20719
+ */
20066
20720
  this.tickBreakeven = async (data) => {
20067
20721
  this.loggerService.log(BREAKEVEN_REPORT_METHOD_NAME_TICK, { data });
20068
20722
  await Report.writeData("breakeven", {
@@ -20092,6 +20746,21 @@ class BreakevenReportService {
20092
20746
  walkerName: "",
20093
20747
  });
20094
20748
  };
20749
+ /**
20750
+ * Subscribes to breakeven signal emitter to receive breakeven events.
20751
+ * Protected against multiple subscriptions.
20752
+ * Returns an unsubscribe function to stop receiving events.
20753
+ *
20754
+ * @returns Unsubscribe function to stop receiving breakeven events
20755
+ *
20756
+ * @example
20757
+ * ```typescript
20758
+ * const service = new BreakevenReportService();
20759
+ * const unsubscribe = service.subscribe();
20760
+ * // ... later
20761
+ * unsubscribe();
20762
+ * ```
20763
+ */
20095
20764
  this.subscribe = functoolsKit.singleshot(() => {
20096
20765
  this.loggerService.log(BREAKEVEN_REPORT_METHOD_NAME_SUBSCRIBE);
20097
20766
  const unsubscribe = breakevenSubject.subscribe(this.tickBreakeven);
@@ -20100,6 +20769,19 @@ class BreakevenReportService {
20100
20769
  unsubscribe();
20101
20770
  };
20102
20771
  });
20772
+ /**
20773
+ * Unsubscribes from breakeven signal emitter to stop receiving events.
20774
+ * Calls the unsubscribe function returned by subscribe().
20775
+ * If not subscribed, does nothing.
20776
+ *
20777
+ * @example
20778
+ * ```typescript
20779
+ * const service = new BreakevenReportService();
20780
+ * service.subscribe();
20781
+ * // ... later
20782
+ * await service.unsubscribe();
20783
+ * ```
20784
+ */
20103
20785
  this.unsubscribe = async () => {
20104
20786
  this.loggerService.log(BREAKEVEN_REPORT_METHOD_NAME_UNSUBSCRIBE);
20105
20787
  if (this.subscribe.hasValue()) {
@@ -20113,9 +20795,45 @@ class BreakevenReportService {
20113
20795
  const RISK_REPORT_METHOD_NAME_SUBSCRIBE = "RiskReportService.subscribe";
20114
20796
  const RISK_REPORT_METHOD_NAME_UNSUBSCRIBE = "RiskReportService.unsubscribe";
20115
20797
  const RISK_REPORT_METHOD_NAME_TICK = "RiskReportService.tickRejection";
20798
+ /**
20799
+ * Service for logging risk rejection events to SQLite database.
20800
+ *
20801
+ * Captures all signal rejection events from the risk management system
20802
+ * and stores them in the Report database for risk analysis and auditing.
20803
+ *
20804
+ * Features:
20805
+ * - Listens to risk rejection events via riskSubject
20806
+ * - Logs all rejected signals with reason and pending signal details
20807
+ * - Stores events in Report.writeData() for risk tracking
20808
+ * - Protected against multiple subscriptions using singleshot
20809
+ *
20810
+ * @example
20811
+ * ```typescript
20812
+ * import { RiskReportService } from "backtest-kit";
20813
+ *
20814
+ * const reportService = new RiskReportService();
20815
+ *
20816
+ * // Subscribe to risk rejection events
20817
+ * const unsubscribe = reportService.subscribe();
20818
+ *
20819
+ * // Run strategy with risk management...
20820
+ * // Rejection events are automatically logged
20821
+ *
20822
+ * // Later: unsubscribe
20823
+ * await reportService.unsubscribe();
20824
+ * ```
20825
+ */
20116
20826
  class RiskReportService {
20117
20827
  constructor() {
20828
+ /** Logger service for debug output */
20118
20829
  this.loggerService = inject(TYPES.loggerService);
20830
+ /**
20831
+ * Processes risk rejection events and logs them to the database.
20832
+ *
20833
+ * @param data - Risk event with rejection reason and pending signal information
20834
+ *
20835
+ * @internal
20836
+ */
20119
20837
  this.tickRejection = async (data) => {
20120
20838
  this.loggerService.log(RISK_REPORT_METHOD_NAME_TICK, { data });
20121
20839
  await Report.writeData("risk", {
@@ -20149,6 +20867,21 @@ class RiskReportService {
20149
20867
  walkerName: "",
20150
20868
  });
20151
20869
  };
20870
+ /**
20871
+ * Subscribes to risk rejection emitter to receive rejection events.
20872
+ * Protected against multiple subscriptions.
20873
+ * Returns an unsubscribe function to stop receiving events.
20874
+ *
20875
+ * @returns Unsubscribe function to stop receiving risk rejection events
20876
+ *
20877
+ * @example
20878
+ * ```typescript
20879
+ * const service = new RiskReportService();
20880
+ * const unsubscribe = service.subscribe();
20881
+ * // ... later
20882
+ * unsubscribe();
20883
+ * ```
20884
+ */
20152
20885
  this.subscribe = functoolsKit.singleshot(() => {
20153
20886
  this.loggerService.log(RISK_REPORT_METHOD_NAME_SUBSCRIBE);
20154
20887
  const unsubscribe = riskSubject.subscribe(this.tickRejection);
@@ -20157,6 +20890,19 @@ class RiskReportService {
20157
20890
  unsubscribe();
20158
20891
  };
20159
20892
  });
20893
+ /**
20894
+ * Unsubscribes from risk rejection emitter to stop receiving events.
20895
+ * Calls the unsubscribe function returned by subscribe().
20896
+ * If not subscribed, does nothing.
20897
+ *
20898
+ * @example
20899
+ * ```typescript
20900
+ * const service = new RiskReportService();
20901
+ * service.subscribe();
20902
+ * // ... later
20903
+ * await service.unsubscribe();
20904
+ * ```
20905
+ */
20160
20906
  this.unsubscribe = async () => {
20161
20907
  this.loggerService.log(RISK_REPORT_METHOD_NAME_UNSUBSCRIBE);
20162
20908
  if (this.subscribe.hasValue()) {