backtest-kit 1.9.1 → 1.10.2

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.
Files changed (6) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +259 -256
  3. package/build/index.cjs +3280 -875
  4. package/build/index.mjs +3276 -876
  5. package/package.json +81 -81
  6. package/types.d.ts +1789 -463
package/types.d.ts CHANGED
@@ -215,166 +215,91 @@ declare function partialLoss(symbol: string, percentToClose: number): Promise<vo
215
215
  *
216
216
  * @param symbol - Trading pair symbol
217
217
  * @param percentShift - Percentage adjustment to SL distance (-100 to 100)
218
+ * @param currentPrice - Current market price to check for intrusion
218
219
  * @returns Promise that resolves when trailing SL is updated
219
220
  *
220
221
  * @example
221
222
  * ```typescript
222
223
  * import { trailingStop } from "backtest-kit";
223
224
  *
224
- * // LONG: entry=100, originalSL=90, distance=10
225
- * // Tighten stop by 50%: newSL = 100 - 10*(1-0.5) = 95
226
- * await trailingStop("BTCUSDT", -50);
225
+ * // LONG: entry=100, originalSL=90, distance=10%, currentPrice=102
226
+ * // Tighten stop by 50%: newSL = 100 - 5% = 95
227
+ * await trailingStop("BTCUSDT", -50, 102);
227
228
  * ```
228
229
  */
229
- declare function trailingStop(symbol: string, percentShift: number): Promise<void>;
230
-
231
- declare const GLOBAL_CONFIG: {
232
- /**
233
- * Time to wait for scheduled signal to activate (in minutes)
234
- * If signal does not activate within this time, it will be cancelled.
235
- */
236
- CC_SCHEDULE_AWAIT_MINUTES: number;
237
- /**
238
- * Number of candles to use for average price calculation (VWAP)
239
- * Default: 5 candles (last 5 minutes when using 1m interval)
240
- */
241
- CC_AVG_PRICE_CANDLES_COUNT: number;
242
- /**
243
- * Slippage percentage applied to entry and exit prices.
244
- * Simulates market impact and order book depth.
245
- * Applied twice (entry and exit) for realistic execution simulation.
246
- * Default: 0.1% per transaction
247
- */
248
- CC_PERCENT_SLIPPAGE: number;
249
- /**
250
- * Fee percentage charged per transaction.
251
- * Applied twice (entry and exit) for total fee calculation.
252
- * Default: 0.1% per transaction (total 0.2%)
253
- */
254
- CC_PERCENT_FEE: number;
255
- /**
256
- * Minimum TakeProfit distance from priceOpen (percentage)
257
- * Must be greater than (slippage + fees) to ensure profitable trades
258
- *
259
- * Calculation:
260
- * - Slippage effect: ~0.2% (0.1% × 2 transactions)
261
- * - Fees: 0.2% (0.1% × 2 transactions)
262
- * - Minimum profit buffer: 0.1%
263
- * - Total: 0.5%
264
- *
265
- * Default: 0.5% (covers all costs + minimum profit margin)
266
- */
267
- CC_MIN_TAKEPROFIT_DISTANCE_PERCENT: number;
268
- /**
269
- * Minimum StopLoss distance from priceOpen (percentage)
270
- * Prevents signals from being immediately stopped out due to price volatility
271
- * Default: 0.5% (buffer to avoid instant stop loss on normal market fluctuations)
272
- */
273
- CC_MIN_STOPLOSS_DISTANCE_PERCENT: number;
274
- /**
275
- * Maximum StopLoss distance from priceOpen (percentage)
276
- * Prevents catastrophic losses from extreme StopLoss values
277
- * Default: 20% (one signal cannot lose more than 20% of position)
278
- */
279
- CC_MAX_STOPLOSS_DISTANCE_PERCENT: number;
280
- /**
281
- * Maximum signal lifetime in minutes
282
- * Prevents eternal signals that block risk limits for weeks/months
283
- * Default: 1440 minutes (1 day)
284
- */
285
- CC_MAX_SIGNAL_LIFETIME_MINUTES: number;
286
- /**
287
- * Maximum time allowed for signal generation (in seconds).
288
- * Prevents long-running or stuck signal generation routines from blocking
289
- * execution or consuming resources indefinitely. If generation exceeds this
290
- * threshold the attempt should be aborted, logged and optionally retried.
291
- *
292
- * Default: 180 seconds (3 minutes)
293
- */
294
- CC_MAX_SIGNAL_GENERATION_SECONDS: number;
295
- /**
296
- * Number of retries for getCandles function
297
- * Default: 3 retries
298
- */
299
- CC_GET_CANDLES_RETRY_COUNT: number;
300
- /**
301
- * Delay between retries for getCandles function (in milliseconds)
302
- * Default: 5000 ms (5 seconds)
303
- */
304
- CC_GET_CANDLES_RETRY_DELAY_MS: number;
305
- /**
306
- * Maximum allowed deviation factor for price anomaly detection.
307
- * Price should not be more than this factor lower than reference price.
308
- *
309
- * Reasoning:
310
- * - Incomplete candles from Binance API typically have prices near 0 (e.g., $0.01-1)
311
- * - Normal BTC price ranges: $20,000-100,000
312
- * - Factor 1000 catches prices below $20-100 when median is $20,000-100,000
313
- * - Factor 100 would be too permissive (allows $200 when median is $20,000)
314
- * - Factor 10000 might be too strict for low-cap altcoins
315
- *
316
- * Example: BTC at $50,000 median → threshold $50 (catches $0.01-1 anomalies)
317
- */
318
- CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
319
- /**
320
- * Minimum number of candles required for reliable median calculation.
321
- * Below this threshold, use simple average instead of median.
322
- *
323
- * Reasoning:
324
- * - Each candle provides 4 price points (OHLC)
325
- * - 5 candles = 20 price points, sufficient for robust median calculation
326
- * - Below 5 candles, single anomaly can heavily skew median
327
- * - Statistical rule of thumb: minimum 7-10 data points for median stability
328
- * - Average is more stable than median for small datasets (n < 20)
329
- *
330
- * Example: 3 candles = 12 points (use average), 5 candles = 20 points (use median)
331
- */
332
- CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
333
- /**
334
- * Controls visibility of signal notes in markdown report tables.
335
- * When enabled, the "Note" column will be displayed in all markdown reports
336
- * (backtest, live, schedule, risk, etc.)
337
- *
338
- * Default: false (notes are hidden to reduce table width and improve readability)
339
- */
340
- CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
341
- };
230
+ declare function trailingStop(symbol: string, percentShift: number, currentPrice: number): Promise<void>;
342
231
  /**
343
- * Type for global configuration object.
232
+ * Moves stop-loss to breakeven when price reaches threshold.
233
+ *
234
+ * Moves SL to entry price (zero-risk position) when current price has moved
235
+ * far enough in profit direction to cover transaction costs.
236
+ * Threshold is calculated as: (CC_PERCENT_SLIPPAGE + CC_PERCENT_FEE) * 2
237
+ *
238
+ * Automatically detects backtest/live mode from execution context.
239
+ * Automatically fetches current price via getAveragePrice.
240
+ *
241
+ * @param symbol - Trading pair symbol
242
+ * @returns Promise<boolean> - true if breakeven was set, false if conditions not met
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * import { breakeven } from "backtest-kit";
247
+ *
248
+ * // LONG: entry=100, slippage=0.1%, fee=0.1%, threshold=0.4%
249
+ * // Try to move SL to breakeven (activates when price >= 100.4)
250
+ * const moved = await breakeven("BTCUSDT");
251
+ * if (moved) {
252
+ * console.log("Position moved to breakeven!");
253
+ * }
254
+ * ```
344
255
  */
345
- type GlobalConfig = typeof GLOBAL_CONFIG;
256
+ declare function breakeven(symbol: string): Promise<boolean>;
346
257
 
347
258
  /**
348
- * Mapping of available table/markdown reports to their column definitions.
259
+ * Execution context containing runtime parameters for strategy/exchange operations.
349
260
  *
350
- * Each property references a column definition object imported from
351
- * `src/assets/*.columns`. These are used by markdown/report generators
352
- * (backtest, live, schedule, risk, heat, performance, partial, walker).
261
+ * Propagated through ExecutionContextService to provide implicit context
262
+ * for getCandles(), tick(), backtest() and other operations.
353
263
  */
354
- declare const COLUMN_CONFIG: {
355
- /** Columns used in backtest markdown tables and reports */
356
- backtest_columns: ColumnModel<IStrategyTickResultClosed>[];
357
- /** Columns used by heatmap / heat reports */
358
- heat_columns: ColumnModel<IHeatmapRow>[];
359
- /** Columns for live trading reports and logs */
360
- live_columns: ColumnModel<TickEvent>[];
361
- /** Columns for partial-results / incremental reports */
362
- partial_columns: ColumnModel<PartialEvent>[];
363
- /** Columns for performance summary reports */
364
- performance_columns: ColumnModel<MetricStats>[];
365
- /** Columns for risk-related reports */
366
- risk_columns: ColumnModel<RiskEvent>[];
367
- /** Columns for scheduled report output */
368
- schedule_columns: ColumnModel<ScheduledEvent>[];
369
- /** Walker: PnL summary columns */
370
- walker_pnl_columns: ColumnModel<SignalData$1>[];
371
- /** Walker: strategy-level summary columns */
372
- walker_strategy_columns: ColumnModel<IStrategyResult>[];
373
- };
264
+ interface IExecutionContext {
265
+ /** Trading pair symbol (e.g., "BTCUSDT") */
266
+ symbol: string;
267
+ /** Current timestamp for operation */
268
+ when: Date;
269
+ /** Whether running in backtest mode (true) or live mode (false) */
270
+ backtest: boolean;
271
+ }
374
272
  /**
375
- * Type for the column configuration object.
273
+ * Scoped service for execution context propagation.
274
+ *
275
+ * Uses di-scoped for implicit context passing without explicit parameters.
276
+ * Context includes symbol, when (timestamp), and backtest flag.
277
+ *
278
+ * Used by GlobalServices to inject context into operations.
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * ExecutionContextService.runInContext(
283
+ * async () => {
284
+ * // Inside this callback, context is automatically available
285
+ * return await someOperation();
286
+ * },
287
+ * { symbol: "BTCUSDT", when: new Date(), backtest: true }
288
+ * );
289
+ * ```
376
290
  */
377
- type ColumnConfig = typeof COLUMN_CONFIG;
291
+ declare const ExecutionContextService: (new () => {
292
+ readonly context: IExecutionContext;
293
+ }) & Omit<{
294
+ new (context: IExecutionContext): {
295
+ readonly context: IExecutionContext;
296
+ };
297
+ }, "prototype"> & di_scoped.IScopedClassRun<[context: IExecutionContext]>;
298
+ /**
299
+ * Type helper for ExecutionContextService instance.
300
+ * Used for dependency injection type annotations.
301
+ */
302
+ type TExecutionContextService = InstanceType<typeof ExecutionContextService>;
378
303
 
379
304
  /**
380
305
  * Interface representing a logging mechanism for the swarm system.
@@ -405,244 +330,30 @@ interface ILogger {
405
330
  }
406
331
 
407
332
  /**
408
- * Sets custom logger implementation for the framework.
409
- *
410
- * All log messages from internal services will be forwarded to the provided logger
411
- * with automatic context injection (strategyName, exchangeName, symbol, etc.).
412
- *
413
- * @param logger - Custom logger implementing ILogger interface
414
- *
415
- * @example
416
- * ```typescript
417
- * setLogger({
418
- * log: (topic, ...args) => console.log(topic, args),
419
- * debug: (topic, ...args) => console.debug(topic, args),
420
- * info: (topic, ...args) => console.info(topic, args),
421
- * });
422
- * ```
333
+ * Candle time interval for fetching historical data.
423
334
  */
424
- declare function setLogger(logger: ILogger): void;
335
+ type CandleInterval = "1m" | "3m" | "5m" | "15m" | "30m" | "1h" | "2h" | "4h" | "6h" | "8h";
425
336
  /**
426
- * Sets global configuration parameters for the framework.
427
- * @param config - Partial configuration object to override default settings
428
- * @param _unsafe - Skip config validations - required for testbed
429
- *
430
- * @example
431
- * ```typescript
432
- * setConfig({
433
- * CC_SCHEDULE_AWAIT_MINUTES: 90,
434
- * });
435
- * ```
337
+ * Single OHLCV candle data point.
338
+ * Used for VWAP calculation and backtesting.
436
339
  */
437
- declare function setConfig(config: Partial<GlobalConfig>, _unsafe?: boolean): void;
340
+ interface ICandleData {
341
+ /** Unix timestamp in milliseconds when candle opened */
342
+ timestamp: number;
343
+ /** Opening price at candle start */
344
+ open: number;
345
+ /** Highest price during candle period */
346
+ high: number;
347
+ /** Lowest price during candle period */
348
+ low: number;
349
+ /** Closing price at candle end */
350
+ close: number;
351
+ /** Trading volume during candle period */
352
+ volume: number;
353
+ }
438
354
  /**
439
- * Retrieves a copy of the current global configuration.
440
- *
441
- * Returns a shallow copy of the current GLOBAL_CONFIG to prevent accidental mutations.
442
- * Use this to inspect the current configuration state without modifying it.
443
- *
444
- * @returns {GlobalConfig} A copy of the current global configuration object
445
- *
446
- * @example
447
- * ```typescript
448
- * const currentConfig = getConfig();
449
- * console.log(currentConfig.CC_SCHEDULE_AWAIT_MINUTES);
450
- * ```
451
- */
452
- declare function getConfig(): {
453
- CC_SCHEDULE_AWAIT_MINUTES: number;
454
- CC_AVG_PRICE_CANDLES_COUNT: number;
455
- CC_PERCENT_SLIPPAGE: number;
456
- CC_PERCENT_FEE: number;
457
- CC_MIN_TAKEPROFIT_DISTANCE_PERCENT: number;
458
- CC_MIN_STOPLOSS_DISTANCE_PERCENT: number;
459
- CC_MAX_STOPLOSS_DISTANCE_PERCENT: number;
460
- CC_MAX_SIGNAL_LIFETIME_MINUTES: number;
461
- CC_MAX_SIGNAL_GENERATION_SECONDS: number;
462
- CC_GET_CANDLES_RETRY_COUNT: number;
463
- CC_GET_CANDLES_RETRY_DELAY_MS: number;
464
- CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
465
- CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
466
- CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
467
- };
468
- /**
469
- * Retrieves the default configuration object for the framework.
470
- *
471
- * Returns a reference to the default configuration with all preset values.
472
- * Use this to see what configuration options are available and their default values.
473
- *
474
- * @returns {GlobalConfig} The default configuration object
475
- *
476
- * @example
477
- * ```typescript
478
- * const defaultConfig = getDefaultConfig();
479
- * console.log(defaultConfig.CC_SCHEDULE_AWAIT_MINUTES);
480
- * ```
481
- */
482
- declare function getDefaultConfig(): Readonly<{
483
- CC_SCHEDULE_AWAIT_MINUTES: number;
484
- CC_AVG_PRICE_CANDLES_COUNT: number;
485
- CC_PERCENT_SLIPPAGE: number;
486
- CC_PERCENT_FEE: number;
487
- CC_MIN_TAKEPROFIT_DISTANCE_PERCENT: number;
488
- CC_MIN_STOPLOSS_DISTANCE_PERCENT: number;
489
- CC_MAX_STOPLOSS_DISTANCE_PERCENT: number;
490
- CC_MAX_SIGNAL_LIFETIME_MINUTES: number;
491
- CC_MAX_SIGNAL_GENERATION_SECONDS: number;
492
- CC_GET_CANDLES_RETRY_COUNT: number;
493
- CC_GET_CANDLES_RETRY_DELAY_MS: number;
494
- CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
495
- CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
496
- CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
497
- }>;
498
- /**
499
- * Sets custom column configurations for markdown report generation.
500
- *
501
- * Allows overriding default column definitions for any report type.
502
- * All columns are validated before assignment to ensure structural correctness.
503
- *
504
- * @param columns - Partial column configuration object to override default column settings
505
- * @param _unsafe - Skip column validations - required for testbed
506
- *
507
- * @example
508
- * ```typescript
509
- * setColumns({
510
- * backtest_columns: [
511
- * {
512
- * key: "customId",
513
- * label: "Custom ID",
514
- * format: (data) => data.signal.id,
515
- * isVisible: () => true
516
- * }
517
- * ],
518
- * });
519
- * ```
520
- *
521
- * @throws {Error} If column configuration is invalid
522
- */
523
- declare function setColumns(columns: Partial<ColumnConfig>, _unsafe?: boolean): void;
524
- /**
525
- * Retrieves a copy of the current column configuration for markdown report generation.
526
- *
527
- * Returns a shallow copy of the current COLUMN_CONFIG to prevent accidental mutations.
528
- * Use this to inspect the current column definitions without modifying them.
529
- *
530
- * @returns {ColumnConfig} A copy of the current column configuration object
531
- *
532
- * @example
533
- * ```typescript
534
- * const currentColumns = getColumns();
535
- * console.log(currentColumns.backtest_columns.length);
536
- * ```
537
- */
538
- declare function getColumns(): {
539
- backtest_columns: ColumnModel<IStrategyTickResultClosed>[];
540
- heat_columns: ColumnModel<IHeatmapRow>[];
541
- live_columns: ColumnModel<TickEvent>[];
542
- partial_columns: ColumnModel<PartialEvent>[];
543
- performance_columns: ColumnModel<MetricStats>[];
544
- risk_columns: ColumnModel<RiskEvent>[];
545
- schedule_columns: ColumnModel<ScheduledEvent>[];
546
- walker_pnl_columns: ColumnModel<SignalData$1>[];
547
- walker_strategy_columns: ColumnModel<IStrategyResult>[];
548
- };
549
- /**
550
- * Retrieves the default column configuration object for markdown report generation.
551
- *
552
- * Returns a reference to the default column definitions with all preset values.
553
- * Use this to see what column options are available and their default definitions.
554
- *
555
- * @returns {ColumnConfig} The default column configuration object
556
- *
557
- * @example
558
- * ```typescript
559
- * const defaultColumns = getDefaultColumns();
560
- * console.log(defaultColumns.backtest_columns);
561
- * ```
562
- */
563
- declare function getDefaultColumns(): Readonly<{
564
- backtest_columns: ColumnModel<IStrategyTickResultClosed>[];
565
- heat_columns: ColumnModel<IHeatmapRow>[];
566
- live_columns: ColumnModel<TickEvent>[];
567
- partial_columns: ColumnModel<PartialEvent>[];
568
- performance_columns: ColumnModel<MetricStats>[];
569
- risk_columns: ColumnModel<RiskEvent>[];
570
- schedule_columns: ColumnModel<ScheduledEvent>[];
571
- walker_pnl_columns: ColumnModel<SignalData$1>[];
572
- walker_strategy_columns: ColumnModel<IStrategyResult>[];
573
- }>;
574
-
575
- /**
576
- * Execution context containing runtime parameters for strategy/exchange operations.
577
- *
578
- * Propagated through ExecutionContextService to provide implicit context
579
- * for getCandles(), tick(), backtest() and other operations.
580
- */
581
- interface IExecutionContext {
582
- /** Trading pair symbol (e.g., "BTCUSDT") */
583
- symbol: string;
584
- /** Current timestamp for operation */
585
- when: Date;
586
- /** Whether running in backtest mode (true) or live mode (false) */
587
- backtest: boolean;
588
- }
589
- /**
590
- * Scoped service for execution context propagation.
591
- *
592
- * Uses di-scoped for implicit context passing without explicit parameters.
593
- * Context includes symbol, when (timestamp), and backtest flag.
594
- *
595
- * Used by GlobalServices to inject context into operations.
596
- *
597
- * @example
598
- * ```typescript
599
- * ExecutionContextService.runInContext(
600
- * async () => {
601
- * // Inside this callback, context is automatically available
602
- * return await someOperation();
603
- * },
604
- * { symbol: "BTCUSDT", when: new Date(), backtest: true }
605
- * );
606
- * ```
607
- */
608
- declare const ExecutionContextService: (new () => {
609
- readonly context: IExecutionContext;
610
- }) & Omit<{
611
- new (context: IExecutionContext): {
612
- readonly context: IExecutionContext;
613
- };
614
- }, "prototype"> & di_scoped.IScopedClassRun<[context: IExecutionContext]>;
615
- /**
616
- * Type helper for ExecutionContextService instance.
617
- * Used for dependency injection type annotations.
618
- */
619
- type TExecutionContextService = InstanceType<typeof ExecutionContextService>;
620
-
621
- /**
622
- * Candle time interval for fetching historical data.
623
- */
624
- type CandleInterval = "1m" | "3m" | "5m" | "15m" | "30m" | "1h" | "2h" | "4h" | "6h" | "8h";
625
- /**
626
- * Single OHLCV candle data point.
627
- * Used for VWAP calculation and backtesting.
628
- */
629
- interface ICandleData {
630
- /** Unix timestamp in milliseconds when candle opened */
631
- timestamp: number;
632
- /** Opening price at candle start */
633
- open: number;
634
- /** Highest price during candle period */
635
- high: number;
636
- /** Lowest price during candle period */
637
- low: number;
638
- /** Closing price at candle end */
639
- close: number;
640
- /** Trading volume during candle period */
641
- volume: number;
642
- }
643
- /**
644
- * Exchange parameters passed to ClientExchange constructor.
645
- * Combines schema with runtime dependencies.
355
+ * Exchange parameters passed to ClientExchange constructor.
356
+ * Combines schema with runtime dependencies.
646
357
  */
