backtest-kit 1.5.16 → 1.5.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backtest-kit",
3
- "version": "1.5.16",
3
+ "version": "1.5.18",
4
4
  "description": "A TypeScript library for trading system backtest",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
package/types.d.ts CHANGED
@@ -104,6 +104,14 @@ declare const GLOBAL_CONFIG: {
104
104
  * Example: 3 candles = 12 points (use average), 5 candles = 20 points (use median)
105
105
  */
106
106
  CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
107
+ /**
108
+ * Controls visibility of signal notes in markdown report tables.
109
+ * When enabled, the "Note" column will be displayed in all markdown reports
110
+ * (backtest, live, schedule, risk, etc.)
111
+ *
112
+ * Default: false (notes are hidden to reduce table width and improve readability)
113
+ */
114
+ CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
107
115
  };
108
116
  /**
109
117
  * Type for global configuration object.
@@ -197,6 +205,7 @@ declare function getConfig(): {
197
205
  CC_GET_CANDLES_RETRY_DELAY_MS: number;
198
206
  CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
199
207
  CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
208
+ CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
200
209
  };
201
210
  /**
202
211
  * Retrieves the default configuration object for the framework.
@@ -226,6 +235,7 @@ declare function getDefaultConfig(): Readonly<{
226
235
  CC_GET_CANDLES_RETRY_DELAY_MS: number;
227
236
  CC_GET_CANDLES_PRICE_ANOMALY_THRESHOLD_FACTOR: number;
228
237
  CC_GET_CANDLES_MIN_CANDLES_FOR_MEDIAN: number;
238
+ CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
229
239
  }>;
230
240
 
231
241
  /**
@@ -624,11 +634,23 @@ interface IRiskSchema {
624
634
  }
625
635
  /**
626
636
  * Risk parameters passed to ClientRisk constructor.
627
- * Combines schema with runtime dependencies.
637
+ * Combines schema with runtime dependencies and emission callbacks.
628
638
  */
629
639
  interface IRiskParams extends IRiskSchema {
630
640
  /** Logger service for debug output */
631
641
  logger: ILogger;
642
+ /**
643
+ * Callback invoked when a signal is rejected due to risk limits.
644
+ * Called before emitting to riskSubject.
645
+ * Used for event emission to riskSubject (separate from schema callbacks).
646
+ *
647
+ * @param symbol - Trading pair symbol
648
+ * @param params - Risk check arguments
649
+ * @param activePositionCount - Number of active positions at rejection time
650
+ * @param comment - Rejection reason from validation note or "N/A"
651
+ * @param timestamp - Event timestamp in milliseconds
652
+ */
653
+ onRejected: (symbol: string, params: IRiskCheckArgs, activePositionCount: number, comment: string, timestamp: number) => void | Promise<void>;
632
654
  }
633
655
  /**
634
656
  * Risk interface implemented by ClientRisk.
@@ -2759,6 +2781,16 @@ interface PartialProfitContract {
2759
2781
  * Identifies which market this profit event belongs to.
2760
2782
  */
2761
2783
  symbol: string;
2784
+ /**
2785
+ * Strategy name that generated this signal.
2786
+ * Identifies which strategy execution this profit event belongs to.
2787
+ */
2788
+ strategyName: string;
2789
+ /**
2790
+ * Exchange name where this signal is being executed.
2791
+ * Identifies which exchange this profit event belongs to.
2792
+ */
2793
+ exchangeName: string;
2762
2794
  /**
2763
2795
  * Complete signal row data.
2764
2796
  * Contains all signal information: id, position, priceOpen, priceTakeProfit, priceStopLoss, etc.
@@ -2844,6 +2876,16 @@ interface PartialLossContract {
2844
2876
  * Identifies which market this loss event belongs to.
2845
2877
  */
2846
2878
  symbol: string;
