Service for accumulating strategy management events and generating markdown reports.
Collects strategy actions (cancel-scheduled, close-pending, partial-profit, partial-loss, trailing-stop, trailing-take, breakeven) in memory and provides methods to retrieve statistics, generate reports, and export to files.
Unlike StrategyReportService which writes each event to disk immediately, this service accumulates events in ReportStorage instances (max 250 per symbol-strategy pair) for batch reporting.
Features:
Lifecycle:
constructor();
loggerService: LoggerService
getStorage: any
Memoized factory for ReportStorage instances.
Creates and caches ReportStorage per unique symbol-strategy-exchange-frame-backtest combination. Uses CREATE_KEY_FN for cache key generation.
cancelScheduled: (symbol: string, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, cancelId?: string) => Promise<...>
Records a cancel-scheduled event when a scheduled signal is cancelled.
closePending: (symbol: string, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, closeId?: string) => Promise<...>
Records a close-pending event when a pending signal is closed.
partialProfit: (symbol: string, percentToClose: number, currentPrice: number, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, totalPartials: number, position: "long" | "short", priceOpen: number, priceTakeProfit: number, price...
Records a partial-profit event when a portion of the position is closed at profit.
partialLoss: (symbol: string, percentToClose: number, currentPrice: number, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, totalPartials: number, position: "long" | "short", priceOpen: number, priceTakeProfit: number, price...
Records a partial-loss event when a portion of the position is closed at loss.
trailingStop: (symbol: string, percentShift: number, currentPrice: number, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, totalPartials: number, position: "long" | "short", priceOpen: number, priceTakeProfit: number, priceSt...
Records a trailing-stop event when the stop-loss is adjusted.
trailingTake: (symbol: string, percentShift: number, currentPrice: number, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, totalPartials: number, position: "long" | "short", priceOpen: number, priceTakeProfit: number, priceSt...
Records a trailing-take event when the take-profit is adjusted.
breakeven: (symbol: string, currentPrice: number, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, totalPartials: number, position: "long" | "short", priceOpen: number, priceTakeProfit: number, priceStopLoss: number, origin...
Records a breakeven event when the stop-loss is moved to entry price.
activateScheduled: (symbol: string, currentPrice: number, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, totalPartials: number, position: "long" | "short", priceOpen: number, priceTakeProfit: number, priceStopLoss: number, origin...
Records an activate-scheduled event when a scheduled signal is activated early.
averageBuy: (symbol: string, currentPrice: number, effectivePriceOpen: number, totalEntries: number, isBacktest: boolean, context: { strategyName: string; exchangeName: string; frameName: string; }, timestamp: number, signalId: string, pnl: IStrategyPnL, totalPartials: number, cost: number, position: "long" | "short", priceOpen...
Records an average-buy (DCA) event when a new averaging entry is added to an open position.
getData: (symbol: string, strategyName: string, exchangeName: string, frameName: string, backtest: boolean) => Promise<StrategyStatisticsModel>
Retrieves aggregated statistics from accumulated strategy events.
Returns counts for each action type and the full event list from the ReportStorage for the specified symbol-strategy pair.
getReport: (symbol: string, strategyName: string, exchangeName: string, frameName: string, backtest: boolean, columns?: Columns[]) => Promise<string>
Generates a markdown report from accumulated strategy events.
Creates a formatted markdown document containing:
dump: (symbol: string, strategyName: string, exchangeName: string, frameName: string, backtest: boolean, path?: string, columns?: Columns[]) => Promise<void>
Generates and saves a markdown report to disk.
Creates the output directory if it doesn't exist and writes the report with a timestamped filename via Markdown.writeData().
Filename format: {symbol}_{strategyName}_{exchangeName}[_{frameName}_backtest|_live]-{timestamp}.md
clear: (payload?: { symbol: string; strategyName: string; exchangeName: string; frameName: string; backtest: boolean; }) => Promise<void>
Clears accumulated events from storage.
Can clear either a specific symbol-strategy pair or all stored data.
subscribe: (() => () => void) & ISingleshotClearable
Initializes the service for event collection.
Must be called before any events can be collected or reports generated. Uses singleshot pattern to ensure only one subscription exists at a time.
unsubscribe: () => Promise<void>
Stops event collection and clears all accumulated data.
Invokes the cleanup function returned by subscribe(), which clears both the subscription and all ReportStorage instances. Safe to call multiple times - only acts if subscription exists.