647
358
  interface IExchangeParams extends IExchangeSchema {
648
359
  /** Logger service for debug output */
@@ -987,6 +698,8 @@ interface IRiskSchema {
987
698
  * Combines schema with runtime dependencies and emission callbacks.
988
699
  */
989
700
  interface IRiskParams extends IRiskSchema {
701
+ /** Exchange name (e.g., "binance") */
702
+ exchangeName: ExchangeName;
990
703
  /** Logger service for debug output */
991
704
  logger: ILogger;
992
705
  /** True if backtest mode, false if live mode */
@@ -1203,6 +916,112 @@ interface IPartial {
1203
916
  clear(symbol: string, data: IPublicSignalRow, priceClose: number, backtest: boolean): Promise<void>;
1204
917
  }
1205
918
 
919
+ /**
920
+ * Serializable breakeven data for persistence layer.
921
+ * Converts state to simple boolean for JSON serialization.
922
+ *
923
+ * Stored in PersistBreakevenAdapter as Record<signalId, IBreakevenData>.
924
+ * Loaded on initialization and converted back to IBreakevenState.
925
+ */
926
+ interface IBreakevenData {
927
+ /**
928
+ * Whether breakeven has been reached for this signal.
929
+ * Serialized form of IBreakevenState.reached.
930
+ */
931
+ reached: boolean;
932
+ }
933
+ /**
934
+ * Breakeven tracking interface.
935
+ * Implemented by ClientBreakeven and BreakevenConnectionService.
936
+ *
937
+ * Tracks when a signal's stop-loss is moved to breakeven (entry price).
938
+ * Emits events when threshold is reached (price moves far enough to cover transaction costs).
939
+ *
940
+ * @example
941
+ * ```typescript
942
+ * import { ClientBreakeven } from "./client/ClientBreakeven";
943
+ *
944
+ * const breakeven = new ClientBreakeven({
945
+ * logger: loggerService,
946
+ * onBreakeven: (symbol, data, price, backtest, timestamp) => {
947
+ * console.log(`Signal ${data.id} reached breakeven at ${price}`);
948
+ * }
949
+ * });
950
+ *
951
+ * await breakeven.waitForInit("BTCUSDT");
952
+ *
953
+ * // During signal monitoring
954
+ * await breakeven.check("BTCUSDT", signal, 100.5, false, new Date());
955
+ * // Emits event when threshold reached and SL moved to entry
956
+ *
957
+ * // When signal closes
958
+ * await breakeven.clear("BTCUSDT", signal, 101, false);
959
+ * ```
960
+ */
961
+ interface IBreakeven {
962
+ /**
963
+ * Checks if breakeven should be triggered and emits event if conditions met.
964
+ *
965
+ * Called by ClientStrategy during signal monitoring.
966
+ * Checks if:
967
+ * 1. Breakeven not already reached
968
+ * 2. Price has moved far enough to cover transaction costs
969
+ * 3. Stop-loss can be moved to entry price
970
+ *
971
+ * If all conditions met:
972
+ * - Marks breakeven as reached
973
+ * - Calls onBreakeven callback (emits to breakevenSubject)
974
+ * - Persists state to disk
975
+ *
976
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
977
+ * @param data - Signal row data
978
+ * @param currentPrice - Current market price
979
+ * @param backtest - True if backtest mode, false if live mode
980
+ * @param when - Event timestamp (current time for live, candle time for backtest)
981
+ * @returns Promise that resolves when breakeven check is complete
982
+ *
983
+ * @example
984
+ * ```typescript
985
+ * // LONG: entry=100, slippage=0.1%, fee=0.1%, threshold=0.4%
986
+ * // Price at 100.3 - threshold not reached
987
+ * await breakeven.check("BTCUSDT", signal, 100.3, false, new Date());
988
+ * // No event emitted (price < 100.4)
989
+ *
990
+ * // Price at 100.5 - threshold reached!
991
+ * await breakeven.check("BTCUSDT", signal, 100.5, false, new Date());
992
+ * // Emits breakevenSubject event
993
+ *
994
+ * // Price at 101 - already at breakeven
995
+ * await breakeven.check("BTCUSDT", signal, 101, false, new Date());
996
+ * // No event emitted (already reached)
997
+ * ```
998
+ */
999
+ check(symbol: string, data: IPublicSignalRow, currentPrice: number, backtest: boolean, when: Date): Promise<boolean>;
1000
+ /**
1001
+ * Clears breakeven state when signal closes.
1002
+ *
1003
+ * Called by ClientStrategy when signal completes (TP/SL/time_expired).
1004
+ * Removes signal state from memory and persists changes to disk.
1005
+ * Cleans up memoized ClientBreakeven instance in BreakevenConnectionService.
1006
+ *
1007
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
1008
+ * @param data - Signal row data
1009
+ * @param priceClose - Final closing price
1010
+ * @param backtest - True if backtest mode, false if live mode
1011
+ * @returns Promise that resolves when clear is complete
1012
+ *
1013
+ * @example
1014
+ * ```typescript
1015
+ * // Signal closes at take profit
1016
+ * await breakeven.clear("BTCUSDT", signal, 101);
1017
+ * // State removed from _states Map
1018
+ * // Persisted to disk without this signal's data
1019
+ * // Memoized instance cleared from getBreakeven cache
1020
+ * ```
1021
+ */
1022
+ clear(symbol: string, data: IPublicSignalRow, priceClose: number, backtest: boolean): Promise<void>;
1023
+ }
1024
+
1206
1025
  /**
1207
1026
  * Signal generation interval for throttling.
1208
1027
  * Enforces minimum time between getSignal calls.
@@ -1354,6 +1173,8 @@ interface IStrategyCallbacks {
1354
1173
  onPartialProfit: (symbol: string, data: IPublicSignalRow, currentPrice: number, revenuePercent: number, backtest: boolean) => void | Promise<void>;
1355
1174
  /** Called when signal is in partial loss state (price moved against position but not hit SL yet) */
1356
1175
  onPartialLoss: (symbol: string, data: IPublicSignalRow, currentPrice: number, lossPercent: number, backtest: boolean) => void | Promise<void>;
1176
+ /** Called when signal reaches breakeven (stop-loss moved to entry price to protect capital) */
1177
+ onBreakeven: (symbol: string, data: IPublicSignalRow, currentPrice: number, backtest: boolean) => void | Promise<void>;
1357
1178
  /** Called every minute regardless of strategy interval (for custom monitoring like checking if signal should be cancelled) */
1358
1179
  onPing: (symbol: string, data: IPublicSignalRow, when: Date, backtest: boolean) => void | Promise<void>;
1359
1180
  }
@@ -1592,17 +1413,53 @@ interface IStrategy {
1592
1413
  */
1593
1414
  getScheduledSignal: (symbol: string) => Promise<IPublicSignalRow | null>;
1594
1415
  /**
1595
- * Checks if the strategy has been stopped.
1416
+ * Checks if breakeven threshold has been reached for the current pending signal.
1596
1417
  *
1597
- * Returns the stopped state indicating whether the strategy should
1598
- * cease processing new ticks or signals.
1418
+ * Uses the same formula as BREAKEVEN_FN to determine if price has moved far enough
1419
+ * to cover transaction costs (slippage + fees) and allow breakeven to be set.
1420
+ * Threshold: (CC_PERCENT_SLIPPAGE + CC_PERCENT_FEE) * 2 transactions
1599
1421
  *
1600
- * @param symbol - Trading pair symbol
1601
- * @returns Promise resolving to true if strategy is stopped, false otherwise
1602
- */
1603
- getStopped: (symbol: string) => Promise<boolean>;
1604
- /**
1605
- * Fast backtest using historical candles.
1422
+ * For LONG position:
1423
+ * - Returns true when: currentPrice >= priceOpen * (1 + threshold%)
1424
+ * - Example: entry=100, threshold=0.4% → true when price >= 100.4
1425
+ *
1426
+ * For SHORT position:
1427
+ * - Returns true when: currentPrice <= priceOpen * (1 - threshold%)
1428
+ * - Example: entry=100, threshold=0.4% → true when price <= 99.6
1429
+ *
1430
+ * Special cases:
1431
+ * - Returns false if no pending signal exists
1432
+ * - Returns true if trailing stop is already in profit zone (breakeven already achieved)
1433
+ * - Returns false if threshold not reached yet
1434
+ *
1435
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
1436
+ * @param currentPrice - Current market price to check against threshold
1437
+ * @returns Promise<boolean> - true if breakeven threshold reached, false otherwise
1438
+ *
1439
+ * @example
1440
+ * ```typescript
1441
+ * // Check if breakeven is available for LONG position (entry=100, threshold=0.4%)
1442
+ * const canBreakeven = await strategy.getBreakeven("BTCUSDT", 100.5);
1443
+ * // Returns true (price >= 100.4)
1444
+ *
1445
+ * if (canBreakeven) {
1446
+ * await strategy.breakeven("BTCUSDT", 100.5, false);
1447
+ * }
1448
+ * ```
1449
+ */
1450
+ getBreakeven: (symbol: string, currentPrice: number) => Promise<boolean>;
1451
+ /**
1452
+ * Checks if the strategy has been stopped.
1453
+ *
1454
+ * Returns the stopped state indicating whether the strategy should
1455
+ * cease processing new ticks or signals.
1456
+ *
1457
+ * @param symbol - Trading pair symbol
1458
+ * @returns Promise resolving to true if strategy is stopped, false otherwise
1459
+ */
1460
+ getStopped: (symbol: string) => Promise<boolean>;
1461
+ /**
1462
+ * Fast backtest using historical candles.
1606
1463
  * Iterates through candles, calculates VWAP, checks TP/SL on each candle.
1607
1464
  *
1608
1465
  * For scheduled signals: first monitors activation/cancellation,
@@ -1770,13 +1627,441 @@ interface IStrategy {
1770
1627
  * }
1771
1628
  * ```
1772
1629
  */
1773
- trailingStop: (symbol: string, percentShift: number, backtest: boolean) => Promise<void>;
1630
+ trailingStop: (symbol: string, percentShift: number, currentPrice: number, backtest: boolean) => Promise<void>;
1631
+ /**
1632
+ * Moves stop-loss to breakeven (entry price) when price reaches threshold.
1633
+ *
1634
+ * Moves SL to entry price (zero-risk position) when current price has moved
1635
+ * far enough in profit direction to cover transaction costs (slippage + fees).
1636
+ * Threshold is calculated as: (CC_PERCENT_SLIPPAGE + CC_PERCENT_FEE) * 2
1637
+ *
1638
+ * Behavior:
1639
+ * - Returns true if SL was moved to breakeven
1640
+ * - Returns false if conditions not met (threshold not reached or already at breakeven)
1641
+ * - Uses _trailingPriceStopLoss to store breakeven SL (preserves original priceStopLoss)
1642
+ * - Only moves SL once per position (idempotent - safe to call multiple times)
1643
+ *
1644
+ * For LONG position (entry=100, slippage=0.1%, fee=0.1%):
1645
+ * - Threshold: (0.1 + 0.1) * 2 = 0.4%
1646
+ * - Breakeven available when price >= 100.4 (entry + 0.4%)
1647
+ * - Moves SL from original (e.g. 95) to 100 (breakeven)
1648
+ * - Returns true on first successful move, false on subsequent calls
1649
+ *
1650
+ * For SHORT position (entry=100, slippage=0.1%, fee=0.1%):
1651
+ * - Threshold: (0.1 + 0.1) * 2 = 0.4%
1652
+ * - Breakeven available when price <= 99.6 (entry - 0.4%)
1653
+ * - Moves SL from original (e.g. 105) to 100 (breakeven)
1654
+ * - Returns true on first successful move, false on subsequent calls
1655
+ *
1656
+ * Validations:
1657
+ * - Throws if no pending signal exists
1658
+ * - Throws if currentPrice is not a positive finite number
1659
+ *
1660
+ * Use case: User-controlled breakeven protection triggered from onPartialProfit callback.
1661
+ *
1662
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
1663
+ * @param currentPrice - Current market price to check threshold
1664
+ * @param backtest - Whether running in backtest mode
1665
+ * @returns Promise<boolean> - true if breakeven was set, false if conditions not met
1666
+ *
1667
+ * @example
1668
+ * ```typescript
1669
+ * callbacks: {
1670
+ * onPartialProfit: async (symbol, signal, currentPrice, percentTp, backtest) => {
1671
+ * // Try to move SL to breakeven when threshold reached
1672
+ * const movedToBreakeven = await strategy.breakeven(symbol, currentPrice, backtest);
1673
+ * if (movedToBreakeven) {
1674
+ * console.log(`Position moved to breakeven at ${currentPrice}`);
1675
+ * }
1676
+ * }
1677
+ * }
1678
+ * ```
1679
+ */
1680
+ breakeven: (symbol: string, currentPrice: number, backtest: boolean) => Promise<boolean>;
1774
1681
  }
1775
1682
  /**
1776
1683
  * Unique strategy identifier.
1777
1684
  */
1778
1685
  type StrategyName = string;
1779
1686
 
1687
+ /**
1688
+ * Unified breakeven event data for report generation.
1689
+ * Contains all information about when signals reached breakeven.
1690
+ */
1691
+ interface BreakevenEvent {
1692
+ /** Event timestamp in milliseconds */
1693
+ timestamp: number;
1694
+ /** Trading pair symbol */
1695
+ symbol: string;
1696
+ /** Strategy name */
1697
+ strategyName: StrategyName;
1698
+ /** Signal ID */
1699
+ signalId: string;
1700
+ /** Position type */
1701
+ position: string;
1702
+ /** Current market price when breakeven was reached */
1703
+ currentPrice: number;
1704
+ /** Entry price (breakeven level) */
1705
+ priceOpen: number;
1706
+ /** True if backtest mode, false if live mode */
1707
+ backtest: boolean;
1708
+ }
1709
+ /**
1710
+ * Statistical data calculated from breakeven events.
1711
+ *
1712
+ * Provides metrics for breakeven milestone tracking.
1713
+ *
1714
+ * @example
1715
+ * ```typescript
1716
+ * const stats = await Breakeven.getData("BTCUSDT", "my-strategy");
1717
+ *
1718
+ * console.log(`Total breakeven events: ${stats.totalEvents}`);
1719
+ * console.log(`Average threshold: ${stats.averageThreshold}%`);
1720
+ * ```
1721
+ */
1722
+ interface BreakevenStatisticsModel {
1723
+ /** Array of all breakeven events with full details */
1724
+ eventList: BreakevenEvent[];
1725
+ /** Total number of breakeven events */
1726
+ totalEvents: number;
1727
+ }
1728
+
1729
+ declare const GLOBAL_CONFIG: {
1730
+ /**
1731
+ * Time to wait for scheduled signal to activate (in minutes)
1732
+ * If signal does not activate within this time, it will be cancelled.
1733
+ */
1734
+ CC_SCHEDULE_AWAIT_MINUTES: number;
1735
+ /**
1736
+ * Number of candles to use for average price calculation (VWAP)
1737
+ * Default: 5 candles (last 5 minutes when using 1m interval)
1738
+ */
1739
+ CC_AVG_PRICE_CANDLES_COUNT: number;
1740
+ /**
1741
+ * Slippage percentage applied to entry and exit prices.
1742
+ * Simulates market impact and order book depth.
1743
+ * Applied twice (entry and exit) for realistic execution simulation.
1744
+ * Default: 0.1% per transaction
1745
+ */
1746
+ CC_PERCENT_SLIPPAGE: number;
1747
+ /**
1748
+ * Fee percentage charged per transaction.
1749
+ * Applied twice (entry and exit) for total fee calculation.
1750
+ * Default: 0.1% per transaction (total 0.2%)
1751
+ */
1752
+ CC_PERCENT_FEE: number;
1753
+ /**
1754
+ * Minimum TakeProfit distance from priceOpen (percentage)
1755
+ * Must be greater than (slippage + fees) to ensure profitable trades
1756
+ *
1757
+ * Calculation:
1758
+ * - Slippage effect: ~0.2% (0.1% × 2 transactions)
1759
+ * - Fees: 0.2% (0.1% × 2 transactions)
1760
+ * - Minimum profit buffer: 0.1%
1761
+ * - Total: 0.5%
1762
+ *
1763
+ * Default: 0.5% (covers all costs + minimum profit margin)
1764
+ */
1765
+ CC_MIN_TAKEPROFIT_DISTANCE_PERCENT: number;
1766
+ /**
1767
+ * Minimum StopLoss distance from priceOpen (percentage)
1768
+ * Prevents signals from being immediately stopped out due to price volatility
1769
+ * Default: 0.5% (buffer to avoid instant stop loss on normal market fluctuations)
1770
+ */
1771
+ CC_MIN_STOPLOSS_DISTANCE_PERCENT: number;
1772
+ /**
1773
+ * Maximum StopLoss distance from priceOpen (percentage)
1774
+ * Prevents catastrophic losses from extreme StopLoss values
1775
+ * Default: 20% (one signal cannot lose more than 20% of position)
1776
+ */
1777
+ CC_MAX_STOPLOSS_DISTANCE_PERCENT: number;
1778
+ /**
1779
+ * Maximum signal lifetime in minutes
1780
+ * Prevents eternal signals that block risk limits for weeks/months
1781
+ * Default: 1440 minutes (1 day)
1782
+ */
1783
+ CC_MAX_SIGNAL_LIFETIME_MINUTES: number;
1784
+ /**
1785
+ * Maximum time allowed for signal generation (in seconds).
1786
+ * Prevents long-running or stuck signal generation routines from blocking
1787
+ * execution or consuming resources indefinitely. If generation exceeds this
1788
+ * threshold the attempt should be aborted, logged and optionally retried.
1789
+ *
1790
+ * Default: 180 seconds (3 minutes)
1791
+ */
1792
+ CC_MAX_SIGNAL_GENERATION_SECONDS: number;
1793
+ /**
1794
+ * Number of retries for getCandles function
1795
+ * Default: 3 retries
1796
+ */
1797
+ CC_GET_CANDLES_RETRY_COUNT: number;
1798
+ /**
1799
+ * Delay between retries for getCandles function (in milliseconds)
1800
+ * Default: 5000 ms (5 seconds)
1801
+ */
1802
+ CC_GET_CANDLES_RETRY_DELAY_MS: number;
1803
+ /**
1804
+ * Maximum allowed deviation factor for price anomaly detection.
1805
+ * Price should not be more than this factor lower than reference price.
1806
+ *
1807
+ * Reasoning:
1808
+ * - Incomplete candles from Binance API typically have prices near 0 (e.g., $0.01-1)
1809
+ * - Normal BTC price ranges: $20,000-100,000
1810
+ * - Factor 1000 catches prices below $20-100 when median is $20,000-100,000
1811
+ * - Factor 100 would be too permissive (allows $200 when median is $20,000)
1812
+ * - Factor 10000 might be too strict for low-cap altcoins
1813
+ *
1814
+ * Example: BTC at $50,000 median → threshold $50 (catches $0.01-1 anomalies)
1815
+ */
1816
+ CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
1817
+ /**
1818
+ * Minimum number of candles required for reliable median calculation.
1819
+ * Below this threshold, use simple average instead of median.
1820
+ *
1821
+ * Reasoning:
1822
+ * - Each candle provides 4 price points (OHLC)
1823
+ * - 5 candles = 20 price points, sufficient for robust median calculation
1824
+ * - Below 5 candles, single anomaly can heavily skew median
1825
+ * - Statistical rule of thumb: minimum 7-10 data points for median stability
1826
+ * - Average is more stable than median for small datasets (n < 20)
1827
+ *
1828
+ * Example: 3 candles = 12 points (use average), 5 candles = 20 points (use median)
1829
+ */
1830
+ CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
1831
+ /**
1832
+ * Controls visibility of signal notes in markdown report tables.
1833
+ * When enabled, the "Note" column will be displayed in all markdown reports
1834
+ * (backtest, live, schedule, risk, etc.)
1835
+ *
1836
+ * Default: false (notes are hidden to reduce table width and improve readability)
1837
+ */
1838
+ CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
1839
+ /**
1840
+ * Breakeven threshold percentage - minimum profit distance from entry to enable breakeven.
1841
+ * When price moves this percentage in profit direction, stop-loss can be moved to entry (breakeven).
1842
+ *
1843
+ * Calculation:
1844
+ * - Slippage effect: ~0.2% (0.1% × 2 transactions)
1845
+ * - Fees: 0.2% (0.1% × 2 transactions)
1846
+ * - Total: 0.4%
1847
+ * - Added buffer: 0.2%
1848
+ * - Overall: 0.6%
1849
+ *
1850
+ * Default: 0.2% (additional buffer above costs to ensure no loss when moving to breakeven)
1851
+ */
1852
+ CC_BREAKEVEN_THRESHOLD: number;
1853
+ };
1854
+ /**
1855
+ * Type for global configuration object.
1856
+ */
1857
+ type GlobalConfig = typeof GLOBAL_CONFIG;
1858
+
1859
+ /**
1860
+ * Mapping of available table/markdown reports to their column definitions.
1861
+ *
1862
+ * Each property references a column definition object imported from
1863
+ * `src/assets/*.columns`. These are used by markdown/report generators
1864
+ * (backtest, live, schedule, risk, heat, performance, partial, walker).
1865
+ */
1866
+ declare const COLUMN_CONFIG: {
1867
+ /** Columns used in backtest markdown tables and reports */
1868
+ backtest_columns: ColumnModel<IStrategyTickResultClosed>[];
1869
+ /** Columns used by heatmap / heat reports */
1870
+ heat_columns: ColumnModel<IHeatmapRow>[];
1871
+ /** Columns for live trading reports and logs */
1872
+ live_columns: ColumnModel<TickEvent>[];
1873
+ /** Columns for partial-results / incremental reports */
1874
+ partial_columns: ColumnModel<PartialEvent>[];
1875
+ /** Columns for breakeven protection events */
1876
+ breakeven_columns: ColumnModel<BreakevenEvent>[];
1877
+ /** Columns for performance summary reports */
1878
+ performance_columns: ColumnModel<MetricStats>[];
1879
+ /** Columns for risk-related reports */
1880
+ risk_columns: ColumnModel<RiskEvent>[];
1881
+ /** Columns for scheduled report output */
1882
+ schedule_columns: ColumnModel<ScheduledEvent>[];
1883
+ /** Walker: PnL summary columns */
1884
+ walker_pnl_columns: ColumnModel<SignalData$1>[];
1885
+ /** Walker: strategy-level summary columns */
1886
+ walker_strategy_columns: ColumnModel<IStrategyResult>[];
1887
+ };
1888
+ /**
1889
+ * Type for the column configuration object.
1890
+ */
1891
+ type ColumnConfig = typeof COLUMN_CONFIG;
1892
+
1893
+ /**
1894
+ * Sets custom logger implementation for the framework.
1895
+ *
1896
+ * All log messages from internal services will be forwarded to the provided logger
1897
+ * with automatic context injection (strategyName, exchangeName, symbol, etc.).
1898
+ *
1899
+ * @param logger - Custom logger implementing ILogger interface
1900
+ *
1901
+ * @example
1902
+ * ```typescript
1903
+ * setLogger({
1904
+ * log: (topic, ...args) => console.log(topic, args),
1905
+ * debug: (topic, ...args) => console.debug(topic, args),
1906
+ * info: (topic, ...args) => console.info(topic, args),
1907
+ * });
1908
+ * ```
1909
+ */
1910
+ declare function setLogger(logger: ILogger): void;
1911
+ /**
1912
+ * Sets global configuration parameters for the framework.
1913
+ * @param config - Partial configuration object to override default settings
1914
+ * @param _unsafe - Skip config validations - required for testbed
1915
+ *
1916
+ * @example
1917
+ * ```typescript
1918
+ * setConfig({
1919
+ * CC_SCHEDULE_AWAIT_MINUTES: 90,
1920
+ * });
1921
+ * ```
1922
+ */
1923
+ declare function setConfig(config: Partial<GlobalConfig>, _unsafe?: boolean): void;
1924
+ /**
1925
+ * Retrieves a copy of the current global configuration.
1926
+ *
1927
+ * Returns a shallow copy of the current GLOBAL_CONFIG to prevent accidental mutations.
1928
+ * Use this to inspect the current configuration state without modifying it.
1929
+ *
1930
+ * @returns {GlobalConfig} A copy of the current global configuration object
1931
+ *
1932
+ * @example
1933
+ * ```typescript
1934
+ * const currentConfig = getConfig();
1935
+ * console.log(currentConfig.CC_SCHEDULE_AWAIT_MINUTES);
1936
+ * ```
1937
+ */
1938
+ declare function getConfig(): {
1939
+ CC_SCHEDULE_AWAIT_MINUTES: number;
1940
+ CC_AVG_PRICE_CANDLES_COUNT: number;
1941
+ CC_PERCENT_SLIPPAGE: number;
1942
+ CC_PERCENT_FEE: number;
1943
+ CC_MIN_TAKEPROFIT_DISTANCE_PERCENT: number;
1944
+ CC_MIN_STOPLOSS_DISTANCE_PERCENT: number;
1945
+ CC_MAX_STOPLOSS_DISTANCE_PERCENT: number;
1946
+ CC_MAX_SIGNAL_LIFETIME_MINUTES: number;
1947
+ CC_MAX_SIGNAL_GENERATION_SECONDS: number;
1948
+ CC_GET_CANDLES_RETRY_COUNT: number;
1949
+ CC_GET_CANDLES_RETRY_DELAY_MS: number;
1950
+ CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
1951
+ CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
1952
+ CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
1953
+ CC_BREAKEVEN_THRESHOLD: number;
1954
+ };
1955
+ /**
1956
+ * Retrieves the default configuration object for the framework.
1957
+ *
1958
+ * Returns a reference to the default configuration with all preset values.
1959
+ * Use this to see what configuration options are available and their default values.
1960
+ *
1961
+ * @returns {GlobalConfig} The default configuration object
1962
+ *
1963
+ * @example
1964
+ * ```typescript
1965
+ * const defaultConfig = getDefaultConfig();
1966
+ * console.log(defaultConfig.CC_SCHEDULE_AWAIT_MINUTES);
1967
+ * ```
1968
+ */
1969
+ declare function getDefaultConfig(): Readonly<{
1970
+ CC_SCHEDULE_AWAIT_MINUTES: number;
1971
+ CC_AVG_PRICE_CANDLES_COUNT: number;
1972
+ CC_PERCENT_SLIPPAGE: number;
1973
+ CC_PERCENT_FEE: number;
1974
+ CC_MIN_TAKEPROFIT_DISTANCE_PERCENT: number;
1975
+ CC_MIN_STOPLOSS_DISTANCE_PERCENT: number;
1976
+ CC_MAX_STOPLOSS_DISTANCE_PERCENT: number;
1977
+ CC_MAX_SIGNAL_LIFETIME_MINUTES: number;
1978
+ CC_MAX_SIGNAL_GENERATION_SECONDS: number;
1979
+ CC_GET_CANDLES_RETRY_COUNT: number;
1980
+ CC_GET_CANDLES_RETRY_DELAY_MS: number;
1981
+ CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
1982
+ CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
1983
+ CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
1984
+ CC_BREAKEVEN_THRESHOLD: number;
1985
+ }>;
1986
+ /**
1987
+ * Sets custom column configurations for markdown report generation.
1988
+ *
1989
+ * Allows overriding default column definitions for any report type.
1990
+ * All columns are validated before assignment to ensure structural correctness.
1991
+ *
1992
+ * @param columns - Partial column configuration object to override default column settings
1993
+ * @param _unsafe - Skip column validations - required for testbed
1994
+ *
1995
+ * @example
1996
+ * ```typescript
1997
+ * setColumns({
1998
+ * backtest_columns: [
1999
+ * {
2000
+ * key: "customId",
2001
+ * label: "Custom ID",
2002
+ * format: (data) => data.signal.id,
2003
+ * isVisible: () => true
2004
+ * }
2005
+ * ],
2006
+ * });
2007
+ * ```
2008
+ *
2009
+ * @throws {Error} If column configuration is invalid
2010
+ */
2011
+ declare function setColumns(columns: Partial<ColumnConfig>, _unsafe?: boolean): void;
2012
+ /**
2013
+ * Retrieves a copy of the current column configuration for markdown report generation.
2014
+ *
2015
+ * Returns a shallow copy of the current COLUMN_CONFIG to prevent accidental mutations.
2016
+ * Use this to inspect the current column definitions without modifying them.
2017
+ *
2018
+ * @returns {ColumnConfig} A copy of the current column configuration object
2019
+ *
2020
+ * @example
2021
+ * ```typescript
2022
+ * const currentColumns = getColumns();
2023
+ * console.log(currentColumns.backtest_columns.length);
2024
+ * ```
2025
+ */
2026
+ declare function getColumns(): {
2027
+ backtest_columns: ColumnModel<IStrategyTickResultClosed>[];
2028
+ heat_columns: ColumnModel<IHeatmapRow>[];
2029
+ live_columns: ColumnModel<TickEvent>[];
2030
+ partial_columns: ColumnModel<PartialEvent>[];
2031
+ breakeven_columns: ColumnModel<BreakevenEvent>[];
2032
+ performance_columns: ColumnModel<MetricStats>[];
2033
+ risk_columns: ColumnModel<RiskEvent>[];
2034
+ schedule_columns: ColumnModel<ScheduledEvent>[];
2035
+ walker_pnl_columns: ColumnModel<SignalData$1>[];
2036
+ walker_strategy_columns: ColumnModel<IStrategyResult>[];
2037
+ };
2038
+ /**
2039
+ * Retrieves the default column configuration object for markdown report generation.
2040
+ *
2041
+ * Returns a reference to the default column definitions with all preset values.
2042
+ * Use this to see what column options are available and their default definitions.
2043
+ *
2044
+ * @returns {ColumnConfig} The default column configuration object
2045
+ *
2046
+ * @example
2047
+ * ```typescript
2048
+ * const defaultColumns = getDefaultColumns();
2049
+ * console.log(defaultColumns.backtest_columns);
2050
+ * ```
2051
+ */
2052
+ declare function getDefaultColumns(): Readonly<{
2053
+ backtest_columns: ColumnModel<IStrategyTickResultClosed>[];
2054
+ heat_columns: ColumnModel<IHeatmapRow>[];
2055
+ live_columns: ColumnModel<TickEvent>[];
2056
+ partial_columns: ColumnModel<PartialEvent>[];
2057
+ breakeven_columns: ColumnModel<BreakevenEvent>[];
2058
+ performance_columns: ColumnModel<MetricStats>[];
2059
+ risk_columns: ColumnModel<RiskEvent>[];
2060
+ schedule_columns: ColumnModel<ScheduledEvent>[];
2061
+ walker_pnl_columns: ColumnModel<SignalData$1>[];
2062
+ walker_strategy_columns: ColumnModel<IStrategyResult>[];
2063
+ }>;
2064
+
1780
2065
  /**
1781
2066
  * Statistical data calculated from backtest results.
1782
2067
  *
@@ -3515,6 +3800,91 @@ interface PartialLossContract {
3515
3800
  timestamp: number;
3516
3801
  }
3517
3802
 
3803
+ /**
3804
+ * Contract for breakeven events.
3805
+ *
3806
+ * Emitted by breakevenSubject when a signal's stop-loss is moved to breakeven (entry price).
3807
+ * Used for tracking risk reduction milestones and monitoring strategy safety.
3808
+ *
3809
+ * Events are emitted only once per signal (idempotent - protected by ClientBreakeven state).
3810
+ * Breakeven is triggered when price moves far enough in profit direction to cover transaction costs.
3811
+ *
3812
+ * Consumers:
3813
+ * - BreakevenMarkdownService: Accumulates events for report generation
3814
+ * - User callbacks via listenBreakeven() / listenBreakevenOnce()
3815
+ *
3816
+ * @example
3817
+ * ```typescript
3818
+ * import { listenBreakeven } from "backtest-kit";
3819
+ *
3820
+ * // Listen to all breakeven events
3821
+ * listenBreakeven((event) => {
3822
+ * console.log(`[${event.backtest ? "Backtest" : "Live"}] Signal ${event.data.id} moved to breakeven`);
3823
+ * console.log(`Symbol: ${event.symbol}, Price: ${event.currentPrice}`);
3824
+ * console.log(`Position: ${event.data.position}, Entry: ${event.data.priceOpen}`);
3825
+ * console.log(`Original SL: ${event.data.priceStopLoss}, New SL: ${event.data.priceOpen}`);
3826
+ * });
3827
+ *
3828
+ * // Wait for specific signal to reach breakeven
3829
+ * listenBreakevenOnce(
3830
+ * (event) => event.data.id === "target-signal-id",
3831
+ * (event) => console.log("Signal reached breakeven:", event.data.id)
3832
+ * );
3833
+ * ```
3834
+ */
3835
+ interface BreakevenContract {
3836
+ /**
3837
+ * Trading pair symbol (e.g., "BTCUSDT").
3838
+ * Identifies which market this breakeven event belongs to.
3839
+ */
3840
+ symbol: string;
3841
+ /**
3842
+ * Strategy name that generated this signal.
3843
+ * Identifies which strategy execution this breakeven event belongs to.
3844
+ */
3845
+ strategyName: StrategyName;
3846
+ /**
3847
+ * Exchange name where this signal is being executed.
3848
+ * Identifies which exchange this breakeven event belongs to.
3849
+ */
3850
+ exchangeName: ExchangeName;
3851
+ /**
3852
+ * Frame name where this signal is being executed.
3853
+ * Identifies which frame this breakeven event belongs to (empty string for live mode).
3854
+ */
3855
+ frameName: FrameName;
3856
+ /**
3857
+ * Complete signal row data.
3858
+ * Contains all signal information: id, position, priceOpen, priceTakeProfit, priceStopLoss, etc.
3859
+ */
3860
+ data: ISignalRow;
3861
+ /**
3862
+ * Current market price at which breakeven was triggered.
3863
+ * Used to verify threshold calculation.
3864
+ */
3865
+ currentPrice: number;
3866
+ /**
3867
+ * Execution mode flag.
3868
+ * - true: Event from backtest execution (historical candle data)
3869
+ * - false: Event from live trading (real-time tick)
3870
+ */
3871
+ backtest: boolean;
3872
+ /**
3873
+ * Event timestamp in milliseconds since Unix epoch.
3874
+ *
3875
+ * Timing semantics:
3876
+ * - Live mode: when.getTime() at the moment breakeven was set
3877
+ * - Backtest mode: candle.timestamp of the candle that triggered breakeven
3878
+ *
3879
+ * @example
3880
+ * ```typescript
3881
+ * const eventDate = new Date(event.timestamp);
3882
+ * console.log(`Breakeven set at: ${eventDate.toISOString()}`);
3883
+ * ```
3884
+ */
3885
+ timestamp: number;
3886
+ }
3887
+
3518
3888
  /**
3519
3889
  * Contract for risk rejection events.
3520
3890
  *
@@ -4414,6 +4784,64 @@ declare function listenPartialLoss(fn: (event: PartialLossContract) => void): ()
4414
4784
  * ```
4415
4785
  */
4416
4786
  declare function listenPartialLossOnce(filterFn: (event: PartialLossContract) => boolean, fn: (event: PartialLossContract) => void): () => void;
4787
+ /**
4788
+ * Subscribes to breakeven protection events with queued async processing.
4789
+ *
4790
+ * Emits when a signal's stop-loss is moved to breakeven (entry price).
4791
+ * This happens when price moves far enough in profit direction to cover transaction costs.
4792
+ * Events are processed sequentially in order received, even if callback is async.
4793
+ * Uses queued wrapper to prevent concurrent execution of the callback.
4794
+ *
4795
+ * @param fn - Callback function to handle breakeven events
4796
+ * @returns Unsubscribe function to stop listening to events
4797
+ *
4798
+ * @example
4799
+ * ```typescript
4800
+ * import { listenBreakeven } from "./function/event";
4801
+ *
4802
+ * const unsubscribe = listenBreakeven((event) => {
4803
+ * console.log(`Signal ${event.data.id} reached breakeven`);
4804
+ * console.log(`Symbol: ${event.symbol}, Position: ${event.data.position}`);
4805
+ * console.log(`Entry: ${event.data.priceOpen}, Current: ${event.currentPrice}`);
4806
+ * console.log(`Mode: ${event.backtest ? "Backtest" : "Live"}`);
4807
+ * });
4808
+ *
4809
+ * // Later: stop listening
4810
+ * unsubscribe();
4811
+ * ```
4812
+ */
4813
+ declare function listenBreakeven(fn: (event: BreakevenContract) => void): () => void;
4814
+ /**
4815
+ * Subscribes to filtered breakeven protection events with one-time execution.
4816
+ *
4817
+ * Listens for events matching the filter predicate, then executes callback once
4818
+ * and automatically unsubscribes. Useful for waiting for specific breakeven conditions.
4819
+ *
4820
+ * @param filterFn - Predicate to filter which events trigger the callback
4821
+ * @param fn - Callback function to handle the filtered event (called only once)
4822
+ * @returns Unsubscribe function to cancel the listener before it fires
4823
+ *
4824
+ * @example
4825
+ * ```typescript
4826
+ * import { listenBreakevenOnce } from "./function/event";
4827
+ *
4828
+ * // Wait for first breakeven on any signal
4829
+ * listenBreakevenOnce(
4830
+ * (event) => true,
4831
+ * (event) => console.log("First breakeven reached:", event.data.id)
4832
+ * );
4833
+ *
4834
+ * // Wait for breakeven on BTCUSDT LONG position
4835
+ * const cancel = listenBreakevenOnce(
4836
+ * (event) => event.symbol === "BTCUSDT" && event.data.position === "long",
4837
+ * (event) => console.log("BTCUSDT LONG reached breakeven at", event.currentPrice)
4838
+ * );
4839
+ *
4840
+ * // Cancel if needed before event fires
4841
+ * cancel();
4842
+ * ```
4843
+ */
4844
+ declare function listenBreakevenOnce(filterFn: (event: BreakevenContract) => boolean, fn: (event: BreakevenContract) => void): () => void;
4417
4845
  /**
4418
4846
  * Subscribes to risk rejection events with queued async processing.
4419
4847
  *
@@ -5481,6 +5909,12 @@ interface IPersistBase<Entity extends IEntity | null = IEntity> {
5481
5909
  * @throws Error if write fails
5482
5910
  */
5483
5911
  writeValue(entityId: EntityId, entity: Entity): Promise<void>;
5912
+ /**
5913
+ * Async generator yielding all entity IDs.
5914
+ *
5915
+ * @returns AsyncGenerator yielding entity IDs
5916
+ */
5917
+ keys(): AsyncGenerator<EntityId>;
5484
5918
  }
5485
5919
  /**
5486
5920
  * Base class for file-based persistence with atomic writes.
@@ -5615,9 +6049,10 @@ declare class PersistSignalUtils {
5615
6049
  *
5616
6050
  * @param symbol - Trading pair symbol
5617
6051
  * @param strategyName - Strategy identifier
6052
+ * @param exchangeName - Exchange identifier
5618
6053
  * @returns Promise resolving to signal or null
5619
6054
  */
5620
- readSignalData: (symbol: string, strategyName: StrategyName) => Promise<ISignalRow | null>;
6055
+ readSignalData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<ISignalRow | null>;
5621
6056
  /**
5622
6057
  * Writes signal data to disk with atomic file writes.
5623
6058
  *
@@ -5627,9 +6062,10 @@ declare class PersistSignalUtils {
5627
6062
  * @param signalRow - Signal data (null to clear)
5628
6063
  * @param symbol - Trading pair symbol
5629
6064
  * @param strategyName - Strategy identifier
6065
+ * @param exchangeName - Exchange identifier
5630
6066
  * @returns Promise that resolves when write is complete
5631
6067
  */
5632
- writeSignalData: (signalRow: ISignalRow | null, symbol: string, strategyName: StrategyName) => Promise<void>;
6068
+ writeSignalData: (signalRow: ISignalRow | null, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<void>;
5633
6069
  }
5634
6070
  /**
5635
6071
  * Global singleton instance of PersistSignalUtils.
@@ -5689,9 +6125,10 @@ declare class PersistRiskUtils {
5689
6125
  * Returns empty Map if no positions exist.
5690
6126
  *
5691
6127
  * @param riskName - Risk profile identifier
6128
+ * @param exchangeName - Exchange identifier
5692
6129
  * @returns Promise resolving to Map of active positions
5693
6130
  */
5694
- readPositionData: (riskName: RiskName) => Promise<RiskData>;
6131
+ readPositionData: (riskName: RiskName, exchangeName: ExchangeName) => Promise<RiskData>;
5695
6132
  /**
5696
6133
  * Writes active positions to disk with atomic file writes.
5697
6134
  *
@@ -5700,9 +6137,10 @@ declare class PersistRiskUtils {
5700
6137
  *
5701
6138
  * @param positions - Map of active positions
5702
6139
  * @param riskName - Risk profile identifier
6140
+ * @param exchangeName - Exchange identifier
5703
6141
  * @returns Promise that resolves when write is complete
5704
6142
  */
5705
- writePositionData: (riskRow: RiskData, riskName: RiskName) => Promise<void>;
6143
+ writePositionData: (riskRow: RiskData, riskName: RiskName, exchangeName: ExchangeName) => Promise<void>;
5706
6144
  }