2879
+ /**
2880
+ * Strategy name that generated this signal.
2881
+ * Identifies which strategy execution this loss event belongs to.
2882
+ */
2883
+ strategyName: string;
2884
+ /**
2885
+ * Exchange name where this signal is being executed.
2886
+ * Identifies which exchange this loss event belongs to.
2887
+ */
2888
+ exchangeName: string;
2847
2889
  /**
2848
2890
  * Complete signal row data.
2849
2891
  * Contains all signal information: id, position, priceOpen, priceTakeProfit, priceStopLoss, etc.
@@ -2896,6 +2938,95 @@ interface PartialLossContract {
2896
2938
  timestamp: number;
2897
2939
  }
2898
2940
 
2941
+ /**
2942
+ * Contract for risk rejection events.
2943
+ *
2944
+ * Emitted by riskSubject ONLY when a signal is REJECTED due to risk validation failure.
2945
+ * Used for tracking actual risk violations and monitoring rejected signals.
2946
+ *
2947
+ * Events are emitted only when risk limits are violated (not for allowed signals).
2948
+ * This prevents spam and allows focusing on actual risk management interventions.
2949
+ *
2950
+ * Consumers:
2951
+ * - RiskMarkdownService: Accumulates rejection events for report generation
2952
+ * - User callbacks via listenRisk() / listenRiskOnce()
2953
+ *
2954
+ * @example
2955
+ * ```typescript
2956
+ * import { listenRisk } from "backtest-kit";
2957
+ *
2958
+ * // Listen to all risk rejection events
2959
+ * listenRisk((event) => {
2960
+ * console.log(`[RISK REJECTED] Signal for ${event.symbol}`);
2961
+ * console.log(`Strategy: ${event.strategyName}`);
2962
+ * console.log(`Active positions: ${event.activePositionCount}`);
2963
+ * console.log(`Price: ${event.currentPrice}`);
2964
+ * console.log(`Timestamp: ${new Date(event.timestamp).toISOString()}`);
2965
+ * });
2966
+ *
2967
+ * // Alert on risk rejections for specific symbol
2968
+ * listenRisk((event) => {
2969
+ * if (event.symbol === "BTCUSDT") {
2970
+ * console.warn("BTC signal rejected due to risk limits!");
2971
+ * }
2972
+ * });
2973
+ * ```
2974
+ */
2975
+ interface RiskContract {
2976
+ /**
2977
+ * Trading pair symbol (e.g., "BTCUSDT").
2978
+ * Identifies which market this rejected signal belongs to.
2979
+ */
2980
+ symbol: string;
2981
+ /**
2982
+ * Pending signal to apply.
2983
+ * Contains signal details (position, priceOpen, priceTakeProfit, priceStopLoss, etc).
2984
+ */
2985
+ pendingSignal: ISignalDto;
2986
+ /**
2987
+ * Strategy name requesting to open a position.
2988
+ * Identifies which strategy attempted to create the signal.
2989
+ */
2990
+ strategyName: StrategyName;
2991
+ /**
2992
+ * Exchange name.
2993
+ * Identifies which exchange this signal was for.
2994
+ */
2995
+ exchangeName: ExchangeName;
2996
+ /**
2997
+ * Current VWAP price at the time of rejection.
2998
+ * Market price when risk check was performed.
2999
+ */
3000
+ currentPrice: number;
3001
+ /**
3002
+ * Number of currently active positions across all strategies at rejection time.
3003
+ * Used to track portfolio-level exposure when signal was rejected.
3004
+ */
3005
+ activePositionCount: number;
3006
+ /**
3007
+ * Comment describing why the signal was rejected.
3008
+ * Captured from IRiskValidation.note or "N/A" if not provided.
3009
+ *
3010
+ * @example
3011
+ * ```typescript
3012
+ * console.log(`Rejection reason: ${event.comment}`);
3013
+ * // Output: "Rejection reason: Max 3 positions allowed"
3014
+ * ```
3015
+ */
3016
+ comment: string;
3017
+ /**
3018
+ * Event timestamp in milliseconds since Unix epoch.
3019
+ * Represents when the signal was rejected.
3020
+ *
3021
+ * @example
3022
+ * ```typescript
3023
+ * const eventDate = new Date(event.timestamp);
3024
+ * console.log(`Signal rejected at: ${eventDate.toISOString()}`);
3025
+ * ```
3026
+ */
3027
+ timestamp: number;
3028
+ }
3029
+
2899
3030
  /**
2900
3031
  * Subscribes to all signal events with queued async processing.
2901
3032
  *
@@ -3616,6 +3747,69 @@ declare function listenPartialLoss(fn: (event: PartialLossContract) => void): ()
3616
3747
  * ```
3617
3748
  */
