backtest-kit 1.5.37 → 1.5.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.cjs +24 -0
- package/build/index.mjs +24 -0
- package/package.json +1 -1
- package/types.d.ts +453 -453
package/build/index.cjs
CHANGED
|
@@ -2879,6 +2879,9 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
2879
2879
|
errors.push(`position must be "long" or "short", got "${signal.position}"`);
|
|
2880
2880
|
}
|
|
2881
2881
|
// ЗАЩИТА ОТ NaN/Infinity: currentPrice должна быть конечным числом
|
|
2882
|
+
if (typeof currentPrice !== "number") {
|
|
2883
|
+
errors.push(`currentPrice must be a number type, got ${currentPrice} (${typeof currentPrice})`);
|
|
2884
|
+
}
|
|
2882
2885
|
if (!isFinite(currentPrice)) {
|
|
2883
2886
|
errors.push(`currentPrice must be a finite number, got ${currentPrice} (${typeof currentPrice})`);
|
|
2884
2887
|
}
|
|
@@ -2886,12 +2889,21 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
2886
2889
|
errors.push(`currentPrice must be positive, got ${currentPrice}`);
|
|
2887
2890
|
}
|
|
2888
2891
|
// ЗАЩИТА ОТ NaN/Infinity: все цены должны быть конечными числами
|
|
2892
|
+
if (typeof signal.priceOpen !== "number") {
|
|
2893
|
+
errors.push(`priceOpen must be a number type, got ${signal.priceOpen} (${typeof signal.priceOpen})`);
|
|
2894
|
+
}
|
|
2889
2895
|
if (!isFinite(signal.priceOpen)) {
|
|
2890
2896
|
errors.push(`priceOpen must be a finite number, got ${signal.priceOpen} (${typeof signal.priceOpen})`);
|
|
2891
2897
|
}
|
|
2898
|
+
if (typeof signal.priceTakeProfit !== "number") {
|
|
2899
|
+
errors.push(`priceTakeProfit must be a number type, got ${signal.priceTakeProfit} (${typeof signal.priceTakeProfit})`);
|
|
2900
|
+
}
|
|
2892
2901
|
if (!isFinite(signal.priceTakeProfit)) {
|
|
2893
2902
|
errors.push(`priceTakeProfit must be a finite number, got ${signal.priceTakeProfit} (${typeof signal.priceTakeProfit})`);
|
|
2894
2903
|
}
|
|
2904
|
+
if (typeof signal.priceStopLoss !== "number") {
|
|
2905
|
+
errors.push(`priceStopLoss must be a number type, got ${signal.priceStopLoss} (${typeof signal.priceStopLoss})`);
|
|
2906
|
+
}
|
|
2895
2907
|
if (!isFinite(signal.priceStopLoss)) {
|
|
2896
2908
|
errors.push(`priceStopLoss must be a finite number, got ${signal.priceStopLoss} (${typeof signal.priceStopLoss})`);
|
|
2897
2909
|
}
|
|
@@ -3030,12 +3042,18 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
3030
3042
|
}
|
|
3031
3043
|
}
|
|
3032
3044
|
// Валидация временных параметров
|
|
3045
|
+
if (typeof signal.minuteEstimatedTime !== "number") {
|
|
3046
|
+
errors.push(`minuteEstimatedTime must be a number type, got ${signal.minuteEstimatedTime} (${typeof signal.minuteEstimatedTime})`);
|
|
3047
|
+
}
|
|
3033
3048
|
if (signal.minuteEstimatedTime <= 0) {
|
|
3034
3049
|
errors.push(`minuteEstimatedTime must be positive, got ${signal.minuteEstimatedTime}`);
|
|
3035
3050
|
}
|
|
3036
3051
|
if (!Number.isInteger(signal.minuteEstimatedTime)) {
|
|
3037
3052
|
errors.push(`minuteEstimatedTime must be an integer (whole number), got ${signal.minuteEstimatedTime}`);
|
|
3038
3053
|
}
|
|
3054
|
+
if (!isFinite(signal.minuteEstimatedTime)) {
|
|
3055
|
+
errors.push(`minuteEstimatedTime must be a finite number, got ${signal.minuteEstimatedTime}`);
|
|
3056
|
+
}
|
|
3039
3057
|
// ЗАЩИТА ОТ ВЕЧНЫХ СИГНАЛОВ: ограничиваем максимальное время жизни сигнала
|
|
3040
3058
|
if (GLOBAL_CONFIG.CC_MAX_SIGNAL_LIFETIME_MINUTES && GLOBAL_CONFIG.CC_MAX_SIGNAL_LIFETIME_MINUTES) {
|
|
3041
3059
|
if (signal.minuteEstimatedTime > GLOBAL_CONFIG.CC_MAX_SIGNAL_LIFETIME_MINUTES) {
|
|
@@ -3046,9 +3064,15 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
3046
3064
|
`Eternal signals block risk limits and prevent new trades.`);
|
|
3047
3065
|
}
|
|
3048
3066
|
}
|
|
3067
|
+
if (typeof signal.scheduledAt !== "number") {
|
|
3068
|
+
errors.push(`scheduledAt must be a number type, got ${signal.scheduledAt} (${typeof signal.scheduledAt})`);
|
|
3069
|
+
}
|
|
3049
3070
|
if (signal.scheduledAt <= 0) {
|
|
3050
3071
|
errors.push(`scheduledAt must be positive, got ${signal.scheduledAt}`);
|
|
3051
3072
|
}
|
|
3073
|
+
if (typeof signal.pendingAt !== "number") {
|
|
3074
|
+
errors.push(`pendingAt must be a number type, got ${signal.pendingAt} (${typeof signal.pendingAt})`);
|
|
3075
|
+
}
|
|
3052
3076
|
if (signal.pendingAt <= 0) {
|
|
3053
3077
|
errors.push(`pendingAt must be positive, got ${signal.pendingAt}`);
|
|
3054
3078
|
}
|
package/build/index.mjs
CHANGED
|
@@ -2877,6 +2877,9 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
2877
2877
|
errors.push(`position must be "long" or "short", got "${signal.position}"`);
|
|
2878
2878
|
}
|
|
2879
2879
|
// ЗАЩИТА ОТ NaN/Infinity: currentPrice должна быть конечным числом
|
|
2880
|
+
if (typeof currentPrice !== "number") {
|
|
2881
|
+
errors.push(`currentPrice must be a number type, got ${currentPrice} (${typeof currentPrice})`);
|
|
2882
|
+
}
|
|
2880
2883
|
if (!isFinite(currentPrice)) {
|
|
2881
2884
|
errors.push(`currentPrice must be a finite number, got ${currentPrice} (${typeof currentPrice})`);
|
|
2882
2885
|
}
|
|
@@ -2884,12 +2887,21 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
2884
2887
|
errors.push(`currentPrice must be positive, got ${currentPrice}`);
|
|
2885
2888
|
}
|
|
2886
2889
|
// ЗАЩИТА ОТ NaN/Infinity: все цены должны быть конечными числами
|
|
2890
|
+
if (typeof signal.priceOpen !== "number") {
|
|
2891
|
+
errors.push(`priceOpen must be a number type, got ${signal.priceOpen} (${typeof signal.priceOpen})`);
|
|
2892
|
+
}
|
|
2887
2893
|
if (!isFinite(signal.priceOpen)) {
|
|
2888
2894
|
errors.push(`priceOpen must be a finite number, got ${signal.priceOpen} (${typeof signal.priceOpen})`);
|
|
2889
2895
|
}
|
|
2896
|
+
if (typeof signal.priceTakeProfit !== "number") {
|
|
2897
|
+
errors.push(`priceTakeProfit must be a number type, got ${signal.priceTakeProfit} (${typeof signal.priceTakeProfit})`);
|
|
2898
|
+
}
|
|
2890
2899
|
if (!isFinite(signal.priceTakeProfit)) {
|
|
2891
2900
|
errors.push(`priceTakeProfit must be a finite number, got ${signal.priceTakeProfit} (${typeof signal.priceTakeProfit})`);
|
|
2892
2901
|
}
|
|
2902
|
+
if (typeof signal.priceStopLoss !== "number") {
|
|
2903
|
+
errors.push(`priceStopLoss must be a number type, got ${signal.priceStopLoss} (${typeof signal.priceStopLoss})`);
|
|
2904
|
+
}
|
|
2893
2905
|
if (!isFinite(signal.priceStopLoss)) {
|
|
2894
2906
|
errors.push(`priceStopLoss must be a finite number, got ${signal.priceStopLoss} (${typeof signal.priceStopLoss})`);
|
|
2895
2907
|
}
|
|
@@ -3028,12 +3040,18 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
3028
3040
|
}
|
|
3029
3041
|
}
|
|
3030
3042
|
// Валидация временных параметров
|
|
3043
|
+
if (typeof signal.minuteEstimatedTime !== "number") {
|
|
3044
|
+
errors.push(`minuteEstimatedTime must be a number type, got ${signal.minuteEstimatedTime} (${typeof signal.minuteEstimatedTime})`);
|
|
3045
|
+
}
|
|
3031
3046
|
if (signal.minuteEstimatedTime <= 0) {
|
|
3032
3047
|
errors.push(`minuteEstimatedTime must be positive, got ${signal.minuteEstimatedTime}`);
|
|
3033
3048
|
}
|
|
3034
3049
|
if (!Number.isInteger(signal.minuteEstimatedTime)) {
|
|
3035
3050
|
errors.push(`minuteEstimatedTime must be an integer (whole number), got ${signal.minuteEstimatedTime}`);
|
|
3036
3051
|
}
|
|
3052
|
+
if (!isFinite(signal.minuteEstimatedTime)) {
|
|
3053
|
+
errors.push(`minuteEstimatedTime must be a finite number, got ${signal.minuteEstimatedTime}`);
|
|
3054
|
+
}
|
|
3037
3055
|
// ЗАЩИТА ОТ ВЕЧНЫХ СИГНАЛОВ: ограничиваем максимальное время жизни сигнала
|
|
3038
3056
|
if (GLOBAL_CONFIG.CC_MAX_SIGNAL_LIFETIME_MINUTES && GLOBAL_CONFIG.CC_MAX_SIGNAL_LIFETIME_MINUTES) {
|
|
3039
3057
|
if (signal.minuteEstimatedTime > GLOBAL_CONFIG.CC_MAX_SIGNAL_LIFETIME_MINUTES) {
|
|
@@ -3044,9 +3062,15 @@ const VALIDATE_SIGNAL_FN = (signal, currentPrice, isScheduled) => {
|
|
|
3044
3062
|
`Eternal signals block risk limits and prevent new trades.`);
|
|
3045
3063
|
}
|
|
3046
3064
|
}
|
|
3065
|
+
if (typeof signal.scheduledAt !== "number") {
|
|
3066
|
+
errors.push(`scheduledAt must be a number type, got ${signal.scheduledAt} (${typeof signal.scheduledAt})`);
|
|
3067
|
+
}
|
|
3047
3068
|
if (signal.scheduledAt <= 0) {
|
|
3048
3069
|
errors.push(`scheduledAt must be positive, got ${signal.scheduledAt}`);
|
|
3049
3070
|
}
|
|
3071
|
+
if (typeof signal.pendingAt !== "number") {
|
|
3072
|
+
errors.push(`pendingAt must be a number type, got ${signal.pendingAt} (${typeof signal.pendingAt})`);
|
|
3073
|
+
}
|
|
3050
3074
|
if (signal.pendingAt <= 0) {
|
|
3051
3075
|
errors.push(`pendingAt must be positive, got ${signal.pendingAt}`);
|
|
3052
3076
|
}
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -1112,359 +1112,6 @@ interface WalkerStatisticsModel extends WalkerCompleteContract {
|
|
|
1112
1112
|
strategyResults: IStrategyResult[];
|
|
1113
1113
|
}
|
|
1114
1114
|
|
|
1115
|
-
/**
|
|
1116
|
-
* Unified scheduled signal event data for report generation.
|
|
1117
|
-
* Contains all information about scheduled, opened and cancelled events.
|
|
1118
|
-
*/
|
|
1119
|
-
interface ScheduledEvent {
|
|
1120
|
-
/** Event timestamp in milliseconds (scheduledAt for scheduled/cancelled events) */
|
|
1121
|
-
timestamp: number;
|
|
1122
|
-
/** Event action type */
|
|
1123
|
-
action: "scheduled" | "opened" | "cancelled";
|
|
1124
|
-
/** Trading pair symbol */
|
|
1125
|
-
symbol: string;
|
|
1126
|
-
/** Signal ID */
|
|
1127
|
-
signalId: string;
|
|
1128
|
-
/** Position type */
|
|
1129
|
-
position: string;
|
|
1130
|
-
/** Signal note */
|
|
1131
|
-
note?: string;
|
|
1132
|
-
/** Current market price */
|
|
1133
|
-
currentPrice: number;
|
|
1134
|
-
/** Scheduled entry price */
|
|
1135
|
-
priceOpen: number;
|
|
1136
|
-
/** Take profit price */
|
|
1137
|
-
takeProfit: number;
|
|
1138
|
-
/** Stop loss price */
|
|
1139
|
-
stopLoss: number;
|
|
1140
|
-
/** Close timestamp (only for cancelled) */
|
|
1141
|
-
closeTimestamp?: number;
|
|
1142
|
-
/** Duration in minutes (only for cancelled/opened) */
|
|
1143
|
-
duration?: number;
|
|
1144
|
-
}
|
|
1145
|
-
/**
|
|
1146
|
-
* Statistical data calculated from scheduled signals.
|
|
1147
|
-
*
|
|
1148
|
-
* Provides metrics for scheduled signal tracking, activation and cancellation analysis.
|
|
1149
|
-
*
|
|
1150
|
-
* @example
|
|
1151
|
-
* ```typescript
|
|
1152
|
-
* const stats = await Schedule.getData("my-strategy");
|
|
1153
|
-
*
|
|
1154
|
-
* console.log(`Total events: ${stats.totalEvents}`);
|
|
1155
|
-
* console.log(`Scheduled signals: ${stats.totalScheduled}`);
|
|
1156
|
-
* console.log(`Opened signals: ${stats.totalOpened}`);
|
|
1157
|
-
* console.log(`Cancelled signals: ${stats.totalCancelled}`);
|
|
1158
|
-
* console.log(`Cancellation rate: ${stats.cancellationRate}%`);
|
|
1159
|
-
*
|
|
1160
|
-
* // Access raw event data (includes scheduled, opened, cancelled)
|
|
1161
|
-
* stats.eventList.forEach(event => {
|
|
1162
|
-
* if (event.action === "cancelled") {
|
|
1163
|
-
* console.log(`Cancelled signal: ${event.signalId}`);
|
|
1164
|
-
* }
|
|
1165
|
-
* });
|
|
1166
|
-
* ```
|
|
1167
|
-
*/
|
|
1168
|
-
interface ScheduleStatisticsModel {
|
|
1169
|
-
/** Array of all scheduled/opened/cancelled events with full details */
|
|
1170
|
-
eventList: ScheduledEvent[];
|
|
1171
|
-
/** Total number of all events (includes scheduled, opened, cancelled) */
|
|
1172
|
-
totalEvents: number;
|
|
1173
|
-
/** Total number of scheduled signals */
|
|
1174
|
-
totalScheduled: number;
|
|
1175
|
-
/** Total number of opened signals (activated from scheduled) */
|
|
1176
|
-
totalOpened: number;
|
|
1177
|
-
/** Total number of cancelled signals */
|
|
1178
|
-
totalCancelled: number;
|
|
1179
|
-
/** Cancellation rate as percentage (0-100), null if no scheduled signals. Lower is better. */
|
|
1180
|
-
cancellationRate: number | null;
|
|
1181
|
-
/** Activation rate as percentage (0-100), null if no scheduled signals. Higher is better. */
|
|
1182
|
-
activationRate: number | null;
|
|
1183
|
-
/** Average waiting time for cancelled signals in minutes, null if no cancelled signals */
|
|
1184
|
-
avgWaitTime: number | null;
|
|
1185
|
-
/** Average waiting time for opened signals in minutes, null if no opened signals */
|
|
1186
|
-
avgActivationTime: number | null;
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
/**
|
|
1190
|
-
* Risk rejection event data for report generation.
|
|
1191
|
-
* Contains all information about rejected signals due to risk limits.
|
|
1192
|
-
*/
|
|
1193
|
-
interface RiskEvent {
|
|
1194
|
-
/** Event timestamp in milliseconds */
|
|
1195
|
-
timestamp: number;
|
|
1196
|
-
/** Trading pair symbol */
|
|
1197
|
-
symbol: string;
|
|
1198
|
-
/** Pending signal details */
|
|
1199
|
-
pendingSignal: ISignalDto;
|
|
1200
|
-
/** Strategy name */
|
|
1201
|
-
strategyName: string;
|
|
1202
|
-
/** Exchange name */
|
|
1203
|
-
exchangeName: string;
|
|
1204
|
-
/** Current market price */
|
|
1205
|
-
currentPrice: number;
|
|
1206
|
-
/** Number of active positions at rejection time */
|
|
1207
|
-
activePositionCount: number;
|
|
1208
|
-
/** Rejection reason from validation note */
|
|
1209
|
-
comment: string;
|
|
1210
|
-
/** Whether this event is from backtest mode (true) or live mode (false) */
|
|
1211
|
-
backtest: boolean;
|
|
1212
|
-
}
|
|
1213
|
-
/**
|
|
1214
|
-
* Statistical data calculated from risk rejection events.
|
|
1215
|
-
*
|
|
1216
|
-
* Provides metrics for risk management tracking.
|
|
1217
|
-
*
|
|
1218
|
-
* @example
|
|
1219
|
-
* ```typescript
|
|
1220
|
-
* const stats = await Risk.getData("BTCUSDT", "my-strategy");
|
|
1221
|
-
*
|
|
1222
|
-
* console.log(`Total rejections: ${stats.totalRejections}`);
|
|
1223
|
-
* console.log(`Rejections by symbol:`, stats.bySymbol);
|
|
1224
|
-
* ```
|
|
1225
|
-
*/
|
|
1226
|
-
interface RiskStatisticsModel {
|
|
1227
|
-
/** Array of all risk rejection events with full details */
|
|
1228
|
-
eventList: RiskEvent[];
|
|
1229
|
-
/** Total number of risk rejections */
|
|
1230
|
-
totalRejections: number;
|
|
1231
|
-
/** Rejections grouped by symbol */
|
|
1232
|
-
bySymbol: Record<string, number>;
|
|
1233
|
-
/** Rejections grouped by strategy */
|
|
1234
|
-
byStrategy: Record<string, number>;
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
/**
|
|
1238
|
-
* Performance metric types tracked by the system.
|
|
1239
|
-
*
|
|
1240
|
-
* Backtest metrics:
|
|
1241
|
-
* - backtest_total: Total backtest duration from start to finish
|
|
1242
|
-
* - backtest_timeframe: Duration to process a single timeframe iteration
|
|
1243
|
-
* - backtest_signal: Duration to process a signal (tick + getNextCandles + backtest)
|
|
1244
|
-
*
|
|
1245
|
-
* Live metrics:
|
|
1246
|
-
* - live_tick: Duration of a single live tick iteration
|
|
1247
|
-
*/
|
|
1248
|
-
type PerformanceMetricType = "backtest_total" | "backtest_timeframe" | "backtest_signal" | "live_tick";
|
|
1249
|
-
/**
|
|
1250
|
-
* Contract for performance tracking events.
|
|
1251
|
-
*
|
|
1252
|
-
* Emitted during execution to track performance metrics for various operations.
|
|
1253
|
-
* Useful for profiling and identifying bottlenecks.
|
|
1254
|
-
*
|
|
1255
|
-
* @example
|
|
1256
|
-
* ```typescript
|
|
1257
|
-
* import { listenPerformance } from "backtest-kit";
|
|
1258
|
-
*
|
|
1259
|
-
* listenPerformance((event) => {
|
|
1260
|
-
* console.log(`${event.metricType}: ${event.duration.toFixed(2)}ms`);
|
|
1261
|
-
* console.log(`${event.strategyName} @ ${event.exchangeName}`);
|
|
1262
|
-
* });
|
|
1263
|
-
* ```
|
|
1264
|
-
*/
|
|
1265
|
-
interface PerformanceContract {
|
|
1266
|
-
/** Timestamp when the metric was recorded (milliseconds since epoch) */
|
|
1267
|
-
timestamp: number;
|
|
1268
|
-
/** Timestamp of the previous event (milliseconds since epoch, null for first event) */
|
|
1269
|
-
previousTimestamp: number | null;
|
|
1270
|
-
/** Type of operation being measured */
|
|
1271
|
-
metricType: PerformanceMetricType;
|
|
1272
|
-
/** Duration of the operation in milliseconds */
|
|
1273
|
-
duration: number;
|
|
1274
|
-
/** Strategy name associated with this metric */
|
|
1275
|
-
strategyName: string;
|
|
1276
|
-
/** Exchange name associated with this metric */
|
|
1277
|
-
exchangeName: string;
|
|
1278
|
-
/** Trading symbol associated with this metric */
|
|
1279
|
-
symbol: string;
|
|
1280
|
-
/** Whether this metric is from backtest mode (true) or live mode (false) */
|
|
1281
|
-
backtest: boolean;
|
|
1282
|
-
}
|
|
1283
|
-
|
|
1284
|
-
/**
|
|
1285
|
-
* Aggregated statistics for a specific metric type.
|
|
1286
|
-
*/
|
|
1287
|
-
interface MetricStats {
|
|
1288
|
-
/** Type of metric */
|
|
1289
|
-
metricType: PerformanceMetricType;
|
|
1290
|
-
/** Number of recorded samples */
|
|
1291
|
-
count: number;
|
|
1292
|
-
/** Total duration across all samples (ms) */
|
|
1293
|
-
totalDuration: number;
|
|
1294
|
-
/** Average duration (ms) */
|
|
1295
|
-
avgDuration: number;
|
|
1296
|
-
/** Minimum duration (ms) */
|
|
1297
|
-
minDuration: number;
|
|
1298
|
-
/** Maximum duration (ms) */
|
|
1299
|
-
maxDuration: number;
|
|
1300
|
-
/** Standard deviation of duration (ms) */
|
|
1301
|
-
stdDev: number;
|
|
1302
|
-
/** Median duration (ms) */
|
|
1303
|
-
median: number;
|
|
1304
|
-
/** 95th percentile duration (ms) */
|
|
1305
|
-
p95: number;
|
|
1306
|
-
/** 99th percentile duration (ms) */
|
|
1307
|
-
p99: number;
|
|
1308
|
-
/** Average wait time between events (ms) */
|
|
1309
|
-
avgWaitTime: number;
|
|
1310
|
-
/** Minimum wait time between events (ms) */
|
|
1311
|
-
minWaitTime: number;
|
|
1312
|
-
/** Maximum wait time between events (ms) */
|
|
1313
|
-
maxWaitTime: number;
|
|
1314
|
-
}
|
|
1315
|
-
/**
|
|
1316
|
-
* Performance statistics aggregated by strategy.
|
|
1317
|
-
*/
|
|
1318
|
-
interface PerformanceStatisticsModel {
|
|
1319
|
-
/** Strategy name */
|
|
1320
|
-
strategyName: string;
|
|
1321
|
-
/** Total number of performance events recorded */
|
|
1322
|
-
totalEvents: number;
|
|
1323
|
-
/** Total execution time across all metrics (ms) */
|
|
1324
|
-
totalDuration: number;
|
|
1325
|
-
/** Statistics grouped by metric type */
|
|
1326
|
-
metricStats: Record<string, MetricStats>;
|
|
1327
|
-
/** All raw performance events */
|
|
1328
|
-
events: PerformanceContract[];
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
/**
|
|
1332
|
-
* Unified partial profit/loss event data for report generation.
|
|
1333
|
-
* Contains all information about profit and loss level milestones.
|
|
1334
|
-
*/
|
|
1335
|
-
interface PartialEvent {
|
|
1336
|
-
/** Event timestamp in milliseconds */
|
|
1337
|
-
timestamp: number;
|
|
1338
|
-
/** Event action type (profit or loss) */
|
|
1339
|
-
action: "profit" | "loss";
|
|
1340
|
-
/** Trading pair symbol */
|
|
1341
|
-
symbol: string;
|
|
1342
|
-
/** Strategy name */
|
|
1343
|
-
strategyName: string;
|
|
1344
|
-
/** Signal ID */
|
|
1345
|
-
signalId: string;
|
|
1346
|
-
/** Position type */
|
|
1347
|
-
position: string;
|
|
1348
|
-
/** Current market price */
|
|
1349
|
-
currentPrice: number;
|
|
1350
|
-
/** Profit/loss level reached (10, 20, 30, etc) */
|
|
1351
|
-
level: PartialLevel;
|
|
1352
|
-
/** True if backtest mode, false if live mode */
|
|
1353
|
-
backtest: boolean;
|
|
1354
|
-
}
|
|
1355
|
-
/**
|
|
1356
|
-
* Statistical data calculated from partial profit/loss events.
|
|
1357
|
-
*
|
|
1358
|
-
* Provides metrics for partial profit/loss milestone tracking.
|
|
1359
|
-
*
|
|
1360
|
-
* @example
|
|
1361
|
-
* ```typescript
|
|
1362
|
-
* const stats = await Partial.getData("BTCUSDT", "my-strategy");
|
|
1363
|
-
*
|
|
1364
|
-
* console.log(`Total events: ${stats.totalEvents}`);
|
|
1365
|
-
* console.log(`Profit events: ${stats.totalProfit}`);
|
|
1366
|
-
* console.log(`Loss events: ${stats.totalLoss}`);
|
|
1367
|
-
* ```
|
|
1368
|
-
*/
|
|
1369
|
-
interface PartialStatisticsModel {
|
|
1370
|
-
/** Array of all profit/loss events with full details */
|
|
1371
|
-
eventList: PartialEvent[];
|
|
1372
|
-
/** Total number of all events (includes profit, loss) */
|
|
1373
|
-
totalEvents: number;
|
|
1374
|
-
/** Total number of profit events */
|
|
1375
|
-
totalProfit: number;
|
|
1376
|
-
/** Total number of loss events */
|
|
1377
|
-
totalLoss: number;
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
/**
|
|
1381
|
-
* Unified tick event data for report generation.
|
|
1382
|
-
* Contains all information about a tick event regardless of action type.
|
|
1383
|
-
*/
|
|
1384
|
-
interface TickEvent {
|
|
1385
|
-
/** Event timestamp in milliseconds (pendingAt for opened/closed events) */
|
|
1386
|
-
timestamp: number;
|
|
1387
|
-
/** Event action type */
|
|
1388
|
-
action: "idle" | "opened" | "active" | "closed";
|
|
1389
|
-
/** Trading pair symbol (only for non-idle events) */
|
|
1390
|
-
symbol?: string;
|
|
1391
|
-
/** Signal ID (only for opened/active/closed) */
|
|
1392
|
-
signalId?: string;
|
|
1393
|
-
/** Position type (only for opened/active/closed) */
|
|
1394
|
-
position?: string;
|
|
1395
|
-
/** Signal note (only for opened/active/closed) */
|
|
1396
|
-
note?: string;
|
|
1397
|
-
/** Current price */
|
|
1398
|
-
currentPrice: number;
|
|
1399
|
-
/** Open price (only for opened/active/closed) */
|
|
1400
|
-
openPrice?: number;
|
|
1401
|
-
/** Take profit price (only for opened/active/closed) */
|
|
1402
|
-
takeProfit?: number;
|
|
1403
|
-
/** Stop loss price (only for opened/active/closed) */
|
|
1404
|
-
stopLoss?: number;
|
|
1405
|
-
/** Percentage progress towards take profit (only for active) */
|
|
1406
|
-
percentTp?: number;
|
|
1407
|
-
/** Percentage progress towards stop loss (only for active) */
|
|
1408
|
-
percentSl?: number;
|
|
1409
|
-
/** PNL percentage (only for closed) */
|
|
1410
|
-
pnl?: number;
|
|
1411
|
-
/** Close reason (only for closed) */
|
|
1412
|
-
closeReason?: string;
|
|
1413
|
-
/** Duration in minutes (only for closed) */
|
|
1414
|
-
duration?: number;
|
|
1415
|
-
}
|
|
1416
|
-
/**
|
|
1417
|
-
* Statistical data calculated from live trading results.
|
|
1418
|
-
*
|
|
1419
|
-
* All numeric values are null if calculation is unsafe (NaN, Infinity, etc).
|
|
1420
|
-
* Provides comprehensive metrics for live trading performance analysis.
|
|
1421
|
-
*
|
|
1422
|
-
* @example
|
|
1423
|
-
* ```typescript
|
|
1424
|
-
* const stats = await Live.getData("my-strategy");
|
|
1425
|
-
*
|
|
1426
|
-
* console.log(`Total events: ${stats.totalEvents}`);
|
|
1427
|
-
* console.log(`Closed signals: ${stats.totalClosed}`);
|
|
1428
|
-
* console.log(`Win rate: ${stats.winRate}%`);
|
|
1429
|
-
* console.log(`Sharpe Ratio: ${stats.sharpeRatio}`);
|
|
1430
|
-
*
|
|
1431
|
-
* // Access raw event data (includes idle, opened, active, closed)
|
|
1432
|
-
* stats.eventList.forEach(event => {
|
|
1433
|
-
* if (event.action === "closed") {
|
|
1434
|
-
* console.log(`Closed signal: ${event.pnl}%`);
|
|
1435
|
-
* }
|
|
1436
|
-
* });
|
|
1437
|
-
* ```
|
|
1438
|
-
*/
|
|
1439
|
-
interface LiveStatisticsModel {
|
|
1440
|
-
/** Array of all events (idle, opened, active, closed) with full details */
|
|
1441
|
-
eventList: TickEvent[];
|
|
1442
|
-
/** Total number of all events (includes idle, opened, active, closed) */
|
|
1443
|
-
totalEvents: number;
|
|
1444
|
-
/** Total number of closed signals only */
|
|
1445
|
-
totalClosed: number;
|
|
1446
|
-
/** Number of winning closed signals (PNL > 0) */
|
|
1447
|
-
winCount: number;
|
|
1448
|
-
/** Number of losing closed signals (PNL < 0) */
|
|
1449
|
-
lossCount: number;
|
|
1450
|
-
/** Win rate as percentage (0-100) based on closed signals, null if unsafe. Higher is better. */
|
|
1451
|
-
winRate: number | null;
|
|
1452
|
-
/** Average PNL per closed signal as percentage, null if unsafe. Higher is better. */
|
|
1453
|
-
avgPnl: number | null;
|
|
1454
|
-
/** Cumulative PNL across all closed signals as percentage, null if unsafe. Higher is better. */
|
|
1455
|
-
totalPnl: number | null;
|
|
1456
|
-
/** Standard deviation of returns (volatility metric), null if unsafe. Lower is better. */
|
|
1457
|
-
stdDev: number | null;
|
|
1458
|
-
/** Sharpe Ratio (risk-adjusted return = avgPnl / stdDev), null if unsafe. Higher is better. */
|
|
1459
|
-
sharpeRatio: number | null;
|
|
1460
|
-
/** Annualized Sharpe Ratio (sharpeRatio × √365), null if unsafe. Higher is better. */
|
|
1461
|
-
annualizedSharpeRatio: number | null;
|
|
1462
|
-
/** Certainty Ratio (avgWin / |avgLoss|), null if unsafe. Higher is better. */
|
|
1463
|
-
certaintyRatio: number | null;
|
|
1464
|
-
/** Expected yearly returns based on average trade duration and PNL, null if unsafe. Higher is better. */
|
|
1465
|
-
expectedYearlyReturns: number | null;
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
1115
|
declare const GLOBAL_CONFIG: {
|
|
1469
1116
|
/**
|
|
1470
1117
|
* Time to wait for scheduled signal to activate (in minutes)
|
|
@@ -3068,12 +2715,59 @@ interface ProgressOptimizerContract {
|
|
|
3068
2715
|
optimizerName: string;
|
|
3069
2716
|
/** symbol - Trading symbol (e.g., "BTCUSDT") */
|
|
3070
2717
|
symbol: string;
|
|
3071
|
-
/** totalSources - Total number of sources to process */
|
|
3072
|
-
totalSources: number;
|
|
3073
|
-
/** processedSources - Number of sources processed so far */
|
|
3074
|
-
processedSources: number;
|
|
3075
|
-
/** progress - Completion percentage from 0.0 to 1.0 */
|
|
3076
|
-
progress: number;
|
|
2718
|
+
/** totalSources - Total number of sources to process */
|
|
2719
|
+
totalSources: number;
|
|
2720
|
+
/** processedSources - Number of sources processed so far */
|
|
2721
|
+
processedSources: number;
|
|
2722
|
+
/** progress - Completion percentage from 0.0 to 1.0 */
|
|
2723
|
+
progress: number;
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
/**
|
|
2727
|
+
* Performance metric types tracked by the system.
|
|
2728
|
+
*
|
|
2729
|
+
* Backtest metrics:
|
|
2730
|
+
* - backtest_total: Total backtest duration from start to finish
|
|
2731
|
+
* - backtest_timeframe: Duration to process a single timeframe iteration
|
|
2732
|
+
* - backtest_signal: Duration to process a signal (tick + getNextCandles + backtest)
|
|
2733
|
+
*
|
|
2734
|
+
* Live metrics:
|
|
2735
|
+
* - live_tick: Duration of a single live tick iteration
|
|
2736
|
+
*/
|
|
2737
|
+
type PerformanceMetricType = "backtest_total" | "backtest_timeframe" | "backtest_signal" | "live_tick";
|
|
2738
|
+
/**
|
|
2739
|
+
* Contract for performance tracking events.
|
|
2740
|
+
*
|
|
2741
|
+
* Emitted during execution to track performance metrics for various operations.
|
|
2742
|
+
* Useful for profiling and identifying bottlenecks.
|
|
2743
|
+
*
|
|
2744
|
+
* @example
|
|
2745
|
+
* ```typescript
|
|
2746
|
+
* import { listenPerformance } from "backtest-kit";
|
|
2747
|
+
*
|
|
2748
|
+
* listenPerformance((event) => {
|
|
2749
|
+
* console.log(`${event.metricType}: ${event.duration.toFixed(2)}ms`);
|
|
2750
|
+
* console.log(`${event.strategyName} @ ${event.exchangeName}`);
|
|
2751
|
+
* });
|
|
2752
|
+
* ```
|
|
2753
|
+
*/
|
|
2754
|
+
interface PerformanceContract {
|
|
2755
|
+
/** Timestamp when the metric was recorded (milliseconds since epoch) */
|
|
2756
|
+
timestamp: number;
|
|
2757
|
+
/** Timestamp of the previous event (milliseconds since epoch, null for first event) */
|
|
2758
|
+
previousTimestamp: number | null;
|
|
2759
|
+
/** Type of operation being measured */
|
|
2760
|
+
metricType: PerformanceMetricType;
|
|
2761
|
+
/** Duration of the operation in milliseconds */
|
|
2762
|
+
duration: number;
|
|
2763
|
+
/** Strategy name associated with this metric */
|
|
2764
|
+
strategyName: string;
|
|
2765
|
+
/** Exchange name associated with this metric */
|
|
2766
|
+
exchangeName: string;
|
|
2767
|
+
/** Trading symbol associated with this metric */
|
|
2768
|
+
symbol: string;
|
|
2769
|
+
/** Whether this metric is from backtest mode (true) or live mode (false) */
|
|
2770
|
+
backtest: boolean;
|
|
3077
2771
|
}
|
|
3078
2772
|
|
|
3079
2773
|
/**
|
|
@@ -4342,123 +4036,429 @@ declare function getMode(): Promise<"backtest" | "live">;
|
|
|
4342
4036
|
* { role: "assistant", content: "Structure analyzed" }
|
|
4343
4037
|
* );
|
|
4344
4038
|
*
|
|
4345
|
-
* // Request signal
|
|
4346
|
-
* messages.push({
|
|
4347
|
-
* role: "user",
|
|
4348
|
-
* content: "Generate trading signal. Use position: 'wait' if uncertain."
|
|
4349
|
-
* });
|
|
4039
|
+
* // Request signal
|
|
4040
|
+
* messages.push({
|
|
4041
|
+
* role: "user",
|
|
4042
|
+
* content: "Generate trading signal. Use position: 'wait' if uncertain."
|
|
4043
|
+
* });
|
|
4044
|
+
*
|
|
4045
|
+
* const resultId = uuid();
|
|
4046
|
+
* const signal = await llmRequest(messages);
|
|
4047
|
+
*
|
|
4048
|
+
* // Save conversation and result for debugging
|
|
4049
|
+
* await dumpSignal(resultId, messages, signal);
|
|
4050
|
+
*
|
|
4051
|
+
* return signal;
|
|
4052
|
+
* }
|
|
4053
|
+
* });
|
|
4054
|
+
*
|
|
4055
|
+
* // Creates: ./dump/strategy/{uuid}/00_system_prompt.md
|
|
4056
|
+
* // ./dump/strategy/{uuid}/01_user_message.md (1h analysis)
|
|
4057
|
+
* // ./dump/strategy/{uuid}/02_assistant_message.md
|
|
4058
|
+
* // ./dump/strategy/{uuid}/03_user_message.md (5m analysis)
|
|
4059
|
+
* // ./dump/strategy/{uuid}/04_assistant_message.md
|
|
4060
|
+
* // ./dump/strategy/{uuid}/05_user_message.md (signal request)
|
|
4061
|
+
* // ./dump/strategy/{uuid}/06_llm_output.md (final signal)
|
|
4062
|
+
* ```
|
|
4063
|
+
*/
|
|
4064
|
+
declare function dumpSignal(signalId: string | number, history: MessageModel[], signal: ISignalDto, outputDir?: string): Promise<void>;
|
|
4065
|
+
|
|
4066
|
+
/**
|
|
4067
|
+
* Portfolio heatmap statistics for a single symbol.
|
|
4068
|
+
* Aggregated metrics across all strategies for one trading pair.
|
|
4069
|
+
*/
|
|
4070
|
+
interface IHeatmapRow {
|
|
4071
|
+
/** Trading pair symbol (e.g., "BTCUSDT") */
|
|
4072
|
+
symbol: string;
|
|
4073
|
+
/** Total profit/loss percentage across all closed trades */
|
|
4074
|
+
totalPnl: number | null;
|
|
4075
|
+
/** Risk-adjusted return (Sharpe Ratio) */
|
|
4076
|
+
sharpeRatio: number | null;
|
|
4077
|
+
/** Maximum drawdown percentage (largest peak-to-trough decline) */
|
|
4078
|
+
maxDrawdown: number | null;
|
|
4079
|
+
/** Total number of closed trades */
|
|
4080
|
+
totalTrades: number;
|
|
4081
|
+
/** Number of winning trades */
|
|
4082
|
+
winCount: number;
|
|
4083
|
+
/** Number of losing trades */
|
|
4084
|
+
lossCount: number;
|
|
4085
|
+
/** Win rate percentage */
|
|
4086
|
+
winRate: number | null;
|
|
4087
|
+
/** Average PNL per trade */
|
|
4088
|
+
avgPnl: number | null;
|
|
4089
|
+
/** Standard deviation of PNL */
|
|
4090
|
+
stdDev: number | null;
|
|
4091
|
+
/** Profit factor: sum of wins / sum of losses */
|
|
4092
|
+
profitFactor: number | null;
|
|
4093
|
+
/** Average profit percentage on winning trades */
|
|
4094
|
+
avgWin: number | null;
|
|
4095
|
+
/** Average loss percentage on losing trades */
|
|
4096
|
+
avgLoss: number | null;
|
|
4097
|
+
/** Maximum consecutive winning trades */
|
|
4098
|
+
maxWinStreak: number;
|
|
4099
|
+
/** Maximum consecutive losing trades */
|
|
4100
|
+
maxLossStreak: number;
|
|
4101
|
+
/** Expectancy: (winRate * avgWin) - (lossRate * avgLoss) */
|
|
4102
|
+
expectancy: number | null;
|
|
4103
|
+
}
|
|
4104
|
+
|
|
4105
|
+
/**
|
|
4106
|
+
* Column configuration for markdown table generation.
|
|
4107
|
+
* Generic interface that defines how to extract and format data from any data type.
|
|
4108
|
+
*
|
|
4109
|
+
* @template T - The data type that this column will format
|
|
4110
|
+
*
|
|
4111
|
+
* @example
|
|
4112
|
+
* ```typescript
|
|
4113
|
+
* // Column for formatting signal data
|
|
4114
|
+
* const signalColumn: ColumnModel<IStrategyTickResultClosed> = {
|
|
4115
|
+
* key: "pnl",
|
|
4116
|
+
* label: "PNL",
|
|
4117
|
+
* format: (signal) => `${signal.pnl.pnlPercentage.toFixed(2)}%`,
|
|
4118
|
+
* isVisible: () => true
|
|
4119
|
+
* };
|
|
4120
|
+
*
|
|
4121
|
+
* // Column for formatting heatmap rows
|
|
4122
|
+
* const heatmapColumn: ColumnModel<IHeatmapRow> = {
|
|
4123
|
+
* key: "symbol",
|
|
4124
|
+
* label: "Symbol",
|
|
4125
|
+
* format: (row) => row.symbol,
|
|
4126
|
+
* isVisible: () => true
|
|
4127
|
+
* };
|
|
4128
|
+
* ```
|
|
4129
|
+
*/
|
|
4130
|
+
interface ColumnModel<T extends object = any> {
|
|
4131
|
+
/** Unique column identifier */
|
|
4132
|
+
key: string;
|
|
4133
|
+
/** Display label for column header */
|
|
4134
|
+
label: string;
|
|
4135
|
+
/** Formatting function to convert data to string */
|
|
4136
|
+
format: (data: T, index: number) => string | Promise<string>;
|
|
4137
|
+
/** Function to determine if column should be visible */
|
|
4138
|
+
isVisible: () => boolean | Promise<boolean>;
|
|
4139
|
+
}
|
|
4140
|
+
|
|
4141
|
+
/**
|
|
4142
|
+
* Unified tick event data for report generation.
|
|
4143
|
+
* Contains all information about a tick event regardless of action type.
|
|
4144
|
+
*/
|
|
4145
|
+
interface TickEvent {
|
|
4146
|
+
/** Event timestamp in milliseconds (pendingAt for opened/closed events) */
|
|
4147
|
+
timestamp: number;
|
|
4148
|
+
/** Event action type */
|
|
4149
|
+
action: "idle" | "opened" | "active" | "closed";
|
|
4150
|
+
/** Trading pair symbol (only for non-idle events) */
|
|
4151
|
+
symbol?: string;
|
|
4152
|
+
/** Signal ID (only for opened/active/closed) */
|
|
4153
|
+
signalId?: string;
|
|
4154
|
+
/** Position type (only for opened/active/closed) */
|
|
4155
|
+
position?: string;
|
|
4156
|
+
/** Signal note (only for opened/active/closed) */
|
|
4157
|
+
note?: string;
|
|
4158
|
+
/** Current price */
|
|
4159
|
+
currentPrice: number;
|
|
4160
|
+
/** Open price (only for opened/active/closed) */
|
|
4161
|
+
openPrice?: number;
|
|
4162
|
+
/** Take profit price (only for opened/active/closed) */
|
|
4163
|
+
takeProfit?: number;
|
|
4164
|
+
/** Stop loss price (only for opened/active/closed) */
|
|
4165
|
+
stopLoss?: number;
|
|
4166
|
+
/** Percentage progress towards take profit (only for active) */
|
|
4167
|
+
percentTp?: number;
|
|
4168
|
+
/** Percentage progress towards stop loss (only for active) */
|
|
4169
|
+
percentSl?: number;
|
|
4170
|
+
/** PNL percentage (only for closed) */
|
|
4171
|
+
pnl?: number;
|
|
4172
|
+
/** Close reason (only for closed) */
|
|
4173
|
+
closeReason?: string;
|
|
4174
|
+
/** Duration in minutes (only for closed) */
|
|
4175
|
+
duration?: number;
|
|
4176
|
+
}
|
|
4177
|
+
/**
|
|
4178
|
+
* Statistical data calculated from live trading results.
|
|
4179
|
+
*
|
|
4180
|
+
* All numeric values are null if calculation is unsafe (NaN, Infinity, etc).
|
|
4181
|
+
* Provides comprehensive metrics for live trading performance analysis.
|
|
4182
|
+
*
|
|
4183
|
+
* @example
|
|
4184
|
+
* ```typescript
|
|
4185
|
+
* const stats = await Live.getData("my-strategy");
|
|
4186
|
+
*
|
|
4187
|
+
* console.log(`Total events: ${stats.totalEvents}`);
|
|
4188
|
+
* console.log(`Closed signals: ${stats.totalClosed}`);
|
|
4189
|
+
* console.log(`Win rate: ${stats.winRate}%`);
|
|
4190
|
+
* console.log(`Sharpe Ratio: ${stats.sharpeRatio}`);
|
|
4191
|
+
*
|
|
4192
|
+
* // Access raw event data (includes idle, opened, active, closed)
|
|
4193
|
+
* stats.eventList.forEach(event => {
|
|
4194
|
+
* if (event.action === "closed") {
|
|
4195
|
+
* console.log(`Closed signal: ${event.pnl}%`);
|
|
4196
|
+
* }
|
|
4197
|
+
* });
|
|
4198
|
+
* ```
|
|
4199
|
+
*/
|
|
4200
|
+
interface LiveStatisticsModel {
|
|
4201
|
+
/** Array of all events (idle, opened, active, closed) with full details */
|
|
4202
|
+
eventList: TickEvent[];
|
|
4203
|
+
/** Total number of all events (includes idle, opened, active, closed) */
|
|
4204
|
+
totalEvents: number;
|
|
4205
|
+
/** Total number of closed signals only */
|
|
4206
|
+
totalClosed: number;
|
|
4207
|
+
/** Number of winning closed signals (PNL > 0) */
|
|
4208
|
+
winCount: number;
|
|
4209
|
+
/** Number of losing closed signals (PNL < 0) */
|
|
4210
|
+
lossCount: number;
|
|
4211
|
+
/** Win rate as percentage (0-100) based on closed signals, null if unsafe. Higher is better. */
|
|
4212
|
+
winRate: number | null;
|
|
4213
|
+
/** Average PNL per closed signal as percentage, null if unsafe. Higher is better. */
|
|
4214
|
+
avgPnl: number | null;
|
|
4215
|
+
/** Cumulative PNL across all closed signals as percentage, null if unsafe. Higher is better. */
|
|
4216
|
+
totalPnl: number | null;
|
|
4217
|
+
/** Standard deviation of returns (volatility metric), null if unsafe. Lower is better. */
|
|
4218
|
+
stdDev: number | null;
|
|
4219
|
+
/** Sharpe Ratio (risk-adjusted return = avgPnl / stdDev), null if unsafe. Higher is better. */
|
|
4220
|
+
sharpeRatio: number | null;
|
|
4221
|
+
/** Annualized Sharpe Ratio (sharpeRatio × √365), null if unsafe. Higher is better. */
|
|
4222
|
+
annualizedSharpeRatio: number | null;
|
|
4223
|
+
/** Certainty Ratio (avgWin / |avgLoss|), null if unsafe. Higher is better. */
|
|
4224
|
+
certaintyRatio: number | null;
|
|
4225
|
+
/** Expected yearly returns based on average trade duration and PNL, null if unsafe. Higher is better. */
|
|
4226
|
+
expectedYearlyReturns: number | null;
|
|
4227
|
+
}
|
|
4228
|
+
|
|
4229
|
+
/**
|
|
4230
|
+
* Portfolio heatmap statistics structure.
|
|
4231
|
+
* Contains aggregated data for all symbols in the portfolio.
|
|
4232
|
+
*/
|
|
4233
|
+
interface HeatmapStatisticsModel {
|
|
4234
|
+
/** Array of symbol statistics */
|
|
4235
|
+
symbols: IHeatmapRow[];
|
|
4236
|
+
/** Total number of symbols tracked */
|
|
4237
|
+
totalSymbols: number;
|
|
4238
|
+
/** Portfolio-wide total PNL */
|
|
4239
|
+
portfolioTotalPnl: number | null;
|
|
4240
|
+
/** Portfolio-wide Sharpe Ratio */
|
|
4241
|
+
portfolioSharpeRatio: number | null;
|
|
4242
|
+
/** Portfolio-wide total trades */
|
|
4243
|
+
portfolioTotalTrades: number;
|
|
4244
|
+
}
|
|
4245
|
+
|
|
4246
|
+
/**
|
|
4247
|
+
* Unified scheduled signal event data for report generation.
|
|
4248
|
+
* Contains all information about scheduled, opened and cancelled events.
|
|
4249
|
+
*/
|
|
4250
|
+
interface ScheduledEvent {
|
|
4251
|
+
/** Event timestamp in milliseconds (scheduledAt for scheduled/cancelled events) */
|
|
4252
|
+
timestamp: number;
|
|
4253
|
+
/** Event action type */
|
|
4254
|
+
action: "scheduled" | "opened" | "cancelled";
|
|
4255
|
+
/** Trading pair symbol */
|
|
4256
|
+
symbol: string;
|
|
4257
|
+
/** Signal ID */
|
|
4258
|
+
signalId: string;
|
|
4259
|
+
/** Position type */
|
|
4260
|
+
position: string;
|
|
4261
|
+
/** Signal note */
|
|
4262
|
+
note?: string;
|
|
4263
|
+
/** Current market price */
|
|
4264
|
+
currentPrice: number;
|
|
4265
|
+
/** Scheduled entry price */
|
|
4266
|
+
priceOpen: number;
|
|
4267
|
+
/** Take profit price */
|
|
4268
|
+
takeProfit: number;
|
|
4269
|
+
/** Stop loss price */
|
|
4270
|
+
stopLoss: number;
|
|
4271
|
+
/** Close timestamp (only for cancelled) */
|
|
4272
|
+
closeTimestamp?: number;
|
|
4273
|
+
/** Duration in minutes (only for cancelled/opened) */
|
|
4274
|
+
duration?: number;
|
|
4275
|
+
}
|
|
4276
|
+
/**
|
|
4277
|
+
* Statistical data calculated from scheduled signals.
|
|
4278
|
+
*
|
|
4279
|
+
* Provides metrics for scheduled signal tracking, activation and cancellation analysis.
|
|
4350
4280
|
*
|
|
4351
|
-
*
|
|
4352
|
-
*
|
|
4281
|
+
* @example
|
|
4282
|
+
* ```typescript
|
|
4283
|
+
* const stats = await Schedule.getData("my-strategy");
|
|
4353
4284
|
*
|
|
4354
|
-
*
|
|
4355
|
-
*
|
|
4285
|
+
* console.log(`Total events: ${stats.totalEvents}`);
|
|
4286
|
+
* console.log(`Scheduled signals: ${stats.totalScheduled}`);
|
|
4287
|
+
* console.log(`Opened signals: ${stats.totalOpened}`);
|
|
4288
|
+
* console.log(`Cancelled signals: ${stats.totalCancelled}`);
|
|
4289
|
+
* console.log(`Cancellation rate: ${stats.cancellationRate}%`);
|
|
4356
4290
|
*
|
|
4357
|
-
*
|
|
4291
|
+
* // Access raw event data (includes scheduled, opened, cancelled)
|
|
4292
|
+
* stats.eventList.forEach(event => {
|
|
4293
|
+
* if (event.action === "cancelled") {
|
|
4294
|
+
* console.log(`Cancelled signal: ${event.signalId}`);
|
|
4358
4295
|
* }
|
|
4359
4296
|
* });
|
|
4360
|
-
*
|
|
4361
|
-
* // Creates: ./dump/strategy/{uuid}/00_system_prompt.md
|
|
4362
|
-
* // ./dump/strategy/{uuid}/01_user_message.md (1h analysis)
|
|
4363
|
-
* // ./dump/strategy/{uuid}/02_assistant_message.md
|
|
4364
|
-
* // ./dump/strategy/{uuid}/03_user_message.md (5m analysis)
|
|
4365
|
-
* // ./dump/strategy/{uuid}/04_assistant_message.md
|
|
4366
|
-
* // ./dump/strategy/{uuid}/05_user_message.md (signal request)
|
|
4367
|
-
* // ./dump/strategy/{uuid}/06_llm_output.md (final signal)
|
|
4368
4297
|
* ```
|
|
4369
4298
|
*/
|
|
4370
|
-
|
|
4299
|
+
interface ScheduleStatisticsModel {
|
|
4300
|
+
/** Array of all scheduled/opened/cancelled events with full details */
|
|
4301
|
+
eventList: ScheduledEvent[];
|
|
4302
|
+
/** Total number of all events (includes scheduled, opened, cancelled) */
|
|
4303
|
+
totalEvents: number;
|
|
4304
|
+
/** Total number of scheduled signals */
|
|
4305
|
+
totalScheduled: number;
|
|
4306
|
+
/** Total number of opened signals (activated from scheduled) */
|
|
4307
|
+
totalOpened: number;
|
|
4308
|
+
/** Total number of cancelled signals */
|
|
4309
|
+
totalCancelled: number;
|
|
4310
|
+
/** Cancellation rate as percentage (0-100), null if no scheduled signals. Lower is better. */
|
|
4311
|
+
cancellationRate: number | null;
|
|
4312
|
+
/** Activation rate as percentage (0-100), null if no scheduled signals. Higher is better. */
|
|
4313
|
+
activationRate: number | null;
|
|
4314
|
+
/** Average waiting time for cancelled signals in minutes, null if no cancelled signals */
|
|
4315
|
+
avgWaitTime: number | null;
|
|
4316
|
+
/** Average waiting time for opened signals in minutes, null if no opened signals */
|
|
4317
|
+
avgActivationTime: number | null;
|
|
4318
|
+
}
|
|
4371
4319
|
|
|
4372
4320
|
/**
|
|
4373
|
-
*
|
|
4374
|
-
* Aggregated metrics across all strategies for one trading pair.
|
|
4321
|
+
* Aggregated statistics for a specific metric type.
|
|
4375
4322
|
*/
|
|
4376
|
-
interface
|
|
4377
|
-
/**
|
|
4378
|
-
|
|
4379
|
-
/**
|
|
4380
|
-
|
|
4381
|
-
/**
|
|
4382
|
-
|
|
4383
|
-
/**
|
|
4384
|
-
|
|
4385
|
-
/**
|
|
4386
|
-
|
|
4387
|
-
/**
|
|
4388
|
-
|
|
4389
|
-
/**
|
|
4390
|
-
|
|
4391
|
-
/**
|
|
4392
|
-
|
|
4393
|
-
/**
|
|
4394
|
-
|
|
4395
|
-
/**
|
|
4396
|
-
|
|
4397
|
-
/**
|
|
4398
|
-
|
|
4399
|
-
/**
|
|
4400
|
-
|
|
4401
|
-
/**
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4323
|
+
interface MetricStats {
|
|
4324
|
+
/** Type of metric */
|
|
4325
|
+
metricType: PerformanceMetricType;
|
|
4326
|
+
/** Number of recorded samples */
|
|
4327
|
+
count: number;
|
|
4328
|
+
/** Total duration across all samples (ms) */
|
|
4329
|
+
totalDuration: number;
|
|
4330
|
+
/** Average duration (ms) */
|
|
4331
|
+
avgDuration: number;
|
|
4332
|
+
/** Minimum duration (ms) */
|
|
4333
|
+
minDuration: number;
|
|
4334
|
+
/** Maximum duration (ms) */
|
|
4335
|
+
maxDuration: number;
|
|
4336
|
+
/** Standard deviation of duration (ms) */
|
|
4337
|
+
stdDev: number;
|
|
4338
|
+
/** Median duration (ms) */
|
|
4339
|
+
median: number;
|
|
4340
|
+
/** 95th percentile duration (ms) */
|
|
4341
|
+
p95: number;
|
|
4342
|
+
/** 99th percentile duration (ms) */
|
|
4343
|
+
p99: number;
|
|
4344
|
+
/** Average wait time between events (ms) */
|
|
4345
|
+
avgWaitTime: number;
|
|
4346
|
+
/** Minimum wait time between events (ms) */
|
|
4347
|
+
minWaitTime: number;
|
|
4348
|
+
/** Maximum wait time between events (ms) */
|
|
4349
|
+
maxWaitTime: number;
|
|
4350
|
+
}
|
|
4351
|
+
/**
|
|
4352
|
+
* Performance statistics aggregated by strategy.
|
|
4353
|
+
*/
|
|
4354
|
+
interface PerformanceStatisticsModel {
|
|
4355
|
+
/** Strategy name */
|
|
4356
|
+
strategyName: string;
|
|
4357
|
+
/** Total number of performance events recorded */
|
|
4358
|
+
totalEvents: number;
|
|
4359
|
+
/** Total execution time across all metrics (ms) */
|
|
4360
|
+
totalDuration: number;
|
|
4361
|
+
/** Statistics grouped by metric type */
|
|
4362
|
+
metricStats: Record<string, MetricStats>;
|
|
4363
|
+
/** All raw performance events */
|
|
4364
|
+
events: PerformanceContract[];
|
|
4409
4365
|
}
|
|
4410
4366
|
|
|
4411
4367
|
/**
|
|
4412
|
-
*
|
|
4413
|
-
*
|
|
4368
|
+
* Unified partial profit/loss event data for report generation.
|
|
4369
|
+
* Contains all information about profit and loss level milestones.
|
|
4370
|
+
*/
|
|
4371
|
+
interface PartialEvent {
|
|
4372
|
+
/** Event timestamp in milliseconds */
|
|
4373
|
+
timestamp: number;
|
|
4374
|
+
/** Event action type (profit or loss) */
|
|
4375
|
+
action: "profit" | "loss";
|
|
4376
|
+
/** Trading pair symbol */
|
|
4377
|
+
symbol: string;
|
|
4378
|
+
/** Strategy name */
|
|
4379
|
+
strategyName: string;
|
|
4380
|
+
/** Signal ID */
|
|
4381
|
+
signalId: string;
|
|
4382
|
+
/** Position type */
|
|
4383
|
+
position: string;
|
|
4384
|
+
/** Current market price */
|
|
4385
|
+
currentPrice: number;
|
|
4386
|
+
/** Profit/loss level reached (10, 20, 30, etc) */
|
|
4387
|
+
level: PartialLevel;
|
|
4388
|
+
/** True if backtest mode, false if live mode */
|
|
4389
|
+
backtest: boolean;
|
|
4390
|
+
}
|
|
4391
|
+
/**
|
|
4392
|
+
* Statistical data calculated from partial profit/loss events.
|
|
4414
4393
|
*
|
|
4415
|
-
*
|
|
4394
|
+
* Provides metrics for partial profit/loss milestone tracking.
|
|
4416
4395
|
*
|
|
4417
4396
|
* @example
|
|
4418
4397
|
* ```typescript
|
|
4419
|
-
*
|
|
4420
|
-
* const signalColumn: ColumnModel<IStrategyTickResultClosed> = {
|
|
4421
|
-
* key: "pnl",
|
|
4422
|
-
* label: "PNL",
|
|
4423
|
-
* format: (signal) => `${signal.pnl.pnlPercentage.toFixed(2)}%`,
|
|
4424
|
-
* isVisible: () => true
|
|
4425
|
-
* };
|
|
4398
|
+
* const stats = await Partial.getData("BTCUSDT", "my-strategy");
|
|
4426
4399
|
*
|
|
4427
|
-
*
|
|
4428
|
-
*
|
|
4429
|
-
*
|
|
4430
|
-
* label: "Symbol",
|
|
4431
|
-
* format: (row) => row.symbol,
|
|
4432
|
-
* isVisible: () => true
|
|
4433
|
-
* };
|
|
4400
|
+
* console.log(`Total events: ${stats.totalEvents}`);
|
|
4401
|
+
* console.log(`Profit events: ${stats.totalProfit}`);
|
|
4402
|
+
* console.log(`Loss events: ${stats.totalLoss}`);
|
|
4434
4403
|
* ```
|
|
4435
4404
|
*/
|
|
4436
|
-
interface
|
|
4437
|
-
/**
|
|
4438
|
-
|
|
4439
|
-
/**
|
|
4440
|
-
|
|
4441
|
-
/**
|
|
4442
|
-
|
|
4443
|
-
/**
|
|
4444
|
-
|
|
4405
|
+
interface PartialStatisticsModel {
|
|
4406
|
+
/** Array of all profit/loss events with full details */
|
|
4407
|
+
eventList: PartialEvent[];
|
|
4408
|
+
/** Total number of all events (includes profit, loss) */
|
|
4409
|
+
totalEvents: number;
|
|
4410
|
+
/** Total number of profit events */
|
|
4411
|
+
totalProfit: number;
|
|
4412
|
+
/** Total number of loss events */
|
|
4413
|
+
totalLoss: number;
|
|
4445
4414
|
}
|
|
4446
4415
|
|
|
4447
4416
|
/**
|
|
4448
|
-
*
|
|
4449
|
-
* Contains
|
|
4417
|
+
* Risk rejection event data for report generation.
|
|
4418
|
+
* Contains all information about rejected signals due to risk limits.
|
|
4450
4419
|
*/
|
|
4451
|
-
interface
|
|
4452
|
-
/**
|
|
4453
|
-
|
|
4454
|
-
/**
|
|
4455
|
-
|
|
4456
|
-
/**
|
|
4457
|
-
|
|
4458
|
-
/**
|
|
4459
|
-
|
|
4460
|
-
/**
|
|
4461
|
-
|
|
4420
|
+
interface RiskEvent {
|
|
4421
|
+
/** Event timestamp in milliseconds */
|
|
4422
|
+
timestamp: number;
|
|
4423
|
+
/** Trading pair symbol */
|
|
4424
|
+
symbol: string;
|
|
4425
|
+
/** Pending signal details */
|
|
4426
|
+
pendingSignal: ISignalDto;
|
|
4427
|
+
/** Strategy name */
|
|
4428
|
+
strategyName: string;
|
|
4429
|
+
/** Exchange name */
|
|
4430
|
+
exchangeName: string;
|
|
4431
|
+
/** Current market price */
|
|
4432
|
+
currentPrice: number;
|
|
4433
|
+
/** Number of active positions at rejection time */
|
|
4434
|
+
activePositionCount: number;
|
|
4435
|
+
/** Rejection reason from validation note */
|
|
4436
|
+
comment: string;
|
|
4437
|
+
/** Whether this event is from backtest mode (true) or live mode (false) */
|
|
4438
|
+
backtest: boolean;
|
|
4439
|
+
}
|
|
4440
|
+
/**
|
|
4441
|
+
* Statistical data calculated from risk rejection events.
|
|
4442
|
+
*
|
|
4443
|
+
* Provides metrics for risk management tracking.
|
|
4444
|
+
*
|
|
4445
|
+
* @example
|
|
4446
|
+
* ```typescript
|
|
4447
|
+
* const stats = await Risk.getData("BTCUSDT", "my-strategy");
|
|
4448
|
+
*
|
|
4449
|
+
* console.log(`Total rejections: ${stats.totalRejections}`);
|
|
4450
|
+
* console.log(`Rejections by symbol:`, stats.bySymbol);
|
|
4451
|
+
* ```
|
|
4452
|
+
*/
|
|
4453
|
+
interface RiskStatisticsModel {
|
|
4454
|
+
/** Array of all risk rejection events with full details */
|
|
4455
|
+
eventList: RiskEvent[];
|
|
4456
|
+
/** Total number of risk rejections */
|
|
4457
|
+
totalRejections: number;
|
|
4458
|
+
/** Rejections grouped by symbol */
|
|
4459
|
+
bySymbol: Record<string, number>;
|
|
4460
|
+
/** Rejections grouped by strategy */
|
|
4461
|
+
byStrategy: Record<string, number>;
|
|
4462
4462
|
}
|
|
4463
4463
|
|
|
4464
4464
|
declare const BASE_WAIT_FOR_INIT_SYMBOL: unique symbol;
|
|
@@ -10778,4 +10778,4 @@ declare const backtest: {
|
|
|
10778
10778
|
loggerService: LoggerService;
|
|
10779
10779
|
};
|
|
10780
10780
|
|
|
10781
|
-
export { Backtest, type BacktestStatisticsModel, Cache, type CandleInterval, type ColumnConfig, type ColumnModel, Constant, 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 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 LiveStatisticsModel, type MessageModel, type MessageRole, MethodContextService, Optimizer, Partial$1 as Partial, type PartialData, type PartialLossContract, type PartialProfitContract, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, type ProgressBacktestContract, type ProgressOptimizerContract, type ProgressWalkerContract, Risk, type RiskContract, type RiskData, type RiskStatisticsModel, Schedule, type ScheduleData, type ScheduleStatisticsModel, type SignalData, type SignalInterval, type TPersistBase, type TPersistBaseCtor, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type WalkerStatisticsModel, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, 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, listenRisk, listenRiskOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, setColumns, setConfig, setLogger };
|
|
10781
|
+
export { Backtest, type BacktestStatisticsModel, Cache, type CandleInterval, type ColumnConfig, type ColumnModel, Constant, 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 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 IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, Live, type LiveStatisticsModel, type MessageModel, type MessageRole, MethodContextService, type MetricStats, Optimizer, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossContract, type PartialProfitContract, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, type ProgressBacktestContract, type ProgressOptimizerContract, type ProgressWalkerContract, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskStatisticsModel, Schedule, type ScheduleData, type ScheduleStatisticsModel, type ScheduledEvent, type SignalData, type SignalInterval, type TPersistBase, type TPersistBaseCtor, type TickEvent, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type WalkerStatisticsModel, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, 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, listenRisk, listenRiskOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, setColumns, setConfig, setLogger };
|