5707
6145
  /**
5708
6146
  * Global singleton instance of PersistRiskUtils.
@@ -5763,9 +6201,10 @@ declare class PersistScheduleUtils {
5763
6201
  *
5764
6202
  * @param symbol - Trading pair symbol
5765
6203
  * @param strategyName - Strategy identifier
6204
+ * @param exchangeName - Exchange identifier
5766
6205
  * @returns Promise resolving to scheduled signal or null
5767
6206
  */
5768
- readScheduleData: (symbol: string, strategyName: StrategyName) => Promise<IScheduledSignalRow | null>;
6207
+ readScheduleData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<IScheduledSignalRow | null>;
5769
6208
  /**
5770
6209
  * Writes scheduled signal data to disk with atomic file writes.
5771
6210
  *
@@ -5775,9 +6214,10 @@ declare class PersistScheduleUtils {
5775
6214
  * @param scheduledSignalRow - Scheduled signal data (null to clear)
5776
6215
  * @param symbol - Trading pair symbol
5777
6216
  * @param strategyName - Strategy identifier
6217
+ * @param exchangeName - Exchange identifier
5778
6218
  * @returns Promise that resolves when write is complete
5779
6219
  */
5780
- writeScheduleData: (scheduledSignalRow: IScheduledSignalRow | null, symbol: string, strategyName: StrategyName) => Promise<void>;
6220
+ writeScheduleData: (scheduledSignalRow: IScheduledSignalRow | null, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<void>;
5781
6221
  }