3618
3749
  declare function listenPartialLossOnce(filterFn: (event: PartialLossContract) => boolean, fn: (event: PartialLossContract) => void): () => void;
3750
+ /**
3751
+ * Subscribes to risk rejection events with queued async processing.
3752
+ *
3753
+ * Emits ONLY when a signal is rejected due to risk validation failure.
3754
+ * Does not emit for allowed signals (prevents spam).
3755
+ * Events are processed sequentially in order received, even if callback is async.
3756
+ * Uses queued wrapper to prevent concurrent execution of the callback.
3757
+ *
3758
+ * @param fn - Callback function to handle risk rejection events
3759
+ * @returns Unsubscribe function to stop listening to events
3760
+ *
3761
+ * @example
3762
+ * ```typescript
3763
+ * import { listenRisk } from "./function/event";
3764
+ *
3765
+ * const unsubscribe = listenRisk((event) => {
3766
+ * console.log(`[RISK REJECTED] Signal for ${event.symbol}`);
3767
+ * console.log(`Strategy: ${event.strategyName}`);
3768
+ * console.log(`Position: ${event.pendingSignal.position}`);
3769
+ * console.log(`Active positions: ${event.activePositionCount}`);
3770
+ * console.log(`Reason: ${event.comment}`);
3771
+ * console.log(`Price: ${event.currentPrice}`);
3772
+ * });
3773
+ *
3774
+ * // Later: stop listening
3775
+ * unsubscribe();
3776
+ * ```
3777
+ */
3778
+ declare function listenRisk(fn: (event: RiskContract) => void): () => void;
3779
+ /**
3780
+ * Subscribes to filtered risk rejection events with one-time execution.
3781
+ *
3782
+ * Listens for events matching the filter predicate, then executes callback once
3783
+ * and automatically unsubscribes. Useful for waiting for specific risk rejection conditions.
3784
+ *
3785
+ * @param filterFn - Predicate to filter which events trigger the callback
3786
+ * @param fn - Callback function to handle the filtered event (called only once)
3787
+ * @returns Unsubscribe function to cancel the listener before it fires
3788
+ *
3789
+ * @example
3790
+ * ```typescript
3791
+ * import { listenRiskOnce } from "./function/event";
3792
+ *
3793
+ * // Wait for first risk rejection on BTCUSDT
3794
+ * listenRiskOnce(
3795
+ * (event) => event.symbol === "BTCUSDT",
3796
+ * (event) => {
3797
+ * console.log("BTCUSDT signal rejected!");
3798
+ * console.log("Reason:", event.comment);
3799
+ * }
3800
+ * );
3801
+ *
3802
+ * // Wait for rejection due to position limit
3803
+ * const cancel = listenRiskOnce(
3804
+ * (event) => event.comment.includes("Max") && event.activePositionCount >= 3,
3805
+ * (event) => console.log("Position limit reached:", event.activePositionCount)
3806
+ * );
3807
+ *
3808
+ * // Cancel if needed before event fires
3809
+ * cancel();
3810
+ * ```
3811
+ */
3812
+ declare function listenRiskOnce(filterFn: (event: RiskContract) => boolean, fn: (event: RiskContract) => void): () => void;
3619
3813
 
