backtest-kit 1.11.5 → 1.11.7
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 +860 -8
- package/build/index.mjs +860 -8
- package/package.json +1 -1
- package/types.d.ts +704 -13
package/build/index.cjs
CHANGED
|
@@ -10217,6 +10217,48 @@ const partial_columns = [
|
|
|
10217
10217
|
format: (data) => `${data.currentPrice.toFixed(8)} USD`,
|
|
10218
10218
|
isVisible: () => true,
|
|
10219
10219
|
},
|
|
10220
|
+
{
|
|
10221
|
+
key: "priceOpen",
|
|
10222
|
+
label: "Entry Price",
|
|
10223
|
+
format: (data) => (data.priceOpen ? `${data.priceOpen.toFixed(8)} USD` : "N/A"),
|
|
10224
|
+
isVisible: () => true,
|
|
10225
|
+
},
|
|
10226
|
+
{
|
|
10227
|
+
key: "priceTakeProfit",
|
|
10228
|
+
label: "Take Profit",
|
|
10229
|
+
format: (data) => (data.priceTakeProfit ? `${data.priceTakeProfit.toFixed(8)} USD` : "N/A"),
|
|
10230
|
+
isVisible: () => true,
|
|
10231
|
+
},
|
|
10232
|
+
{
|
|
10233
|
+
key: "priceStopLoss",
|
|
10234
|
+
label: "Stop Loss",
|
|
10235
|
+
format: (data) => (data.priceStopLoss ? `${data.priceStopLoss.toFixed(8)} USD` : "N/A"),
|
|
10236
|
+
isVisible: () => true,
|
|
10237
|
+
},
|
|
10238
|
+
{
|
|
10239
|
+
key: "originalPriceTakeProfit",
|
|
10240
|
+
label: "Original TP",
|
|
10241
|
+
format: (data) => (data.originalPriceTakeProfit ? `${data.originalPriceTakeProfit.toFixed(8)} USD` : "N/A"),
|
|
10242
|
+
isVisible: () => true,
|
|
10243
|
+
},
|
|
10244
|
+
{
|
|
10245
|
+
key: "originalPriceStopLoss",
|
|
10246
|
+
label: "Original SL",
|
|
10247
|
+
format: (data) => (data.originalPriceStopLoss ? `${data.originalPriceStopLoss.toFixed(8)} USD` : "N/A"),
|
|
10248
|
+
isVisible: () => true,
|
|
10249
|
+
},
|
|
10250
|
+
{
|
|
10251
|
+
key: "totalExecuted",
|
|
10252
|
+
label: "Total Executed %",
|
|
10253
|
+
format: (data) => (data.totalExecuted !== undefined ? `${data.totalExecuted.toFixed(2)}%` : "N/A"),
|
|
10254
|
+
isVisible: () => true,
|
|
10255
|
+
},
|
|
10256
|
+
{
|
|
10257
|
+
key: "note",
|
|
10258
|
+
label: "Note",
|
|
10259
|
+
format: (data) => data.note || "",
|
|
10260
|
+
isVisible: () => GLOBAL_CONFIG.CC_REPORT_SHOW_SIGNAL_NOTE,
|
|
10261
|
+
},
|
|
10220
10262
|
{
|
|
10221
10263
|
key: "timestamp",
|
|
10222
10264
|
label: "Timestamp",
|
|
@@ -10303,6 +10345,42 @@ const breakeven_columns = [
|
|
|
10303
10345
|
format: (data) => `${data.currentPrice.toFixed(8)} USD`,
|
|
10304
10346
|
isVisible: () => true,
|
|
10305
10347
|
},
|
|
10348
|
+
{
|
|
10349
|
+
key: "priceTakeProfit",
|
|
10350
|
+
label: "Take Profit",
|
|
10351
|
+
format: (data) => (data.priceTakeProfit ? `${data.priceTakeProfit.toFixed(8)} USD` : "N/A"),
|
|
10352
|
+
isVisible: () => true,
|
|
10353
|
+
},
|
|
10354
|
+
{
|
|
10355
|
+
key: "priceStopLoss",
|
|
10356
|
+
label: "Stop Loss",
|
|
10357
|
+
format: (data) => (data.priceStopLoss ? `${data.priceStopLoss.toFixed(8)} USD` : "N/A"),
|
|
10358
|
+
isVisible: () => true,
|
|
10359
|
+
},
|
|
10360
|
+
{
|
|
10361
|
+
key: "originalPriceTakeProfit",
|
|
10362
|
+
label: "Original TP",
|
|
10363
|
+
format: (data) => (data.originalPriceTakeProfit ? `${data.originalPriceTakeProfit.toFixed(8)} USD` : "N/A"),
|
|
10364
|
+
isVisible: () => true,
|
|
10365
|
+
},
|
|
10366
|
+
{
|
|
10367
|
+
key: "originalPriceStopLoss",
|
|
10368
|
+
label: "Original SL",
|
|
10369
|
+
format: (data) => (data.originalPriceStopLoss ? `${data.originalPriceStopLoss.toFixed(8)} USD` : "N/A"),
|
|
10370
|
+
isVisible: () => true,
|
|
10371
|
+
},
|
|
10372
|
+
{
|
|
10373
|
+
key: "totalExecuted",
|
|
10374
|
+
label: "Total Executed %",
|
|
10375
|
+
format: (data) => (data.totalExecuted !== undefined ? `${data.totalExecuted.toFixed(2)}%` : "N/A"),
|
|
10376
|
+
isVisible: () => true,
|
|
10377
|
+
},
|
|
10378
|
+
{
|
|
10379
|
+
key: "note",
|
|
10380
|
+
label: "Note",
|
|
10381
|
+
format: (data) => data.note || "",
|
|
10382
|
+
isVisible: () => GLOBAL_CONFIG.CC_REPORT_SHOW_SIGNAL_NOTE,
|
|
10383
|
+
},
|
|
10306
10384
|
{
|
|
10307
10385
|
key: "timestamp",
|
|
10308
10386
|
label: "Timestamp",
|
|
@@ -10960,6 +11038,7 @@ const DEFAULT_COLUMNS = Object.freeze({ ...COLUMN_CONFIG });
|
|
|
10960
11038
|
|
|
10961
11039
|
var _a$1, _b$1, _c$1;
|
|
10962
11040
|
const MARKDOWN_METHOD_NAME_ENABLE = "MarkdownUtils.enable";
|
|
11041
|
+
const MARKDOWN_METHOD_NAME_DISABLE = "MarkdownUtils.disable";
|
|
10963
11042
|
const MARKDOWN_METHOD_NAME_USE_ADAPTER = "MarkdownAdapter.useMarkdownAdapter";
|
|
10964
11043
|
const WAIT_FOR_INIT_SYMBOL$1 = Symbol("wait-for-init");
|
|
10965
11044
|
const WRITE_SAFE_SYMBOL$1 = Symbol("write-safe");
|
|
@@ -11244,6 +11323,83 @@ class MarkdownUtils {
|
|
|
11244
11323
|
}
|
|
11245
11324
|
return functoolsKit.compose(...unList.map((un) => () => void un()));
|
|
11246
11325
|
};
|
|
11326
|
+
/**
|
|
11327
|
+
* Disables markdown report services selectively.
|
|
11328
|
+
*
|
|
11329
|
+
* Unsubscribes from specified markdown services to stop report generation.
|
|
11330
|
+
* Use this method to stop markdown report generation for specific services while keeping others active.
|
|
11331
|
+
*
|
|
11332
|
+
* Each disabled service will:
|
|
11333
|
+
* - Stop listening to events immediately
|
|
11334
|
+
* - Stop accumulating data for reports
|
|
11335
|
+
* - Stop generating markdown files
|
|
11336
|
+
* - Free up event listener and memory resources
|
|
11337
|
+
*
|
|
11338
|
+
* Unlike enable(), this method does NOT return an unsubscribe function.
|
|
11339
|
+
* Services are unsubscribed immediately upon calling this method.
|
|
11340
|
+
*
|
|
11341
|
+
* @param config - Service configuration object specifying which services to disable. Defaults to disabling all services.
|
|
11342
|
+
* @param config.backtest - Disable backtest result reports with full trade history
|
|
11343
|
+
* @param config.breakeven - Disable breakeven event tracking
|
|
11344
|
+
* @param config.partial - Disable partial profit/loss event tracking
|
|
11345
|
+
* @param config.heat - Disable portfolio heatmap analysis
|
|
11346
|
+
* @param config.walker - Disable walker strategy comparison reports
|
|
11347
|
+
* @param config.performance - Disable performance bottleneck analysis
|
|
11348
|
+
* @param config.risk - Disable risk rejection tracking
|
|
11349
|
+
* @param config.schedule - Disable scheduled signal tracking
|
|
11350
|
+
* @param config.live - Disable live trading event reports
|
|
11351
|
+
*
|
|
11352
|
+
* @example
|
|
11353
|
+
* ```typescript
|
|
11354
|
+
* import { Markdown } from "backtest-kit";
|
|
11355
|
+
*
|
|
11356
|
+
* // Disable specific services
|
|
11357
|
+
* Markdown.disable({ backtest: true, walker: true });
|
|
11358
|
+
*
|
|
11359
|
+
* // Disable all services
|
|
11360
|
+
* Markdown.disable();
|
|
11361
|
+
* ```
|
|
11362
|
+
*/
|
|
11363
|
+
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) => {
|
|
11364
|
+
bt.loggerService.debug(MARKDOWN_METHOD_NAME_DISABLE, {
|
|
11365
|
+
backtest: bt$1,
|
|
11366
|
+
breakeven,
|
|
11367
|
+
heat,
|
|
11368
|
+
live,
|
|
11369
|
+
partial,
|
|
11370
|
+
performance,
|
|
11371
|
+
risk,
|
|
11372
|
+
schedule,
|
|
11373
|
+
walker,
|
|
11374
|
+
});
|
|
11375
|
+
if (bt$1) {
|
|
11376
|
+
bt.backtestMarkdownService.unsubscribe();
|
|
11377
|
+
}
|
|
11378
|
+
if (breakeven) {
|
|
11379
|
+
bt.breakevenMarkdownService.unsubscribe();
|
|
11380
|
+
}
|
|
11381
|
+
if (heat) {
|
|
11382
|
+
bt.heatMarkdownService.unsubscribe();
|
|
11383
|
+
}
|
|
11384
|
+
if (live) {
|
|
11385
|
+
bt.liveMarkdownService.unsubscribe();
|
|
11386
|
+
}
|
|
11387
|
+
if (partial) {
|
|
11388
|
+
bt.partialMarkdownService.unsubscribe();
|
|
11389
|
+
}
|
|
11390
|
+
if (performance) {
|
|
11391
|
+
bt.performanceMarkdownService.unsubscribe();
|
|
11392
|
+
}
|
|
11393
|
+
if (risk) {
|
|
11394
|
+
bt.riskMarkdownService.unsubscribe();
|
|
11395
|
+
}
|
|
11396
|
+
if (schedule) {
|
|
11397
|
+
bt.scheduleMarkdownService.unsubscribe();
|
|
11398
|
+
}
|
|
11399
|
+
if (walker) {
|
|
11400
|
+
bt.walkerMarkdownService.unsubscribe();
|
|
11401
|
+
}
|
|
11402
|
+
};
|
|
11247
11403
|
}
|
|
11248
11404
|
}
|
|
11249
11405
|
/**
|
|
@@ -16824,6 +16980,13 @@ let ReportStorage$2 = class ReportStorage {
|
|
|
16824
16980
|
position: data.position,
|
|
16825
16981
|
currentPrice,
|
|
16826
16982
|
level,
|
|
16983
|
+
priceOpen: data.priceOpen,
|
|
16984
|
+
priceTakeProfit: data.priceTakeProfit,
|
|
16985
|
+
priceStopLoss: data.priceStopLoss,
|
|
16986
|
+
originalPriceTakeProfit: data.originalPriceTakeProfit,
|
|
16987
|
+
originalPriceStopLoss: data.originalPriceStopLoss,
|
|
16988
|
+
totalExecuted: data.totalExecuted,
|
|
16989
|
+
note: data.note,
|
|
16827
16990
|
backtest,
|
|
16828
16991
|
});
|
|
16829
16992
|
// Trim queue if exceeded MAX_EVENTS
|
|
@@ -16849,6 +17012,13 @@ let ReportStorage$2 = class ReportStorage {
|
|
|
16849
17012
|
position: data.position,
|
|
16850
17013
|
currentPrice,
|
|
16851
17014
|
level,
|
|
17015
|
+
priceOpen: data.priceOpen,
|
|
17016
|
+
priceTakeProfit: data.priceTakeProfit,
|
|
17017
|
+
priceStopLoss: data.priceStopLoss,
|
|
17018
|
+
originalPriceTakeProfit: data.originalPriceTakeProfit,
|
|
17019
|
+
originalPriceStopLoss: data.originalPriceStopLoss,
|
|
17020
|
+
totalExecuted: data.totalExecuted,
|
|
17021
|
+
note: data.note,
|
|
16852
17022
|
backtest,
|
|
16853
17023
|
});
|
|
16854
17024
|
// Trim queue if exceeded MAX_EVENTS
|
|
@@ -17901,7 +18071,7 @@ let ReportStorage$1 = class ReportStorage {
|
|
|
17901
18071
|
/**
|
|
17902
18072
|
* Adds a breakeven event to the storage.
|
|
17903
18073
|
*
|
|
17904
|
-
* @param data - Signal row data
|
|
18074
|
+
* @param data - Signal row data with original prices
|
|
17905
18075
|
* @param currentPrice - Current market price when breakeven was reached
|
|
17906
18076
|
* @param backtest - True if backtest mode
|
|
17907
18077
|
* @param timestamp - Event timestamp in milliseconds
|
|
@@ -17915,6 +18085,12 @@ let ReportStorage$1 = class ReportStorage {
|
|
|
17915
18085
|
position: data.position,
|
|
17916
18086
|
currentPrice,
|
|
17917
18087
|
priceOpen: data.priceOpen,
|
|
18088
|
+
priceTakeProfit: data.priceTakeProfit,
|
|
18089
|
+
priceStopLoss: data.priceStopLoss,
|
|
18090
|
+
originalPriceTakeProfit: data.originalPriceTakeProfit,
|
|
18091
|
+
originalPriceStopLoss: data.originalPriceStopLoss,
|
|
18092
|
+
totalExecuted: data.totalExecuted,
|
|
18093
|
+
note: data.note,
|
|
17918
18094
|
backtest,
|
|
17919
18095
|
});
|
|
17920
18096
|
// Trim queue if exceeded MAX_EVENTS
|
|
@@ -19147,6 +19323,7 @@ const REPORT_BASE_METHOD_NAME_WRITE = "ReportBase.write";
|
|
|
19147
19323
|
const REPORT_UTILS_METHOD_NAME_USE_REPORT_ADAPTER = "ReportUtils.useReportAdapter";
|
|
19148
19324
|
const REPORT_UTILS_METHOD_NAME_WRITE_DATA = "ReportUtils.writeReportData";
|
|
19149
19325
|
const REPORT_UTILS_METHOD_NAME_ENABLE = "ReportUtils.enable";
|
|
19326
|
+
const REPORT_UTILS_METHOD_NAME_DISABLE = "ReportUtils.disable";
|
|
19150
19327
|
const REPORT_UTILS_METHOD_NAME_USE_DUMMY = "ReportUtils.useDummy";
|
|
19151
19328
|
const REPORT_UTILS_METHOD_NAME_USE_JSONL = "ReportUtils.useJsonl";
|
|
19152
19329
|
const WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
|
|
@@ -19388,6 +19565,82 @@ class ReportUtils {
|
|
|
19388
19565
|
}
|
|
19389
19566
|
return functoolsKit.compose(...unList.map((un) => () => void un()));
|
|
19390
19567
|
};
|
|
19568
|
+
/**
|
|
19569
|
+
* Disables report services selectively.
|
|
19570
|
+
*
|
|
19571
|
+
* Unsubscribes from specified report services to stop event logging.
|
|
19572
|
+
* Use this method to stop JSONL logging for specific services while keeping others active.
|
|
19573
|
+
*
|
|
19574
|
+
* Each disabled service will:
|
|
19575
|
+
* - Stop listening to events immediately
|
|
19576
|
+
* - Stop writing to JSONL files
|
|
19577
|
+
* - Free up event listener resources
|
|
19578
|
+
*
|
|
19579
|
+
* Unlike enable(), this method does NOT return an unsubscribe function.
|
|
19580
|
+
* Services are unsubscribed immediately upon calling this method.
|
|
19581
|
+
*
|
|
19582
|
+
* @param config - Service configuration object specifying which services to disable. Defaults to disabling all services.
|
|
19583
|
+
* @param config.backtest - Disable backtest closed signal logging
|
|
19584
|
+
* @param config.breakeven - Disable breakeven event logging
|
|
19585
|
+
* @param config.partial - Disable partial close event logging
|
|
19586
|
+
* @param config.heat - Disable heatmap data logging
|
|
19587
|
+
* @param config.walker - Disable walker iteration logging
|
|
19588
|
+
* @param config.performance - Disable performance metrics logging
|
|
19589
|
+
* @param config.risk - Disable risk rejection logging
|
|
19590
|
+
* @param config.schedule - Disable scheduled signal logging
|
|
19591
|
+
* @param config.live - Disable live trading event logging
|
|
19592
|
+
*
|
|
19593
|
+
* @example
|
|
19594
|
+
* ```typescript
|
|
19595
|
+
* import { Report } from "backtest-kit";
|
|
19596
|
+
*
|
|
19597
|
+
* // Disable specific services
|
|
19598
|
+
* Report.disable({ backtest: true, live: true });
|
|
19599
|
+
*
|
|
19600
|
+
* // Disable all services
|
|
19601
|
+
* Report.disable();
|
|
19602
|
+
* ```
|
|
19603
|
+
*/
|
|
19604
|
+
this.disable = ({ backtest: bt$1 = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, schedule = false, walker = false, } = WILDCARD_TARGET) => {
|
|
19605
|
+
bt.loggerService.debug(REPORT_UTILS_METHOD_NAME_DISABLE, {
|
|
19606
|
+
backtest: bt$1,
|
|
19607
|
+
breakeven,
|
|
19608
|
+
heat,
|
|
19609
|
+
live,
|
|
19610
|
+
partial,
|
|
19611
|
+
performance,
|
|
19612
|
+
risk,
|
|
19613
|
+
schedule,
|
|
19614
|
+
walker,
|
|
19615
|
+
});
|
|
19616
|
+
if (bt$1) {
|
|
19617
|
+
bt.backtestReportService.unsubscribe();
|
|
19618
|
+
}
|
|
19619
|
+
if (breakeven) {
|
|
19620
|
+
bt.breakevenReportService.unsubscribe();
|
|
19621
|
+
}
|
|
19622
|
+
if (heat) {
|
|
19623
|
+
bt.heatReportService.unsubscribe();
|
|
19624
|
+
}
|
|
19625
|
+
if (live) {
|
|
19626
|
+
bt.liveReportService.unsubscribe();
|
|
19627
|
+
}
|
|
19628
|
+
if (partial) {
|
|
19629
|
+
bt.partialReportService.unsubscribe();
|
|
19630
|
+
}
|
|
19631
|
+
if (performance) {
|
|
19632
|
+
bt.performanceReportService.unsubscribe();
|
|
19633
|
+
}
|
|
19634
|
+
if (risk) {
|
|
19635
|
+
bt.riskReportService.unsubscribe();
|
|
19636
|
+
}
|
|
19637
|
+
if (schedule) {
|
|
19638
|
+
bt.scheduleReportService.unsubscribe();
|
|
19639
|
+
}
|
|
19640
|
+
if (walker) {
|
|
19641
|
+
bt.walkerReportService.unsubscribe();
|
|
19642
|
+
}
|
|
19643
|
+
};
|
|
19391
19644
|
}
|
|
19392
19645
|
}
|
|
19393
19646
|
/**
|
|
@@ -19477,9 +19730,46 @@ const Report = new ReportAdapter();
|
|
|
19477
19730
|
const BACKTEST_REPORT_METHOD_NAME_SUBSCRIBE = "BacktestReportService.subscribe";
|
|
19478
19731
|
const BACKTEST_REPORT_METHOD_NAME_UNSUBSCRIBE = "BacktestReportService.unsubscribe";
|
|
19479
19732
|
const BACKTEST_REPORT_METHOD_NAME_TICK = "BacktestReportService.tick";
|
|
19733
|
+
/**
|
|
19734
|
+
* Service for logging backtest strategy tick events to SQLite database.
|
|
19735
|
+
*
|
|
19736
|
+
* Captures all backtest signal lifecycle events (idle, opened, active, closed)
|
|
19737
|
+
* and stores them in the Report database for analysis and debugging.
|
|
19738
|
+
*
|
|
19739
|
+
* Features:
|
|
19740
|
+
* - Listens to backtest signal events via signalBacktestEmitter
|
|
19741
|
+
* - Logs all tick event types with full signal details
|
|
19742
|
+
* - Stores events in Report.writeData() for persistence
|
|
19743
|
+
* - Protected against multiple subscriptions using singleshot
|
|
19744
|
+
*
|
|
19745
|
+
* @example
|
|
19746
|
+
* ```typescript
|
|
19747
|
+
* import { BacktestReportService } from "backtest-kit";
|
|
19748
|
+
*
|
|
19749
|
+
* const reportService = new BacktestReportService();
|
|
19750
|
+
*
|
|
19751
|
+
* // Subscribe to backtest events
|
|
19752
|
+
* const unsubscribe = reportService.subscribe();
|
|
19753
|
+
*
|
|
19754
|
+
* // Run backtest...
|
|
19755
|
+
* // Events are automatically logged
|
|
19756
|
+
*
|
|
19757
|
+
* // Later: unsubscribe
|
|
19758
|
+
* await reportService.unsubscribe();
|
|
19759
|
+
* ```
|
|
19760
|
+
*/
|
|
19480
19761
|
class BacktestReportService {
|
|
19481
19762
|
constructor() {
|
|
19763
|
+
/** Logger service for debug output */
|
|
19482
19764
|
this.loggerService = inject(TYPES.loggerService);
|
|
19765
|
+
/**
|
|
19766
|
+
* Processes backtest tick events and logs them to the database.
|
|
19767
|
+
* Handles all event types: idle, opened, active, closed.
|
|
19768
|
+
*
|
|
19769
|
+
* @param data - Backtest tick result with signal lifecycle information
|
|
19770
|
+
*
|
|
19771
|
+
* @internal
|
|
19772
|
+
*/
|
|
19483
19773
|
this.tick = async (data) => {
|
|
19484
19774
|
this.loggerService.log(BACKTEST_REPORT_METHOD_NAME_TICK, { data });
|
|
19485
19775
|
const baseEvent = {
|
|
@@ -19570,6 +19860,21 @@ class BacktestReportService {
|
|
|
19570
19860
|
}, { ...searchOptions, signalId: data.signal?.id });
|
|
19571
19861
|
}
|
|
19572
19862
|
};
|
|
19863
|
+
/**
|
|
19864
|
+
* Subscribes to backtest signal emitter to receive tick events.
|
|
19865
|
+
* Protected against multiple subscriptions.
|
|
19866
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
19867
|
+
*
|
|
19868
|
+
* @returns Unsubscribe function to stop receiving backtest events
|
|
19869
|
+
*
|
|
19870
|
+
* @example
|
|
19871
|
+
* ```typescript
|
|
19872
|
+
* const service = new BacktestReportService();
|
|
19873
|
+
* const unsubscribe = service.subscribe();
|
|
19874
|
+
* // ... later
|
|
19875
|
+
* unsubscribe();
|
|
19876
|
+
* ```
|
|
19877
|
+
*/
|
|
19573
19878
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
19574
19879
|
this.loggerService.log(BACKTEST_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
19575
19880
|
const unsubscribe = signalBacktestEmitter.subscribe(this.tick);
|
|
@@ -19578,6 +19883,19 @@ class BacktestReportService {
|
|
|
19578
19883
|
unsubscribe();
|
|
19579
19884
|
};
|
|
19580
19885
|
});
|
|
19886
|
+
/**
|
|
19887
|
+
* Unsubscribes from backtest signal emitter to stop receiving tick events.
|
|
19888
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
19889
|
+
* If not subscribed, does nothing.
|
|
19890
|
+
*
|
|
19891
|
+
* @example
|
|
19892
|
+
* ```typescript
|
|
19893
|
+
* const service = new BacktestReportService();
|
|
19894
|
+
* service.subscribe();
|
|
19895
|
+
* // ... later
|
|
19896
|
+
* await service.unsubscribe();
|
|
19897
|
+
* ```
|
|
19898
|
+
*/
|
|
19581
19899
|
this.unsubscribe = async () => {
|
|
19582
19900
|
this.loggerService.log(BACKTEST_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
19583
19901
|
if (this.subscribe.hasValue()) {
|
|
@@ -19591,9 +19909,46 @@ class BacktestReportService {
|
|
|
19591
19909
|
const LIVE_REPORT_METHOD_NAME_SUBSCRIBE = "LiveReportService.subscribe";
|
|
19592
19910
|
const LIVE_REPORT_METHOD_NAME_UNSUBSCRIBE = "LiveReportService.unsubscribe";
|
|
19593
19911
|
const LIVE_REPORT_METHOD_NAME_TICK = "LiveReportService.tick";
|
|
19912
|
+
/**
|
|
19913
|
+
* Service for logging live trading strategy tick events to SQLite database.
|
|
19914
|
+
*
|
|
19915
|
+
* Captures all live trading signal lifecycle events (idle, opened, active, closed)
|
|
19916
|
+
* and stores them in the Report database for real-time monitoring and analysis.
|
|
19917
|
+
*
|
|
19918
|
+
* Features:
|
|
19919
|
+
* - Listens to live signal events via signalLiveEmitter
|
|
19920
|
+
* - Logs all tick event types with full signal details
|
|
19921
|
+
* - Stores events in Report.writeData() for persistence
|
|
19922
|
+
* - Protected against multiple subscriptions using singleshot
|
|
19923
|
+
*
|
|
19924
|
+
* @example
|
|
19925
|
+
* ```typescript
|
|
19926
|
+
* import { LiveReportService } from "backtest-kit";
|
|
19927
|
+
*
|
|
19928
|
+
* const reportService = new LiveReportService();
|
|
19929
|
+
*
|
|
19930
|
+
* // Subscribe to live trading events
|
|
19931
|
+
* const unsubscribe = reportService.subscribe();
|
|
19932
|
+
*
|
|
19933
|
+
* // Run live trading...
|
|
19934
|
+
* // Events are automatically logged
|
|
19935
|
+
*
|
|
19936
|
+
* // Later: unsubscribe
|
|
19937
|
+
* await reportService.unsubscribe();
|
|
19938
|
+
* ```
|
|
19939
|
+
*/
|
|
19594
19940
|
class LiveReportService {
|
|
19595
19941
|
constructor() {
|
|
19942
|
+
/** Logger service for debug output */
|
|
19596
19943
|
this.loggerService = inject(TYPES.loggerService);
|
|
19944
|
+
/**
|
|
19945
|
+
* Processes live trading tick events and logs them to the database.
|
|
19946
|
+
* Handles all event types: idle, opened, active, closed.
|
|
19947
|
+
*
|
|
19948
|
+
* @param data - Live trading tick result with signal lifecycle information
|
|
19949
|
+
*
|
|
19950
|
+
* @internal
|
|
19951
|
+
*/
|
|
19597
19952
|
this.tick = async (data) => {
|
|
19598
19953
|
this.loggerService.log(LIVE_REPORT_METHOD_NAME_TICK, { data });
|
|
19599
19954
|
const baseEvent = {
|
|
@@ -19684,6 +20039,21 @@ class LiveReportService {
|
|
|
19684
20039
|
}, { ...searchOptions, signalId: data.signal?.id });
|
|
19685
20040
|
}
|
|
19686
20041
|
};
|
|
20042
|
+
/**
|
|
20043
|
+
* Subscribes to live signal emitter to receive tick events.
|
|
20044
|
+
* Protected against multiple subscriptions.
|
|
20045
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20046
|
+
*
|
|
20047
|
+
* @returns Unsubscribe function to stop receiving live trading events
|
|
20048
|
+
*
|
|
20049
|
+
* @example
|
|
20050
|
+
* ```typescript
|
|
20051
|
+
* const service = new LiveReportService();
|
|
20052
|
+
* const unsubscribe = service.subscribe();
|
|
20053
|
+
* // ... later
|
|
20054
|
+
* unsubscribe();
|
|
20055
|
+
* ```
|
|
20056
|
+
*/
|
|
19687
20057
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
19688
20058
|
this.loggerService.log(LIVE_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
19689
20059
|
const unsubscribe = signalLiveEmitter.subscribe(this.tick);
|
|
@@ -19692,6 +20062,19 @@ class LiveReportService {
|
|
|
19692
20062
|
unsubscribe();
|
|
19693
20063
|
};
|
|
19694
20064
|
});
|
|
20065
|
+
/**
|
|
20066
|
+
* Unsubscribes from live signal emitter to stop receiving tick events.
|
|
20067
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
20068
|
+
* If not subscribed, does nothing.
|
|
20069
|
+
*
|
|
20070
|
+
* @example
|
|
20071
|
+
* ```typescript
|
|
20072
|
+
* const service = new LiveReportService();
|
|
20073
|
+
* service.subscribe();
|
|
20074
|
+
* // ... later
|
|
20075
|
+
* await service.unsubscribe();
|
|
20076
|
+
* ```
|
|
20077
|
+
*/
|
|
19695
20078
|
this.unsubscribe = async () => {
|
|
19696
20079
|
this.loggerService.log(LIVE_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
19697
20080
|
if (this.subscribe.hasValue()) {
|
|
@@ -19705,9 +20088,47 @@ class LiveReportService {
|
|
|
19705
20088
|
const SCHEDULE_REPORT_METHOD_NAME_SUBSCRIBE = "ScheduleReportService.subscribe";
|
|
19706
20089
|
const SCHEDULE_REPORT_METHOD_NAME_UNSUBSCRIBE = "ScheduleReportService.unsubscribe";
|
|
19707
20090
|
const SCHEDULE_REPORT_METHOD_NAME_TICK = "ScheduleReportService.tick";
|
|
20091
|
+
/**
|
|
20092
|
+
* Service for logging scheduled signal events to SQLite database.
|
|
20093
|
+
*
|
|
20094
|
+
* Captures all scheduled signal lifecycle events (scheduled, opened, cancelled)
|
|
20095
|
+
* and stores them in the Report database for tracking delayed order execution.
|
|
20096
|
+
*
|
|
20097
|
+
* Features:
|
|
20098
|
+
* - Listens to signal events via signalEmitter
|
|
20099
|
+
* - Logs scheduled, opened (from scheduled), and cancelled events
|
|
20100
|
+
* - Calculates duration between scheduling and execution/cancellation
|
|
20101
|
+
* - Stores events in Report.writeData() for schedule tracking
|
|
20102
|
+
* - Protected against multiple subscriptions using singleshot
|
|
20103
|
+
*
|
|
20104
|
+
* @example
|
|
20105
|
+
* ```typescript
|
|
20106
|
+
* import { ScheduleReportService } from "backtest-kit";
|
|
20107
|
+
*
|
|
20108
|
+
* const reportService = new ScheduleReportService();
|
|
20109
|
+
*
|
|
20110
|
+
* // Subscribe to scheduled signal events
|
|
20111
|
+
* const unsubscribe = reportService.subscribe();
|
|
20112
|
+
*
|
|
20113
|
+
* // Run strategy with scheduled orders...
|
|
20114
|
+
* // Scheduled events are automatically logged
|
|
20115
|
+
*
|
|
20116
|
+
* // Later: unsubscribe
|
|
20117
|
+
* await reportService.unsubscribe();
|
|
20118
|
+
* ```
|
|
20119
|
+
*/
|
|
19708
20120
|
class ScheduleReportService {
|
|
19709
20121
|
constructor() {
|
|
20122
|
+
/** Logger service for debug output */
|
|
19710
20123
|
this.loggerService = inject(TYPES.loggerService);
|
|
20124
|
+
/**
|
|
20125
|
+
* Processes signal tick events and logs scheduled signal lifecycle to the database.
|
|
20126
|
+
* Handles scheduled, opened (from scheduled), and cancelled event types.
|
|
20127
|
+
*
|
|
20128
|
+
* @param data - Strategy tick result with signal lifecycle information
|
|
20129
|
+
*
|
|
20130
|
+
* @internal
|
|
20131
|
+
*/
|
|
19711
20132
|
this.tick = async (data) => {
|
|
19712
20133
|
this.loggerService.log(SCHEDULE_REPORT_METHOD_NAME_TICK, { data });
|
|
19713
20134
|
const baseEvent = {
|
|
@@ -19794,14 +20215,42 @@ class ScheduleReportService {
|
|
|
19794
20215
|
}, searchOptions);
|
|
19795
20216
|
}
|
|
19796
20217
|
};
|
|
19797
|
-
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
|
|
19801
|
-
|
|
19802
|
-
|
|
19803
|
-
|
|
20218
|
+
/**
|
|
20219
|
+
* Subscribes to signal emitter to receive scheduled signal events.
|
|
20220
|
+
* Protected against multiple subscriptions.
|
|
20221
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20222
|
+
*
|
|
20223
|
+
* @returns Unsubscribe function to stop receiving scheduled signal events
|
|
20224
|
+
*
|
|
20225
|
+
* @example
|
|
20226
|
+
* ```typescript
|
|
20227
|
+
* const service = new ScheduleReportService();
|
|
20228
|
+
* const unsubscribe = service.subscribe();
|
|
20229
|
+
* // ... later
|
|
20230
|
+
* unsubscribe();
|
|
20231
|
+
* ```
|
|
20232
|
+
*/
|
|
20233
|
+
this.subscribe = functoolsKit.singleshot(() => {
|
|
20234
|
+
this.loggerService.log(SCHEDULE_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
20235
|
+
const unsubscribe = signalEmitter.subscribe(this.tick);
|
|
20236
|
+
return () => {
|
|
20237
|
+
this.subscribe.clear();
|
|
20238
|
+
unsubscribe();
|
|
20239
|
+
};
|
|
19804
20240
|
});
|
|
20241
|
+
/**
|
|
20242
|
+
* Unsubscribes from signal emitter to stop receiving events.
|
|
20243
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
20244
|
+
* If not subscribed, does nothing.
|
|
20245
|
+
*
|
|
20246
|
+
* @example
|
|
20247
|
+
* ```typescript
|
|
20248
|
+
* const service = new ScheduleReportService();
|
|
20249
|
+
* service.subscribe();
|
|
20250
|
+
* // ... later
|
|
20251
|
+
* await service.unsubscribe();
|
|
20252
|
+
* ```
|
|
20253
|
+
*/
|
|
19805
20254
|
this.unsubscribe = async () => {
|
|
19806
20255
|
this.loggerService.log(SCHEDULE_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
19807
20256
|
if (this.subscribe.hasValue()) {
|
|
@@ -19815,9 +20264,45 @@ class ScheduleReportService {
|
|
|
19815
20264
|
const PERFORMANCE_REPORT_METHOD_NAME_SUBSCRIBE = "PerformanceReportService.subscribe";
|
|
19816
20265
|
const PERFORMANCE_REPORT_METHOD_NAME_UNSUBSCRIBE = "PerformanceReportService.unsubscribe";
|
|
19817
20266
|
const PERFORMANCE_REPORT_METHOD_NAME_TRACK = "PerformanceReportService.track";
|
|
20267
|
+
/**
|
|
20268
|
+
* Service for logging performance metrics to SQLite database.
|
|
20269
|
+
*
|
|
20270
|
+
* Captures all performance timing events from strategy execution
|
|
20271
|
+
* and stores them in the Report database for bottleneck analysis and optimization.
|
|
20272
|
+
*
|
|
20273
|
+
* Features:
|
|
20274
|
+
* - Listens to performance events via performanceEmitter
|
|
20275
|
+
* - Logs all timing metrics with duration and metadata
|
|
20276
|
+
* - Stores events in Report.writeData() for performance analysis
|
|
20277
|
+
* - Protected against multiple subscriptions using singleshot
|
|
20278
|
+
*
|
|
20279
|
+
* @example
|
|
20280
|
+
* ```typescript
|
|
20281
|
+
* import { PerformanceReportService } from "backtest-kit";
|
|
20282
|
+
*
|
|
20283
|
+
* const reportService = new PerformanceReportService();
|
|
20284
|
+
*
|
|
20285
|
+
* // Subscribe to performance events
|
|
20286
|
+
* const unsubscribe = reportService.subscribe();
|
|
20287
|
+
*
|
|
20288
|
+
* // Run strategy...
|
|
20289
|
+
* // Performance metrics are automatically logged
|
|
20290
|
+
*
|
|
20291
|
+
* // Later: unsubscribe
|
|
20292
|
+
* await reportService.unsubscribe();
|
|
20293
|
+
* ```
|
|
20294
|
+
*/
|
|
19818
20295
|
class PerformanceReportService {
|
|
19819
20296
|
constructor() {
|
|
20297
|
+
/** Logger service for debug output */
|
|
19820
20298
|
this.loggerService = inject(TYPES.loggerService);
|
|
20299
|
+
/**
|
|
20300
|
+
* Processes performance tracking events and logs them to the database.
|
|
20301
|
+
*
|
|
20302
|
+
* @param event - Performance contract with timing and metric information
|
|
20303
|
+
*
|
|
20304
|
+
* @internal
|
|
20305
|
+
*/
|
|
19821
20306
|
this.track = async (event) => {
|
|
19822
20307
|
this.loggerService.log(PERFORMANCE_REPORT_METHOD_NAME_TRACK, { event });
|
|
19823
20308
|
await Report.writeData("performance", {
|
|
@@ -19839,6 +20324,21 @@ class PerformanceReportService {
|
|
|
19839
20324
|
walkerName: "",
|
|
19840
20325
|
});
|
|
19841
20326
|
};
|
|
20327
|
+
/**
|
|
20328
|
+
* Subscribes to performance emitter to receive timing events.
|
|
20329
|
+
* Protected against multiple subscriptions.
|
|
20330
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20331
|
+
*
|
|
20332
|
+
* @returns Unsubscribe function to stop receiving performance events
|
|
20333
|
+
*
|
|
20334
|
+
* @example
|
|
20335
|
+
* ```typescript
|
|
20336
|
+
* const service = new PerformanceReportService();
|
|
20337
|
+
* const unsubscribe = service.subscribe();
|
|
20338
|
+
* // ... later
|
|
20339
|
+
* unsubscribe();
|
|
20340
|
+
* ```
|
|
20341
|
+
*/
|
|
19842
20342
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
19843
20343
|
this.loggerService.log(PERFORMANCE_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
19844
20344
|
const unsubscribe = performanceEmitter.subscribe(this.track);
|
|
@@ -19847,6 +20347,19 @@ class PerformanceReportService {
|
|
|
19847
20347
|
unsubscribe();
|
|
19848
20348
|
};
|
|
19849
20349
|
});
|
|
20350
|
+
/**
|
|
20351
|
+
* Unsubscribes from performance emitter to stop receiving events.
|
|
20352
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
20353
|
+
* If not subscribed, does nothing.
|
|
20354
|
+
*
|
|
20355
|
+
* @example
|
|
20356
|
+
* ```typescript
|
|
20357
|
+
* const service = new PerformanceReportService();
|
|
20358
|
+
* service.subscribe();
|
|
20359
|
+
* // ... later
|
|
20360
|
+
* await service.unsubscribe();
|
|
20361
|
+
* ```
|
|
20362
|
+
*/
|
|
19850
20363
|
this.unsubscribe = async () => {
|
|
19851
20364
|
this.loggerService.log(PERFORMANCE_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
19852
20365
|
if (this.subscribe.hasValue()) {
|
|
@@ -19860,9 +20373,46 @@ class PerformanceReportService {
|
|
|
19860
20373
|
const WALKER_REPORT_METHOD_NAME_SUBSCRIBE = "WalkerReportService.subscribe";
|
|
19861
20374
|
const WALKER_REPORT_METHOD_NAME_UNSUBSCRIBE = "WalkerReportService.unsubscribe";
|
|
19862
20375
|
const WALKER_REPORT_METHOD_NAME_TICK = "WalkerReportService.tick";
|
|
20376
|
+
/**
|
|
20377
|
+
* Service for logging walker optimization progress to SQLite database.
|
|
20378
|
+
*
|
|
20379
|
+
* Captures walker strategy optimization results and stores them in the Report database
|
|
20380
|
+
* for tracking parameter optimization and comparing strategy performance.
|
|
20381
|
+
*
|
|
20382
|
+
* Features:
|
|
20383
|
+
* - Listens to walker events via walkerEmitter
|
|
20384
|
+
* - Logs each strategy test result with metrics and statistics
|
|
20385
|
+
* - Tracks best strategy and optimization progress
|
|
20386
|
+
* - Stores events in Report.writeData() for optimization analysis
|
|
20387
|
+
* - Protected against multiple subscriptions using singleshot
|
|
20388
|
+
*
|
|
20389
|
+
* @example
|
|
20390
|
+
* ```typescript
|
|
20391
|
+
* import { WalkerReportService } from "backtest-kit";
|
|
20392
|
+
*
|
|
20393
|
+
* const reportService = new WalkerReportService();
|
|
20394
|
+
*
|
|
20395
|
+
* // Subscribe to walker optimization events
|
|
20396
|
+
* const unsubscribe = reportService.subscribe();
|
|
20397
|
+
*
|
|
20398
|
+
* // Run walker optimization...
|
|
20399
|
+
* // Each strategy result is automatically logged
|
|
20400
|
+
*
|
|
20401
|
+
* // Later: unsubscribe
|
|
20402
|
+
* await reportService.unsubscribe();
|
|
20403
|
+
* ```
|
|
20404
|
+
*/
|
|
19863
20405
|
class WalkerReportService {
|
|
19864
20406
|
constructor() {
|
|
20407
|
+
/** Logger service for debug output */
|
|
19865
20408
|
this.loggerService = inject(TYPES.loggerService);
|
|
20409
|
+
/**
|
|
20410
|
+
* Processes walker optimization events and logs them to the database.
|
|
20411
|
+
*
|
|
20412
|
+
* @param data - Walker contract with strategy optimization results
|
|
20413
|
+
*
|
|
20414
|
+
* @internal
|
|
20415
|
+
*/
|
|
19866
20416
|
this.tick = async (data) => {
|
|
19867
20417
|
this.loggerService.log(WALKER_REPORT_METHOD_NAME_TICK, { data });
|
|
19868
20418
|
await Report.writeData("walker", {
|
|
@@ -19898,6 +20448,21 @@ class WalkerReportService {
|
|
|
19898
20448
|
walkerName: data.walkerName,
|
|
19899
20449
|
});
|
|
19900
20450
|
};
|
|
20451
|
+
/**
|
|
20452
|
+
* Subscribes to walker emitter to receive optimization progress events.
|
|
20453
|
+
* Protected against multiple subscriptions.
|
|
20454
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20455
|
+
*
|
|
20456
|
+
* @returns Unsubscribe function to stop receiving walker optimization events
|
|
20457
|
+
*
|
|
20458
|
+
* @example
|
|
20459
|
+
* ```typescript
|
|
20460
|
+
* const service = new WalkerReportService();
|
|
20461
|
+
* const unsubscribe = service.subscribe();
|
|
20462
|
+
* // ... later
|
|
20463
|
+
* unsubscribe();
|
|
20464
|
+
* ```
|
|
20465
|
+
*/
|
|
19901
20466
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
19902
20467
|
this.loggerService.log(WALKER_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
19903
20468
|
const unsubscribe = walkerEmitter.subscribe(this.tick);
|
|
@@ -19906,6 +20471,19 @@ class WalkerReportService {
|
|
|
19906
20471
|
unsubscribe();
|
|
19907
20472
|
};
|
|
19908
20473
|
});
|
|
20474
|
+
/**
|
|
20475
|
+
* Unsubscribes from walker emitter to stop receiving events.
|
|
20476
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
20477
|
+
* If not subscribed, does nothing.
|
|
20478
|
+
*
|
|
20479
|
+
* @example
|
|
20480
|
+
* ```typescript
|
|
20481
|
+
* const service = new WalkerReportService();
|
|
20482
|
+
* service.subscribe();
|
|
20483
|
+
* // ... later
|
|
20484
|
+
* await service.unsubscribe();
|
|
20485
|
+
* ```
|
|
20486
|
+
*/
|
|
19909
20487
|
this.unsubscribe = async () => {
|
|
19910
20488
|
this.loggerService.log(WALKER_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
19911
20489
|
if (this.subscribe.hasValue()) {
|
|
@@ -19919,9 +20497,46 @@ class WalkerReportService {
|
|
|
19919
20497
|
const HEAT_REPORT_METHOD_NAME_SUBSCRIBE = "HeatReportService.subscribe";
|
|
19920
20498
|
const HEAT_REPORT_METHOD_NAME_UNSUBSCRIBE = "HeatReportService.unsubscribe";
|
|
19921
20499
|
const HEAT_REPORT_METHOD_NAME_TICK = "HeatReportService.tick";
|
|
20500
|
+
/**
|
|
20501
|
+
* Service for logging heatmap (closed signals) events to SQLite database.
|
|
20502
|
+
*
|
|
20503
|
+
* Captures closed signal events across all symbols for portfolio-wide
|
|
20504
|
+
* heatmap analysis and stores them in the Report database.
|
|
20505
|
+
*
|
|
20506
|
+
* Features:
|
|
20507
|
+
* - Listens to signal events via signalEmitter
|
|
20508
|
+
* - Logs only closed signals with PNL data
|
|
20509
|
+
* - Stores events in Report.writeData() for heatmap generation
|
|
20510
|
+
* - Protected against multiple subscriptions using singleshot
|
|
20511
|
+
*
|
|
20512
|
+
* @example
|
|
20513
|
+
* ```typescript
|
|
20514
|
+
* import { HeatReportService } from "backtest-kit";
|
|
20515
|
+
*
|
|
20516
|
+
* const reportService = new HeatReportService();
|
|
20517
|
+
*
|
|
20518
|
+
* // Subscribe to signal events
|
|
20519
|
+
* const unsubscribe = reportService.subscribe();
|
|
20520
|
+
*
|
|
20521
|
+
* // Run strategy...
|
|
20522
|
+
* // Closed signals are automatically logged
|
|
20523
|
+
*
|
|
20524
|
+
* // Later: unsubscribe
|
|
20525
|
+
* await reportService.unsubscribe();
|
|
20526
|
+
* ```
|
|
20527
|
+
*/
|
|
19922
20528
|
class HeatReportService {
|
|
19923
20529
|
constructor() {
|
|
20530
|
+
/** Logger service for debug output */
|
|
19924
20531
|
this.loggerService = inject(TYPES.loggerService);
|
|
20532
|
+
/**
|
|
20533
|
+
* Processes signal tick events and logs closed signals to the database.
|
|
20534
|
+
* Only processes closed signals - other actions are ignored.
|
|
20535
|
+
*
|
|
20536
|
+
* @param data - Strategy tick result with signal lifecycle information
|
|
20537
|
+
*
|
|
20538
|
+
* @internal
|
|
20539
|
+
*/
|
|
19925
20540
|
this.tick = async (data) => {
|
|
19926
20541
|
this.loggerService.log(HEAT_REPORT_METHOD_NAME_TICK, { data });
|
|
19927
20542
|
if (data.action !== "closed") {
|
|
@@ -19951,6 +20566,21 @@ class HeatReportService {
|
|
|
19951
20566
|
walkerName: "",
|
|
19952
20567
|
});
|
|
19953
20568
|
};
|
|
20569
|
+
/**
|
|
20570
|
+
* Subscribes to signal emitter to receive closed signal events.
|
|
20571
|
+
* Protected against multiple subscriptions.
|
|
20572
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20573
|
+
*
|
|
20574
|
+
* @returns Unsubscribe function to stop receiving signal events
|
|
20575
|
+
*
|
|
20576
|
+
* @example
|
|
20577
|
+
* ```typescript
|
|
20578
|
+
* const service = new HeatReportService();
|
|
20579
|
+
* const unsubscribe = service.subscribe();
|
|
20580
|
+
* // ... later
|
|
20581
|
+
* unsubscribe();
|
|
20582
|
+
* ```
|
|
20583
|
+
*/
|
|
19954
20584
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
19955
20585
|
this.loggerService.log(HEAT_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
19956
20586
|
const unsubscribe = signalEmitter.subscribe(this.tick);
|
|
@@ -19959,6 +20589,19 @@ class HeatReportService {
|
|
|
19959
20589
|
unsubscribe();
|
|
19960
20590
|
};
|
|
19961
20591
|
});
|
|
20592
|
+
/**
|
|
20593
|
+
* Unsubscribes from signal emitter to stop receiving events.
|
|
20594
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
20595
|
+
* If not subscribed, does nothing.
|
|
20596
|
+
*
|
|
20597
|
+
* @example
|
|
20598
|
+
* ```typescript
|
|
20599
|
+
* const service = new HeatReportService();
|
|
20600
|
+
* service.subscribe();
|
|
20601
|
+
* // ... later
|
|
20602
|
+
* await service.unsubscribe();
|
|
20603
|
+
* ```
|
|
20604
|
+
*/
|
|
19962
20605
|
this.unsubscribe = async () => {
|
|
19963
20606
|
this.loggerService.log(HEAT_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
19964
20607
|
if (this.subscribe.hasValue()) {
|
|
@@ -19973,9 +20616,46 @@ const PARTIAL_REPORT_METHOD_NAME_SUBSCRIBE = "PartialReportService.subscribe";
|
|
|
19973
20616
|
const PARTIAL_REPORT_METHOD_NAME_UNSUBSCRIBE = "PartialReportService.unsubscribe";
|
|
19974
20617
|
const PARTIAL_REPORT_METHOD_NAME_TICK_PROFIT = "PartialReportService.tickProfit";
|
|
19975
20618
|
const PARTIAL_REPORT_METHOD_NAME_TICK_LOSS = "PartialReportService.tickLoss";
|
|
20619
|
+
/**
|
|
20620
|
+
* Service for logging partial profit/loss events to SQLite database.
|
|
20621
|
+
*
|
|
20622
|
+
* Captures all partial position exit events (profit and loss levels)
|
|
20623
|
+
* and stores them in the Report database for tracking partial closures.
|
|
20624
|
+
*
|
|
20625
|
+
* Features:
|
|
20626
|
+
* - Listens to partial profit events via partialProfitSubject
|
|
20627
|
+
* - Listens to partial loss events via partialLossSubject
|
|
20628
|
+
* - Logs all partial exit events with level and price information
|
|
20629
|
+
* - Stores events in Report.writeData() for persistence
|
|
20630
|
+
* - Protected against multiple subscriptions using singleshot
|
|
20631
|
+
*
|
|
20632
|
+
* @example
|
|
20633
|
+
* ```typescript
|
|
20634
|
+
* import { PartialReportService } from "backtest-kit";
|
|
20635
|
+
*
|
|
20636
|
+
* const reportService = new PartialReportService();
|
|
20637
|
+
*
|
|
20638
|
+
* // Subscribe to partial events
|
|
20639
|
+
* const unsubscribe = reportService.subscribe();
|
|
20640
|
+
*
|
|
20641
|
+
* // Run strategy with partial exits...
|
|
20642
|
+
* // Partial events are automatically logged
|
|
20643
|
+
*
|
|
20644
|
+
* // Later: unsubscribe
|
|
20645
|
+
* await reportService.unsubscribe();
|
|
20646
|
+
* ```
|
|
20647
|
+
*/
|
|
19976
20648
|
class PartialReportService {
|
|
19977
20649
|
constructor() {
|
|
20650
|
+
/** Logger service for debug output */
|
|
19978
20651
|
this.loggerService = inject(TYPES.loggerService);
|
|
20652
|
+
/**
|
|
20653
|
+
* Processes partial profit events and logs them to the database.
|
|
20654
|
+
*
|
|
20655
|
+
* @param data - Partial profit event data with signal, level, and price information
|
|
20656
|
+
*
|
|
20657
|
+
* @internal
|
|
20658
|
+
*/
|
|
19979
20659
|
this.tickProfit = async (data) => {
|
|
19980
20660
|
this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_TICK_PROFIT, { data });
|
|
19981
20661
|
await Report.writeData("partial", {
|
|
@@ -19993,6 +20673,9 @@ class PartialReportService {
|
|
|
19993
20673
|
priceOpen: data.data.priceOpen,
|
|
19994
20674
|
priceTakeProfit: data.data.priceTakeProfit,
|
|
19995
20675
|
priceStopLoss: data.data.priceStopLoss,
|
|
20676
|
+
originalPriceTakeProfit: data.data.originalPriceTakeProfit,
|
|
20677
|
+
originalPriceStopLoss: data.data.originalPriceStopLoss,
|
|
20678
|
+
totalExecuted: data.data.totalExecuted,
|
|
19996
20679
|
_partial: data.data._partial,
|
|
19997
20680
|
note: data.data.note,
|
|
19998
20681
|
pendingAt: data.data.pendingAt,
|
|
@@ -20007,6 +20690,13 @@ class PartialReportService {
|
|
|
20007
20690
|
walkerName: "",
|
|
20008
20691
|
});
|
|
20009
20692
|
};
|
|
20693
|
+
/**
|
|
20694
|
+
* Processes partial loss events and logs them to the database.
|
|
20695
|
+
*
|
|
20696
|
+
* @param data - Partial loss event data with signal, level, and price information
|
|
20697
|
+
*
|
|
20698
|
+
* @internal
|
|
20699
|
+
*/
|
|
20010
20700
|
this.tickLoss = async (data) => {
|
|
20011
20701
|
this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_TICK_LOSS, { data });
|
|
20012
20702
|
await Report.writeData("partial", {
|
|
@@ -20024,6 +20714,9 @@ class PartialReportService {
|
|
|
20024
20714
|
priceOpen: data.data.priceOpen,
|
|
20025
20715
|
priceTakeProfit: data.data.priceTakeProfit,
|
|
20026
20716
|
priceStopLoss: data.data.priceStopLoss,
|
|
20717
|
+
originalPriceTakeProfit: data.data.originalPriceTakeProfit,
|
|
20718
|
+
originalPriceStopLoss: data.data.originalPriceStopLoss,
|
|
20719
|
+
totalExecuted: data.data.totalExecuted,
|
|
20027
20720
|
_partial: data.data._partial,
|
|
20028
20721
|
note: data.data.note,
|
|
20029
20722
|
pendingAt: data.data.pendingAt,
|
|
@@ -20038,6 +20731,21 @@ class PartialReportService {
|
|
|
20038
20731
|
walkerName: "",
|
|
20039
20732
|
});
|
|
20040
20733
|
};
|
|
20734
|
+
/**
|
|
20735
|
+
* Subscribes to partial profit/loss emitters to receive partial exit events.
|
|
20736
|
+
* Protected against multiple subscriptions.
|
|
20737
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20738
|
+
*
|
|
20739
|
+
* @returns Unsubscribe function to stop receiving partial events
|
|
20740
|
+
*
|
|
20741
|
+
* @example
|
|
20742
|
+
* ```typescript
|
|
20743
|
+
* const service = new PartialReportService();
|
|
20744
|
+
* const unsubscribe = service.subscribe();
|
|
20745
|
+
* // ... later
|
|
20746
|
+
* unsubscribe();
|
|
20747
|
+
* ```
|
|
20748
|
+
*/
|
|
20041
20749
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
20042
20750
|
this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
20043
20751
|
const unProfit = partialProfitSubject.subscribe(this.tickProfit);
|
|
@@ -20048,6 +20756,19 @@ class PartialReportService {
|
|
|
20048
20756
|
unLoss();
|
|
20049
20757
|
};
|
|
20050
20758
|
});
|
|
20759
|
+
/**
|
|
20760
|
+
* Unsubscribes from partial profit/loss emitters to stop receiving events.
|
|
20761
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
20762
|
+
* If not subscribed, does nothing.
|
|
20763
|
+
*
|
|
20764
|
+
* @example
|
|
20765
|
+
* ```typescript
|
|
20766
|
+
* const service = new PartialReportService();
|
|
20767
|
+
* service.subscribe();
|
|
20768
|
+
* // ... later
|
|
20769
|
+
* await service.unsubscribe();
|
|
20770
|
+
* ```
|
|
20771
|
+
*/
|
|
20051
20772
|
this.unsubscribe = async () => {
|
|
20052
20773
|
this.loggerService.log(PARTIAL_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
20053
20774
|
if (this.subscribe.hasValue()) {
|
|
@@ -20061,9 +20782,45 @@ class PartialReportService {
|
|
|
20061
20782
|
const BREAKEVEN_REPORT_METHOD_NAME_SUBSCRIBE = "BreakevenReportService.subscribe";
|
|
20062
20783
|
const BREAKEVEN_REPORT_METHOD_NAME_UNSUBSCRIBE = "BreakevenReportService.unsubscribe";
|
|
20063
20784
|
const BREAKEVEN_REPORT_METHOD_NAME_TICK = "BreakevenReportService.tickBreakeven";
|
|
20785
|
+
/**
|
|
20786
|
+
* Service for logging breakeven events to SQLite database.
|
|
20787
|
+
*
|
|
20788
|
+
* Captures all breakeven events (when signal reaches breakeven point)
|
|
20789
|
+
* and stores them in the Report database for analysis and tracking.
|
|
20790
|
+
*
|
|
20791
|
+
* Features:
|
|
20792
|
+
* - Listens to breakeven events via breakevenSubject
|
|
20793
|
+
* - Logs all breakeven achievements with full signal details
|
|
20794
|
+
* - Stores events in Report.writeData() for persistence
|
|
20795
|
+
* - Protected against multiple subscriptions using singleshot
|
|
20796
|
+
*
|
|
20797
|
+
* @example
|
|
20798
|
+
* ```typescript
|
|
20799
|
+
* import { BreakevenReportService } from "backtest-kit";
|
|
20800
|
+
*
|
|
20801
|
+
* const reportService = new BreakevenReportService();
|
|
20802
|
+
*
|
|
20803
|
+
* // Subscribe to breakeven events
|
|
20804
|
+
* const unsubscribe = reportService.subscribe();
|
|
20805
|
+
*
|
|
20806
|
+
* // Run strategy...
|
|
20807
|
+
* // Breakeven events are automatically logged
|
|
20808
|
+
*
|
|
20809
|
+
* // Later: unsubscribe
|
|
20810
|
+
* await reportService.unsubscribe();
|
|
20811
|
+
* ```
|
|
20812
|
+
*/
|
|
20064
20813
|
class BreakevenReportService {
|
|
20065
20814
|
constructor() {
|
|
20815
|
+
/** Logger service for debug output */
|
|
20066
20816
|
this.loggerService = inject(TYPES.loggerService);
|
|
20817
|
+
/**
|
|
20818
|
+
* Processes breakeven events and logs them to the database.
|
|
20819
|
+
*
|
|
20820
|
+
* @param data - Breakeven event data with signal and price information
|
|
20821
|
+
*
|
|
20822
|
+
* @internal
|
|
20823
|
+
*/
|
|
20067
20824
|
this.tickBreakeven = async (data) => {
|
|
20068
20825
|
this.loggerService.log(BREAKEVEN_REPORT_METHOD_NAME_TICK, { data });
|
|
20069
20826
|
await Report.writeData("breakeven", {
|
|
@@ -20079,6 +20836,9 @@ class BreakevenReportService {
|
|
|
20079
20836
|
priceOpen: data.data.priceOpen,
|
|
20080
20837
|
priceTakeProfit: data.data.priceTakeProfit,
|
|
20081
20838
|
priceStopLoss: data.data.priceStopLoss,
|
|
20839
|
+
originalPriceTakeProfit: data.data.originalPriceTakeProfit,
|
|
20840
|
+
originalPriceStopLoss: data.data.originalPriceStopLoss,
|
|
20841
|
+
totalExecuted: data.data.totalExecuted,
|
|
20082
20842
|
_partial: data.data._partial,
|
|
20083
20843
|
note: data.data.note,
|
|
20084
20844
|
pendingAt: data.data.pendingAt,
|
|
@@ -20093,6 +20853,21 @@ class BreakevenReportService {
|
|
|
20093
20853
|
walkerName: "",
|
|
20094
20854
|
});
|
|
20095
20855
|
};
|
|
20856
|
+
/**
|
|
20857
|
+
* Subscribes to breakeven signal emitter to receive breakeven events.
|
|
20858
|
+
* Protected against multiple subscriptions.
|
|
20859
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20860
|
+
*
|
|
20861
|
+
* @returns Unsubscribe function to stop receiving breakeven events
|
|
20862
|
+
*
|
|
20863
|
+
* @example
|
|
20864
|
+
* ```typescript
|
|
20865
|
+
* const service = new BreakevenReportService();
|
|
20866
|
+
* const unsubscribe = service.subscribe();
|
|
20867
|
+
* // ... later
|
|
20868
|
+
* unsubscribe();
|
|
20869
|
+
* ```
|
|
20870
|
+
*/
|
|
20096
20871
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
20097
20872
|
this.loggerService.log(BREAKEVEN_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
20098
20873
|
const unsubscribe = breakevenSubject.subscribe(this.tickBreakeven);
|
|
@@ -20101,6 +20876,19 @@ class BreakevenReportService {
|
|
|
20101
20876
|
unsubscribe();
|
|
20102
20877
|
};
|
|
20103
20878
|
});
|
|
20879
|
+
/**
|
|
20880
|
+
* Unsubscribes from breakeven signal emitter to stop receiving events.
|
|
20881
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
20882
|
+
* If not subscribed, does nothing.
|
|
20883
|
+
*
|
|
20884
|
+
* @example
|
|
20885
|
+
* ```typescript
|
|
20886
|
+
* const service = new BreakevenReportService();
|
|
20887
|
+
* service.subscribe();
|
|
20888
|
+
* // ... later
|
|
20889
|
+
* await service.unsubscribe();
|
|
20890
|
+
* ```
|
|
20891
|
+
*/
|
|
20104
20892
|
this.unsubscribe = async () => {
|
|
20105
20893
|
this.loggerService.log(BREAKEVEN_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
20106
20894
|
if (this.subscribe.hasValue()) {
|
|
@@ -20114,9 +20902,45 @@ class BreakevenReportService {
|
|
|
20114
20902
|
const RISK_REPORT_METHOD_NAME_SUBSCRIBE = "RiskReportService.subscribe";
|
|
20115
20903
|
const RISK_REPORT_METHOD_NAME_UNSUBSCRIBE = "RiskReportService.unsubscribe";
|
|
20116
20904
|
const RISK_REPORT_METHOD_NAME_TICK = "RiskReportService.tickRejection";
|
|
20905
|
+
/**
|
|
20906
|
+
* Service for logging risk rejection events to SQLite database.
|
|
20907
|
+
*
|
|
20908
|
+
* Captures all signal rejection events from the risk management system
|
|
20909
|
+
* and stores them in the Report database for risk analysis and auditing.
|
|
20910
|
+
*
|
|
20911
|
+
* Features:
|
|
20912
|
+
* - Listens to risk rejection events via riskSubject
|
|
20913
|
+
* - Logs all rejected signals with reason and pending signal details
|
|
20914
|
+
* - Stores events in Report.writeData() for risk tracking
|
|
20915
|
+
* - Protected against multiple subscriptions using singleshot
|
|
20916
|
+
*
|
|
20917
|
+
* @example
|
|
20918
|
+
* ```typescript
|
|
20919
|
+
* import { RiskReportService } from "backtest-kit";
|
|
20920
|
+
*
|
|
20921
|
+
* const reportService = new RiskReportService();
|
|
20922
|
+
*
|
|
20923
|
+
* // Subscribe to risk rejection events
|
|
20924
|
+
* const unsubscribe = reportService.subscribe();
|
|
20925
|
+
*
|
|
20926
|
+
* // Run strategy with risk management...
|
|
20927
|
+
* // Rejection events are automatically logged
|
|
20928
|
+
*
|
|
20929
|
+
* // Later: unsubscribe
|
|
20930
|
+
* await reportService.unsubscribe();
|
|
20931
|
+
* ```
|
|
20932
|
+
*/
|
|
20117
20933
|
class RiskReportService {
|
|
20118
20934
|
constructor() {
|
|
20935
|
+
/** Logger service for debug output */
|
|
20119
20936
|
this.loggerService = inject(TYPES.loggerService);
|
|
20937
|
+
/**
|
|
20938
|
+
* Processes risk rejection events and logs them to the database.
|
|
20939
|
+
*
|
|
20940
|
+
* @param data - Risk event with rejection reason and pending signal information
|
|
20941
|
+
*
|
|
20942
|
+
* @internal
|
|
20943
|
+
*/
|
|
20120
20944
|
this.tickRejection = async (data) => {
|
|
20121
20945
|
this.loggerService.log(RISK_REPORT_METHOD_NAME_TICK, { data });
|
|
20122
20946
|
await Report.writeData("risk", {
|
|
@@ -20150,6 +20974,21 @@ class RiskReportService {
|
|
|
20150
20974
|
walkerName: "",
|
|
20151
20975
|
});
|
|
20152
20976
|
};
|
|
20977
|
+
/**
|
|
20978
|
+
* Subscribes to risk rejection emitter to receive rejection events.
|
|
20979
|
+
* Protected against multiple subscriptions.
|
|
20980
|
+
* Returns an unsubscribe function to stop receiving events.
|
|
20981
|
+
*
|
|
20982
|
+
* @returns Unsubscribe function to stop receiving risk rejection events
|
|
20983
|
+
*
|
|
20984
|
+
* @example
|
|
20985
|
+
* ```typescript
|
|
20986
|
+
* const service = new RiskReportService();
|
|
20987
|
+
* const unsubscribe = service.subscribe();
|
|
20988
|
+
* // ... later
|
|
20989
|
+
* unsubscribe();
|
|
20990
|
+
* ```
|
|
20991
|
+
*/
|
|
20153
20992
|
this.subscribe = functoolsKit.singleshot(() => {
|
|
20154
20993
|
this.loggerService.log(RISK_REPORT_METHOD_NAME_SUBSCRIBE);
|
|
20155
20994
|
const unsubscribe = riskSubject.subscribe(this.tickRejection);
|
|
@@ -20158,6 +20997,19 @@ class RiskReportService {
|
|
|
20158
20997
|
unsubscribe();
|
|
20159
20998
|
};
|
|
20160
20999
|
});
|
|
21000
|
+
/**
|
|
21001
|
+
* Unsubscribes from risk rejection emitter to stop receiving events.
|
|
21002
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
21003
|
+
* If not subscribed, does nothing.
|
|
21004
|
+
*
|
|
21005
|
+
* @example
|
|
21006
|
+
* ```typescript
|
|
21007
|
+
* const service = new RiskReportService();
|
|
21008
|
+
* service.subscribe();
|
|
21009
|
+
* // ... later
|
|
21010
|
+
* await service.unsubscribe();
|
|
21011
|
+
* ```
|
|
21012
|
+
*/
|
|
20161
21013
|
this.unsubscribe = async () => {
|
|
20162
21014
|
this.loggerService.log(RISK_REPORT_METHOD_NAME_UNSUBSCRIBE);
|
|
20163
21015
|
if (this.subscribe.hasValue()) {
|