5782
6222
  /**
5783
6223
  * Global singleton instance of PersistScheduleUtils.
@@ -5838,9 +6278,11 @@ declare class PersistPartialUtils {
5838
6278
  *
5839
6279
  * @param symbol - Trading pair symbol
5840
6280
  * @param strategyName - Strategy identifier
6281
+ * @param signalId - Signal identifier
6282
+ * @param exchangeName - Exchange identifier
5841
6283
  * @returns Promise resolving to partial data record
5842
6284
  */
5843
- readPartialData: (symbol: string, strategyName: StrategyName) => Promise<PartialData>;
6285
+ readPartialData: (symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<PartialData>;
5844
6286
  /**
5845
6287
  * Writes partial data to disk with atomic file writes.
5846
6288
  *
@@ -5850,9 +6292,11 @@ declare class PersistPartialUtils {
5850
6292
  * @param partialData - Record of signal IDs to partial data
5851
6293
  * @param symbol - Trading pair symbol
5852
6294
  * @param strategyName - Strategy identifier
6295
+ * @param signalId - Signal identifier
6296
+ * @param exchangeName - Exchange identifier
5853
6297
  * @returns Promise that resolves when write is complete
5854
6298
  */
5855
- writePartialData: (partialData: PartialData, symbol: string, strategyName: StrategyName) => Promise<void>;
6299
+ writePartialData: (partialData: PartialData, symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<void>;
5856
6300
  }
5857
6301
  /**
5858
6302
  * Global singleton instance of PersistPartialUtils.
@@ -5871,6 +6315,120 @@ declare class PersistPartialUtils {
5871
6315
  * ```
5872
6316
  */
5873
6317
  declare const PersistPartialAdapter: PersistPartialUtils;
6318
+ /**
6319
+ * Type for persisted breakeven data.
6320
+ * Stores breakeven state (reached flag) for each signal ID.
6321
+ */
6322
+ type BreakevenData = Record<string, IBreakevenData>;
6323
+ /**
6324
+ * Persistence utility class for breakeven state management.
6325
+ *
6326
+ * Handles reading and writing breakeven state to disk.
6327
+ * Uses memoized PersistBase instances per symbol-strategy pair.
6328
+ *
6329
+ * Features:
6330
+ * - Atomic file writes via PersistBase.writeValue()
6331
+ * - Lazy initialization on first access
6332
+ * - Singleton pattern for global access
6333
+ * - Custom adapter support via usePersistBreakevenAdapter()
6334
+ *
6335
+ * File structure:
6336
+ * ```
6337
+ * ./dump/data/breakeven/
6338
+ * ├── BTCUSDT_my-strategy/
6339
+ * │ └── state.json // { "signal-id-1": { reached: true }, ... }
6340
+ * └── ETHUSDT_other-strategy/
6341
+ * └── state.json
6342
+ * ```
6343
+ *
6344
+ * @example
6345
+ * ```typescript
6346
+ * // Read breakeven data
6347
+ * const breakevenData = await PersistBreakevenAdapter.readBreakevenData("BTCUSDT", "my-strategy");
6348
+ * // Returns: { "signal-id": { reached: true }, ... }
6349
+ *
6350
+ * // Write breakeven data
6351
+ * await PersistBreakevenAdapter.writeBreakevenData(breakevenData, "BTCUSDT", "my-strategy");
6352
+ * ```
6353
+ */
6354
+ declare class PersistBreakevenUtils {
6355
+ /**
6356
+ * Factory for creating PersistBase instances.
6357
+ * Can be replaced via usePersistBreakevenAdapter().
6358
+ */
6359
+ private PersistBreakevenFactory;
6360
+ /**
6361
+ * Memoized storage factory for breakeven data.
6362
+ * Creates one PersistBase instance per symbol-strategy-exchange combination.
6363
+ * Key format: "symbol:strategyName:exchangeName"
6364
+ *
6365
+ * @param symbol - Trading pair symbol
6366
+ * @param strategyName - Strategy identifier
6367
+ * @param exchangeName - Exchange identifier
6368
+ * @returns PersistBase instance for this symbol-strategy-exchange combination
6369
+ */
6370
+ private getBreakevenStorage;
6371
+ /**
6372
+ * Registers a custom persistence adapter.
6373
+ *
6374
+ * @param Ctor - Custom PersistBase constructor
6375
+ *
6376
+ * @example
6377
+ * ```typescript
6378
+ * class RedisPersist extends PersistBase {
6379
+ * async readValue(id) { return JSON.parse(await redis.get(id)); }
6380
+ * async writeValue(id, entity) { await redis.set(id, JSON.stringify(entity)); }
6381
+ * }
6382
+ * PersistBreakevenAdapter.usePersistBreakevenAdapter(RedisPersist);
6383
+ * ```
6384
+ */
6385
+ usePersistBreakevenAdapter(Ctor: TPersistBaseCtor<string, BreakevenData>): void;
6386
+ /**
6387
+ * Reads persisted breakeven data for a symbol and strategy.
6388
+ *
6389
+ * Called by ClientBreakeven.waitForInit() to restore state.
6390
+ * Returns empty object if no breakeven data exists.
6391
+ *
6392
+ * @param symbol - Trading pair symbol
6393
+ * @param strategyName - Strategy identifier
6394
+ * @param signalId - Signal identifier
6395
+ * @param exchangeName - Exchange identifier
6396
+ * @returns Promise resolving to breakeven data record
6397
+ */
6398
+ readBreakevenData: (symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<BreakevenData>;
6399
+ /**
6400
+ * Writes breakeven data to disk.
6401
+ *
6402
+ * Called by ClientBreakeven._persistState() after state changes.
6403
+ * Creates directory and file if they don't exist.
6404
+ * Uses atomic writes to prevent data corruption.
6405
+ *
6406
+ * @param breakevenData - Breakeven data record to persist
6407
+ * @param symbol - Trading pair symbol
6408
+ * @param strategyName - Strategy identifier
6409
+ * @param signalId - Signal identifier
6410
+ * @param exchangeName - Exchange identifier
6411
+ * @returns Promise that resolves when write is complete
6412
+ */
6413
+ writeBreakevenData: (breakevenData: BreakevenData, symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<void>;
6414
+ }
6415
+ /**
6416
+ * Global singleton instance of PersistBreakevenUtils.
6417
+ * Used by ClientBreakeven for breakeven state persistence.
6418
+ *
6419
+ * @example
6420
+ * ```typescript
6421
+ * // Custom adapter
6422
+ * PersistBreakevenAdapter.usePersistBreakevenAdapter(RedisPersist);
6423
+ *
6424
+ * // Read breakeven data
6425
+ * const breakevenData = await PersistBreakevenAdapter.readBreakevenData("BTCUSDT", "my-strategy");
6426
+ *
6427
+ * // Write breakeven data
6428
+ * await PersistBreakevenAdapter.writeBreakevenData(breakevenData, "BTCUSDT", "my-strategy");
6429
+ * ```
6430
+ */
6431
+ declare const PersistBreakevenAdapter: PersistBreakevenUtils;
5874
6432
 
5875
6433
  /**
5876
6434
  * Type alias for column configuration used in backtest markdown reports.
@@ -5903,7 +6461,7 @@ declare const PersistPartialAdapter: PersistPartialUtils;
5903
6461
  * @see ColumnModel for the base interface
5904
6462
  * @see IStrategyTickResultClosed for the signal data structure
5905
6463
  */
5906
- type Columns$6 = ColumnModel<IStrategyTickResultClosed>;
6464
+ type Columns$7 = ColumnModel<IStrategyTickResultClosed>;
5907
6465
  /**
5908
6466
  * Service for generating and saving backtest markdown reports.
5909
6467
  *
@@ -5997,7 +6555,7 @@ declare class BacktestMarkdownService {
5997
6555
  * console.log(markdown);
5998
6556
  * ```
5999
6557
  */
6000
- getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$6[]) => Promise<string>;
6558
+ getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$7[]) => Promise<string>;
6001
6559
  /**
6002
6560
  * Saves symbol-strategy report to disk.
6003
6561
  * Creates directory if it doesn't exist.
@@ -6022,7 +6580,7 @@ declare class BacktestMarkdownService {
6022
6580
  * await service.dump("BTCUSDT", "my-strategy", "binance", "1h", true, "./custom/path");
6023
6581
  * ```
6024
6582
  */
6025
- dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$6[]) => Promise<void>;
6583
+ dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$7[]) => Promise<void>;
6026
6584
  /**
6027
6585
  * Clears accumulated signal data from storage.
6028
6586
  * If payload is provided, clears only that specific symbol-strategy-exchange-frame-backtest combination's data.
@@ -6172,6 +6730,35 @@ declare class BacktestUtils {
6172
6730
  exchangeName: ExchangeName;
6173
6731
  frameName: FrameName;
6174
6732
  }) => Promise<IScheduledSignalRow>;
6733
+ /**
6734
+ * Checks if breakeven threshold has been reached for the current pending signal.
6735
+ *
6736
+ * Uses the same formula as BREAKEVEN_FN to determine if price has moved far enough
6737
+ * to cover transaction costs (slippage + fees) and allow breakeven to be set.
6738
+ *
6739
+ * @param symbol - Trading pair symbol
6740
+ * @param currentPrice - Current market price to check against threshold
6741
+ * @param context - Execution context with strategyName, exchangeName, frameName
6742
+ * @returns Promise<boolean> - true if breakeven threshold reached, false otherwise
6743
+ *
6744
+ * @example
6745
+ * ```typescript
6746
+ * const canBreakeven = await Backtest.getBreakeven("BTCUSDT", 100.5, {
6747
+ * strategyName: "my-strategy",
6748
+ * exchangeName: "binance",
6749
+ * frameName: "backtest_frame"
6750
+ * });
6751
+ * if (canBreakeven) {
6752
+ * console.log("Breakeven threshold reached");
6753
+ * await Backtest.breakeven("BTCUSDT", 100.5, context);
6754
+ * }
6755
+ * ```
6756
+ */
6757
+ getBreakeven: (symbol: string, currentPrice: number, context: {
6758
+ strategyName: StrategyName;
6759
+ exchangeName: ExchangeName;
6760
+ frameName: FrameName;
6761
+ }) => Promise<boolean>;
6175
6762
  /**
6176
6763
  * Stops the strategy from generating new signals.
6177
6764
  *
@@ -6297,25 +6884,52 @@ declare class BacktestUtils {
6297
6884
  *
6298
6885
  * @param symbol - Trading pair symbol
6299
6886
  * @param percentShift - Percentage adjustment to SL distance (-100 to 100)
6887
+ * @param currentPrice - Current market price to check for intrusion
6300
6888
  * @param context - Execution context with strategyName, exchangeName, and frameName
6301
6889
  * @returns Promise that resolves when trailing SL is updated
6302
6890
  *
6303
6891
  * @example
6304
6892
  * ```typescript
6305
- * // LONG: entry=100, originalSL=90, distance=10
6306
- * // Tighten stop by 50%: newSL = 100 - 10*(1-0.5) = 95
6307
- * await Backtest.trailingStop("BTCUSDT", -50, {
6893
+ * // LONG: entry=100, originalSL=90, distance=10%, currentPrice=102
6894
+ * // Tighten stop by 50%: newSL = 100 - 5% = 95
6895
+ * await Backtest.trailingStop("BTCUSDT", -50, 102, {
6308
6896
  * exchangeName: "binance",
6309
6897
  * frameName: "frame1",
6310
6898
  * strategyName: "my-strategy"
6311
6899
  * });
6312
6900
  * ```
6313
6901
  */