3620
3814
  /**
3621
3815
  * Fetches historical candle data from the registered exchange.
@@ -4787,6 +4981,182 @@ declare class PartialMarkdownService {
4787
4981
  protected init: (() => Promise<void>) & functools_kit.ISingleshotClearable;
4788
4982
  }
4789
4983
 
4984
+ /**
4985
+ * Risk rejection event data for report generation.
4986
+ * Contains all information about rejected signals due to risk limits.
4987
+ */
4988
+ interface RiskEvent {
4989
+ /** Event timestamp in milliseconds */
4990
+ timestamp: number;
4991
+ /** Trading pair symbol */
4992
+ symbol: string;
4993
+ /** Pending signal details */
4994
+ pendingSignal: ISignalDto;
4995
+ /** Strategy name */
4996
+ strategyName: string;
4997
+ /** Exchange name */
4998
+ exchangeName: string;
4999
+ /** Current market price */
5000
+ currentPrice: number;
5001
+ /** Number of active positions at rejection time */
5002
+ activePositionCount: number;
5003
+ /** Rejection reason from validation note */
5004
+ comment: string;
5005
+ }
5006
+ /**
5007
+ * Statistical data calculated from risk rejection events.
5008
+ *
5009
+ * Provides metrics for risk management tracking.
5010
+ *
5011
+ * @example
5012
+ * ```typescript
5013
+ * const stats = await Risk.getData("BTCUSDT", "my-strategy");
5014
+ *
5015
+ * console.log(`Total rejections: ${stats.totalRejections}`);
5016
+ * console.log(`Rejections by symbol:`, stats.bySymbol);
5017
+ * ```
5018
+ */
5019
+ interface RiskStatistics {
5020
+ /** Array of all risk rejection events with full details */
5021
+ eventList: RiskEvent[];
5022
+ /** Total number of risk rejections */
5023
+ totalRejections: number;
5024
+ /** Rejections grouped by symbol */
5025
+ bySymbol: Record<string, number>;
5026
+ /** Rejections grouped by strategy */
5027
+ byStrategy: Record<string, number>;
5028
+ }
5029
+ /**
5030
+ * Service for generating and saving risk rejection markdown reports.
5031
+ *
5032
+ * Features:
5033
+ * - Listens to risk rejection events via riskSubject
5034
+ * - Accumulates all rejection events per symbol-strategy pair
5035
+ * - Generates markdown tables with detailed rejection information
5036
+ * - Provides statistics (total rejections, by symbol, by strategy)
5037
+ * - Saves reports to disk in dump/risk/{symbol}_{strategyName}.md
5038
+ *
5039
+ * @example
5040
+ * ```typescript
5041
+ * const service = new RiskMarkdownService();
5042
+ *
5043
+ * // Service automatically subscribes to subjects on init
5044
+ * // No manual callback setup needed
5045
+ *
5046
+ * // Later: generate and save report
5047
+ * await service.dump("BTCUSDT", "my-strategy");
5048
+ * ```
5049
+ */
5050
+ declare class RiskMarkdownService {
5051
+ /** Logger service for debug output */
5052
+ private readonly loggerService;
5053
+ /**
5054
+ * Memoized function to get or create ReportStorage for a symbol-strategy pair.
5055
+ * Each symbol-strategy combination gets its own isolated storage instance.
5056
+ */
5057
+ private getStorage;
5058
+ /**
5059
+ * Processes risk rejection events and accumulates them.
5060
+ * Should be called from riskSubject subscription.
5061
+ *
5062
+ * @param data - Risk rejection event data
5063
+ *
5064
+ * @example
5065
+ * ```typescript
5066
+ * const service = new RiskMarkdownService();
5067
+ * // Service automatically subscribes in init()
5068
+ * ```
5069
+ */
5070
+ private tickRejection;
5071
+ /**
5072
+ * Gets statistical data from all risk rejection events for a symbol-strategy pair.
5073
+ * Delegates to ReportStorage.getData().
5074
+ *
5075
+ * @param symbol - Trading pair symbol to get data for
5076
+ * @param strategyName - Strategy name to get data for
5077
+ * @returns Statistical data object with all metrics
5078
+ *
5079
+ * @example
5080
+ * ```typescript
5081
+ * const service = new RiskMarkdownService();
5082
+ * const stats = await service.getData("BTCUSDT", "my-strategy");
5083
+ * console.log(stats.totalRejections, stats.bySymbol);
5084
+ * ```
5085
+ */
5086
+ getData: (symbol: string, strategyName: string) => Promise<RiskStatistics>;
5087
+ /**
5088
+ * Generates markdown report with all risk rejection events for a symbol-strategy pair.
5089
+ * Delegates to ReportStorage.getReport().
5090
+ *
5091
+ * @param symbol - Trading pair symbol to generate report for
5092
+ * @param strategyName - Strategy name to generate report for
5093
+ * @returns Markdown formatted report string with table of all events
5094
+ *
5095
+ * @example
5096
+ * ```typescript
5097
+ * const service = new RiskMarkdownService();
5098
+ * const markdown = await service.getReport("BTCUSDT", "my-strategy");
5099
+ * console.log(markdown);
5100
+ * ```
5101
+ */
5102
+ getReport: (symbol: string, strategyName: string) => Promise<string>;
5103
+ /**
5104
+ * Saves symbol-strategy report to disk.
5105
+ * Creates directory if it doesn't exist.
5106
+ * Delegates to ReportStorage.dump().
5107
+ *
5108
+ * @param symbol - Trading pair symbol to save report for
5109
+ * @param strategyName - Strategy name to save report for
5110
+ * @param path - Directory path to save report (default: "./dump/risk")
5111
+ *
5112
+ * @example
5113
+ * ```typescript
5114
+ * const service = new RiskMarkdownService();
5115
+ *
5116
+ * // Save to default path: ./dump/risk/BTCUSDT_my-strategy.md
5117
+ * await service.dump("BTCUSDT", "my-strategy");
5118
+ *
5119
+ * // Save to custom path: ./custom/path/BTCUSDT_my-strategy.md
5120
+ * await service.dump("BTCUSDT", "my-strategy", "./custom/path");
5121
+ * ```
5122
+ */
5123
+ dump: (symbol: string, strategyName: string, path?: string) => Promise<void>;
5124
+ /**
5125
+ * Clears accumulated event data from storage.
5126
+ * If ctx is provided, clears only that specific symbol-strategy pair's data.
5127
+ * If nothing is provided, clears all data.
5128
+ *
5129
+ * @param ctx - Optional context with symbol and strategyName
5130
+ *
5131
+ * @example
5132
+ * ```typescript
5133
+ * const service = new RiskMarkdownService();
5134
+ *
5135
+ * // Clear specific symbol-strategy pair
5136
+ * await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
5137
+ *
5138
+ * // Clear all data
5139
+ * await service.clear();
5140
+ * ```
5141
+ */
5142
+ clear: (ctx?: {
5143
+ symbol: string;
5144
+ strategyName: string;
5145
+ }) => Promise<void>;
5146
+ /**
5147
+ * Initializes the service by subscribing to risk rejection events.
5148
+ * Uses singleshot to ensure initialization happens only once.
5149
+ * Automatically called on first use.
5150
+ *
5151
+ * @example
5152
+ * ```typescript
5153
+ * const service = new RiskMarkdownService();
5154
+ * await service.init(); // Subscribe to rejection events
5155
+ * ```
5156
+ */
5157
+ protected init: (() => Promise<void>) & functools_kit.ISingleshotClearable;
5158
+ }
5159
+
4790
5160
  declare const BASE_WAIT_FOR_INIT_SYMBOL: unique symbol;
