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.
- package/LICENSE +21 -21
- package/README.md +259 -256
- package/build/index.cjs +3280 -875
- package/build/index.mjs +3276 -876
- package/package.json +81 -81
- 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 -
|
|
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
|
-
*
|
|
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
|
-
|
|
256
|
+
declare function breakeven(symbol: string): Promise<boolean>;
|
|
346
257
|
|
|
347
258
|
/**
|
|
348
|
-
*
|
|
259
|
+
* Execution context containing runtime parameters for strategy/exchange operations.
|
|
349
260
|
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
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
|
-
|
|
355
|
-
/**
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
|
|
361
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
335
|
+
type CandleInterval = "1m" | "3m" | "5m" | "15m" | "30m" | "1h" | "2h" | "4h" | "6h" | "8h";
|
|
425
336
|
/**
|
|
426
|
-
*
|
|
427
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
1416
|
+
* Checks if breakeven threshold has been reached for the current pending signal.
|
|
1596
1417
|
*
|
|
1597
|
-
*
|
|
1598
|
-
*
|
|
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
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
*
|
|
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$
|
|
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$
|
|
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$
|
|
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 -
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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 -
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
-
|
|
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
|
-
*
|
|
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 {
|
|
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
|
-
* //
|
|
9577
|
-
* await
|
|
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
|
|
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 -
|
|
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 -
|
|
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 };
|