6314
- trailingStop: (symbol: string, percentShift: number, context: {
6902
+ trailingStop: (symbol: string, percentShift: number, currentPrice: number, context: {
6315
6903
  strategyName: StrategyName;
6316
6904
  exchangeName: ExchangeName;
6317
6905
  frameName: FrameName;
6318
6906
  }) => Promise<void>;
6907
+ /**
6908
+ * Moves stop-loss to breakeven when price reaches threshold.
6909
+ *
6910
+ * Moves SL to entry price (zero-risk position) when current price has moved
6911
+ * far enough in profit direction. Threshold is calculated as: (CC_PERCENT_SLIPPAGE + CC_PERCENT_FEE) * 2
6912
+ *
6913
+ * @param symbol - Trading pair symbol
6914
+ * @param currentPrice - Current market price to check threshold
6915
+ * @param context - Strategy context with strategyName, exchangeName, frameName
6916
+ * @returns Promise<boolean> - true if breakeven was set, false otherwise
6917
+ *
6918
+ * @example
6919
+ * ```typescript
6920
+ * const moved = await Backtest.breakeven(
6921
+ * "BTCUSDT",
6922
+ * 112,
6923
+ * { strategyName: "my-strategy", exchangeName: "binance", frameName: "1h" }
6924
+ * );
6925
+ * console.log(moved); // true (SL moved to entry price)
6926
+ * ```
6927
+ */
6928
+ breakeven: (symbol: string, currentPrice: number, context: {
6929
+ strategyName: StrategyName;
6930
+ exchangeName: ExchangeName;
6931
+ frameName: FrameName;
6932
+ }) => Promise<boolean>;
6319
6933
  /**
6320
6934
  * Gets statistical data from all closed signals for a symbol-strategy pair.
6321
6935
  *
@@ -6362,7 +6976,7 @@ declare class BacktestUtils {
6362
6976
  strategyName: StrategyName;
6363
6977
  exchangeName: ExchangeName;
6364
6978
  frameName: FrameName;
6365
- }, columns?: Columns$6[]) => Promise<string>;
6979
+ }, columns?: Columns$7[]) => Promise<string>;
6366
6980
  /**
6367
6981
  * Saves strategy report to disk.
6368
6982
  *
@@ -6393,7 +7007,7 @@ declare class BacktestUtils {
6393
7007
  strategyName: StrategyName;
6394
7008
  exchangeName: ExchangeName;
6395
7009
  frameName: FrameName;
6396
- }, path?: string, columns?: Columns$6[]) => Promise<void>;
7010
+ }, path?: string, columns?: Columns$7[]) => Promise<void>;
6397
7011
  /**
6398
7012
  * Lists all active backtest instances with their current status.
6399
7013
  *
@@ -6467,7 +7081,7 @@ declare const Backtest: BacktestUtils;
6467
7081
  * @see ColumnModel for the base interface
6468
7082
  * @see TickEvent for the event data structure
6469
7083
  */
6470
- type Columns$5 = ColumnModel<TickEvent>;
7084
+ type Columns$6 = ColumnModel<TickEvent>;
6471
7085
  /**
6472
7086
  * Service for generating and saving live trading markdown reports.
6473
7087
  *
@@ -6566,7 +7180,7 @@ declare class LiveMarkdownService {
6566
7180
  * console.log(markdown);
6567
7181
  * ```
6568
7182
  */
6569
- getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$5[]) => Promise<string>;
7183
+ getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$6[]) => Promise<string>;
6570
7184
  /**
6571
7185
  * Saves symbol-strategy report to disk.
6572
7186
  * Creates directory if it doesn't exist.
@@ -6591,7 +7205,7 @@ declare class LiveMarkdownService {
6591
7205
  * await service.dump("BTCUSDT", "my-strategy", "binance", "1h", false, "./custom/path");
6592
7206
  * ```
6593
7207
  */
6594
- dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$5[]) => Promise<void>;
7208
+ dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$6[]) => Promise<void>;
6595
7209
  /**
6596
7210
  * Clears accumulated event data from storage.
6597
7211
  * If payload is provided, clears only that specific symbol-strategy-exchange-frame-backtest combination's data.
@@ -6750,6 +7364,33 @@ declare class LiveUtils {
6750
7364
  strategyName: StrategyName;
6751
7365
  exchangeName: ExchangeName;
6752
7366
  }) => Promise<IScheduledSignalRow>;
7367
+ /**
7368
+ * Checks if breakeven threshold has been reached for the current pending signal.
7369
+ *
7370
+ * Uses the same formula as BREAKEVEN_FN to determine if price has moved far enough
7371
+ * to cover transaction costs (slippage + fees) and allow breakeven to be set.
7372
+ *
7373
+ * @param symbol - Trading pair symbol
7374
+ * @param currentPrice - Current market price to check against threshold
7375
+ * @param context - Execution context with strategyName and exchangeName
7376
+ * @returns Promise<boolean> - true if breakeven threshold reached, false otherwise
7377
+ *
7378
+ * @example
7379
+ * ```typescript
7380
+ * const canBreakeven = await Live.getBreakeven("BTCUSDT", 100.5, {
7381
+ * strategyName: "my-strategy",
7382
+ * exchangeName: "binance"
7383
+ * });
7384
+ * if (canBreakeven) {
7385
+ * console.log("Breakeven threshold reached");
7386
+ * await Live.breakeven("BTCUSDT", 100.5, context);
7387
+ * }
7388
+ * ```
7389
+ */
7390
+ getBreakeven: (symbol: string, currentPrice: number, context: {
7391
+ strategyName: StrategyName;
7392
+ exchangeName: ExchangeName;
7393
+ }) => Promise<boolean>;
6753
7394
  /**
6754
7395
  * Stops the strategy from generating new signals.
6755
7396
  *
@@ -6864,23 +7505,49 @@ declare class LiveUtils {
6864
7505
  *
6865
7506
  * @param symbol - Trading pair symbol
6866
7507
  * @param percentShift - Percentage adjustment to SL distance (-100 to 100)
7508
+ * @param currentPrice - Current market price to check for intrusion
6867
7509
  * @param context - Execution context with strategyName and exchangeName
6868
7510
  * @returns Promise that resolves when trailing SL is updated
6869
7511
  *
6870
7512
  * @example
6871
7513
  * ```typescript
6872
- * // LONG: entry=100, originalSL=90, distance=10
6873
- * // Tighten stop by 50%: newSL = 100 - 10*(1-0.5) = 95
6874
- * await Live.trailingStop("BTCUSDT", -50, {
7514
+ * // LONG: entry=100, originalSL=90, distance=10%, currentPrice=102
7515
+ * // Tighten stop by 50%: newSL = 100 - 5% = 95
7516
+ * await Live.trailingStop("BTCUSDT", -50, 102, {
6875
7517
  * exchangeName: "binance",
6876
7518
  * strategyName: "my-strategy"
6877
7519
  * });
6878
7520
  * ```
6879
7521
  */
6880
- trailingStop: (symbol: string, percentShift: number, context: {
7522
+ trailingStop: (symbol: string, percentShift: number, currentPrice: number, context: {
6881
7523
  strategyName: StrategyName;
6882
7524
  exchangeName: ExchangeName;
6883
7525
  }) => Promise<void>;
7526
+ /**
7527
+ * Moves stop-loss to breakeven when price reaches threshold.
7528
+ *
7529
+ * Moves SL to entry price (zero-risk position) when current price has moved
7530
+ * far enough in profit direction. Threshold is calculated as: (CC_PERCENT_SLIPPAGE + CC_PERCENT_FEE) * 2
7531
+ *
7532
+ * @param symbol - Trading pair symbol
7533
+ * @param currentPrice - Current market price to check threshold
7534
+ * @param context - Strategy context with strategyName and exchangeName
7535
+ * @returns Promise<boolean> - true if breakeven was set, false otherwise
7536
+ *
7537
+ * @example
7538
+ * ```typescript
7539
+ * const moved = await Live.breakeven(
7540
+ * "BTCUSDT",
7541
+ * 112,
7542
+ * { strategyName: "my-strategy", exchangeName: "binance" }
7543
+ * );
7544
+ * console.log(moved); // true (SL moved to entry price)
7545
+ * ```
7546
+ */
7547
+ breakeven: (symbol: string, currentPrice: number, context: {
7548
+ strategyName: StrategyName;
7549
+ exchangeName: ExchangeName;
7550
+ }) => Promise<boolean>;
6884
7551
  /**
6885
7552
  * Gets statistical data from all live trading events for a symbol-strategy pair.
6886
7553
  *
@@ -6925,7 +7592,7 @@ declare class LiveUtils {
6925
7592
  getReport: (symbol: string, context: {
6926
7593
  strategyName: StrategyName;
6927
7594
  exchangeName: ExchangeName;
6928
- }, columns?: Columns$5[]) => Promise<string>;
7595
+ }, columns?: Columns$6[]) => Promise<string>;
6929
7596
  /**
6930
7597
  * Saves strategy report to disk.
6931
7598
  *
@@ -6955,7 +7622,7 @@ declare class LiveUtils {
6955
7622
  dump: (symbol: string, context: {
6956
7623
  strategyName: StrategyName;
6957
7624
  exchangeName: ExchangeName;
6958
- }, path?: string, columns?: Columns$5[]) => Promise<void>;
7625
+ }, path?: string, columns?: Columns$6[]) => Promise<void>;
6959
7626
  /**
6960
7627
  * Lists all active live trading instances with their current status.
6961
7628
  *
@@ -7025,7 +7692,7 @@ declare const Live: LiveUtils;
7025
7692
  * @see ColumnModel for the base interface
7026
7693
  * @see ScheduledEvent for the event data structure
7027
7694
  */
7028
- type Columns$4 = ColumnModel<ScheduledEvent>;
7695
+ type Columns$5 = ColumnModel<ScheduledEvent>;
7029
7696
  /**
7030
7697
  * Service for generating and saving scheduled signals markdown reports.
7031
7698
  *
@@ -7108,7 +7775,7 @@ declare class ScheduleMarkdownService {
7108
7775
  * console.log(markdown);
7109
7776
  * ```
7110
7777
  */
7111
- getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$4[]) => Promise<string>;
7778
+ getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$5[]) => Promise<string>;
7112
7779
  /**
7113
7780
  * Saves symbol-strategy report to disk.
7114
7781
  * Creates directory if it doesn't exist.
@@ -7133,7 +7800,7 @@ declare class ScheduleMarkdownService {
7133
7800
  * await service.dump("BTCUSDT", "my-strategy", "binance", "1h", false, "./custom/path");
7134
7801
  * ```
7135
7802
  */
7136
- dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$4[]) => Promise<void>;
7803
+ dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$5[]) => Promise<void>;
7137
7804
  /**
7138
7805
  * Clears accumulated event data from storage.
7139
7806
  * If payload is provided, clears only that specific symbol-strategy-exchange-frame-backtest combination's data.
@@ -7240,7 +7907,7 @@ declare class ScheduleUtils {
7240
7907
  strategyName: StrategyName;
7241
7908
  exchangeName: ExchangeName;
7242
7909
  frameName: FrameName;
7243
- }, backtest?: boolean, columns?: Columns$4[]) => Promise<string>;
7910
+ }, backtest?: boolean, columns?: Columns$5[]) => Promise<string>;
7244
7911
  /**
7245
7912
  * Saves strategy report to disk.
7246
7913
  *
@@ -7262,7 +7929,7 @@ declare class ScheduleUtils {
7262
7929
  strategyName: StrategyName;
7263
7930
  exchangeName: ExchangeName;
7264
7931
  frameName: FrameName;
7265
- }, backtest?: boolean, path?: string, columns?: Columns$4[]) => Promise<void>;
7932
+ }, backtest?: boolean, path?: string, columns?: Columns$5[]) => Promise<void>;
7266
7933
  }
7267
7934
  /**
7268
7935
  * Singleton instance of ScheduleUtils for convenient scheduled signals reporting.
@@ -7308,7 +7975,7 @@ declare const Schedule: ScheduleUtils;
7308
7975
  * @see ColumnModel for the base interface
7309
7976
  * @see MetricStats for the metric data structure
7310
7977
  */
7311
- type Columns$3 = ColumnModel<MetricStats>;
7978
+ type Columns$4 = ColumnModel<MetricStats>;
7312
7979
  /**
7313
7980
  * Service for collecting and analyzing performance metrics.
7314
7981
  *
@@ -7387,7 +8054,7 @@ declare class PerformanceMarkdownService {
7387
8054
  * console.log(markdown);
7388
8055
  * ```
7389
8056
  */
7390
- getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$3[]) => Promise<string>;
8057
+ getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$4[]) => Promise<string>;
7391
8058
  /**
7392
8059
  * Saves performance report to disk.
7393
8060
  *
@@ -7408,7 +8075,7 @@ declare class PerformanceMarkdownService {
7408
8075
  * await performanceService.dump("BTCUSDT", "my-strategy", "binance", "1h", false, "./custom/path");
7409
8076
  * ```
7410
8077
  */
7411
- dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$3[]) => Promise<void>;
8078
+ dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$4[]) => Promise<void>;
7412
8079
  /**
7413
8080
  * Clears accumulated performance data from storage.
7414
8081
  *
@@ -7526,7 +8193,7 @@ declare class Performance {
7526
8193
  strategyName: StrategyName;
7527
8194
  exchangeName: ExchangeName;
7528
8195
  frameName: FrameName;
7529
- }, backtest?: boolean, columns?: Columns$3[]): Promise<string>;
8196
+ }, backtest?: boolean, columns?: Columns$4[]): Promise<string>;
7530
8197
  /**
7531
8198
  * Saves performance report to disk.
7532
8199
  *
@@ -7551,7 +8218,7 @@ declare class Performance {
7551
8218
  strategyName: StrategyName;
7552
8219
  exchangeName: ExchangeName;
7553
8220
  frameName: FrameName;
7554
- }, backtest?: boolean, path?: string, columns?: Columns$3[]): Promise<void>;
8221
+ }, backtest?: boolean, path?: string, columns?: Columns$4[]): Promise<void>;
7555
8222
  }
7556
8223
 
7557
8224
  /**
@@ -7971,7 +8638,7 @@ declare const Walker: WalkerUtils;
7971
8638
  * @see ColumnModel for the base interface
7972
8639
  * @see IHeatmapRow for the row data structure
7973
8640
  */