4791
5161
  /**
4792
5162
  * Signal data stored in persistence layer.
@@ -6444,6 +6814,157 @@ declare class ConstantUtils {
6444
6814
  */
6445
6815
  declare const Constant: ConstantUtils;
6446
6816
 
6817
+ /**
6818
+ * Utility class for accessing risk rejection reports and statistics.
6819
+ *
6820
+ * Provides static-like methods (via singleton instance) to retrieve data
6821
+ * accumulated by RiskMarkdownService from risk rejection events.
6822
+ *
6823
+ * Features:
6824
+ * - Statistical data extraction (total rejections count, by symbol, by strategy)
6825
+ * - Markdown report generation with event tables
6826
+ * - File export to disk
6827
+ *
6828
+ * Data source:
6829
+ * - RiskMarkdownService listens to riskSubject
6830
+ * - Accumulates rejection events in ReportStorage (max 250 events per symbol-strategy pair)
6831
+ * - Events include: timestamp, symbol, strategyName, position, exchangeName, price, activePositionCount, comment
6832
+ *
6833
+ * @example
6834
+ * ```typescript
6835
+ * import { Risk } from "./classes/Risk";
6836
+ *
6837
+ * // Get statistical data for BTCUSDT:my-strategy
6838
+ * const stats = await Risk.getData("BTCUSDT", "my-strategy");
6839
+ * console.log(`Total rejections: ${stats.totalRejections}`);
6840
+ * console.log(`By symbol:`, stats.bySymbol);
6841
+ * console.log(`By strategy:`, stats.byStrategy);
6842
+ *
6843
+ * // Generate markdown report
6844
+ * const markdown = await Risk.getReport("BTCUSDT", "my-strategy");
6845
+ * console.log(markdown); // Formatted table with all rejection events
6846
+ *
6847
+ * // Export report to file
6848
+ * await Risk.dump("BTCUSDT", "my-strategy"); // Saves to ./dump/risk/BTCUSDT_my-strategy.md
6849
+ * await Risk.dump("BTCUSDT", "my-strategy", "./custom/path"); // Custom directory
6850
+ * ```
6851
+ */
6852
+ declare class RiskUtils {
6853
+ /**
6854
+ * Retrieves statistical data from accumulated risk rejection events.
6855
+ *
6856
+ * Delegates to RiskMarkdownService.getData() which reads from ReportStorage.
6857
+ * Returns aggregated metrics calculated from all rejection events.
6858
+ *
6859
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
6860
+ * @param strategyName - Strategy name (e.g., "my-strategy")
6861
+ * @returns Promise resolving to RiskStatistics object with counts and event list
6862
+ *
6863
+ * @example
6864
+ * ```typescript
6865
+ * const stats = await Risk.getData("BTCUSDT", "my-strategy");
6866
+ *
6867
+ * console.log(`Total rejections: ${stats.totalRejections}`);
6868
+ * console.log(`Rejections by symbol:`, stats.bySymbol);
6869
+ * console.log(`Rejections by strategy:`, stats.byStrategy);
6870
+ *
6871
+ * // Iterate through all rejection events
6872
+ * for (const event of stats.eventList) {
6873
+ * console.log(`REJECTED: ${event.symbol} - ${event.comment} (${event.activePositionCount} active)`);
6874
+ * }
6875
+ * ```
6876
+ */
6877
+ getData: (symbol: string, strategyName: string) => Promise<RiskStatistics>;
6878
+ /**
6879
+ * Generates markdown report with all risk rejection events for a symbol-strategy pair.
6880
+ *
6881
+ * Creates formatted table containing:
6882
+ * - Symbol
6883
+ * - Strategy
6884
+ * - Position (LONG/SHORT)
6885
+ * - Exchange
6886
+ * - Price
6887
+ * - Active Positions (at rejection time)
6888
+ * - Reason (from validation note)
6889
+ * - Timestamp (ISO 8601)
6890
+ *
6891
+ * Also includes summary statistics at the end (total rejections, by symbol, by strategy).
6892
+ *
6893
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
6894
+ * @param strategyName - Strategy name (e.g., "my-strategy")
6895
+ * @returns Promise resolving to markdown formatted report string
6896
+ *
6897
+ * @example
6898
+ * ```typescript
6899
+ * const markdown = await Risk.getReport("BTCUSDT", "my-strategy");
6900
+ * console.log(markdown);
6901
+ *
6902
+ * // Output:
6903
+ * // # Risk Rejection Report: BTCUSDT:my-strategy
6904
+ * //
6905
+ * // | Symbol | Strategy | Position | Exchange | Price | Active Positions | Reason | Timestamp |
6906
+ * // | --- | --- | --- | --- | --- | --- | --- | --- |
6907
+ * // | BTCUSDT | my-strategy | LONG | binance | 50000.00000000 USD | 3 | Max 3 positions allowed | 2024-01-15T10:30:00.000Z |
6908
+ * //
6909
+ * // **Total rejections:** 1
6910
+ * //
6911
+ * // ## Rejections by Symbol
6912
+ * // - BTCUSDT: 1
6913
+ * //
6914
+ * // ## Rejections by Strategy
6915
+ * // - my-strategy: 1
6916
+ * ```
6917
+ */
6918
+ getReport: (symbol: string, strategyName: string) => Promise<string>;
6919
+ /**
6920
+ * Generates and saves markdown report to file.
6921
+ *
6922
+ * Creates directory if it doesn't exist.
6923
+ * Filename format: {symbol}_{strategyName}.md (e.g., "BTCUSDT_my-strategy.md")
6924
+ *
6925
+ * Delegates to RiskMarkdownService.dump() which:
6926
+ * 1. Generates markdown report via getReport()
6927
+ * 2. Creates output directory (recursive mkdir)
6928
+ * 3. Writes file with UTF-8 encoding
6929
+ * 4. Logs success/failure to console
6930
+ *
6931
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
6932
+ * @param strategyName - Strategy name (e.g., "my-strategy")
6933
+ * @param path - Output directory path (default: "./dump/risk")
6934
+ * @returns Promise that resolves when file is written
6935
+ *
6936
+ * @example
6937
+ * ```typescript
6938
+ * // Save to default path: ./dump/risk/BTCUSDT_my-strategy.md
6939
+ * await Risk.dump("BTCUSDT", "my-strategy");
6940
+ *
6941
+ * // Save to custom path: ./reports/risk/BTCUSDT_my-strategy.md
6942
+ * await Risk.dump("BTCUSDT", "my-strategy", "./reports/risk");
6943
+ *
6944
+ * // After multiple symbols backtested, export all risk reports
6945
+ * for (const symbol of ["BTCUSDT", "ETHUSDT", "BNBUSDT"]) {
6946
+ * await Risk.dump(symbol, "my-strategy", "./backtest-results");
6947
+ * }
6948
+ * ```
6949
+ */
6950
+ dump: (symbol: string, strategyName: string, path?: string) => Promise<void>;
6951
+ }
6952
+ /**
6953
+ * Global singleton instance of RiskUtils.
6954
+ * Provides static-like access to risk rejection reporting methods.
6955
+ *
6956
+ * @example
6957
+ * ```typescript
6958
+ * import { Risk } from "backtest-kit";
6959
+ *
6960
+ * // Usage same as RiskUtils methods
6961
+ * const stats = await Risk.getData("BTCUSDT", "my-strategy");
6962
+ * const report = await Risk.getReport("BTCUSDT", "my-strategy");
6963
+ * await Risk.dump("BTCUSDT", "my-strategy");
6964
+ * ```
6965
+ */
6966
+ declare const Risk: RiskUtils;
6967
+
6447
6968
  /**
6448
6969
  * Contract for walker stop signal events.
6449
6970
  *
@@ -6567,6 +7088,12 @@ declare const partialProfitSubject: Subject<PartialProfitContract>;
6567
7088
  * Emits when a signal reaches a loss level (10%, 20%, 30%, etc).
6568
7089
  */
