backtest-kit 1.11.8 → 1.11.10
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 +168 -44
- package/build/index.mjs +168 -45
- package/package.json +1 -1
- package/types.d.ts +75 -10
package/build/index.cjs
CHANGED
|
@@ -422,6 +422,13 @@ const GLOBAL_CONFIG = {
|
|
|
422
422
|
* Default: 10 minutes
|
|
423
423
|
*/
|
|
424
424
|
CC_ORDER_BOOK_TIME_OFFSET_MINUTES: 10,
|
|
425
|
+
/**
|
|
426
|
+
* Maximum depth levels for order book fetching.
|
|
427
|
+
* Specifies how many price levels to fetch from both bids and asks.
|
|
428
|
+
*
|
|
429
|
+
* Default: 20 levels
|
|
430
|
+
*/
|
|
431
|
+
CC_ORDER_BOOK_MAX_DEPTH_LEVELS: 1000,
|
|
425
432
|
};
|
|
426
433
|
const DEFAULT_CONFIG = Object.freeze({ ...GLOBAL_CONFIG });
|
|
427
434
|
|
|
@@ -891,17 +898,23 @@ class ClientExchange {
|
|
|
891
898
|
/**
|
|
892
899
|
* Fetches order book for a trading pair.
|
|
893
900
|
*
|
|
901
|
+
* Calculates time range based on execution context time (when) and
|
|
902
|
+
* CC_ORDER_BOOK_TIME_OFFSET_MINUTES, then delegates to the exchange
|
|
903
|
+
* schema implementation which may use or ignore the time range.
|
|
904
|
+
*
|
|
894
905
|
* @param symbol - Trading pair symbol
|
|
906
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
895
907
|
* @returns Promise resolving to order book data
|
|
896
908
|
* @throws Error if getOrderBook is not implemented
|
|
897
909
|
*/
|
|
898
|
-
async getOrderBook(symbol) {
|
|
910
|
+
async getOrderBook(symbol, depth = GLOBAL_CONFIG.CC_ORDER_BOOK_MAX_DEPTH_LEVELS) {
|
|
899
911
|
this.params.logger.debug("ClientExchange getOrderBook", {
|
|
900
912
|
symbol,
|
|
913
|
+
depth,
|
|
901
914
|
});
|
|
902
915
|
const to = new Date(this.params.execution.context.when.getTime());
|
|
903
916
|
const from = new Date(to.getTime() - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * 60 * 1000);
|
|
904
|
-
return await this.params.getOrderBook(symbol, from, to);
|
|
917
|
+
return await this.params.getOrderBook(symbol, depth, from, to);
|
|
905
918
|
}
|
|
906
919
|
}
|
|
907
920
|
|
|
@@ -929,8 +942,13 @@ const DEFAULT_FORMAT_PRICE_FN$1 = async (_symbol, price) => {
|
|
|
929
942
|
/**
|
|
930
943
|
* Default implementation for getOrderBook.
|
|
931
944
|
* Throws an error indicating the method is not implemented.
|
|
945
|
+
*
|
|
946
|
+
* @param _symbol - Trading pair symbol (unused)
|
|
947
|
+
* @param _depth - Maximum depth levels (unused)
|
|
948
|
+
* @param _from - Start of time range (unused - can be ignored in live implementations)
|
|
949
|
+
* @param _to - End of time range (unused - can be ignored in live implementations)
|
|
932
950
|
*/
|
|
933
|
-
const DEFAULT_GET_ORDER_BOOK_FN$1 = async (_symbol, _from, _to) => {
|
|
951
|
+
const DEFAULT_GET_ORDER_BOOK_FN$1 = async (_symbol, _depth, _from, _to) => {
|
|
934
952
|
throw new Error(`getOrderBook is not implemented for this exchange`);
|
|
935
953
|
};
|
|
936
954
|
/**
|
|
@@ -1071,15 +1089,19 @@ class ExchangeConnectionService {
|
|
|
1071
1089
|
* Fetches order book for a trading pair using configured exchange.
|
|
1072
1090
|
*
|
|
1073
1091
|
* Routes to exchange determined by methodContextService.context.exchangeName.
|
|
1092
|
+
* The ClientExchange will calculate time range and pass it to the schema
|
|
1093
|
+
* implementation, which may use (backtest) or ignore (live) the parameters.
|
|
1074
1094
|
*
|
|
1075
1095
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
1096
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
1076
1097
|
* @returns Promise resolving to order book data
|
|
1077
1098
|
*/
|
|
1078
|
-
this.getOrderBook = async (symbol) => {
|
|
1099
|
+
this.getOrderBook = async (symbol, depth) => {
|
|
1079
1100
|
this.loggerService.log("exchangeConnectionService getOrderBook", {
|
|
1080
1101
|
symbol,
|
|
1102
|
+
depth,
|
|
1081
1103
|
});
|
|
1082
|
-
return await this.getExchange(this.methodContextService.context.exchangeName).getOrderBook(symbol);
|
|
1104
|
+
return await this.getExchange(this.methodContextService.context.exchangeName).getOrderBook(symbol, depth);
|
|
1083
1105
|
};
|
|
1084
1106
|
}
|
|
1085
1107
|
}
|
|
@@ -2231,6 +2253,48 @@ const toPlainString = (content) => {
|
|
|
2231
2253
|
return text.trim();
|
|
2232
2254
|
};
|
|
2233
2255
|
|
|
2256
|
+
/**
|
|
2257
|
+
* Wraps a function to execute it outside of the current execution context if one exists.
|
|
2258
|
+
*
|
|
2259
|
+
* This utility ensures that the wrapped function runs in isolation from any existing
|
|
2260
|
+
* ExecutionContext, preventing context leakage and unintended context sharing between
|
|
2261
|
+
* async operations.
|
|
2262
|
+
*
|
|
2263
|
+
* @template T - Function type with any parameters and return type
|
|
2264
|
+
* @param {T} run - The function to be wrapped and executed outside of context
|
|
2265
|
+
* @returns {Function} A curried function that accepts the original function's parameters
|
|
2266
|
+
* and executes it outside of the current context if one exists
|
|
2267
|
+
*
|
|
2268
|
+
* @example
|
|
2269
|
+
* ```ts
|
|
2270
|
+
* const myFunction = async (param: string) => {
|
|
2271
|
+
* // This code will run outside of any ExecutionContext
|
|
2272
|
+
* return param.toUpperCase();
|
|
2273
|
+
* };
|
|
2274
|
+
*
|
|
2275
|
+
* const wrappedFunction = beginTime(myFunction);
|
|
2276
|
+
* const result = wrappedFunction('hello'); // Returns 'HELLO'
|
|
2277
|
+
* ```
|
|
2278
|
+
*
|
|
2279
|
+
* @example
|
|
2280
|
+
* ```ts
|
|
2281
|
+
* // Usage with trycatch wrapper
|
|
2282
|
+
* const safeFunction = trycatch(
|
|
2283
|
+
* beginTime(async (id: number) => {
|
|
2284
|
+
* // Function body runs isolated from parent context
|
|
2285
|
+
* return await fetchData(id);
|
|
2286
|
+
* })
|
|
2287
|
+
* );
|
|
2288
|
+
* ```
|
|
2289
|
+
*/
|
|
2290
|
+
const beginTime = (run) => (...args) => {
|
|
2291
|
+
let fn = () => run(...args);
|
|
2292
|
+
if (ExecutionContextService.hasContext()) {
|
|
2293
|
+
fn = ExecutionContextService.runOutOfContext(fn);
|
|
2294
|
+
}
|
|
2295
|
+
return fn();
|
|
2296
|
+
};
|
|
2297
|
+
|
|
2234
2298
|
const INTERVAL_MINUTES$3 = {
|
|
2235
2299
|
"1m": 1,
|
|
2236
2300
|
"3m": 3,
|
|
@@ -3330,7 +3394,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
3330
3394
|
await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, activationTime, self.params.execution.context.backtest);
|
|
3331
3395
|
return result;
|
|
3332
3396
|
};
|
|
3333
|
-
const CALL_PING_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, scheduled, timestamp, backtest) => {
|
|
3397
|
+
const CALL_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, scheduled, timestamp, backtest) => {
|
|
3334
3398
|
await ExecutionContextService.runInContext(async () => {
|
|
3335
3399
|
const publicSignal = TO_PUBLIC_SIGNAL(scheduled);
|
|
3336
3400
|
// Call system onPing callback first (emits to pingSubject)
|
|
@@ -3344,7 +3408,7 @@ const CALL_PING_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, schedu
|
|
|
3344
3408
|
symbol: symbol,
|
|
3345
3409
|
backtest: backtest,
|
|
3346
3410
|
});
|
|
3347
|
-
}, {
|
|
3411
|
+
}), {
|
|
3348
3412
|
fallback: (error) => {
|
|
3349
3413
|
const message = "ClientStrategy CALL_PING_CALLBACKS_FN thrown";
|
|
3350
3414
|
const payload = {
|
|
@@ -3356,7 +3420,7 @@ const CALL_PING_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, schedu
|
|
|
3356
3420
|
errorEmitter.next(error);
|
|
3357
3421
|
},
|
|
3358
3422
|
});
|
|
3359
|
-
const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3423
|
+
const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3360
3424
|
await ExecutionContextService.runInContext(async () => {
|
|
3361
3425
|
if (self.params.callbacks?.onActive) {
|
|
3362
3426
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3367,7 +3431,7 @@ const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, sign
|
|
|
3367
3431
|
symbol: symbol,
|
|
3368
3432
|
backtest: backtest,
|
|
3369
3433
|
});
|
|
3370
|
-
}, {
|
|
3434
|
+
}), {
|
|
3371
3435
|
fallback: (error) => {
|
|
3372
3436
|
const message = "ClientStrategy CALL_ACTIVE_CALLBACKS_FN thrown";
|
|
3373
3437
|
const payload = {
|
|
@@ -3379,7 +3443,7 @@ const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, sign
|
|
|
3379
3443
|
errorEmitter.next(error);
|
|
3380
3444
|
},
|
|
3381
3445
|
});
|
|
3382
|
-
const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3446
|
+
const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3383
3447
|
await ExecutionContextService.runInContext(async () => {
|
|
3384
3448
|
if (self.params.callbacks?.onSchedule) {
|
|
3385
3449
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3390,7 +3454,7 @@ const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, si
|
|
|
3390
3454
|
symbol: symbol,
|
|
3391
3455
|
backtest: backtest,
|
|
3392
3456
|
});
|
|
3393
|
-
}, {
|
|
3457
|
+
}), {
|
|
3394
3458
|
fallback: (error) => {
|
|
3395
3459
|
const message = "ClientStrategy CALL_SCHEDULE_CALLBACKS_FN thrown";
|
|
3396
3460
|
const payload = {
|
|
@@ -3402,7 +3466,7 @@ const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, si
|
|
|
3402
3466
|
errorEmitter.next(error);
|
|
3403
3467
|
},
|
|
3404
3468
|
});
|
|
3405
|
-
const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3469
|
+
const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3406
3470
|
await ExecutionContextService.runInContext(async () => {
|
|
3407
3471
|
if (self.params.callbacks?.onCancel) {
|
|
3408
3472
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3413,7 +3477,7 @@ const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, sign
|
|
|
3413
3477
|
symbol: symbol,
|
|
3414
3478
|
backtest: backtest,
|
|
3415
3479
|
});
|
|
3416
|
-
}, {
|
|
3480
|
+
}), {
|
|
3417
3481
|
fallback: (error) => {
|
|
3418
3482
|
const message = "ClientStrategy CALL_CANCEL_CALLBACKS_FN thrown";
|
|
3419
3483
|
const payload = {
|
|
@@ -3425,7 +3489,7 @@ const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, sign
|
|
|
3425
3489
|
errorEmitter.next(error);
|
|
3426
3490
|
},
|
|
3427
3491
|
});
|
|
3428
|
-
const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal, priceOpen, timestamp, backtest) => {
|
|
3492
|
+
const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, priceOpen, timestamp, backtest) => {
|
|
3429
3493
|
await ExecutionContextService.runInContext(async () => {
|
|
3430
3494
|
if (self.params.callbacks?.onOpen) {
|
|
3431
3495
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3436,7 +3500,7 @@ const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal
|
|
|
3436
3500
|
symbol: symbol,
|
|
3437
3501
|
backtest: backtest,
|
|
3438
3502
|
});
|
|
3439
|
-
}, {
|
|
3503
|
+
}), {
|
|
3440
3504
|
fallback: (error) => {
|
|
3441
3505
|
const message = "ClientStrategy CALL_OPEN_CALLBACKS_FN thrown";
|
|
3442
3506
|
const payload = {
|
|
@@ -3448,7 +3512,7 @@ const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal
|
|
|
3448
3512
|
errorEmitter.next(error);
|
|
3449
3513
|
},
|
|
3450
3514
|
});
|
|
3451
|
-
const CALL_CLOSE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3515
|
+
const CALL_CLOSE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3452
3516
|
await ExecutionContextService.runInContext(async () => {
|
|
3453
3517
|
if (self.params.callbacks?.onClose) {
|
|
3454
3518
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3459,7 +3523,7 @@ const CALL_CLOSE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signa
|
|
|
3459
3523
|
symbol: symbol,
|
|
3460
3524
|
backtest: backtest,
|
|
3461
3525
|
});
|
|
3462
|
-
}, {
|
|
3526
|
+
}), {
|
|
3463
3527
|
fallback: (error) => {
|
|
3464
3528
|
const message = "ClientStrategy CALL_CLOSE_CALLBACKS_FN thrown";
|
|
3465
3529
|
const payload = {
|
|
@@ -3471,7 +3535,7 @@ const CALL_CLOSE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signa
|
|
|
3471
3535
|
errorEmitter.next(error);
|
|
3472
3536
|
},
|
|
3473
3537
|
});
|
|
3474
|
-
const CALL_TICK_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, result, timestamp, backtest) => {
|
|
3538
|
+
const CALL_TICK_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, result, timestamp, backtest) => {
|
|
3475
3539
|
await ExecutionContextService.runInContext(async () => {
|
|
3476
3540
|
if (self.params.callbacks?.onTick) {
|
|
3477
3541
|
await self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3481,7 +3545,7 @@ const CALL_TICK_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, result
|
|
|
3481
3545
|
symbol: symbol,
|
|
3482
3546
|
backtest: backtest,
|
|
3483
3547
|
});
|
|
3484
|
-
}, {
|
|
3548
|
+
}), {
|
|
3485
3549
|
fallback: (error) => {
|
|
3486
3550
|
const message = "ClientStrategy CALL_TICK_CALLBACKS_FN thrown";
|
|
3487
3551
|
const payload = {
|
|
@@ -3493,7 +3557,7 @@ const CALL_TICK_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, result
|
|
|
3493
3557
|
errorEmitter.next(error);
|
|
3494
3558
|
},
|
|
3495
3559
|
});
|
|
3496
|
-
const CALL_IDLE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, currentPrice, timestamp, backtest) => {
|
|
3560
|
+
const CALL_IDLE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, currentPrice, timestamp, backtest) => {
|
|
3497
3561
|
await ExecutionContextService.runInContext(async () => {
|
|
3498
3562
|
if (self.params.callbacks?.onIdle) {
|
|
3499
3563
|
await self.params.callbacks.onIdle(self.params.execution.context.symbol, currentPrice, self.params.execution.context.backtest);
|
|
@@ -3503,7 +3567,7 @@ const CALL_IDLE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, curren
|
|
|
3503
3567
|
symbol: symbol,
|
|
3504
3568
|
backtest: backtest,
|
|
3505
3569
|
});
|
|
3506
|
-
}, {
|
|
3570
|
+
}), {
|
|
3507
3571
|
fallback: (error) => {
|
|
3508
3572
|
const message = "ClientStrategy CALL_IDLE_CALLBACKS_FN thrown";
|
|
3509
3573
|
const payload = {
|
|
@@ -3515,7 +3579,7 @@ const CALL_IDLE_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, curren
|
|
|
3515
3579
|
errorEmitter.next(error);
|
|
3516
3580
|
},
|
|
3517
3581
|
});
|
|
3518
|
-
const CALL_RISK_ADD_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, signal, timestamp, backtest) => {
|
|
3582
|
+
const CALL_RISK_ADD_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, timestamp, backtest) => {
|
|
3519
3583
|
await ExecutionContextService.runInContext(async () => {
|
|
3520
3584
|
await self.params.risk.addSignal(symbol, {
|
|
3521
3585
|
strategyName: self.params.method.context.strategyName,
|
|
@@ -3535,7 +3599,7 @@ const CALL_RISK_ADD_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, signa
|
|
|
3535
3599
|
symbol: symbol,
|
|
3536
3600
|
backtest: backtest,
|
|
3537
3601
|
});
|
|
3538
|
-
}, {
|
|
3602
|
+
}), {
|
|
3539
3603
|
fallback: (error) => {
|
|
3540
3604
|
const message = "ClientStrategy CALL_RISK_ADD_SIGNAL_FN thrown";
|
|
3541
3605
|
const payload = {
|
|
@@ -3547,7 +3611,7 @@ const CALL_RISK_ADD_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, signa
|
|
|
3547
3611
|
errorEmitter.next(error);
|
|
3548
3612
|
},
|
|
3549
3613
|
});
|
|
3550
|
-
const CALL_RISK_REMOVE_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, timestamp, backtest) => {
|
|
3614
|
+
const CALL_RISK_REMOVE_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self, symbol, timestamp, backtest) => {
|
|
3551
3615
|
await ExecutionContextService.runInContext(async () => {
|
|
3552
3616
|
await self.params.risk.removeSignal(symbol, {
|
|
3553
3617
|
strategyName: self.params.method.context.strategyName,
|
|
@@ -3560,7 +3624,7 @@ const CALL_RISK_REMOVE_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, ti
|
|
|
3560
3624
|
symbol: symbol,
|
|
3561
3625
|
backtest: backtest,
|
|
3562
3626
|
});
|
|
3563
|
-
}, {
|
|
3627
|
+
}), {
|
|
3564
3628
|
fallback: (error) => {
|
|
3565
3629
|
const message = "ClientStrategy CALL_RISK_REMOVE_SIGNAL_FN thrown";
|
|
3566
3630
|
const payload = {
|
|
@@ -3572,7 +3636,7 @@ const CALL_RISK_REMOVE_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, ti
|
|
|
3572
3636
|
errorEmitter.next(error);
|
|
3573
3637
|
},
|
|
3574
3638
|
});
|
|
3575
|
-
const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3639
|
+
const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3576
3640
|
await ExecutionContextService.runInContext(async () => {
|
|
3577
3641
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3578
3642
|
await self.params.partial.clear(symbol, publicSignal, currentPrice, backtest);
|
|
@@ -3581,7 +3645,7 @@ const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(async (self, symbol, signal,
|
|
|
3581
3645
|
symbol: symbol,
|
|
3582
3646
|
backtest: backtest,
|
|
3583
3647
|
});
|
|
3584
|
-
}, {
|
|
3648
|
+
}), {
|
|
3585
3649
|
fallback: (error) => {
|
|
3586
3650
|
const message = "ClientStrategy CALL_PARTIAL_CLEAR_FN thrown";
|
|
3587
3651
|
const payload = {
|
|
@@ -3593,7 +3657,7 @@ const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(async (self, symbol, signal,
|
|
|
3593
3657
|
errorEmitter.next(error);
|
|
3594
3658
|
},
|
|
3595
3659
|
});
|
|
3596
|
-
const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, pendingSignal, currentPrice, timestamp, backtest) => {
|
|
3660
|
+
const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self, symbol, pendingSignal, currentPrice, timestamp, backtest) => {
|
|
3597
3661
|
return await ExecutionContextService.runInContext(async () => {
|
|
3598
3662
|
return await self.params.risk.checkSignal({
|
|
3599
3663
|
pendingSignal: TO_PUBLIC_SIGNAL(pendingSignal),
|
|
@@ -3610,7 +3674,7 @@ const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, pen
|
|
|
3610
3674
|
symbol: symbol,
|
|
3611
3675
|
backtest: backtest,
|
|
3612
3676
|
});
|
|
3613
|
-
}, {
|
|
3677
|
+
}), {
|
|
3614
3678
|
defaultValue: false,
|
|
3615
3679
|
fallback: (error) => {
|
|
3616
3680
|
const message = "ClientStrategy CALL_RISK_CHECK_SIGNAL_FN thrown";
|
|
@@ -3623,7 +3687,7 @@ const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(async (self, symbol, pen
|
|
|
3623
3687
|
errorEmitter.next(error);
|
|
3624
3688
|
},
|
|
3625
3689
|
});
|
|
3626
|
-
const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, percentTp, timestamp, backtest) => {
|
|
3690
|
+
const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, percentTp, timestamp, backtest) => {
|
|
3627
3691
|
await ExecutionContextService.runInContext(async () => {
|
|
3628
3692
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3629
3693
|
await self.params.partial.profit(symbol, publicSignal, currentPrice, percentTp, backtest, new Date(timestamp));
|
|
@@ -3635,7 +3699,7 @@ const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(async (self, symb
|
|
|
3635
3699
|
symbol: symbol,
|
|
3636
3700
|
backtest: backtest,
|
|
3637
3701
|
});
|
|
3638
|
-
}, {
|
|
3702
|
+
}), {
|
|
3639
3703
|
fallback: (error) => {
|
|
3640
3704
|
const message = "ClientStrategy CALL_PARTIAL_PROFIT_CALLBACKS_FN thrown";
|
|
3641
3705
|
const payload = {
|
|
@@ -3647,7 +3711,7 @@ const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(async (self, symb
|
|
|
3647
3711
|
errorEmitter.next(error);
|
|
3648
3712
|
},
|
|
3649
3713
|
});
|
|
3650
|
-
const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, percentSl, timestamp, backtest) => {
|
|
3714
|
+
const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, percentSl, timestamp, backtest) => {
|
|
3651
3715
|
await ExecutionContextService.runInContext(async () => {
|
|
3652
3716
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3653
3717
|
await self.params.partial.loss(symbol, publicSignal, currentPrice, percentSl, backtest, new Date(timestamp));
|
|
@@ -3659,7 +3723,7 @@ const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol
|
|
|
3659
3723
|
symbol: symbol,
|
|
3660
3724
|
backtest: backtest,
|
|
3661
3725
|
});
|
|
3662
|
-
}, {
|
|
3726
|
+
}), {
|
|
3663
3727
|
fallback: (error) => {
|
|
3664
3728
|
const message = "ClientStrategy CALL_PARTIAL_LOSS_CALLBACKS_FN thrown";
|
|
3665
3729
|
const payload = {
|
|
@@ -3671,7 +3735,7 @@ const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(async (self, symbol
|
|
|
3671
3735
|
errorEmitter.next(error);
|
|
3672
3736
|
},
|
|
3673
3737
|
});
|
|
3674
|
-
const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3738
|
+
const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3675
3739
|
await ExecutionContextService.runInContext(async () => {
|
|
3676
3740
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3677
3741
|
const isBreakeven = await self.params.breakeven.check(symbol, publicSignal, currentPrice, backtest, new Date(timestamp));
|
|
@@ -3683,7 +3747,7 @@ const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(async (self, symbol, signa
|
|
|
3683
3747
|
symbol: symbol,
|
|
3684
3748
|
backtest: backtest,
|
|
3685
3749
|
});
|
|
3686
|
-
}, {
|
|
3750
|
+
}), {
|
|
3687
3751
|
fallback: (error) => {
|
|
3688
3752
|
const message = "ClientStrategy CALL_BREAKEVEN_CHECK_FN thrown";
|
|
3689
3753
|
const payload = {
|
|
@@ -3695,7 +3759,7 @@ const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(async (self, symbol, signa
|
|
|
3695
3759
|
errorEmitter.next(error);
|
|
3696
3760
|
},
|
|
3697
3761
|
});
|
|
3698
|
-
const CALL_BREAKEVEN_CLEAR_FN = functoolsKit.trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3762
|
+
const CALL_BREAKEVEN_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3699
3763
|
await ExecutionContextService.runInContext(async () => {
|
|
3700
3764
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3701
3765
|
await self.params.breakeven.clear(symbol, publicSignal, currentPrice, backtest);
|
|
@@ -3704,7 +3768,7 @@ const CALL_BREAKEVEN_CLEAR_FN = functoolsKit.trycatch(async (self, symbol, signa
|
|
|
3704
3768
|
symbol: symbol,
|
|
3705
3769
|
backtest: backtest,
|
|
3706
3770
|
});
|
|
3707
|
-
}, {
|
|
3771
|
+
}), {
|
|
3708
3772
|
fallback: (error) => {
|
|
3709
3773
|
const message = "ClientStrategy CALL_BREAKEVEN_CLEAR_FN thrown";
|
|
3710
3774
|
const payload = {
|
|
@@ -7466,23 +7530,29 @@ class ExchangeCoreService {
|
|
|
7466
7530
|
/**
|
|
7467
7531
|
* Fetches order book with execution context.
|
|
7468
7532
|
*
|
|
7533
|
+
* Sets up execution context with the provided when/backtest parameters.
|
|
7534
|
+
* The exchange implementation will receive time range parameters but may
|
|
7535
|
+
* choose to use them (backtest) or ignore them (live).
|
|
7536
|
+
*
|
|
7469
7537
|
* @param symbol - Trading pair symbol
|
|
7470
7538
|
* @param when - Timestamp for context
|
|
7471
7539
|
* @param backtest - Whether running in backtest mode
|
|
7540
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
7472
7541
|
* @returns Promise resolving to order book data
|
|
7473
7542
|
*/
|
|
7474
|
-
this.getOrderBook = async (symbol, when, backtest) => {
|
|
7543
|
+
this.getOrderBook = async (symbol, when, backtest, depth) => {
|
|
7475
7544
|
this.loggerService.log("exchangeCoreService getOrderBook", {
|
|
7476
7545
|
symbol,
|
|
7477
7546
|
when,
|
|
7478
7547
|
backtest,
|
|
7548
|
+
depth,
|
|
7479
7549
|
});
|
|
7480
7550
|
if (!MethodContextService.hasContext()) {
|
|
7481
7551
|
throw new Error("exchangeCoreService getOrderBook requires a method context");
|
|
7482
7552
|
}
|
|
7483
7553
|
await this.validate(this.methodContextService.context.exchangeName);
|
|
7484
7554
|
return await ExecutionContextService.runInContext(async () => {
|
|
7485
|
-
return await this.exchangeConnectionService.getOrderBook(symbol);
|
|
7555
|
+
return await this.exchangeConnectionService.getOrderBook(symbol, depth);
|
|
7486
7556
|
}, {
|
|
7487
7557
|
symbol,
|
|
7488
7558
|
when,
|
|
@@ -21351,6 +21421,7 @@ const FORMAT_QUANTITY_METHOD_NAME = "exchange.formatQuantity";
|
|
|
21351
21421
|
const GET_DATE_METHOD_NAME = "exchange.getDate";
|
|
21352
21422
|
const GET_MODE_METHOD_NAME = "exchange.getMode";
|
|
21353
21423
|
const HAS_TRADE_CONTEXT_METHOD_NAME = "exchange.hasTradeContext";
|
|
21424
|
+
const GET_ORDER_BOOK_METHOD_NAME = "exchange.getOrderBook";
|
|
21354
21425
|
/**
|
|
21355
21426
|
* Checks if trade context is active (execution and method contexts).
|
|
21356
21427
|
*
|
|
@@ -21531,6 +21602,41 @@ async function getMode() {
|
|
|
21531
21602
|
const { backtest: bt$1 } = bt.executionContextService.context;
|
|
21532
21603
|
return bt$1 ? "backtest" : "live";
|
|
21533
21604
|
}
|
|
21605
|
+
/**
|
|
21606
|
+
* Fetches order book for a trading pair from the registered exchange.
|
|
21607
|
+
*
|
|
21608
|
+
* Uses current execution context to determine timing. The underlying exchange
|
|
21609
|
+
* implementation receives time range parameters but may use them (backtest)
|
|
21610
|
+
* or ignore them (live trading).
|
|
21611
|
+
*
|
|
21612
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
21613
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
21614
|
+
* @returns Promise resolving to order book data
|
|
21615
|
+
* @throws Error if execution or method context is missing
|
|
21616
|
+
*
|
|
21617
|
+
* @example
|
|
21618
|
+
* ```typescript
|
|
21619
|
+
* const orderBook = await getOrderBook("BTCUSDT");
|
|
21620
|
+
* console.log(orderBook.bids); // [{ price: "50000.00", quantity: "0.5" }, ...]
|
|
21621
|
+
* console.log(orderBook.asks); // [{ price: "50001.00", quantity: "0.3" }, ...]
|
|
21622
|
+
*
|
|
21623
|
+
* // Fetch deeper order book
|
|
21624
|
+
* const deepBook = await getOrderBook("BTCUSDT", 100);
|
|
21625
|
+
* ```
|
|
21626
|
+
*/
|
|
21627
|
+
async function getOrderBook(symbol, depth) {
|
|
21628
|
+
bt.loggerService.info(GET_ORDER_BOOK_METHOD_NAME, {
|
|
21629
|
+
symbol,
|
|
21630
|
+
depth,
|
|
21631
|
+
});
|
|
21632
|
+
if (!ExecutionContextService.hasContext()) {
|
|
21633
|
+
throw new Error("getOrderBook requires an execution context");
|
|
21634
|
+
}
|
|
21635
|
+
if (!MethodContextService.hasContext()) {
|
|
21636
|
+
throw new Error("getOrderBook requires a method context");
|
|
21637
|
+
}
|
|
21638
|
+
return await bt.exchangeConnectionService.getOrderBook(symbol, depth);
|
|
21639
|
+
}
|
|
21534
21640
|
|
|
21535
21641
|
const STOP_METHOD_NAME = "strategy.stop";
|
|
21536
21642
|
const CANCEL_METHOD_NAME = "strategy.cancel";
|
|
@@ -27131,8 +27237,13 @@ const DEFAULT_FORMAT_PRICE_FN = async (_symbol, price) => {
|
|
|
27131
27237
|
/**
|
|
27132
27238
|
* Default implementation for getOrderBook.
|
|
27133
27239
|
* Throws an error indicating the method is not implemented.
|
|
27240
|
+
*
|
|
27241
|
+
* @param _symbol - Trading pair symbol (unused)
|
|
27242
|
+
* @param _depth - Maximum depth levels (unused)
|
|
27243
|
+
* @param _from - Start of time range (unused - can be ignored in live implementations)
|
|
27244
|
+
* @param _to - End of time range (unused - can be ignored in live implementations)
|
|
27134
27245
|
*/
|
|
27135
|
-
const DEFAULT_GET_ORDER_BOOK_FN = async (_symbol, _from, _to) => {
|
|
27246
|
+
const DEFAULT_GET_ORDER_BOOK_FN = async (_symbol, _depth, _from, _to) => {
|
|
27136
27247
|
throw new Error(`getOrderBook is not implemented for this exchange`);
|
|
27137
27248
|
};
|
|
27138
27249
|
const INTERVAL_MINUTES$1 = {
|
|
@@ -27343,7 +27454,12 @@ class ExchangeInstance {
|
|
|
27343
27454
|
/**
|
|
27344
27455
|
* Fetch order book for a trading pair.
|
|
27345
27456
|
*
|
|
27457
|
+
* Calculates time range using CC_ORDER_BOOK_TIME_OFFSET_MINUTES (default 10 minutes)
|
|
27458
|
+
* and passes it to the exchange schema implementation. The implementation may use
|
|
27459
|
+
* the time range (backtest) or ignore it (live trading).
|
|
27460
|
+
*
|
|
27346
27461
|
* @param symbol - Trading pair symbol
|
|
27462
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
27347
27463
|
* @returns Promise resolving to order book data
|
|
27348
27464
|
* @throws Error if getOrderBook is not implemented
|
|
27349
27465
|
*
|
|
@@ -27352,16 +27468,18 @@ class ExchangeInstance {
|
|
|
27352
27468
|
* const instance = new ExchangeInstance("binance");
|
|
27353
27469
|
* const orderBook = await instance.getOrderBook("BTCUSDT");
|
|
27354
27470
|
* console.log(orderBook.bids); // [{ price: "50000.00", quantity: "0.5" }, ...]
|
|
27471
|
+
* const deepOrderBook = await instance.getOrderBook("BTCUSDT", 100);
|
|
27355
27472
|
* ```
|
|
27356
27473
|
*/
|
|
27357
|
-
this.getOrderBook = async (symbol) => {
|
|
27474
|
+
this.getOrderBook = async (symbol, depth = GLOBAL_CONFIG.CC_ORDER_BOOK_MAX_DEPTH_LEVELS) => {
|
|
27358
27475
|
bt.loggerService.info(EXCHANGE_METHOD_NAME_GET_ORDER_BOOK, {
|
|
27359
27476
|
exchangeName: this.exchangeName,
|
|
27360
27477
|
symbol,
|
|
27478
|
+
depth,
|
|
27361
27479
|
});
|
|
27362
27480
|
const to = new Date(Date.now());
|
|
27363
27481
|
const from = new Date(to.getTime() - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * 60 * 1000);
|
|
27364
|
-
return await this._methods.getOrderBook(symbol, from, to);
|
|
27482
|
+
return await this._methods.getOrderBook(symbol, depth, from, to);
|
|
27365
27483
|
};
|
|
27366
27484
|
const schema = bt.exchangeSchemaService.get(this.exchangeName);
|
|
27367
27485
|
this._methods = CREATE_EXCHANGE_INSTANCE_FN(schema);
|
|
@@ -27453,14 +27571,19 @@ class ExchangeUtils {
|
|
|
27453
27571
|
/**
|
|
27454
27572
|
* Fetch order book for a trading pair.
|
|
27455
27573
|
*
|
|
27574
|
+
* Delegates to ExchangeInstance which calculates time range and passes it
|
|
27575
|
+
* to the exchange schema implementation. The from/to parameters may be used
|
|
27576
|
+
* (backtest) or ignored (live) depending on the implementation.
|
|
27577
|
+
*
|
|
27456
27578
|
* @param symbol - Trading pair symbol
|
|
27457
27579
|
* @param context - Execution context with exchange name
|
|
27580
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
27458
27581
|
* @returns Promise resolving to order book data
|
|
27459
27582
|
*/
|
|
27460
|
-
this.getOrderBook = async (symbol, context) => {
|
|
27583
|
+
this.getOrderBook = async (symbol, context, depth = GLOBAL_CONFIG.CC_ORDER_BOOK_MAX_DEPTH_LEVELS) => {
|
|
27461
27584
|
bt.exchangeValidationService.validate(context.exchangeName, EXCHANGE_METHOD_NAME_GET_ORDER_BOOK);
|
|
27462
27585
|
const instance = this._getInstance(context.exchangeName);
|
|
27463
|
-
return await instance.getOrderBook(symbol);
|
|
27586
|
+
return await instance.getOrderBook(symbol, depth);
|
|
27464
27587
|
};
|
|
27465
27588
|
}
|
|
27466
27589
|
}
|
|
@@ -28455,6 +28578,7 @@ exports.getDate = getDate;
|
|
|
28455
28578
|
exports.getDefaultColumns = getDefaultColumns;
|
|
28456
28579
|
exports.getDefaultConfig = getDefaultConfig;
|
|
28457
28580
|
exports.getMode = getMode;
|
|
28581
|
+
exports.getOrderBook = getOrderBook;
|
|
28458
28582
|
exports.hasTradeContext = hasTradeContext;
|
|
28459
28583
|
exports.lib = backtest;
|
|
28460
28584
|
exports.listExchanges = listExchanges;
|
package/build/index.mjs
CHANGED
|
@@ -402,6 +402,13 @@ const GLOBAL_CONFIG = {
|
|
|
402
402
|
* Default: 10 minutes
|
|
403
403
|
*/
|
|
404
404
|
CC_ORDER_BOOK_TIME_OFFSET_MINUTES: 10,
|
|
405
|
+
/**
|
|
406
|
+
* Maximum depth levels for order book fetching.
|
|
407
|
+
* Specifies how many price levels to fetch from both bids and asks.
|
|
408
|
+
*
|
|
409
|
+
* Default: 20 levels
|
|
410
|
+
*/
|
|
411
|
+
CC_ORDER_BOOK_MAX_DEPTH_LEVELS: 1000,
|
|
405
412
|
};
|
|
406
413
|
const DEFAULT_CONFIG = Object.freeze({ ...GLOBAL_CONFIG });
|
|
407
414
|
|
|
@@ -871,17 +878,23 @@ class ClientExchange {
|
|
|
871
878
|
/**
|
|
872
879
|
* Fetches order book for a trading pair.
|
|
873
880
|
*
|
|
881
|
+
* Calculates time range based on execution context time (when) and
|
|
882
|
+
* CC_ORDER_BOOK_TIME_OFFSET_MINUTES, then delegates to the exchange
|
|
883
|
+
* schema implementation which may use or ignore the time range.
|
|
884
|
+
*
|
|
874
885
|
* @param symbol - Trading pair symbol
|
|
886
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
875
887
|
* @returns Promise resolving to order book data
|
|
876
888
|
* @throws Error if getOrderBook is not implemented
|
|
877
889
|
*/
|
|
878
|
-
async getOrderBook(symbol) {
|
|
890
|
+
async getOrderBook(symbol, depth = GLOBAL_CONFIG.CC_ORDER_BOOK_MAX_DEPTH_LEVELS) {
|
|
879
891
|
this.params.logger.debug("ClientExchange getOrderBook", {
|
|
880
892
|
symbol,
|
|
893
|
+
depth,
|
|
881
894
|
});
|
|
882
895
|
const to = new Date(this.params.execution.context.when.getTime());
|
|
883
896
|
const from = new Date(to.getTime() - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * 60 * 1000);
|
|
884
|
-
return await this.params.getOrderBook(symbol, from, to);
|
|
897
|
+
return await this.params.getOrderBook(symbol, depth, from, to);
|
|
885
898
|
}
|
|
886
899
|
}
|
|
887
900
|
|
|
@@ -909,8 +922,13 @@ const DEFAULT_FORMAT_PRICE_FN$1 = async (_symbol, price) => {
|
|
|
909
922
|
/**
|
|
910
923
|
* Default implementation for getOrderBook.
|
|
911
924
|
* Throws an error indicating the method is not implemented.
|
|
925
|
+
*
|
|
926
|
+
* @param _symbol - Trading pair symbol (unused)
|
|
927
|
+
* @param _depth - Maximum depth levels (unused)
|
|
928
|
+
* @param _from - Start of time range (unused - can be ignored in live implementations)
|
|
929
|
+
* @param _to - End of time range (unused - can be ignored in live implementations)
|
|
912
930
|
*/
|
|
913
|
-
const DEFAULT_GET_ORDER_BOOK_FN$1 = async (_symbol, _from, _to) => {
|
|
931
|
+
const DEFAULT_GET_ORDER_BOOK_FN$1 = async (_symbol, _depth, _from, _to) => {
|
|
914
932
|
throw new Error(`getOrderBook is not implemented for this exchange`);
|
|
915
933
|
};
|
|
916
934
|
/**
|
|
@@ -1051,15 +1069,19 @@ class ExchangeConnectionService {
|
|
|
1051
1069
|
* Fetches order book for a trading pair using configured exchange.
|
|
1052
1070
|
*
|
|
1053
1071
|
* Routes to exchange determined by methodContextService.context.exchangeName.
|
|
1072
|
+
* The ClientExchange will calculate time range and pass it to the schema
|
|
1073
|
+
* implementation, which may use (backtest) or ignore (live) the parameters.
|
|
1054
1074
|
*
|
|
1055
1075
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
1076
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
1056
1077
|
* @returns Promise resolving to order book data
|
|
1057
1078
|
*/
|
|
1058
|
-
this.getOrderBook = async (symbol) => {
|
|
1079
|
+
this.getOrderBook = async (symbol, depth) => {
|
|
1059
1080
|
this.loggerService.log("exchangeConnectionService getOrderBook", {
|
|
1060
1081
|
symbol,
|
|
1082
|
+
depth,
|
|
1061
1083
|
});
|
|
1062
|
-
return await this.getExchange(this.methodContextService.context.exchangeName).getOrderBook(symbol);
|
|
1084
|
+
return await this.getExchange(this.methodContextService.context.exchangeName).getOrderBook(symbol, depth);
|
|
1063
1085
|
};
|
|
1064
1086
|
}
|
|
1065
1087
|
}
|
|
@@ -2211,6 +2233,48 @@ const toPlainString = (content) => {
|
|
|
2211
2233
|
return text.trim();
|
|
2212
2234
|
};
|
|
2213
2235
|
|
|
2236
|
+
/**
|
|
2237
|
+
* Wraps a function to execute it outside of the current execution context if one exists.
|
|
2238
|
+
*
|
|
2239
|
+
* This utility ensures that the wrapped function runs in isolation from any existing
|
|
2240
|
+
* ExecutionContext, preventing context leakage and unintended context sharing between
|
|
2241
|
+
* async operations.
|
|
2242
|
+
*
|
|
2243
|
+
* @template T - Function type with any parameters and return type
|
|
2244
|
+
* @param {T} run - The function to be wrapped and executed outside of context
|
|
2245
|
+
* @returns {Function} A curried function that accepts the original function's parameters
|
|
2246
|
+
* and executes it outside of the current context if one exists
|
|
2247
|
+
*
|
|
2248
|
+
* @example
|
|
2249
|
+
* ```ts
|
|
2250
|
+
* const myFunction = async (param: string) => {
|
|
2251
|
+
* // This code will run outside of any ExecutionContext
|
|
2252
|
+
* return param.toUpperCase();
|
|
2253
|
+
* };
|
|
2254
|
+
*
|
|
2255
|
+
* const wrappedFunction = beginTime(myFunction);
|
|
2256
|
+
* const result = wrappedFunction('hello'); // Returns 'HELLO'
|
|
2257
|
+
* ```
|
|
2258
|
+
*
|
|
2259
|
+
* @example
|
|
2260
|
+
* ```ts
|
|
2261
|
+
* // Usage with trycatch wrapper
|
|
2262
|
+
* const safeFunction = trycatch(
|
|
2263
|
+
* beginTime(async (id: number) => {
|
|
2264
|
+
* // Function body runs isolated from parent context
|
|
2265
|
+
* return await fetchData(id);
|
|
2266
|
+
* })
|
|
2267
|
+
* );
|
|
2268
|
+
* ```
|
|
2269
|
+
*/
|
|
2270
|
+
const beginTime = (run) => (...args) => {
|
|
2271
|
+
let fn = () => run(...args);
|
|
2272
|
+
if (ExecutionContextService.hasContext()) {
|
|
2273
|
+
fn = ExecutionContextService.runOutOfContext(fn);
|
|
2274
|
+
}
|
|
2275
|
+
return fn();
|
|
2276
|
+
};
|
|
2277
|
+
|
|
2214
2278
|
const INTERVAL_MINUTES$3 = {
|
|
2215
2279
|
"1m": 1,
|
|
2216
2280
|
"3m": 3,
|
|
@@ -3310,7 +3374,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
3310
3374
|
await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, activationTime, self.params.execution.context.backtest);
|
|
3311
3375
|
return result;
|
|
3312
3376
|
};
|
|
3313
|
-
const CALL_PING_CALLBACKS_FN = trycatch(async (self, symbol, scheduled, timestamp, backtest) => {
|
|
3377
|
+
const CALL_PING_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, scheduled, timestamp, backtest) => {
|
|
3314
3378
|
await ExecutionContextService.runInContext(async () => {
|
|
3315
3379
|
const publicSignal = TO_PUBLIC_SIGNAL(scheduled);
|
|
3316
3380
|
// Call system onPing callback first (emits to pingSubject)
|
|
@@ -3324,7 +3388,7 @@ const CALL_PING_CALLBACKS_FN = trycatch(async (self, symbol, scheduled, timestam
|
|
|
3324
3388
|
symbol: symbol,
|
|
3325
3389
|
backtest: backtest,
|
|
3326
3390
|
});
|
|
3327
|
-
}, {
|
|
3391
|
+
}), {
|
|
3328
3392
|
fallback: (error) => {
|
|
3329
3393
|
const message = "ClientStrategy CALL_PING_CALLBACKS_FN thrown";
|
|
3330
3394
|
const payload = {
|
|
@@ -3336,7 +3400,7 @@ const CALL_PING_CALLBACKS_FN = trycatch(async (self, symbol, scheduled, timestam
|
|
|
3336
3400
|
errorEmitter.next(error);
|
|
3337
3401
|
},
|
|
3338
3402
|
});
|
|
3339
|
-
const CALL_ACTIVE_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3403
|
+
const CALL_ACTIVE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3340
3404
|
await ExecutionContextService.runInContext(async () => {
|
|
3341
3405
|
if (self.params.callbacks?.onActive) {
|
|
3342
3406
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3347,7 +3411,7 @@ const CALL_ACTIVE_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPr
|
|
|
3347
3411
|
symbol: symbol,
|
|
3348
3412
|
backtest: backtest,
|
|
3349
3413
|
});
|
|
3350
|
-
}, {
|
|
3414
|
+
}), {
|
|
3351
3415
|
fallback: (error) => {
|
|
3352
3416
|
const message = "ClientStrategy CALL_ACTIVE_CALLBACKS_FN thrown";
|
|
3353
3417
|
const payload = {
|
|
@@ -3359,7 +3423,7 @@ const CALL_ACTIVE_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPr
|
|
|
3359
3423
|
errorEmitter.next(error);
|
|
3360
3424
|
},
|
|
3361
3425
|
});
|
|
3362
|
-
const CALL_SCHEDULE_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3426
|
+
const CALL_SCHEDULE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3363
3427
|
await ExecutionContextService.runInContext(async () => {
|
|
3364
3428
|
if (self.params.callbacks?.onSchedule) {
|
|
3365
3429
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3370,7 +3434,7 @@ const CALL_SCHEDULE_CALLBACKS_FN = trycatch(async (self, symbol, signal, current
|
|
|
3370
3434
|
symbol: symbol,
|
|
3371
3435
|
backtest: backtest,
|
|
3372
3436
|
});
|
|
3373
|
-
}, {
|
|
3437
|
+
}), {
|
|
3374
3438
|
fallback: (error) => {
|
|
3375
3439
|
const message = "ClientStrategy CALL_SCHEDULE_CALLBACKS_FN thrown";
|
|
3376
3440
|
const payload = {
|
|
@@ -3382,7 +3446,7 @@ const CALL_SCHEDULE_CALLBACKS_FN = trycatch(async (self, symbol, signal, current
|
|
|
3382
3446
|
errorEmitter.next(error);
|
|
3383
3447
|
},
|
|
3384
3448
|
});
|
|
3385
|
-
const CALL_CANCEL_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3449
|
+
const CALL_CANCEL_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3386
3450
|
await ExecutionContextService.runInContext(async () => {
|
|
3387
3451
|
if (self.params.callbacks?.onCancel) {
|
|
3388
3452
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3393,7 +3457,7 @@ const CALL_CANCEL_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPr
|
|
|
3393
3457
|
symbol: symbol,
|
|
3394
3458
|
backtest: backtest,
|
|
3395
3459
|
});
|
|
3396
|
-
}, {
|
|
3460
|
+
}), {
|
|
3397
3461
|
fallback: (error) => {
|
|
3398
3462
|
const message = "ClientStrategy CALL_CANCEL_CALLBACKS_FN thrown";
|
|
3399
3463
|
const payload = {
|
|
@@ -3405,7 +3469,7 @@ const CALL_CANCEL_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPr
|
|
|
3405
3469
|
errorEmitter.next(error);
|
|
3406
3470
|
},
|
|
3407
3471
|
});
|
|
3408
|
-
const CALL_OPEN_CALLBACKS_FN = trycatch(async (self, symbol, signal, priceOpen, timestamp, backtest) => {
|
|
3472
|
+
const CALL_OPEN_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, priceOpen, timestamp, backtest) => {
|
|
3409
3473
|
await ExecutionContextService.runInContext(async () => {
|
|
3410
3474
|
if (self.params.callbacks?.onOpen) {
|
|
3411
3475
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3416,7 +3480,7 @@ const CALL_OPEN_CALLBACKS_FN = trycatch(async (self, symbol, signal, priceOpen,
|
|
|
3416
3480
|
symbol: symbol,
|
|
3417
3481
|
backtest: backtest,
|
|
3418
3482
|
});
|
|
3419
|
-
}, {
|
|
3483
|
+
}), {
|
|
3420
3484
|
fallback: (error) => {
|
|
3421
3485
|
const message = "ClientStrategy CALL_OPEN_CALLBACKS_FN thrown";
|
|
3422
3486
|
const payload = {
|
|
@@ -3428,7 +3492,7 @@ const CALL_OPEN_CALLBACKS_FN = trycatch(async (self, symbol, signal, priceOpen,
|
|
|
3428
3492
|
errorEmitter.next(error);
|
|
3429
3493
|
},
|
|
3430
3494
|
});
|
|
3431
|
-
const CALL_CLOSE_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3495
|
+
const CALL_CLOSE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3432
3496
|
await ExecutionContextService.runInContext(async () => {
|
|
3433
3497
|
if (self.params.callbacks?.onClose) {
|
|
3434
3498
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
@@ -3439,7 +3503,7 @@ const CALL_CLOSE_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPri
|
|
|
3439
3503
|
symbol: symbol,
|
|
3440
3504
|
backtest: backtest,
|
|
3441
3505
|
});
|
|
3442
|
-
}, {
|
|
3506
|
+
}), {
|
|
3443
3507
|
fallback: (error) => {
|
|
3444
3508
|
const message = "ClientStrategy CALL_CLOSE_CALLBACKS_FN thrown";
|
|
3445
3509
|
const payload = {
|
|
@@ -3451,7 +3515,7 @@ const CALL_CLOSE_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPri
|
|
|
3451
3515
|
errorEmitter.next(error);
|
|
3452
3516
|
},
|
|
3453
3517
|
});
|
|
3454
|
-
const CALL_TICK_CALLBACKS_FN = trycatch(async (self, symbol, result, timestamp, backtest) => {
|
|
3518
|
+
const CALL_TICK_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, result, timestamp, backtest) => {
|
|
3455
3519
|
await ExecutionContextService.runInContext(async () => {
|
|
3456
3520
|
if (self.params.callbacks?.onTick) {
|
|
3457
3521
|
await self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3461,7 +3525,7 @@ const CALL_TICK_CALLBACKS_FN = trycatch(async (self, symbol, result, timestamp,
|
|
|
3461
3525
|
symbol: symbol,
|
|
3462
3526
|
backtest: backtest,
|
|
3463
3527
|
});
|
|
3464
|
-
}, {
|
|
3528
|
+
}), {
|
|
3465
3529
|
fallback: (error) => {
|
|
3466
3530
|
const message = "ClientStrategy CALL_TICK_CALLBACKS_FN thrown";
|
|
3467
3531
|
const payload = {
|
|
@@ -3473,7 +3537,7 @@ const CALL_TICK_CALLBACKS_FN = trycatch(async (self, symbol, result, timestamp,
|
|
|
3473
3537
|
errorEmitter.next(error);
|
|
3474
3538
|
},
|
|
3475
3539
|
});
|
|
3476
|
-
const CALL_IDLE_CALLBACKS_FN = trycatch(async (self, symbol, currentPrice, timestamp, backtest) => {
|
|
3540
|
+
const CALL_IDLE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, currentPrice, timestamp, backtest) => {
|
|
3477
3541
|
await ExecutionContextService.runInContext(async () => {
|
|
3478
3542
|
if (self.params.callbacks?.onIdle) {
|
|
3479
3543
|
await self.params.callbacks.onIdle(self.params.execution.context.symbol, currentPrice, self.params.execution.context.backtest);
|
|
@@ -3483,7 +3547,7 @@ const CALL_IDLE_CALLBACKS_FN = trycatch(async (self, symbol, currentPrice, times
|
|
|
3483
3547
|
symbol: symbol,
|
|
3484
3548
|
backtest: backtest,
|
|
3485
3549
|
});
|
|
3486
|
-
}, {
|
|
3550
|
+
}), {
|
|
3487
3551
|
fallback: (error) => {
|
|
3488
3552
|
const message = "ClientStrategy CALL_IDLE_CALLBACKS_FN thrown";
|
|
3489
3553
|
const payload = {
|
|
@@ -3495,7 +3559,7 @@ const CALL_IDLE_CALLBACKS_FN = trycatch(async (self, symbol, currentPrice, times
|
|
|
3495
3559
|
errorEmitter.next(error);
|
|
3496
3560
|
},
|
|
3497
3561
|
});
|
|
3498
|
-
const CALL_RISK_ADD_SIGNAL_FN = trycatch(async (self, symbol, signal, timestamp, backtest) => {
|
|
3562
|
+
const CALL_RISK_ADD_SIGNAL_FN = trycatch(beginTime(async (self, symbol, signal, timestamp, backtest) => {
|
|
3499
3563
|
await ExecutionContextService.runInContext(async () => {
|
|
3500
3564
|
await self.params.risk.addSignal(symbol, {
|
|
3501
3565
|
strategyName: self.params.method.context.strategyName,
|
|
@@ -3515,7 +3579,7 @@ const CALL_RISK_ADD_SIGNAL_FN = trycatch(async (self, symbol, signal, timestamp,
|
|
|
3515
3579
|
symbol: symbol,
|
|
3516
3580
|
backtest: backtest,
|
|
3517
3581
|
});
|
|
3518
|
-
}, {
|
|
3582
|
+
}), {
|
|
3519
3583
|
fallback: (error) => {
|
|
3520
3584
|
const message = "ClientStrategy CALL_RISK_ADD_SIGNAL_FN thrown";
|
|
3521
3585
|
const payload = {
|
|
@@ -3527,7 +3591,7 @@ const CALL_RISK_ADD_SIGNAL_FN = trycatch(async (self, symbol, signal, timestamp,
|
|
|
3527
3591
|
errorEmitter.next(error);
|
|
3528
3592
|
},
|
|
3529
3593
|
});
|
|
3530
|
-
const CALL_RISK_REMOVE_SIGNAL_FN = trycatch(async (self, symbol, timestamp, backtest) => {
|
|
3594
|
+
const CALL_RISK_REMOVE_SIGNAL_FN = trycatch(beginTime(async (self, symbol, timestamp, backtest) => {
|
|
3531
3595
|
await ExecutionContextService.runInContext(async () => {
|
|
3532
3596
|
await self.params.risk.removeSignal(symbol, {
|
|
3533
3597
|
strategyName: self.params.method.context.strategyName,
|
|
@@ -3540,7 +3604,7 @@ const CALL_RISK_REMOVE_SIGNAL_FN = trycatch(async (self, symbol, timestamp, back
|
|
|
3540
3604
|
symbol: symbol,
|
|
3541
3605
|
backtest: backtest,
|
|
3542
3606
|
});
|
|
3543
|
-
}, {
|
|
3607
|
+
}), {
|
|
3544
3608
|
fallback: (error) => {
|
|
3545
3609
|
const message = "ClientStrategy CALL_RISK_REMOVE_SIGNAL_FN thrown";
|
|
3546
3610
|
const payload = {
|
|
@@ -3552,7 +3616,7 @@ const CALL_RISK_REMOVE_SIGNAL_FN = trycatch(async (self, symbol, timestamp, back
|
|
|
3552
3616
|
errorEmitter.next(error);
|
|
3553
3617
|
},
|
|
3554
3618
|
});
|
|
3555
|
-
const CALL_PARTIAL_CLEAR_FN = trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3619
|
+
const CALL_PARTIAL_CLEAR_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3556
3620
|
await ExecutionContextService.runInContext(async () => {
|
|
3557
3621
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3558
3622
|
await self.params.partial.clear(symbol, publicSignal, currentPrice, backtest);
|
|
@@ -3561,7 +3625,7 @@ const CALL_PARTIAL_CLEAR_FN = trycatch(async (self, symbol, signal, currentPrice
|
|
|
3561
3625
|
symbol: symbol,
|
|
3562
3626
|
backtest: backtest,
|
|
3563
3627
|
});
|
|
3564
|
-
}, {
|
|
3628
|
+
}), {
|
|
3565
3629
|
fallback: (error) => {
|
|
3566
3630
|
const message = "ClientStrategy CALL_PARTIAL_CLEAR_FN thrown";
|
|
3567
3631
|
const payload = {
|
|
@@ -3573,7 +3637,7 @@ const CALL_PARTIAL_CLEAR_FN = trycatch(async (self, symbol, signal, currentPrice
|
|
|
3573
3637
|
errorEmitter.next(error);
|
|
3574
3638
|
},
|
|
3575
3639
|
});
|
|
3576
|
-
const CALL_RISK_CHECK_SIGNAL_FN = trycatch(async (self, symbol, pendingSignal, currentPrice, timestamp, backtest) => {
|
|
3640
|
+
const CALL_RISK_CHECK_SIGNAL_FN = trycatch(beginTime(async (self, symbol, pendingSignal, currentPrice, timestamp, backtest) => {
|
|
3577
3641
|
return await ExecutionContextService.runInContext(async () => {
|
|
3578
3642
|
return await self.params.risk.checkSignal({
|
|
3579
3643
|
pendingSignal: TO_PUBLIC_SIGNAL(pendingSignal),
|
|
@@ -3590,7 +3654,7 @@ const CALL_RISK_CHECK_SIGNAL_FN = trycatch(async (self, symbol, pendingSignal, c
|
|
|
3590
3654
|
symbol: symbol,
|
|
3591
3655
|
backtest: backtest,
|
|
3592
3656
|
});
|
|
3593
|
-
}, {
|
|
3657
|
+
}), {
|
|
3594
3658
|
defaultValue: false,
|
|
3595
3659
|
fallback: (error) => {
|
|
3596
3660
|
const message = "ClientStrategy CALL_RISK_CHECK_SIGNAL_FN thrown";
|
|
@@ -3603,7 +3667,7 @@ const CALL_RISK_CHECK_SIGNAL_FN = trycatch(async (self, symbol, pendingSignal, c
|
|
|
3603
3667
|
errorEmitter.next(error);
|
|
3604
3668
|
},
|
|
3605
3669
|
});
|
|
3606
|
-
const CALL_PARTIAL_PROFIT_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPrice, percentTp, timestamp, backtest) => {
|
|
3670
|
+
const CALL_PARTIAL_PROFIT_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, percentTp, timestamp, backtest) => {
|
|
3607
3671
|
await ExecutionContextService.runInContext(async () => {
|
|
3608
3672
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3609
3673
|
await self.params.partial.profit(symbol, publicSignal, currentPrice, percentTp, backtest, new Date(timestamp));
|
|
@@ -3615,7 +3679,7 @@ const CALL_PARTIAL_PROFIT_CALLBACKS_FN = trycatch(async (self, symbol, signal, c
|
|
|
3615
3679
|
symbol: symbol,
|
|
3616
3680
|
backtest: backtest,
|
|
3617
3681
|
});
|
|
3618
|
-
}, {
|
|
3682
|
+
}), {
|
|
3619
3683
|
fallback: (error) => {
|
|
3620
3684
|
const message = "ClientStrategy CALL_PARTIAL_PROFIT_CALLBACKS_FN thrown";
|
|
3621
3685
|
const payload = {
|
|
@@ -3627,7 +3691,7 @@ const CALL_PARTIAL_PROFIT_CALLBACKS_FN = trycatch(async (self, symbol, signal, c
|
|
|
3627
3691
|
errorEmitter.next(error);
|
|
3628
3692
|
},
|
|
3629
3693
|
});
|
|
3630
|
-
const CALL_PARTIAL_LOSS_CALLBACKS_FN = trycatch(async (self, symbol, signal, currentPrice, percentSl, timestamp, backtest) => {
|
|
3694
|
+
const CALL_PARTIAL_LOSS_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, percentSl, timestamp, backtest) => {
|
|
3631
3695
|
await ExecutionContextService.runInContext(async () => {
|
|
3632
3696
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3633
3697
|
await self.params.partial.loss(symbol, publicSignal, currentPrice, percentSl, backtest, new Date(timestamp));
|
|
@@ -3639,7 +3703,7 @@ const CALL_PARTIAL_LOSS_CALLBACKS_FN = trycatch(async (self, symbol, signal, cur
|
|
|
3639
3703
|
symbol: symbol,
|
|
3640
3704
|
backtest: backtest,
|
|
3641
3705
|
});
|
|
3642
|
-
}, {
|
|
3706
|
+
}), {
|
|
3643
3707
|
fallback: (error) => {
|
|
3644
3708
|
const message = "ClientStrategy CALL_PARTIAL_LOSS_CALLBACKS_FN thrown";
|
|
3645
3709
|
const payload = {
|
|
@@ -3651,7 +3715,7 @@ const CALL_PARTIAL_LOSS_CALLBACKS_FN = trycatch(async (self, symbol, signal, cur
|
|
|
3651
3715
|
errorEmitter.next(error);
|
|
3652
3716
|
},
|
|
3653
3717
|
});
|
|
3654
|
-
const CALL_BREAKEVEN_CHECK_FN = trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3718
|
+
const CALL_BREAKEVEN_CHECK_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3655
3719
|
await ExecutionContextService.runInContext(async () => {
|
|
3656
3720
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3657
3721
|
const isBreakeven = await self.params.breakeven.check(symbol, publicSignal, currentPrice, backtest, new Date(timestamp));
|
|
@@ -3663,7 +3727,7 @@ const CALL_BREAKEVEN_CHECK_FN = trycatch(async (self, symbol, signal, currentPri
|
|
|
3663
3727
|
symbol: symbol,
|
|
3664
3728
|
backtest: backtest,
|
|
3665
3729
|
});
|
|
3666
|
-
}, {
|
|
3730
|
+
}), {
|
|
3667
3731
|
fallback: (error) => {
|
|
3668
3732
|
const message = "ClientStrategy CALL_BREAKEVEN_CHECK_FN thrown";
|
|
3669
3733
|
const payload = {
|
|
@@ -3675,7 +3739,7 @@ const CALL_BREAKEVEN_CHECK_FN = trycatch(async (self, symbol, signal, currentPri
|
|
|
3675
3739
|
errorEmitter.next(error);
|
|
3676
3740
|
},
|
|
3677
3741
|
});
|
|
3678
|
-
const CALL_BREAKEVEN_CLEAR_FN = trycatch(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3742
|
+
const CALL_BREAKEVEN_CLEAR_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
3679
3743
|
await ExecutionContextService.runInContext(async () => {
|
|
3680
3744
|
const publicSignal = TO_PUBLIC_SIGNAL(signal);
|
|
3681
3745
|
await self.params.breakeven.clear(symbol, publicSignal, currentPrice, backtest);
|
|
@@ -3684,7 +3748,7 @@ const CALL_BREAKEVEN_CLEAR_FN = trycatch(async (self, symbol, signal, currentPri
|
|
|
3684
3748
|
symbol: symbol,
|
|
3685
3749
|
backtest: backtest,
|
|
3686
3750
|
});
|
|
3687
|
-
}, {
|
|
3751
|
+
}), {
|
|
3688
3752
|
fallback: (error) => {
|
|
3689
3753
|
const message = "ClientStrategy CALL_BREAKEVEN_CLEAR_FN thrown";
|
|
3690
3754
|
const payload = {
|
|
@@ -7446,23 +7510,29 @@ class ExchangeCoreService {
|
|
|
7446
7510
|
/**
|
|
7447
7511
|
* Fetches order book with execution context.
|
|
7448
7512
|
*
|
|
7513
|
+
* Sets up execution context with the provided when/backtest parameters.
|
|
7514
|
+
* The exchange implementation will receive time range parameters but may
|
|
7515
|
+
* choose to use them (backtest) or ignore them (live).
|
|
7516
|
+
*
|
|
7449
7517
|
* @param symbol - Trading pair symbol
|
|
7450
7518
|
* @param when - Timestamp for context
|
|
7451
7519
|
* @param backtest - Whether running in backtest mode
|
|
7520
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
7452
7521
|
* @returns Promise resolving to order book data
|
|
7453
7522
|
*/
|
|
7454
|
-
this.getOrderBook = async (symbol, when, backtest) => {
|
|
7523
|
+
this.getOrderBook = async (symbol, when, backtest, depth) => {
|
|
7455
7524
|
this.loggerService.log("exchangeCoreService getOrderBook", {
|
|
7456
7525
|
symbol,
|
|
7457
7526
|
when,
|
|
7458
7527
|
backtest,
|
|
7528
|
+
depth,
|
|
7459
7529
|
});
|
|
7460
7530
|
if (!MethodContextService.hasContext()) {
|
|
7461
7531
|
throw new Error("exchangeCoreService getOrderBook requires a method context");
|
|
7462
7532
|
}
|
|
7463
7533
|
await this.validate(this.methodContextService.context.exchangeName);
|
|
7464
7534
|
return await ExecutionContextService.runInContext(async () => {
|
|
7465
|
-
return await this.exchangeConnectionService.getOrderBook(symbol);
|
|
7535
|
+
return await this.exchangeConnectionService.getOrderBook(symbol, depth);
|
|
7466
7536
|
}, {
|
|
7467
7537
|
symbol,
|
|
7468
7538
|
when,
|
|
@@ -21331,6 +21401,7 @@ const FORMAT_QUANTITY_METHOD_NAME = "exchange.formatQuantity";
|
|
|
21331
21401
|
const GET_DATE_METHOD_NAME = "exchange.getDate";
|
|
21332
21402
|
const GET_MODE_METHOD_NAME = "exchange.getMode";
|
|
21333
21403
|
const HAS_TRADE_CONTEXT_METHOD_NAME = "exchange.hasTradeContext";
|
|
21404
|
+
const GET_ORDER_BOOK_METHOD_NAME = "exchange.getOrderBook";
|
|
21334
21405
|
/**
|
|
21335
21406
|
* Checks if trade context is active (execution and method contexts).
|
|
21336
21407
|
*
|
|
@@ -21511,6 +21582,41 @@ async function getMode() {
|
|
|
21511
21582
|
const { backtest: bt$1 } = bt.executionContextService.context;
|
|
21512
21583
|
return bt$1 ? "backtest" : "live";
|
|
21513
21584
|
}
|
|
21585
|
+
/**
|
|
21586
|
+
* Fetches order book for a trading pair from the registered exchange.
|
|
21587
|
+
*
|
|
21588
|
+
* Uses current execution context to determine timing. The underlying exchange
|
|
21589
|
+
* implementation receives time range parameters but may use them (backtest)
|
|
21590
|
+
* or ignore them (live trading).
|
|
21591
|
+
*
|
|
21592
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
21593
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
21594
|
+
* @returns Promise resolving to order book data
|
|
21595
|
+
* @throws Error if execution or method context is missing
|
|
21596
|
+
*
|
|
21597
|
+
* @example
|
|
21598
|
+
* ```typescript
|
|
21599
|
+
* const orderBook = await getOrderBook("BTCUSDT");
|
|
21600
|
+
* console.log(orderBook.bids); // [{ price: "50000.00", quantity: "0.5" }, ...]
|
|
21601
|
+
* console.log(orderBook.asks); // [{ price: "50001.00", quantity: "0.3" }, ...]
|
|
21602
|
+
*
|
|
21603
|
+
* // Fetch deeper order book
|
|
21604
|
+
* const deepBook = await getOrderBook("BTCUSDT", 100);
|
|
21605
|
+
* ```
|
|
21606
|
+
*/
|
|
21607
|
+
async function getOrderBook(symbol, depth) {
|
|
21608
|
+
bt.loggerService.info(GET_ORDER_BOOK_METHOD_NAME, {
|
|
21609
|
+
symbol,
|
|
21610
|
+
depth,
|
|
21611
|
+
});
|
|
21612
|
+
if (!ExecutionContextService.hasContext()) {
|
|
21613
|
+
throw new Error("getOrderBook requires an execution context");
|
|
21614
|
+
}
|
|
21615
|
+
if (!MethodContextService.hasContext()) {
|
|
21616
|
+
throw new Error("getOrderBook requires a method context");
|
|
21617
|
+
}
|
|
21618
|
+
return await bt.exchangeConnectionService.getOrderBook(symbol, depth);
|
|
21619
|
+
}
|
|
21514
21620
|
|
|
21515
21621
|
const STOP_METHOD_NAME = "strategy.stop";
|
|
21516
21622
|
const CANCEL_METHOD_NAME = "strategy.cancel";
|
|
@@ -27111,8 +27217,13 @@ const DEFAULT_FORMAT_PRICE_FN = async (_symbol, price) => {
|
|
|
27111
27217
|
/**
|
|
27112
27218
|
* Default implementation for getOrderBook.
|
|
27113
27219
|
* Throws an error indicating the method is not implemented.
|
|
27220
|
+
*
|
|
27221
|
+
* @param _symbol - Trading pair symbol (unused)
|
|
27222
|
+
* @param _depth - Maximum depth levels (unused)
|
|
27223
|
+
* @param _from - Start of time range (unused - can be ignored in live implementations)
|
|
27224
|
+
* @param _to - End of time range (unused - can be ignored in live implementations)
|
|
27114
27225
|
*/
|
|
27115
|
-
const DEFAULT_GET_ORDER_BOOK_FN = async (_symbol, _from, _to) => {
|
|
27226
|
+
const DEFAULT_GET_ORDER_BOOK_FN = async (_symbol, _depth, _from, _to) => {
|
|
27116
27227
|
throw new Error(`getOrderBook is not implemented for this exchange`);
|
|
27117
27228
|
};
|
|
27118
27229
|
const INTERVAL_MINUTES$1 = {
|
|
@@ -27323,7 +27434,12 @@ class ExchangeInstance {
|
|
|
27323
27434
|
/**
|
|
27324
27435
|
* Fetch order book for a trading pair.
|
|
27325
27436
|
*
|
|
27437
|
+
* Calculates time range using CC_ORDER_BOOK_TIME_OFFSET_MINUTES (default 10 minutes)
|
|
27438
|
+
* and passes it to the exchange schema implementation. The implementation may use
|
|
27439
|
+
* the time range (backtest) or ignore it (live trading).
|
|
27440
|
+
*
|
|
27326
27441
|
* @param symbol - Trading pair symbol
|
|
27442
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
27327
27443
|
* @returns Promise resolving to order book data
|
|
27328
27444
|
* @throws Error if getOrderBook is not implemented
|
|
27329
27445
|
*
|
|
@@ -27332,16 +27448,18 @@ class ExchangeInstance {
|
|
|
27332
27448
|
* const instance = new ExchangeInstance("binance");
|
|
27333
27449
|
* const orderBook = await instance.getOrderBook("BTCUSDT");
|
|
27334
27450
|
* console.log(orderBook.bids); // [{ price: "50000.00", quantity: "0.5" }, ...]
|
|
27451
|
+
* const deepOrderBook = await instance.getOrderBook("BTCUSDT", 100);
|
|
27335
27452
|
* ```
|
|
27336
27453
|
*/
|
|
27337
|
-
this.getOrderBook = async (symbol) => {
|
|
27454
|
+
this.getOrderBook = async (symbol, depth = GLOBAL_CONFIG.CC_ORDER_BOOK_MAX_DEPTH_LEVELS) => {
|
|
27338
27455
|
bt.loggerService.info(EXCHANGE_METHOD_NAME_GET_ORDER_BOOK, {
|
|
27339
27456
|
exchangeName: this.exchangeName,
|
|
27340
27457
|
symbol,
|
|
27458
|
+
depth,
|
|
27341
27459
|
});
|
|
27342
27460
|
const to = new Date(Date.now());
|
|
27343
27461
|
const from = new Date(to.getTime() - GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES * 60 * 1000);
|
|
27344
|
-
return await this._methods.getOrderBook(symbol, from, to);
|
|
27462
|
+
return await this._methods.getOrderBook(symbol, depth, from, to);
|
|
27345
27463
|
};
|
|
27346
27464
|
const schema = bt.exchangeSchemaService.get(this.exchangeName);
|
|
27347
27465
|
this._methods = CREATE_EXCHANGE_INSTANCE_FN(schema);
|
|
@@ -27433,14 +27551,19 @@ class ExchangeUtils {
|
|
|
27433
27551
|
/**
|
|
27434
27552
|
* Fetch order book for a trading pair.
|
|
27435
27553
|
*
|
|
27554
|
+
* Delegates to ExchangeInstance which calculates time range and passes it
|
|
27555
|
+
* to the exchange schema implementation. The from/to parameters may be used
|
|
27556
|
+
* (backtest) or ignored (live) depending on the implementation.
|
|
27557
|
+
*
|
|
27436
27558
|
* @param symbol - Trading pair symbol
|
|
27437
27559
|
* @param context - Execution context with exchange name
|
|
27560
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
27438
27561
|
* @returns Promise resolving to order book data
|
|
27439
27562
|
*/
|
|
27440
|
-
this.getOrderBook = async (symbol, context) => {
|
|
27563
|
+
this.getOrderBook = async (symbol, context, depth = GLOBAL_CONFIG.CC_ORDER_BOOK_MAX_DEPTH_LEVELS) => {
|
|
27441
27564
|
bt.exchangeValidationService.validate(context.exchangeName, EXCHANGE_METHOD_NAME_GET_ORDER_BOOK);
|
|
27442
27565
|
const instance = this._getInstance(context.exchangeName);
|
|
27443
|
-
return await instance.getOrderBook(symbol);
|
|
27566
|
+
return await instance.getOrderBook(symbol, depth);
|
|
27444
27567
|
};
|
|
27445
27568
|
}
|
|
27446
27569
|
}
|
|
@@ -28386,4 +28509,4 @@ class BreakevenUtils {
|
|
|
28386
28509
|
*/
|
|
28387
28510
|
const Breakeven = new BreakevenUtils();
|
|
28388
28511
|
|
|
28389
|
-
export { Backtest, Breakeven, Cache, Constant, Exchange, ExecutionContextService, Heat, Live, Markdown, MarkdownFileBase, MarkdownFolderBase, MethodContextService, Notification, Optimizer, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, Report, ReportBase, Risk, Schedule, Walker, 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, trailingTake, validate };
|
|
28512
|
+
export { Backtest, Breakeven, Cache, Constant, Exchange, ExecutionContextService, Heat, Live, Markdown, MarkdownFileBase, MarkdownFolderBase, MethodContextService, Notification, Optimizer, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, Report, ReportBase, Risk, Schedule, Walker, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, breakeven, cancel, dumpSignal, emitters, formatPrice, formatQuantity, getAveragePrice, getCandles, getColumns, getConfig, getDate, getDefaultColumns, getDefaultConfig, getMode, getOrderBook, 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, trailingTake, validate };
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -460,7 +460,7 @@ interface IExchangeParams extends IExchangeSchema {
|
|
|
460
460
|
/** Format price according to exchange precision rules (required, defaults applied) */
|
|
461
461
|
formatPrice: (symbol: string, price: number) => Promise<string>;
|
|
462
462
|
/** Fetch order book for a trading pair (required, defaults applied) */
|
|
463
|
-
getOrderBook: (symbol: string, from: Date, to: Date) => Promise<IOrderBookData>;
|
|
463
|
+
getOrderBook: (symbol: string, depth: number, from: Date, to: Date) => Promise<IOrderBookData>;
|
|
464
464
|
}
|
|
465
465
|
/**
|
|
466
466
|
* Optional callbacks for exchange data events.
|
|
@@ -514,11 +514,25 @@ interface IExchangeSchema {
|
|
|
514
514
|
* Optional. If not provided, throws an error when called.
|
|
515
515
|
*
|
|
516
516
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
517
|
-
* @param
|
|
518
|
-
* @param
|
|
517
|
+
* @param depth - Maximum depth levels for both bids and asks (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
518
|
+
* @param from - Start of time range (used in backtest for historical data, can be ignored in live)
|
|
519
|
+
* @param to - End of time range (used in backtest for historical data, can be ignored in live)
|
|
519
520
|
* @returns Promise resolving to order book data
|
|
521
|
+
*
|
|
522
|
+
* @example
|
|
523
|
+
* ```typescript
|
|
524
|
+
* // Backtest implementation: returns historical order book for the time range
|
|
525
|
+
* const backtestOrderBook = async (symbol: string, depth: number, from: Date, to: Date) => {
|
|
526
|
+
* return await database.getOrderBookSnapshot(symbol, depth, from, to);
|
|
527
|
+
* };
|
|
528
|
+
*
|
|
529
|
+
* // Live implementation: ignores from/to and returns current snapshot
|
|
530
|
+
* const liveOrderBook = async (symbol: string, depth: number, _from: Date, _to: Date) => {
|
|
531
|
+
* return await exchange.fetchOrderBook(symbol, depth);
|
|
532
|
+
* };
|
|
533
|
+
* ```
|
|
520
534
|
*/
|
|
521
|
-
getOrderBook?: (symbol: string, from: Date, to: Date) => Promise<IOrderBookData>;
|
|
535
|
+
getOrderBook?: (symbol: string, depth: number, from: Date, to: Date) => Promise<IOrderBookData>;
|
|
522
536
|
/** Optional lifecycle event callbacks (onCandleData) */
|
|
523
537
|
callbacks?: Partial<IExchangeCallbacks>;
|
|
524
538
|
}
|
|
@@ -575,9 +589,10 @@ interface IExchange {
|
|
|
575
589
|
* Fetch order book for a trading pair.
|
|
576
590
|
*
|
|
577
591
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
592
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
578
593
|
* @returns Promise resolving to order book data
|
|
579
594
|
*/
|
|
580
|
-
getOrderBook: (symbol: string) => Promise<IOrderBookData>;
|
|
595
|
+
getOrderBook: (symbol: string, depth?: number) => Promise<IOrderBookData>;
|
|
581
596
|
}
|
|
582
597
|
/**
|
|
583
598
|
* Unique exchange identifier.
|
|
@@ -2124,6 +2139,13 @@ declare const GLOBAL_CONFIG: {
|
|
|
2124
2139
|
* Default: 10 minutes
|
|
2125
2140
|
*/
|
|
2126
2141
|
CC_ORDER_BOOK_TIME_OFFSET_MINUTES: number;
|
|
2142
|
+
/**
|
|
2143
|
+
* Maximum depth levels for order book fetching.
|
|
2144
|
+
* Specifies how many price levels to fetch from both bids and asks.
|
|
2145
|
+
*
|
|
2146
|
+
* Default: 20 levels
|
|
2147
|
+
*/
|
|
2148
|
+
CC_ORDER_BOOK_MAX_DEPTH_LEVELS: number;
|
|
2127
2149
|
};
|
|
2128
2150
|
/**
|
|
2129
2151
|
* Type for global configuration object.
|
|
@@ -2227,6 +2249,7 @@ declare function getConfig(): {
|
|
|
2227
2249
|
CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
|
|
2228
2250
|
CC_BREAKEVEN_THRESHOLD: number;
|
|
2229
2251
|
CC_ORDER_BOOK_TIME_OFFSET_MINUTES: number;
|
|
2252
|
+
CC_ORDER_BOOK_MAX_DEPTH_LEVELS: number;
|
|
2230
2253
|
};
|
|
2231
2254
|
/**
|
|
2232
2255
|
* Retrieves the default configuration object for the framework.
|
|
@@ -2260,6 +2283,7 @@ declare function getDefaultConfig(): Readonly<{
|
|
|
2260
2283
|
CC_REPORT_SHOW_SIGNAL_NOTE: boolean;
|
|
2261
2284
|
CC_BREAKEVEN_THRESHOLD: number;
|
|
2262
2285
|
CC_ORDER_BOOK_TIME_OFFSET_MINUTES: number;
|
|
2286
|
+
CC_ORDER_BOOK_MAX_DEPTH_LEVELS: number;
|
|
2263
2287
|
}>;
|
|
2264
2288
|
/**
|
|
2265
2289
|
* Sets custom column configurations for markdown report generation.
|
|
@@ -5360,6 +5384,29 @@ declare function getDate(): Promise<Date>;
|
|
|
5360
5384
|
* ```
|
|
5361
5385
|
*/
|
|
5362
5386
|
declare function getMode(): Promise<"backtest" | "live">;
|
|
5387
|
+
/**
|
|
5388
|
+
* Fetches order book for a trading pair from the registered exchange.
|
|
5389
|
+
*
|
|
5390
|
+
* Uses current execution context to determine timing. The underlying exchange
|
|
5391
|
+
* implementation receives time range parameters but may use them (backtest)
|
|
5392
|
+
* or ignore them (live trading).
|
|
5393
|
+
*
|
|
5394
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
5395
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
5396
|
+
* @returns Promise resolving to order book data
|
|
5397
|
+
* @throws Error if execution or method context is missing
|
|
5398
|
+
*
|
|
5399
|
+
* @example
|
|
5400
|
+
* ```typescript
|
|
5401
|
+
* const orderBook = await getOrderBook("BTCUSDT");
|
|
5402
|
+
* console.log(orderBook.bids); // [{ price: "50000.00", quantity: "0.5" }, ...]
|
|
5403
|
+
* console.log(orderBook.asks); // [{ price: "50001.00", quantity: "0.3" }, ...]
|
|
5404
|
+
*
|
|
5405
|
+
* // Fetch deeper order book
|
|
5406
|
+
* const deepBook = await getOrderBook("BTCUSDT", 100);
|
|
5407
|
+
* ```
|
|
5408
|
+
*/
|
|
5409
|
+
declare function getOrderBook(symbol: string, depth?: number): Promise<IOrderBookData>;
|
|
5363
5410
|
|
|
5364
5411
|
/**
|
|
5365
5412
|
* Dumps signal data and LLM conversation history to markdown files.
|
|
@@ -11138,13 +11185,18 @@ declare class ExchangeUtils {
|
|
|
11138
11185
|
/**
|
|
11139
11186
|
* Fetch order book for a trading pair.
|
|
11140
11187
|
*
|
|
11188
|
+
* Delegates to ExchangeInstance which calculates time range and passes it
|
|
11189
|
+
* to the exchange schema implementation. The from/to parameters may be used
|
|
11190
|
+
* (backtest) or ignored (live) depending on the implementation.
|
|
11191
|
+
*
|
|
11141
11192
|
* @param symbol - Trading pair symbol
|
|
11142
11193
|
* @param context - Execution context with exchange name
|
|
11194
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
11143
11195
|
* @returns Promise resolving to order book data
|
|
11144
11196
|
*/
|
|
11145
11197
|
getOrderBook: (symbol: string, context: {
|
|
11146
11198
|
exchangeName: ExchangeName;
|
|
11147
|
-
}) => Promise<IOrderBookData>;
|
|
11199
|
+
}, depth?: number) => Promise<IOrderBookData>;
|
|
11148
11200
|
}
|
|
11149
11201
|
/**
|
|
11150
11202
|
* Singleton instance of ExchangeUtils for convenient exchange operations.
|
|
@@ -12057,11 +12109,16 @@ declare class ClientExchange implements IExchange {
|
|
|
12057
12109
|
/**
|
|
12058
12110
|
* Fetches order book for a trading pair.
|
|
12059
12111
|
*
|
|
12112
|
+
* Calculates time range based on execution context time (when) and
|
|
12113
|
+
* CC_ORDER_BOOK_TIME_OFFSET_MINUTES, then delegates to the exchange
|
|
12114
|
+
* schema implementation which may use or ignore the time range.
|
|
12115
|
+
*
|
|
12060
12116
|
* @param symbol - Trading pair symbol
|
|
12117
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
12061
12118
|
* @returns Promise resolving to order book data
|
|
12062
12119
|
* @throws Error if getOrderBook is not implemented
|
|
12063
12120
|
*/
|
|
12064
|
-
getOrderBook(symbol: string): Promise<IOrderBookData>;
|
|
12121
|
+
getOrderBook(symbol: string, depth?: number): Promise<IOrderBookData>;
|
|
12065
12122
|
}
|
|
12066
12123
|
|
|
12067
12124
|
/**
|
|
@@ -12158,11 +12215,14 @@ declare class ExchangeConnectionService implements IExchange {
|
|
|
12158
12215
|
* Fetches order book for a trading pair using configured exchange.
|
|
12159
12216
|
*
|
|
12160
12217
|
* Routes to exchange determined by methodContextService.context.exchangeName.
|
|
12218
|
+
* The ClientExchange will calculate time range and pass it to the schema
|
|
12219
|
+
* implementation, which may use (backtest) or ignore (live) the parameters.
|
|
12161
12220
|
*
|
|
12162
12221
|
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
12222
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
12163
12223
|
* @returns Promise resolving to order book data
|
|
12164
12224
|
*/
|
|
12165
|
-
getOrderBook: (symbol: string) => Promise<IOrderBookData>;
|
|
12225
|
+
getOrderBook: (symbol: string, depth?: number) => Promise<IOrderBookData>;
|
|
12166
12226
|
}
|
|
12167
12227
|
|
|
12168
12228
|
/**
|
|
@@ -13222,12 +13282,17 @@ declare class ExchangeCoreService implements TExchange {
|
|
|
13222
13282
|
/**
|
|
13223
13283
|
* Fetches order book with execution context.
|
|
13224
13284
|
*
|
|
13285
|
+
* Sets up execution context with the provided when/backtest parameters.
|
|
13286
|
+
* The exchange implementation will receive time range parameters but may
|
|
13287
|
+
* choose to use them (backtest) or ignore them (live).
|
|
13288
|
+
*
|
|
13225
13289
|
* @param symbol - Trading pair symbol
|
|
13226
13290
|
* @param when - Timestamp for context
|
|
13227
13291
|
* @param backtest - Whether running in backtest mode
|
|
13292
|
+
* @param depth - Maximum depth levels (default: CC_ORDER_BOOK_MAX_DEPTH_LEVELS)
|
|
13228
13293
|
* @returns Promise resolving to order book data
|
|
13229
13294
|
*/
|
|
13230
|
-
getOrderBook: (symbol: string, when: Date, backtest: boolean) => Promise<IOrderBookData>;
|
|
13295
|
+
getOrderBook: (symbol: string, when: Date, backtest: boolean, depth?: number) => Promise<IOrderBookData>;
|
|
13231
13296
|
}
|
|
13232
13297
|
|
|
13233
13298
|
/**
|
|
@@ -16194,4 +16259,4 @@ declare const backtest: {
|
|
|
16194
16259
|
loggerService: LoggerService;
|
|
16195
16260
|
};
|
|
16196
16261
|
|
|
16197
|
-
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 IBidData, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IMarkdownDumpOptions, type IOptimizerCallbacks, type IOptimizerData, type IOptimizerFetchArgs, type IOptimizerFilterArgs, type IOptimizerRange, type IOptimizerSchema, type IOptimizerSource, type IOptimizerStrategy, type IOptimizerTemplate, type IOrderBookData, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IReportDumpOptions, 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, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, 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, Report, ReportBase, type ReportName, 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 TMarkdownBase, type TPersistBase, type TPersistBaseCtor, type TReportBase, 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, trailingTake, validate };
|
|
16262
|
+
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 IBidData, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IMarkdownDumpOptions, type IOptimizerCallbacks, type IOptimizerData, type IOptimizerFetchArgs, type IOptimizerFilterArgs, type IOptimizerRange, type IOptimizerSchema, type IOptimizerSource, type IOptimizerStrategy, type IOptimizerTemplate, type IOrderBookData, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IReportDumpOptions, 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, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, 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, Report, ReportBase, type ReportName, 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 TMarkdownBase, type TPersistBase, type TPersistBaseCtor, type TReportBase, 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, getOrderBook, 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, trailingTake, validate };
|