7974
- type Columns$2 = ColumnModel<IHeatmapRow>;
8641
+ type Columns$3 = ColumnModel<IHeatmapRow>;
7975
8642
  /**
7976
8643
  * Portfolio Heatmap Markdown Service.
7977
8644
  *
@@ -8064,7 +8731,7 @@ declare class HeatMarkdownService {
8064
8731
  * // ...
8065
8732
  * ```
8066
8733
  */
8067
- getReport: (strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$2[]) => Promise<string>;
8734
+ getReport: (strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$3[]) => Promise<string>;
8068
8735
  /**
8069
8736
  * Saves heatmap report to disk.
8070
8737
  *
@@ -8089,7 +8756,7 @@ declare class HeatMarkdownService {
8089
8756
  * await service.dump("my-strategy", "binance", "frame1", true, "./reports");
8090
8757
  * ```
8091
8758
  */
8092
- dump: (strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$2[]) => Promise<void>;
8759
+ dump: (strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$3[]) => Promise<void>;
8093
8760
  /**
8094
8761
  * Clears accumulated heatmap data from storage.
8095
8762
  * If payload is provided, clears only that exchangeName+frameName+backtest combination's data.
@@ -8236,7 +8903,7 @@ declare class HeatUtils {
8236
8903
  strategyName: StrategyName;
8237
8904
  exchangeName: ExchangeName;
8238
8905
  frameName: FrameName;
8239
- }, backtest?: boolean, columns?: Columns$2[]) => Promise<string>;
8906
+ }, backtest?: boolean, columns?: Columns$3[]) => Promise<string>;
8240
8907
  /**
8241
8908
  * Saves heatmap report to disk for a strategy.
8242
8909
  *
@@ -8269,7 +8936,7 @@ declare class HeatUtils {
8269
8936
  strategyName: StrategyName;
8270
8937
  exchangeName: ExchangeName;
8271
8938
  frameName: FrameName;
8272
- }, backtest?: boolean, path?: string, columns?: Columns$2[]) => Promise<void>;
8939
+ }, backtest?: boolean, path?: string, columns?: Columns$3[]) => Promise<void>;
8273
8940
  }
8274
8941
  /**
8275
8942
  * Singleton instance of HeatUtils for convenient heatmap operations.
@@ -8500,7 +9167,7 @@ declare const Optimizer: OptimizerUtils;
8500
9167
  * @see ColumnModel for the base interface
8501
9168
  * @see PartialEvent for the event data structure
8502
9169
  */
8503
- type Columns$1 = ColumnModel<PartialEvent>;
9170
+ type Columns$2 = ColumnModel<PartialEvent>;
8504
9171
  /**
8505
9172
  * Service for generating and saving partial profit/loss markdown reports.
8506
9173
  *
@@ -8594,7 +9261,7 @@ declare class PartialMarkdownService {
8594
9261
  * console.log(markdown);
8595
9262
  * ```
8596
9263
  */
8597
- getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$1[]) => Promise<string>;
9264
+ getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$2[]) => Promise<string>;
8598
9265
  /**
8599
9266
  * Saves symbol-strategy report to disk.
8600
9267
  * Creates directory if it doesn't exist.
@@ -8619,7 +9286,7 @@ declare class PartialMarkdownService {
8619
9286
  * await service.dump("BTCUSDT", "my-strategy", "binance", "1h", false, "./custom/path");
8620
9287
  * ```
8621
9288
  */
8622
- dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$1[]) => Promise<void>;
9289
+ dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$2[]) => Promise<void>;
8623
9290
  /**
8624
9291
  * Clears accumulated event data from storage.
8625
9292
  * If payload is provided, clears only that specific symbol-strategy-exchange-frame-backtest combination's data.
@@ -8772,7 +9439,7 @@ declare class PartialUtils {
8772
9439
  strategyName: StrategyName;
8773
9440
  exchangeName: ExchangeName;
8774
9441
  frameName: FrameName;
8775
- }, backtest?: boolean, columns?: Columns$1[]) => Promise<string>;
9442
+ }, backtest?: boolean, columns?: Columns$2[]) => Promise<string>;
8776
9443
  /**
8777
9444
  * Generates and saves markdown report to file.
8778
9445
  *
@@ -8809,7 +9476,7 @@ declare class PartialUtils {
8809
9476
  strategyName: StrategyName;
8810
9477
  exchangeName: ExchangeName;
8811
9478
  frameName: FrameName;
8812
- }, backtest?: boolean, path?: string, columns?: Columns$1[]) => Promise<void>;
9479
+ }, backtest?: boolean, path?: string, columns?: Columns$2[]) => Promise<void>;
8813
9480
  }
8814
9481
  /**
8815
9482
  * Global singleton instance of PartialUtils.
@@ -8937,7 +9604,7 @@ declare const Constant: ConstantUtils;
8937
9604
  * @see ColumnModel for the base interface
8938
9605
  * @see RiskEvent for the event data structure
8939
9606
  */
8940
- type Columns = ColumnModel<RiskEvent>;
9607
+ type Columns$1 = ColumnModel<RiskEvent>;
8941
9608
  /**
8942
9609
  * Service for generating and saving risk rejection markdown reports.
8943
9610
  *
@@ -9018,7 +9685,7 @@ declare class RiskMarkdownService {
9018
9685
  * console.log(markdown);
9019
9686
  * ```
9020
9687
  */
9021
- getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns[]) => Promise<string>;
9688
+ getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns$1[]) => Promise<string>;
9022
9689
  /**
9023
9690
  * Saves symbol-strategy report to disk.
9024
9691
  * Creates directory if it doesn't exist.
@@ -9043,7 +9710,7 @@ declare class RiskMarkdownService {
9043
9710
  * await service.dump("BTCUSDT", "my-strategy", "binance", "1h", false, "./custom/path");
9044
9711
  * ```
9045
9712
  */
9046
- dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns[]) => Promise<void>;
9713
+ dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns$1[]) => Promise<void>;
9047
9714
  /**
9048
9715
  * Clears accumulated event data from storage.
9049
9716
  * If payload is provided, clears only that specific symbol-strategy-exchange-frame-backtest combination's data.
@@ -9198,7 +9865,7 @@ declare class RiskUtils {
9198
9865
  strategyName: StrategyName;
9199
9866
  exchangeName: ExchangeName;
9200
9867
  frameName: FrameName;
9201
- }, backtest?: boolean, columns?: Columns[]) => Promise<string>;
9868
+ }, backtest?: boolean, columns?: Columns$1[]) => Promise<string>;
9202
9869
  /**
9203
9870
  * Generates and saves markdown report to file.
9204
9871
  *
@@ -9235,7 +9902,7 @@ declare class RiskUtils {
9235
9902
  strategyName: StrategyName;
9236
9903
  exchangeName: ExchangeName;
9237
9904
  frameName: FrameName;
9238
- }, backtest?: boolean, path?: string, columns?: Columns[]) => Promise<void>;
9905
+ }, backtest?: boolean, path?: string, columns?: Columns$1[]) => Promise<void>;
9239
9906
  }
9240
9907
  /**
9241
9908
  * Global singleton instance of RiskUtils.
@@ -9552,32 +10219,369 @@ declare class NotificationUtils {
9552
10219
  *
9553
10220
  * @example
9554
10221
  * ```typescript
9555
- * await Notification.clear();
10222
+ * await Notification.clear();
10223
+ * ```
10224
+ */
10225
+ clear(): Promise<void>;
10226
+ }
10227
+ /**
10228
+ * Singleton instance of NotificationUtils for convenient notification access.
10229
+ *
10230
+ * @example
10231
+ * ```typescript
10232
+ * import { Notification } from "./classes/Notification";
10233
+ *
10234
+ * // Get all notifications
10235
+ * const all = await Notification.getData();
10236
+ *
10237
+ * // Filter by type using type discrimination
10238
+ * const closedSignals = all.filter(n => n.type === "signal.closed");
10239
+ * const highLosses = all.filter(n =>
10240
+ * n.type === "partial.loss" && n.level >= 30
10241
+ * );
10242
+ *
10243
+ * // Clear history
10244
+ * await Notification.clear();
10245
+ * ```
10246
+ */
10247
+ declare const Notification: NotificationUtils;
10248
+
10249
+ /**
10250
+ * Type alias for column configuration used in breakeven markdown reports.
10251
+ *
10252
+ * Represents a column model specifically designed to format and display
10253
+ * breakeven events in markdown tables.
10254
+ *
10255
+ * @typeParam BreakevenEvent - The breakeven event data type containing
10256
+ * signal information, symbol, and timing details
10257
+ *
10258
+ * @example
10259
+ * ```typescript
10260
+ * // Column to display symbol
10261
+ * const symbolColumn: Columns = {
10262
+ * key: "symbol",
10263
+ * label: "Symbol",
10264
+ * format: (event) => event.symbol,
10265
+ * isVisible: () => true
10266
+ * };
10267
+ *
10268
+ * // Column to display price when breakeven was reached
10269
+ * const priceColumn: Columns = {
10270
+ * key: "currentPrice",
10271
+ * label: "Price",
10272
+ * format: (event) => event.currentPrice.toString(),
10273
+ * isVisible: () => true
10274
+ * };
10275
+ * ```
10276
+ *
10277
+ * @see ColumnModel for the base interface
10278
+ * @see BreakevenEvent for the event data structure
10279
+ */
10280
+ type Columns = ColumnModel<BreakevenEvent>;
10281
+ /**
10282
+ * Service for generating and saving breakeven markdown reports.
10283
+ *
10284
+ * Features:
10285
+ * - Listens to breakeven events via breakevenSubject
10286
+ * - Accumulates all events per symbol-strategy pair
10287
+ * - Generates markdown tables with detailed event information
10288
+ * - Provides statistics (total breakeven events)
10289
+ * - Saves reports to disk in dump/breakeven/{symbol}_{strategyName}.md
10290
+ *
10291
+ * @example
10292
+ * ```typescript
10293
+ * const service = new BreakevenMarkdownService();
10294
+ *
10295
+ * // Service automatically subscribes to subjects on init
10296
+ * // No manual callback setup needed
10297
+ *
10298
+ * // Later: generate and save report
10299
+ * await service.dump("BTCUSDT", "my-strategy");
10300
+ * ```
10301
+ */
10302
+ declare class BreakevenMarkdownService {
10303
+ /** Logger service for debug output */
10304
+ private readonly loggerService;
10305
+ /**
10306
+ * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
10307
+ * Each combination gets its own isolated storage instance.
10308
+ */
10309
+ private getStorage;
10310
+ /**
10311
+ * Processes breakeven events and accumulates them.
10312
+ * Should be called from breakevenSubject subscription.
10313
+ *
10314
+ * @param data - Breakeven event data with frameName wrapper
10315
+ *
10316
+ * @example
10317
+ * ```typescript
10318
+ * const service = new BreakevenMarkdownService();
10319
+ * // Service automatically subscribes in init()
10320
+ * ```
10321
+ */
10322
+ private tickBreakeven;
10323
+ /**
10324
+ * Gets statistical data from all breakeven events for a symbol-strategy pair.
10325
+ * Delegates to ReportStorage.getData().
10326
+ *
10327
+ * @param symbol - Trading pair symbol to get data for
10328
+ * @param strategyName - Strategy name to get data for
10329
+ * @param exchangeName - Exchange name
10330
+ * @param frameName - Frame name
10331
+ * @param backtest - True if backtest mode, false if live mode
10332
+ * @returns Statistical data object with all metrics
10333
+ *
10334
+ * @example
10335
+ * ```typescript
10336
+ * const service = new BreakevenMarkdownService();
10337
+ * const stats = await service.getData("BTCUSDT", "my-strategy", "binance", "1h", false);
10338
+ * console.log(stats.totalEvents);
10339
+ * ```
10340
+ */
10341
+ getData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<BreakevenStatisticsModel>;
10342
+ /**
10343
+ * Generates markdown report with all breakeven events for a symbol-strategy pair.
10344
+ * Delegates to ReportStorage.getReport().
10345
+ *
10346
+ * @param symbol - Trading pair symbol to generate report for
10347
+ * @param strategyName - Strategy name to generate report for
10348
+ * @param exchangeName - Exchange name
10349
+ * @param frameName - Frame name
10350
+ * @param backtest - True if backtest mode, false if live mode
10351
+ * @param columns - Column configuration for formatting the table
10352
+ * @returns Markdown formatted report string with table of all events
10353
+ *
10354
+ * @example
10355
+ * ```typescript
10356
+ * const service = new BreakevenMarkdownService();
10357
+ * const markdown = await service.getReport("BTCUSDT", "my-strategy", "binance", "1h", false);
10358
+ * console.log(markdown);
10359
+ * ```
10360
+ */
10361
+ getReport: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, columns?: Columns[]) => Promise<string>;
10362
+ /**
10363
+ * Saves symbol-strategy report to disk.
10364
+ * Creates directory if it doesn't exist.
10365
+ * Delegates to ReportStorage.dump().
10366
+ *
10367
+ * @param symbol - Trading pair symbol to save report for
10368
+ * @param strategyName - Strategy name to save report for
10369
+ * @param exchangeName - Exchange name
10370
+ * @param frameName - Frame name
10371
+ * @param backtest - True if backtest mode, false if live mode
10372
+ * @param path - Directory path to save report (default: "./dump/breakeven")
10373
+ * @param columns - Column configuration for formatting the table
10374
+ *
10375
+ * @example
10376
+ * ```typescript
10377
+ * const service = new BreakevenMarkdownService();
10378
+ *
10379
+ * // Save to default path: ./dump/breakeven/BTCUSDT_my-strategy.md
10380
+ * await service.dump("BTCUSDT", "my-strategy", "binance", "1h", false);
10381
+ *
10382
+ * // Save to custom path: ./custom/path/BTCUSDT_my-strategy.md
10383
+ * await service.dump("BTCUSDT", "my-strategy", "binance", "1h", false, "./custom/path");
10384
+ * ```
10385
+ */
10386
+ dump: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, path?: string, columns?: Columns[]) => Promise<void>;
10387
+ /**
10388
+ * Clears accumulated event data from storage.
10389
+ * If payload is provided, clears only that specific symbol-strategy-exchange-frame-backtest combination's data.
10390
+ * If nothing is provided, clears all data.
10391
+ *
10392
+ * @param payload - Optional payload with symbol, strategyName, exchangeName, frameName, backtest
10393
+ *
10394
+ * @example
10395
+ * ```typescript
10396
+ * const service = new BreakevenMarkdownService();
10397
+ *
10398
+ * // Clear specific combination
10399
+ * await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy", exchangeName: "binance", frameName: "1h", backtest: false });
10400
+ *
10401
+ * // Clear all data
10402
+ * await service.clear();
10403
+ * ```
10404
+ */
10405
+ clear: (payload?: {
10406
+ symbol: string;
10407
+ strategyName: StrategyName;
10408
+ exchangeName: ExchangeName;
10409
+ frameName: FrameName;
10410
+ backtest: boolean;
10411
+ }) => Promise<void>;
10412
+ /**
10413
+ * Initializes the service by subscribing to breakeven events.
10414
+ * Uses singleshot to ensure initialization happens only once.
10415
+ * Automatically called on first use.
10416
+ *
10417
+ * @example
10418
+ * ```typescript
10419
+ * const service = new BreakevenMarkdownService();
10420
+ * await service.init(); // Subscribe to breakeven events
10421
+ * ```
10422
+ */
10423
+ protected init: (() => Promise<void>) & functools_kit.ISingleshotClearable;
10424
+ /**
10425
+ * Function to unsubscribe from breakeven events.
10426
+ * Assigned during init().
10427
+ */
10428
+ unsubscribe: Function;
10429
+ }
10430
+
10431
+ /**
10432
+ * Utility class for accessing breakeven protection reports and statistics.
10433
+ *
10434
+ * Provides static-like methods (via singleton instance) to retrieve data
10435
+ * accumulated by BreakevenMarkdownService from breakeven events.
10436
+ *
10437
+ * Features:
10438
+ * - Statistical data extraction (total breakeven events count)
10439
+ * - Markdown report generation with event tables
10440
+ * - File export to disk
10441
+ *
10442
+ * Data source:
10443
+ * - BreakevenMarkdownService listens to breakevenSubject
10444
+ * - Accumulates events in ReportStorage (max 250 events per symbol-strategy pair)
10445
+ * - Events include: timestamp, symbol, strategyName, signalId, position, priceOpen, currentPrice, mode
10446
+ *
10447
+ * @example
10448
+ * ```typescript
10449
+ * import { Breakeven } from "./classes/Breakeven";
10450
+ *
10451
+ * // Get statistical data for BTCUSDT:my-strategy
10452
+ * const stats = await Breakeven.getData("BTCUSDT", "my-strategy");
10453
+ * console.log(`Total breakeven events: ${stats.totalEvents}`);
10454
+ *
10455
+ * // Generate markdown report
10456
+ * const markdown = await Breakeven.getReport("BTCUSDT", "my-strategy");
10457
+ * console.log(markdown); // Formatted table with all events
10458
+ *
10459
+ * // Export report to file
10460
+ * await Breakeven.dump("BTCUSDT", "my-strategy"); // Saves to ./dump/breakeven/BTCUSDT_my-strategy.md
10461
+ * await Breakeven.dump("BTCUSDT", "my-strategy", "./custom/path"); // Custom directory
10462
+ * ```
10463
+ */
10464
+ declare class BreakevenUtils {
10465
+ /**
10466
+ * Retrieves statistical data from accumulated breakeven events.
10467
+ *
10468
+ * Delegates to BreakevenMarkdownService.getData() which reads from ReportStorage.
10469
+ * Returns aggregated metrics calculated from all breakeven events.
10470
+ *
10471
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
10472
+ * @param strategyName - Strategy name (e.g., "my-strategy")
10473
+ * @returns Promise resolving to BreakevenStatisticsModel object with counts and event list
10474
+ *
10475
+ * @example
10476
+ * ```typescript
10477
+ * const stats = await Breakeven.getData("BTCUSDT", "my-strategy");
10478
+ *
10479
+ * console.log(`Total breakeven events: ${stats.totalEvents}`);
10480
+ *
10481
+ * // Iterate through all events
10482
+ * for (const event of stats.eventList) {
10483
+ * console.log(`Signal ${event.signalId} reached breakeven at ${event.currentPrice}`);
10484
+ * }
10485
+ * ```
10486
+ */
10487
+ getData: (symbol: string, context: {
10488
+ strategyName: StrategyName;
10489
+ exchangeName: ExchangeName;
10490
+ frameName: FrameName;
10491
+ }, backtest?: boolean) => Promise<BreakevenStatisticsModel>;
10492
+ /**
10493
+ * Generates markdown report with all breakeven events for a symbol-strategy pair.
10494
+ *
10495
+ * Creates formatted table containing:
10496
+ * - Symbol
10497
+ * - Strategy
10498
+ * - Signal ID
10499
+ * - Position (LONG/SHORT)
10500
+ * - Entry Price
10501
+ * - Breakeven Price
10502
+ * - Timestamp (ISO 8601)
10503
+ * - Mode (Backtest/Live)
10504
+ *
10505
+ * Also includes summary statistics at the end.
10506
+ *
10507
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
10508
+ * @param strategyName - Strategy name (e.g., "my-strategy")
10509
+ * @param columns - Optional columns configuration for the report
10510
+ * @returns Promise resolving to markdown formatted report string
10511
+ *
10512
+ * @example
10513
+ * ```typescript
10514
+ * const markdown = await Breakeven.getReport("BTCUSDT", "my-strategy");
10515
+ * console.log(markdown);
10516
+ *
10517
+ * // Output:
10518
+ * // # Breakeven Protection Report: BTCUSDT:my-strategy
10519
+ * //
10520
+ * // | Symbol | Strategy | Signal ID | Position | Entry Price | Breakeven Price | Timestamp | Mode |
10521
+ * // | --- | --- | --- | --- | --- | --- | --- | --- |
10522
+ * // | BTCUSDT | my-strategy | abc123 | LONG | 50000.00000000 USD | 50100.00000000 USD | 2024-01-15T10:30:00.000Z | Backtest |
10523
+ * //
10524
+ * // **Total events:** 1
10525
+ * ```
10526
+ */
10527
+ getReport: (symbol: string, context: {
10528
+ strategyName: StrategyName;
10529
+ exchangeName: ExchangeName;
10530
+ frameName: FrameName;
10531
+ }, backtest?: boolean, columns?: Columns[]) => Promise<string>;
10532
+ /**
10533
+ * Generates and saves markdown report to file.
10534
+ *
10535
+ * Creates directory if it doesn't exist.
10536
+ * Filename format: {symbol}_{strategyName}.md (e.g., "BTCUSDT_my-strategy.md")
10537
+ *
10538
+ * Delegates to BreakevenMarkdownService.dump() which:
10539
+ * 1. Generates markdown report via getReport()
10540
+ * 2. Creates output directory (recursive mkdir)
10541
+ * 3. Writes file with UTF-8 encoding
10542
+ * 4. Logs success/failure to console
10543
+ *
10544
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
10545
+ * @param strategyName - Strategy name (e.g., "my-strategy")
10546
+ * @param path - Output directory path (default: "./dump/breakeven")
10547
+ * @param columns - Optional columns configuration for the report
10548
+ * @returns Promise that resolves when file is written
10549
+ *
10550
+ * @example
10551
+ * ```typescript
10552
+ * // Save to default path: ./dump/breakeven/BTCUSDT_my-strategy.md
10553
+ * await Breakeven.dump("BTCUSDT", "my-strategy");
10554
+ *
10555
+ * // Save to custom path: ./reports/breakeven/BTCUSDT_my-strategy.md
10556
+ * await Breakeven.dump("BTCUSDT", "my-strategy", "./reports/breakeven");
10557
+ *
10558
+ * // After multiple symbols backtested, export all reports
10559
+ * for (const symbol of ["BTCUSDT", "ETHUSDT", "BNBUSDT"]) {
10560
+ * await Breakeven.dump(symbol, "my-strategy", "./backtest-results");
10561
+ * }
9556
10562
  * ```
9557
10563
  */
9558
- clear(): Promise<void>;
10564
+ dump: (symbol: string, context: {
10565
+ strategyName: StrategyName;
10566
+ exchangeName: ExchangeName;
10567
+ frameName: FrameName;
10568
+ }, backtest?: boolean, path?: string, columns?: Columns[]) => Promise<void>;
9559
10569
  }