6569
7090
  declare const partialLossSubject: Subject<PartialLossContract>;
7091
+ /**
7092
+ * Risk rejection emitter for risk management violations.
7093
+ * Emits ONLY when a signal is rejected due to risk validation failure.
7094
+ * Does not emit for allowed signals (prevents spam).
7095
+ */
7096
+ declare const riskSubject: Subject<RiskContract>;
6570
7097
 
6571
7098
  declare const emitters_doneBacktestSubject: typeof doneBacktestSubject;
6572
7099
  declare const emitters_doneLiveSubject: typeof doneLiveSubject;
@@ -6579,6 +7106,7 @@ declare const emitters_performanceEmitter: typeof performanceEmitter;
6579
7106
  declare const emitters_progressBacktestEmitter: typeof progressBacktestEmitter;
6580
7107
  declare const emitters_progressOptimizerEmitter: typeof progressOptimizerEmitter;
6581
7108
  declare const emitters_progressWalkerEmitter: typeof progressWalkerEmitter;
7109
+ declare const emitters_riskSubject: typeof riskSubject;
6582
7110
  declare const emitters_signalBacktestEmitter: typeof signalBacktestEmitter;
6583
7111
  declare const emitters_signalEmitter: typeof signalEmitter;
6584
7112
  declare const emitters_signalLiveEmitter: typeof signalLiveEmitter;