9560
10570
  /**
9561
- * Singleton instance of NotificationUtils for convenient notification access.
10571
+ * Global singleton instance of BreakevenUtils.
10572
+ * Provides static-like access to breakeven protection reporting methods.
9562
10573
  *
9563
10574
  * @example
9564
10575
  * ```typescript
9565
- * import { Notification } from "./classes/Notification";
9566
- *
9567
- * // Get all notifications
9568
- * const all = await Notification.getData();
9569
- *
9570
- * // Filter by type using type discrimination
9571
- * const closedSignals = all.filter(n => n.type === "signal.closed");
9572
- * const highLosses = all.filter(n =>
9573
- * n.type === "partial.loss" && n.level >= 30
9574
- * );
10576
+ * import { Breakeven } from "backtest-kit";
9575
10577
  *
9576
- * // Clear history
9577
- * await Notification.clear();
10578
+ * // Usage same as BreakevenUtils methods
10579
+ * const stats = await Breakeven.getData("BTCUSDT", "my-strategy");
10580
+ * const report = await Breakeven.getReport("BTCUSDT", "my-strategy");
10581
+ * await Breakeven.dump("BTCUSDT", "my-strategy");
9578
10582
  * ```
9579
10583
  */
9580
- declare const Notification: NotificationUtils;
10584
+ declare const Breakeven: BreakevenUtils;
9581
10585
 
9582
10586
  /**
9583
10587
  * Contract for walker stop signal events.
@@ -9702,6 +10706,11 @@ declare const partialProfitSubject: Subject<PartialProfitContract>;
9702
10706
  * Emits when a signal reaches a loss level (10%, 20%, 30%, etc).
9703
10707
  */
9704
10708
  declare const partialLossSubject: Subject<PartialLossContract>;
10709
+ /**
10710
+ * Breakeven emitter for stop-loss protection milestones.
10711
+ * Emits when a signal's stop-loss is moved to breakeven (entry price).
10712
+ */
10713
+ declare const breakevenSubject: Subject<BreakevenContract>;
9705
10714
  /**
9706
10715
  * Risk rejection emitter for risk management violations.
9707
10716
  * Emits ONLY when a signal is rejected due to risk validation failure.
@@ -9715,6 +10724,7 @@ declare const riskSubject: Subject<RiskContract>;
9715
10724
  */
9716
10725
  declare const pingSubject: Subject<PingContract>;
9717
10726
 
10727
+ declare const emitters_breakevenSubject: typeof breakevenSubject;
9718
10728
  declare const emitters_doneBacktestSubject: typeof doneBacktestSubject;
9719
10729
  declare const emitters_doneLiveSubject: typeof doneLiveSubject;
9720
10730
  declare const emitters_doneWalkerSubject: typeof doneWalkerSubject;
@@ -9736,7 +10746,7 @@ declare const emitters_walkerCompleteSubject: typeof walkerCompleteSubject;
9736
10746
  declare const emitters_walkerEmitter: typeof walkerEmitter;
9737
10747
  declare const emitters_walkerStopSubject: typeof walkerStopSubject;
9738
10748
  declare namespace emitters {
9739
- export { emitters_doneBacktestSubject as doneBacktestSubject, emitters_doneLiveSubject as doneLiveSubject, emitters_doneWalkerSubject as doneWalkerSubject, emitters_errorEmitter as errorEmitter, emitters_exitEmitter as exitEmitter, emitters_partialLossSubject as partialLossSubject, emitters_partialProfitSubject as partialProfitSubject, emitters_performanceEmitter as performanceEmitter, emitters_pingSubject as pingSubject, emitters_progressBacktestEmitter as progressBacktestEmitter, emitters_progressOptimizerEmitter as progressOptimizerEmitter, emitters_progressWalkerEmitter as progressWalkerEmitter, emitters_riskSubject as riskSubject, emitters_signalBacktestEmitter as signalBacktestEmitter, emitters_signalEmitter as signalEmitter, emitters_signalLiveEmitter as signalLiveEmitter, emitters_validationSubject as validationSubject, emitters_walkerCompleteSubject as walkerCompleteSubject, emitters_walkerEmitter as walkerEmitter, emitters_walkerStopSubject as walkerStopSubject };
10749
+ export { emitters_breakevenSubject as breakevenSubject, emitters_doneBacktestSubject as doneBacktestSubject, emitters_doneLiveSubject as doneLiveSubject, emitters_doneWalkerSubject as doneWalkerSubject, emitters_errorEmitter as errorEmitter, emitters_exitEmitter as exitEmitter, emitters_partialLossSubject as partialLossSubject, emitters_partialProfitSubject as partialProfitSubject, emitters_performanceEmitter as performanceEmitter, emitters_pingSubject as pingSubject, emitters_progressBacktestEmitter as progressBacktestEmitter, emitters_progressOptimizerEmitter as progressOptimizerEmitter, emitters_progressWalkerEmitter as progressWalkerEmitter, emitters_riskSubject as riskSubject, emitters_signalBacktestEmitter as signalBacktestEmitter, emitters_signalEmitter as signalEmitter, emitters_signalLiveEmitter as signalLiveEmitter, emitters_validationSubject as validationSubject, emitters_walkerCompleteSubject as walkerCompleteSubject, emitters_walkerEmitter as walkerEmitter, emitters_walkerStopSubject as walkerStopSubject };
9740
10750
  }
9741
10751
 
9742
10752
  /**
@@ -10305,6 +11315,88 @@ declare class PartialConnectionService implements IPartial {
10305
11315
  clear: (symbol: string, data: ISignalRow, priceClose: number, backtest: boolean) => Promise<void>;
10306
11316
  }
10307
11317
 
11318
+ /**
11319
+ * Connection service for breakeven tracking.
11320
+ *
11321
+ * Provides memoized ClientBreakeven instances per signal ID.
11322
+ * Acts as factory and lifetime manager for ClientBreakeven objects.
11323
+ *
11324
+ * Features:
11325
+ * - Creates one ClientBreakeven instance per signal ID (memoized)
11326
+ * - Configures instances with logger and event emitter callbacks
11327
+ * - Delegates check/clear operations to appropriate ClientBreakeven
11328
+ * - Cleans up memoized instances when signals are cleared
11329
+ *
11330
+ * Architecture:
11331
+ * - Injected into ClientStrategy via BreakevenGlobalService
11332
+ * - Uses memoize from functools-kit for instance caching
11333
+ * - Emits events to breakevenSubject
11334
+ *
11335
+ * @example
11336
+ * ```typescript
11337
+ * // Service injected via DI
11338
+ * const service = inject<BreakevenConnectionService>(TYPES.breakevenConnectionService);
11339
+ *
11340
+ * // Called by ClientStrategy during signal monitoring
11341
+ * await service.check("BTCUSDT", signal, 100.5, false, new Date());
11342
+ * // Creates or reuses ClientBreakeven for signal.id
11343
+ * // Delegates to ClientBreakeven.check()
11344
+ *
11345
+ * // When signal closes
11346
+ * await service.clear("BTCUSDT", signal, 101, false);
11347
+ * // Clears signal state and removes memoized instance
11348
+ * ```
11349
+ */
11350
+ declare class BreakevenConnectionService implements IBreakeven {
11351
+ /**
11352
+ * Logger service injected from DI container.
11353
+ */
11354
+ private readonly loggerService;
11355
+ /**
11356
+ * Memoized factory function for ClientBreakeven instances.
11357
+ *
11358
+ * Creates one ClientBreakeven per signal ID and backtest mode with configured callbacks.
11359
+ * Instances are cached until clear() is called.
11360
+ *
11361
+ * Key format: "signalId:backtest" or "signalId:live"
11362
+ * Value: ClientBreakeven instance with logger and event emitter
11363
+ */
11364
+ private getBreakeven;
11365
+ /**
11366
+ * Checks if breakeven should be triggered and emits event if conditions met.
11367
+ *
11368
+ * Retrieves or creates ClientBreakeven for signal ID, initializes it if needed,
11369
+ * then delegates to ClientBreakeven.check() method.
11370
+ *
11371
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
11372
+ * @param data - Signal row data
11373
+ * @param currentPrice - Current market price
11374
+ * @param backtest - True if backtest mode, false if live mode
11375
+ * @param when - Event timestamp (current time for live, candle time for backtest)
11376
+ * @returns Promise that resolves when breakeven check is complete
11377
+ */
11378
+ check: (symbol: string, data: IPublicSignalRow, currentPrice: number, backtest: boolean, when: Date) => Promise<boolean>;
11379
+ /**
11380
+ * Clears breakeven state when signal closes.
11381
+ *
11382
+ * Retrieves ClientBreakeven for signal ID, initializes if needed,
11383
+ * delegates clear operation, then removes memoized instance.
11384
+ *
11385
+ * Sequence:
11386
+ * 1. Get ClientBreakeven from memoize cache
11387
+ * 2. Ensure initialization (waitForInit)
11388
+ * 3. Call ClientBreakeven.clear() - removes state, persists to disk
11389
+ * 4. Clear memoized instance - prevents memory leaks
11390
+ *
11391
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
11392
+ * @param data - Signal row data
11393
+ * @param priceClose - Final closing price
11394
+ * @param backtest - True if backtest mode, false if live mode
11395
+ * @returns Promise that resolves when clear is complete
11396
+ */
11397
+ clear: (symbol: string, data: ISignalRow, priceClose: number, backtest: boolean) => Promise<void>;
11398
+ }
11399
+
10308
11400
  /**
10309
11401
  * Type definition for strategy methods.
10310
11402
  * Maps all keys of IStrategy to any type.
@@ -10345,6 +11437,7 @@ declare class StrategyConnectionService implements TStrategy$1 {
10345
11437
  readonly riskConnectionService: RiskConnectionService;
10346
11438
  readonly exchangeConnectionService: ExchangeConnectionService;
10347
11439
  readonly partialConnectionService: PartialConnectionService;
11440
+ readonly breakevenConnectionService: BreakevenConnectionService;
10348
11441
  /**
10349
11442
  * Retrieves memoized ClientStrategy instance for given symbol-strategy pair with exchange and frame isolation.
10350
11443
  *
@@ -10391,6 +11484,41 @@ declare class StrategyConnectionService implements TStrategy$1 {
10391
11484
  exchangeName: ExchangeName;
10392
11485
  frameName: FrameName;
10393
11486
  }) => Promise<IScheduledSignalRow | null>;
11487
+ /**
11488
+ * Checks if breakeven threshold has been reached for the current pending signal.
11489
+ *
11490
+ * Uses the same formula as BREAKEVEN_FN to determine if price has moved far enough
11491
+ * to cover transaction costs and allow breakeven to be set.
11492
+ *
11493
+ * Delegates to ClientStrategy.getBreakeven() with current execution context.
11494
+ *
11495
+ * @param backtest - Whether running in backtest mode
11496
+ * @param symbol - Trading pair symbol
11497
+ * @param currentPrice - Current market price to check against threshold
11498
+ * @param context - Execution context with strategyName, exchangeName, frameName
11499
+ * @returns Promise<boolean> - true if breakeven threshold reached, false otherwise
11500
+ *
11501
+ * @example
11502
+ * ```typescript
11503
+ * // Check if breakeven is available for LONG position (entry=100, threshold=0.4%)
11504
+ * const canBreakeven = await strategyConnectionService.getBreakeven(
11505
+ * false,
11506
+ * "BTCUSDT",
11507
+ * 100.5,
11508
+ * { strategyName: "my-strategy", exchangeName: "binance", frameName: "" }
11509
+ * );
11510
+ * // Returns true (price >= 100.4)
11511
+ *
11512
+ * if (canBreakeven) {
11513
+ * await strategyConnectionService.breakeven(false, "BTCUSDT", 100.5, context);
11514
+ * }
11515
+ * ```
11516
+ */
11517
+ getBreakeven: (backtest: boolean, symbol: string, currentPrice: number, context: {
11518
+ strategyName: StrategyName;
11519
+ exchangeName: ExchangeName;
11520
+ frameName: FrameName;
11521
+ }) => Promise<boolean>;
10394
11522
  /**
10395
11523
  * Retrieves the stopped state of the strategy.
10396
11524
  *
@@ -10564,26 +11692,55 @@ declare class StrategyConnectionService implements TStrategy$1 {
10564
11692
  * @param backtest - Whether running in backtest mode
10565
11693
  * @param symbol - Trading pair symbol
10566
11694
  * @param percentShift - Percentage adjustment to SL distance (-100 to 100)
11695
+ * @param currentPrice - Current market price to check for intrusion
10567
11696
  * @param context - Execution context with strategyName, exchangeName, frameName
10568
11697
  * @returns Promise that resolves when trailing SL is updated
10569
11698
  *
10570
11699
  * @example
10571
11700
  * ```typescript
10572
- * // LONG: entry=100, originalSL=90, distance=10
10573
- * // Tighten stop by 50%: newSL = 100 - 10*(1-0.5) = 95
11701
+ * // LONG: entry=100, originalSL=90, distance=10%, currentPrice=102
11702
+ * // Tighten stop by 50%: newSL = 100 - 5% = 95
10574
11703
  * await strategyConnectionService.trailingStop(
10575
11704
  * false,
10576
11705
  * "BTCUSDT",
10577
11706
  * -50,
11707
+ * 102,
10578
11708
  * { strategyName: "my-strategy", exchangeName: "binance", frameName: "" }
10579
11709
  * );
10580
11710
  * ```
10581
11711
  */