@@ -6587,7 +7115,7 @@ declare const emitters_walkerCompleteSubject: typeof walkerCompleteSubject;
6587
7115
  declare const emitters_walkerEmitter: typeof walkerEmitter;
6588
7116
  declare const emitters_walkerStopSubject: typeof walkerStopSubject;
6589
7117
  declare namespace emitters {
6590
- 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_progressBacktestEmitter as progressBacktestEmitter, emitters_progressOptimizerEmitter as progressOptimizerEmitter, emitters_progressWalkerEmitter as progressWalkerEmitter, 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 };
7118
+ 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_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 };
6591
7119
  }
6592
7120
 
6593
7121
  /**
@@ -7210,6 +7738,7 @@ declare class RiskConnectionService {
7210
7738
  *
7211
7739
  * Routes to appropriate ClientRisk instance based on provided context.
7212
7740
  * Validates portfolio drawdown, symbol exposure, position count, and daily loss limits.
7741
+ * ClientRisk will emit riskSubject event via onRejected callback when signal is rejected.
7213
7742
  *
7214
7743
  * @param params - Risk check arguments (portfolio state, position details)
7215
7744
  * @param context - Execution context with risk name
@@ -9312,6 +9841,7 @@ declare const backtest: {
9312
9841
  heatMarkdownService: HeatMarkdownService;
9313
9842
  partialMarkdownService: PartialMarkdownService;
9314
9843
  outlineMarkdownService: OutlineMarkdownService;
9844
+ riskMarkdownService: RiskMarkdownService;
9315
9845
  backtestLogicPublicService: BacktestLogicPublicService;
9316
9846
  liveLogicPublicService: LiveLogicPublicService;
9317
9847
  walkerLogicPublicService: WalkerLogicPublicService;
@@ -9351,4 +9881,4 @@ declare const backtest: {
9351
9881
  loggerService: LoggerService;
9352
9882
  };
9353
9883
 
9354
- export { Backtest, type BacktestStatistics, type CandleInterval, Constant, type DoneContract, type EntityId, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IHeatmapStatistics, 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 IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, 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 IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, Live, type LiveStatistics, type MessageModel, type MessageRole, MethodContextService, Optimizer, Partial$1 as Partial, type PartialData, type PartialLossContract, type PartialProfitContract, type PartialStatistics, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatistics, PersistBase, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, type ProgressBacktestContract, type ProgressOptimizerContract, type ProgressWalkerContract, type RiskData, Schedule, type ScheduleData, type ScheduleStatistics, type SignalData, type SignalInterval, type TPersistBase, type TPersistBaseCtor, Walker, type WalkerContract, type WalkerMetric, type WalkerStatistics, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, dumpSignal, emitters, formatPrice, formatQuantity, getAveragePrice, getCandles, getConfig, getDate, getDefaultConfig, getMode, 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, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, setConfig, setLogger };
9884
+ export { Backtest, type BacktestStatistics, type CandleInterval, Constant, type DoneContract, type EntityId, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IHeatmapStatistics, 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 IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, 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 IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, Live, type LiveStatistics, type MessageModel, type MessageRole, MethodContextService, Optimizer, Partial$1 as Partial, type PartialData, type PartialLossContract, type PartialProfitContract, type PartialStatistics, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatistics, PersistBase, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, type ProgressBacktestContract, type ProgressOptimizerContract, type ProgressWalkerContract, Risk, type RiskContract, type RiskData, type RiskStatistics, Schedule, type ScheduleData, type ScheduleStatistics, type SignalData, type SignalInterval, type TPersistBase, type TPersistBaseCtor, Walker, type WalkerContract, type WalkerMetric, type WalkerStatistics, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, dumpSignal, emitters, formatPrice, formatQuantity, getAveragePrice, getCandles, getConfig, getDate, getDefaultConfig, getMode, 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, listenRisk, listenRiskOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, setConfig, setLogger };