10582
- trailingStop: (backtest: boolean, symbol: string, percentShift: number, context: {
11712
+ trailingStop: (backtest: boolean, symbol: string, percentShift: number, currentPrice: number, context: {
10583
11713
  strategyName: StrategyName;
10584
11714
  exchangeName: ExchangeName;
10585
11715
  frameName: FrameName;
10586
11716
  }) => Promise<void>;
11717
+ /**
11718
+ * Delegates to ClientStrategy.breakeven() with current execution context.
11719
+ *
11720
+ * @param backtest - Whether running in backtest mode
11721
+ * @param symbol - Trading pair symbol
11722
+ * @param currentPrice - Current market price to check threshold
11723
+ * @param context - Execution context with strategyName, exchangeName, frameName
11724
+ * @returns Promise<boolean> - true if breakeven was set, false otherwise
11725
+ *
11726
+ * @example
11727
+ * ```typescript
11728
+ * // LONG: entry=100, slippage=0.1%, fee=0.1%, threshold=0.4%
11729
+ * // Try to move SL to breakeven when price >= 100.4
11730
+ * const moved = await strategyConnectionService.breakeven(
11731
+ * false,
11732
+ * "BTCUSDT",
11733
+ * 100.5,
11734
+ * { strategyName: "my-strategy", exchangeName: "binance", frameName: "" }
11735
+ * );
11736
+ * console.log(moved); // true (SL moved to 100)
11737
+ * ```
11738
+ */
11739
+ breakeven: (backtest: boolean, symbol: string, currentPrice: number, context: {
11740
+ strategyName: StrategyName;
11741
+ exchangeName: ExchangeName;
11742
+ frameName: FrameName;
11743
+ }) => Promise<boolean>;
10587
11744
  }
10588
11745
 
10589
11746
  /**
@@ -10892,6 +12049,41 @@ declare class StrategyCoreService implements TStrategy {
10892
12049
  exchangeName: ExchangeName;
10893
12050
  frameName: FrameName;
10894
12051
  }) => Promise<IScheduledSignalRow | null>;
12052
+ /**
12053
+ * Checks if breakeven threshold has been reached for the current pending signal.
12054
+ *
12055
+ * Validates strategy existence and delegates to connection service
12056
+ * to check if price has moved far enough to cover transaction costs.
12057
+ *
12058
+ * Does not require execution context as this is a state query operation.
12059
+ *
12060
+ * @param backtest - Whether running in backtest mode
12061
+ * @param symbol - Trading pair symbol
12062
+ * @param currentPrice - Current market price to check against threshold
12063
+ * @param context - Execution context with strategyName, exchangeName, frameName
12064
+ * @returns Promise<boolean> - true if breakeven threshold reached, false otherwise
12065
+ *
12066
+ * @example
12067
+ * ```typescript
12068
+ * // Check if breakeven is available for LONG position (entry=100, threshold=0.4%)
12069
+ * const canBreakeven = await strategyCoreService.getBreakeven(
12070
+ * false,
12071
+ * "BTCUSDT",
12072
+ * 100.5,
12073
+ * { strategyName: "my-strategy", exchangeName: "binance", frameName: "" }
12074
+ * );
12075
+ * // Returns true (price >= 100.4)
12076
+ *
12077
+ * if (canBreakeven) {
12078
+ * await strategyCoreService.breakeven(false, "BTCUSDT", 100.5, context);
12079
+ * }
12080
+ * ```
12081
+ */
12082
+ getBreakeven: (backtest: boolean, symbol: string, currentPrice: number, context: {
12083
+ strategyName: StrategyName;
12084
+ exchangeName: ExchangeName;
12085
+ frameName: FrameName;
12086
+ }) => Promise<boolean>;
10895
12087
  /**
10896
12088
  * Checks if the strategy has been stopped.
10897
12089
  *
@@ -11067,26 +12259,53 @@ declare class StrategyCoreService implements TStrategy {
11067
12259
  * @param backtest - Whether running in backtest mode
11068
12260
  * @param symbol - Trading pair symbol
11069
12261
  * @param percentShift - Percentage adjustment to SL distance (-100 to 100)
12262
+ * @param currentPrice - Current market price to check for intrusion
11070
12263
  * @param context - Execution context with strategyName, exchangeName, frameName
11071
12264
  * @returns Promise that resolves when trailing SL is updated
11072
12265
  *
11073
12266
  * @example
11074
12267
  * ```typescript
11075
- * // LONG: entry=100, originalSL=90, distance=10
11076
- * // Tighten stop by 50%: newSL = 100 - 10*(1-0.5) = 95
12268
+ * // LONG: entry=100, originalSL=90, distance=10%, currentPrice=102
12269
+ * // Tighten stop by 50%: newSL = 100 - 5% = 95
11077
12270
  * await strategyCoreService.trailingStop(
11078
12271
  * false,
11079
12272
  * "BTCUSDT",
11080
12273
  * -50,
12274
+ * 102,
11081
12275
  * { strategyName: "my-strategy", exchangeName: "binance", frameName: "" }
11082
12276
  * );
11083
12277
  * ```
11084
12278
  */
11085
- trailingStop: (backtest: boolean, symbol: string, percentShift: number, context: {
12279
+ trailingStop: (backtest: boolean, symbol: string, percentShift: number, currentPrice: number, context: {
11086
12280
  strategyName: StrategyName;
11087
12281
  exchangeName: ExchangeName;
11088
12282
  frameName: FrameName;
11089
12283
  }) => Promise<void>;
12284
+ /**
12285
+ * Moves stop-loss to breakeven when price reaches threshold.
12286
+ * Validates context and delegates to StrategyConnectionService.
12287
+ *
12288
+ * @param backtest - Whether running in backtest mode
12289
+ * @param symbol - Trading pair symbol
12290
+ * @param currentPrice - Current market price to check threshold
12291
+ * @param context - Strategy context with strategyName, exchangeName, frameName
12292
+ * @returns Promise<boolean> - true if breakeven was set, false otherwise
12293
+ *
12294
+ * @example
12295
+ * ```typescript
12296
+ * const moved = await strategyCoreService.breakeven(
12297
+ * false,
12298
+ * "BTCUSDT",
12299
+ * 112,
12300
+ * { strategyName: "my-strategy", exchangeName: "binance", frameName: "" }
12301
+ * );
12302
+ * ```
12303
+ */
12304
+ breakeven: (backtest: boolean, symbol: string, currentPrice: number, context: {
12305
+ strategyName: StrategyName;
12306
+ exchangeName: ExchangeName;
12307
+ frameName: FrameName;
12308
+ }) => Promise<boolean>;
11090
12309
  }
11091
12310
 
11092
12311
  /**
@@ -11164,6 +12383,7 @@ declare class RiskGlobalService implements TRisk {
11164
12383
  private readonly loggerService;
11165
12384
  private readonly riskConnectionService;
11166
12385
  private readonly riskValidationService;
12386
+ private readonly exchangeValidationService;
11167
12387
  /**
11168
12388
  * Validates risk configuration.
11169
12389
  * Memoized to avoid redundant validations for the same risk-exchange-frame combination.
@@ -12654,6 +13874,10 @@ declare class PartialGlobalService implements TPartial {
12654
13874
  * Risk validation service for validating risk existence.
12655
13875
  */
12656
13876
  private readonly riskValidationService;
13877
+ /**
13878
+ * Exchange validation service for validating exchange existence.
13879
+ */
13880
+ private readonly exchangeValidationService;
12657
13881
  /**
12658
13882
  * Validates strategy and associated risk configuration.
12659
13883
  * Memoized to avoid redundant validations for the same strategy-exchange-frame combination.
@@ -12703,6 +13927,105 @@ declare class PartialGlobalService implements TPartial {
12703
13927
  clear: (symbol: string, data: ISignalRow, priceClose: number, backtest: boolean) => Promise<void>;
12704
13928
  }
12705
13929
 
13930
+ /**
13931
+ * Type definition for breakeven methods.
13932
+ * Maps all keys of IBreakeven to any type.
13933
+ * Used for dynamic method routing in BreakevenGlobalService.
13934
+ */
13935
+ type TBreakeven = {
13936
+ [key in keyof IBreakeven]: any;
13937
+ };
13938
+ /**
13939
+ * Global service for breakeven tracking.
13940
+ *
13941
+ * Thin delegation layer that forwards operations to BreakevenConnectionService.
13942
+ * Provides centralized logging for all breakeven operations at the global level.
13943
+ *
13944
+ * Architecture:
13945
+ * - Injected into ClientStrategy constructor via IStrategyParams
13946
+ * - Delegates all operations to BreakevenConnectionService
13947
+ * - Logs operations at "breakevenGlobalService" level before delegation
13948
+ *
13949
+ * Purpose:
13950
+ * - Single injection point for ClientStrategy (dependency injection pattern)
13951
+ * - Centralized logging for monitoring breakeven operations
13952
+ * - Layer of abstraction between strategy and connection layer
13953
+ *
13954
+ * @example
13955
+ * ```typescript
13956
+ * // Service injected into ClientStrategy via DI
13957
+ * const strategy = new ClientStrategy({
13958
+ * breakeven: breakevenGlobalService,
13959
+ * ...
13960
+ * });
13961
+ *
13962
+ * // Called during signal monitoring
13963
+ * await strategy.params.breakeven.check("BTCUSDT", signal, 100.5, false, new Date());
13964
+ * // Logs at global level → delegates to BreakevenConnectionService
13965
+ * ```
13966
+ */
13967
+ declare class BreakevenGlobalService implements TBreakeven {
13968
+ /**
13969
+ * Logger service injected from DI container.
13970
+ * Used for logging operations at global service level.
13971
+ */
13972
+ private readonly loggerService;
13973
+ /**
13974
+ * Connection service injected from DI container.
13975
+ * Handles actual ClientBreakeven instance creation and management.
13976
+ */
13977
+ private readonly breakevenConnectionService;
13978
+ /**
13979
+ * Strategy validation service for validating strategy existence.
13980
+ */
13981
+ private readonly strategyValidationService;
13982
+ /**
13983
+ * Strategy schema service for retrieving strategy configuration.
13984
+ */
13985
+ private readonly strategySchemaService;
13986
+ /**
13987
+ * Risk validation service for validating risk existence.
13988
+ */
13989
+ private readonly riskValidationService;
13990
+ /**
13991
+ * Exchange validation service for validating exchange existence.
13992
+ */
13993
+ private readonly exchangeValidationService;
13994
+ /**
13995
+ * Validates strategy and associated risk configuration.
13996
+ * Memoized to avoid redundant validations for the same strategy-exchange-frame combination.
13997
+ *
13998
+ * @param context - Context with strategyName, exchangeName and frameName
13999
+ * @param methodName - Name of the calling method for error tracking
14000
+ */
14001
+ private validate;
14002
+ /**
14003
+ * Checks if breakeven should be triggered and emits event if conditions met.
14004
+ *
14005
+ * Logs operation at global service level, then delegates to BreakevenConnectionService.
14006
+ *
14007
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
14008
+ * @param data - Signal row data
14009
+ * @param currentPrice - Current market price
14010
+ * @param backtest - True if backtest mode, false if live mode
14011
+ * @param when - Event timestamp (current time for live, candle time for backtest)
14012
+ * @returns Promise that resolves when breakeven check is complete
14013
+ */
14014
+ check: (symbol: string, data: IPublicSignalRow, currentPrice: number, backtest: boolean, when: Date) => Promise<boolean>;
14015
+ /**
14016
+ * Clears breakeven state when signal closes.
14017
+ *
14018
+ * Logs operation at global service level, then delegates to BreakevenConnectionService.
14019
+ *
14020
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
14021
+ * @param data - Signal row data
14022
+ * @param priceClose - Final closing price
14023
+ * @param backtest - True if backtest mode, false if live mode
14024
+ * @returns Promise that resolves when clear is complete
14025
+ */
14026
+ clear: (symbol: string, data: ISignalRow, priceClose: number, backtest: boolean) => Promise<void>;
14027
+ }
14028
+
12706
14029
  /**
12707
14030
  * Unique identifier for outline result.
12708
14031
  * Can be string or number for flexible ID formats.
@@ -12867,6 +14190,7 @@ declare const backtest: {
12867
14190
  walkerMarkdownService: WalkerMarkdownService;
12868
14191
  heatMarkdownService: HeatMarkdownService;
12869
14192
  partialMarkdownService: PartialMarkdownService;
14193
+ breakevenMarkdownService: BreakevenMarkdownService;
12870
14194
  outlineMarkdownService: OutlineMarkdownService;
12871
14195
  riskMarkdownService: RiskMarkdownService;
12872
14196
  backtestLogicPublicService: BacktestLogicPublicService;
@@ -12882,6 +14206,7 @@ declare const backtest: {
12882
14206
  riskGlobalService: RiskGlobalService;
12883
14207
  optimizerGlobalService: OptimizerGlobalService;
12884
14208
  partialGlobalService: PartialGlobalService;
14209
+ breakevenGlobalService: BreakevenGlobalService;
12885
14210
  exchangeCoreService: ExchangeCoreService;
12886
14211
  strategyCoreService: StrategyCoreService;
12887
14212
  frameCoreService: FrameCoreService;
@@ -12899,6 +14224,7 @@ declare const backtest: {
12899
14224
  riskConnectionService: RiskConnectionService;
12900
14225
  optimizerConnectionService: OptimizerConnectionService;
12901
14226
  partialConnectionService: PartialConnectionService;
14227
+ breakevenConnectionService: BreakevenConnectionService;
12902
14228
  executionContextService: {
12903
14229
  readonly context: IExecutionContext;
12904
14230
  };
@@ -12908,4 +14234,4 @@ declare const backtest: {
12908
14234
  loggerService: LoggerService;
12909
14235
  };
12910
14236
 
12911
- export { Backtest, type BacktestDoneNotification, type BacktestStatisticsModel, type BootstrapNotification, Cache, type CandleInterval, type ColumnConfig, type ColumnModel, Constant, type CriticalErrorNotification, type DoneContract, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IOptimizerCallbacks, type IOptimizerData, type IOptimizerFetchArgs, type IOptimizerFilterArgs, type IOptimizerRange, type IOptimizerSchema, type IOptimizerSource, type IOptimizerStrategy, type IOptimizerTemplate, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISignalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type InfoErrorNotification, Live, type LiveDoneNotification, type LiveStatisticsModel, type MessageModel, type MessageRole, MethodContextService, type MetricStats, Notification, type NotificationModel, Optimizer, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossContract, type PartialLossNotification, type PartialProfitContract, type PartialProfitNotification, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, type PingContract, PositionSize, type ProgressBacktestContract, type ProgressBacktestNotification, type ProgressOptimizerContract, type ProgressWalkerContract, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type ScheduleStatisticsModel, type ScheduledEvent, type SignalCancelledNotification, type SignalClosedNotification, type SignalData, type SignalInterval, type SignalOpenedNotification, type SignalScheduledNotification, type TPersistBase, type TPersistBaseCtor, type TickEvent, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, cancel, dumpSignal, emitters, formatPrice, formatQuantity, getAveragePrice, getCandles, getColumns, getConfig, getDate, getDefaultColumns, getDefaultConfig, getMode, hasTradeContext, backtest as lib, listExchanges, listFrames, listOptimizers, listRisks, listSizings, listStrategies, listWalkers, listenBacktestProgress, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenOptimizerProgress, listenPartialLoss, listenPartialLossOnce, listenPartialProfit, listenPartialProfitOnce, listenPerformance, listenPing, listenPingOnce, listenRisk, listenRiskOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, partialLoss, partialProfit, setColumns, setConfig, setLogger, stop, trailingStop, validate };
14237
+ export { Backtest, type BacktestDoneNotification, type BacktestStatisticsModel, type BootstrapNotification, Breakeven, type BreakevenContract, type BreakevenData, Cache, type CandleInterval, type ColumnConfig, type ColumnModel, Constant, type CriticalErrorNotification, type DoneContract, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IOptimizerCallbacks, type IOptimizerData, type IOptimizerFetchArgs, type IOptimizerFilterArgs, type IOptimizerRange, type IOptimizerSchema, type IOptimizerSource, type IOptimizerStrategy, type IOptimizerTemplate, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISignalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type InfoErrorNotification, Live, type LiveDoneNotification, type LiveStatisticsModel, type MessageModel, type MessageRole, MethodContextService, type MetricStats, Notification, type NotificationModel, Optimizer, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossContract, type PartialLossNotification, type PartialProfitContract, type PartialProfitNotification, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistBreakevenAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, type PingContract, PositionSize, type ProgressBacktestContract, type ProgressBacktestNotification, type ProgressOptimizerContract, type ProgressWalkerContract, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type ScheduleStatisticsModel, type ScheduledEvent, type SignalCancelledNotification, type SignalClosedNotification, type SignalData, type SignalInterval, type SignalOpenedNotification, type SignalScheduledNotification, type TPersistBase, type TPersistBaseCtor, type TickEvent, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, breakeven, cancel, dumpSignal, emitters, formatPrice, formatQuantity, getAveragePrice, getCandles, getColumns, getConfig, getDate, getDefaultColumns, getDefaultConfig, getMode, hasTradeContext, backtest as lib, listExchanges, listFrames, listOptimizers, listRisks, listSizings, listStrategies, listWalkers, listenBacktestProgress, listenBreakeven, listenBreakevenOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenOptimizerProgress, listenPartialLoss, listenPartialLossOnce, listenPartialProfit, listenPartialProfitOnce, listenPerformance, listenPing, listenPingOnce, listenRisk, listenRiskOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, partialLoss, partialProfit, setColumns, setConfig, setLogger, stop, trailingStop, validate };