backtest-kit 3.0.6 → 3.0.7
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 +40 -15
- package/build/index.mjs +40 -15
- package/package.json +1 -1
- package/types.d.ts +16 -5
package/build/index.cjs
CHANGED
|
@@ -36307,6 +36307,11 @@ const CREATE_KEY_FN = (strategyName, exchangeName, frameName, backtest) => {
|
|
|
36307
36307
|
parts.push(backtest ? "backtest" : "live");
|
|
36308
36308
|
return parts.join(":");
|
|
36309
36309
|
};
|
|
36310
|
+
/**
|
|
36311
|
+
* A unique symbol representing a value that should never occur.
|
|
36312
|
+
* Used as default key when no key function is provided.
|
|
36313
|
+
*/
|
|
36314
|
+
const NEVER_VALUE = Symbol("never");
|
|
36310
36315
|
/**
|
|
36311
36316
|
* Instance class for caching function results with timeframe-based invalidation.
|
|
36312
36317
|
*
|
|
@@ -36315,6 +36320,7 @@ const CREATE_KEY_FN = (strategyName, exchangeName, frameName, backtest) => {
|
|
|
36315
36320
|
* Cache is invalidated when the current time moves to a different interval.
|
|
36316
36321
|
*
|
|
36317
36322
|
* @template T - Function type to cache
|
|
36323
|
+
* @template K - Key type for argument-based caching
|
|
36318
36324
|
*
|
|
36319
36325
|
* @example
|
|
36320
36326
|
* ```typescript
|
|
@@ -36331,11 +36337,13 @@ class CacheInstance {
|
|
|
36331
36337
|
*
|
|
36332
36338
|
* @param fn - Function to cache
|
|
36333
36339
|
* @param interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
36340
|
+
* @param key - Optional key generator function for argument-based caching
|
|
36334
36341
|
*/
|
|
36335
|
-
constructor(fn, interval) {
|
|
36342
|
+
constructor(fn, interval, key = () => NEVER_VALUE) {
|
|
36336
36343
|
this.fn = fn;
|
|
36337
36344
|
this.interval = interval;
|
|
36338
|
-
|
|
36345
|
+
this.key = key;
|
|
36346
|
+
/** Cache map storing results per strategy/exchange/mode/argKey combination */
|
|
36339
36347
|
this._cacheMap = new Map();
|
|
36340
36348
|
/**
|
|
36341
36349
|
* Execute function with caching based on timeframe intervals.
|
|
@@ -36382,7 +36390,9 @@ class CacheInstance {
|
|
|
36382
36390
|
throw new Error(`CacheInstance unknown cache ttl interval=${this.interval}`);
|
|
36383
36391
|
}
|
|
36384
36392
|
}
|
|
36385
|
-
const
|
|
36393
|
+
const contextKey = CREATE_KEY_FN(bt.methodContextService.context.strategyName, bt.methodContextService.context.exchangeName, bt.methodContextService.context.frameName, bt.executionContextService.context.backtest);
|
|
36394
|
+
const argKey = String(this.key(args));
|
|
36395
|
+
const key = `${contextKey}:${argKey}`;
|
|
36386
36396
|
const currentWhen = bt.executionContextService.context.when;
|
|
36387
36397
|
const cached = this._cacheMap.get(key);
|
|
36388
36398
|
if (cached) {
|
|
@@ -36400,13 +36410,13 @@ class CacheInstance {
|
|
|
36400
36410
|
return newCache;
|
|
36401
36411
|
};
|
|
36402
36412
|
/**
|
|
36403
|
-
* Clear cached
|
|
36413
|
+
* Clear cached values for current execution context.
|
|
36404
36414
|
*
|
|
36405
|
-
* Removes
|
|
36415
|
+
* Removes all cached entries for the current strategy/exchange/mode combination
|
|
36406
36416
|
* from this instance's cache map. The next `run()` call will recompute the value.
|
|
36407
36417
|
*
|
|
36408
36418
|
* Requires active execution context (strategy, exchange, backtest mode) and method context
|
|
36409
|
-
* to determine which cache
|
|
36419
|
+
* to determine which cache entries to clear.
|
|
36410
36420
|
*
|
|
36411
36421
|
* @example
|
|
36412
36422
|
* ```typescript
|
|
@@ -36414,14 +36424,19 @@ class CacheInstance {
|
|
|
36414
36424
|
* const result1 = instance.run("BTCUSDT", 14); // Computed
|
|
36415
36425
|
* const result2 = instance.run("BTCUSDT", 14); // Cached
|
|
36416
36426
|
*
|
|
36417
|
-
* instance.clear(); // Clear cache for current context
|
|
36427
|
+
* instance.clear(); // Clear all cache entries for current context
|
|
36418
36428
|
*
|
|
36419
36429
|
* const result3 = instance.run("BTCUSDT", 14); // Recomputed
|
|
36420
36430
|
* ```
|
|
36421
36431
|
*/
|
|
36422
36432
|
this.clear = () => {
|
|
36423
|
-
const
|
|
36424
|
-
|
|
36433
|
+
const contextKey = CREATE_KEY_FN(bt.methodContextService.context.strategyName, bt.methodContextService.context.exchangeName, bt.methodContextService.context.frameName, bt.executionContextService.context.backtest);
|
|
36434
|
+
const prefix = `${contextKey}:`;
|
|
36435
|
+
for (const key of this._cacheMap.keys()) {
|
|
36436
|
+
if (key.startsWith(prefix)) {
|
|
36437
|
+
this._cacheMap.delete(key);
|
|
36438
|
+
}
|
|
36439
|
+
}
|
|
36425
36440
|
};
|
|
36426
36441
|
}
|
|
36427
36442
|
}
|
|
@@ -36446,7 +36461,7 @@ class CacheUtils {
|
|
|
36446
36461
|
* Memoized function to get or create CacheInstance for a function.
|
|
36447
36462
|
* Each function gets its own isolated cache instance.
|
|
36448
36463
|
*/
|
|
36449
|
-
this._getInstance = functoolsKit.memoize(([run]) => run, (run, interval) => new CacheInstance(run, interval));
|
|
36464
|
+
this._getInstance = functoolsKit.memoize(([run]) => run, (run, interval, key) => new CacheInstance(run, interval, key));
|
|
36450
36465
|
/**
|
|
36451
36466
|
* Wrap a function with caching based on timeframe intervals.
|
|
36452
36467
|
*
|
|
@@ -36454,8 +36469,10 @@ class CacheUtils {
|
|
|
36454
36469
|
* and invalidates based on the specified candle interval.
|
|
36455
36470
|
*
|
|
36456
36471
|
* @template T - Function type to cache
|
|
36472
|
+
* @template K - Key type for argument-based caching
|
|
36457
36473
|
* @param run - Function to wrap with caching
|
|
36458
|
-
* @param interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
36474
|
+
* @param context.interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
36475
|
+
* @param context.key - Optional key generator function for argument-based caching
|
|
36459
36476
|
* @returns Wrapped function with automatic caching
|
|
36460
36477
|
*
|
|
36461
36478
|
* @example
|
|
@@ -36465,9 +36482,17 @@ class CacheUtils {
|
|
|
36465
36482
|
* return result;
|
|
36466
36483
|
* };
|
|
36467
36484
|
*
|
|
36468
|
-
*
|
|
36469
|
-
* const
|
|
36470
|
-
*
|
|
36485
|
+
* // Without key - single cache entry per context
|
|
36486
|
+
* const cachedCalculate = Cache.fn(calculateIndicator, { interval: "15m" });
|
|
36487
|
+
*
|
|
36488
|
+
* // With key - separate cache entries per symbol
|
|
36489
|
+
* const cachedCalculate = Cache.fn(calculateIndicator, {
|
|
36490
|
+
* interval: "15m",
|
|
36491
|
+
* key: ([symbol]) => symbol,
|
|
36492
|
+
* });
|
|
36493
|
+
* const result1 = cachedCalculate("BTCUSDT", 14); // Computed
|
|
36494
|
+
* const result2 = cachedCalculate("ETHUSDT", 14); // Computed (different key)
|
|
36495
|
+
* const result3 = cachedCalculate("BTCUSDT", 14); // Cached (same key, same interval)
|
|
36471
36496
|
* ```
|
|
36472
36497
|
*/
|
|
36473
36498
|
this.fn = (run, context) => {
|
|
@@ -36475,7 +36500,7 @@ class CacheUtils {
|
|
|
36475
36500
|
context,
|
|
36476
36501
|
});
|
|
36477
36502
|
const wrappedFn = (...args) => {
|
|
36478
|
-
const instance = this._getInstance(run, context.interval);
|
|
36503
|
+
const instance = this._getInstance(run, context.interval, context.key);
|
|
36479
36504
|
return instance.run(...args).value;
|
|
36480
36505
|
};
|
|
36481
36506
|
return wrappedFn;
|
package/build/index.mjs
CHANGED
|
@@ -36287,6 +36287,11 @@ const CREATE_KEY_FN = (strategyName, exchangeName, frameName, backtest) => {
|
|
|
36287
36287
|
parts.push(backtest ? "backtest" : "live");
|
|
36288
36288
|
return parts.join(":");
|
|
36289
36289
|
};
|
|
36290
|
+
/**
|
|
36291
|
+
* A unique symbol representing a value that should never occur.
|
|
36292
|
+
* Used as default key when no key function is provided.
|
|
36293
|
+
*/
|
|
36294
|
+
const NEVER_VALUE = Symbol("never");
|
|
36290
36295
|
/**
|
|
36291
36296
|
* Instance class for caching function results with timeframe-based invalidation.
|
|
36292
36297
|
*
|
|
@@ -36295,6 +36300,7 @@ const CREATE_KEY_FN = (strategyName, exchangeName, frameName, backtest) => {
|
|
|
36295
36300
|
* Cache is invalidated when the current time moves to a different interval.
|
|
36296
36301
|
*
|
|
36297
36302
|
* @template T - Function type to cache
|
|
36303
|
+
* @template K - Key type for argument-based caching
|
|
36298
36304
|
*
|
|
36299
36305
|
* @example
|
|
36300
36306
|
* ```typescript
|
|
@@ -36311,11 +36317,13 @@ class CacheInstance {
|
|
|
36311
36317
|
*
|
|
36312
36318
|
* @param fn - Function to cache
|
|
36313
36319
|
* @param interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
36320
|
+
* @param key - Optional key generator function for argument-based caching
|
|
36314
36321
|
*/
|
|
36315
|
-
constructor(fn, interval) {
|
|
36322
|
+
constructor(fn, interval, key = () => NEVER_VALUE) {
|
|
36316
36323
|
this.fn = fn;
|
|
36317
36324
|
this.interval = interval;
|
|
36318
|
-
|
|
36325
|
+
this.key = key;
|
|
36326
|
+
/** Cache map storing results per strategy/exchange/mode/argKey combination */
|
|
36319
36327
|
this._cacheMap = new Map();
|
|
36320
36328
|
/**
|
|
36321
36329
|
* Execute function with caching based on timeframe intervals.
|
|
@@ -36362,7 +36370,9 @@ class CacheInstance {
|
|
|
36362
36370
|
throw new Error(`CacheInstance unknown cache ttl interval=${this.interval}`);
|
|
36363
36371
|
}
|
|
36364
36372
|
}
|
|
36365
|
-
const
|
|
36373
|
+
const contextKey = CREATE_KEY_FN(bt.methodContextService.context.strategyName, bt.methodContextService.context.exchangeName, bt.methodContextService.context.frameName, bt.executionContextService.context.backtest);
|
|
36374
|
+
const argKey = String(this.key(args));
|
|
36375
|
+
const key = `${contextKey}:${argKey}`;
|
|
36366
36376
|
const currentWhen = bt.executionContextService.context.when;
|
|
36367
36377
|
const cached = this._cacheMap.get(key);
|
|
36368
36378
|
if (cached) {
|
|
@@ -36380,13 +36390,13 @@ class CacheInstance {
|
|
|
36380
36390
|
return newCache;
|
|
36381
36391
|
};
|
|
36382
36392
|
/**
|
|
36383
|
-
* Clear cached
|
|
36393
|
+
* Clear cached values for current execution context.
|
|
36384
36394
|
*
|
|
36385
|
-
* Removes
|
|
36395
|
+
* Removes all cached entries for the current strategy/exchange/mode combination
|
|
36386
36396
|
* from this instance's cache map. The next `run()` call will recompute the value.
|
|
36387
36397
|
*
|
|
36388
36398
|
* Requires active execution context (strategy, exchange, backtest mode) and method context
|
|
36389
|
-
* to determine which cache
|
|
36399
|
+
* to determine which cache entries to clear.
|
|
36390
36400
|
*
|
|
36391
36401
|
* @example
|
|
36392
36402
|
* ```typescript
|
|
@@ -36394,14 +36404,19 @@ class CacheInstance {
|
|
|
36394
36404
|
* const result1 = instance.run("BTCUSDT", 14); // Computed
|
|
36395
36405
|
* const result2 = instance.run("BTCUSDT", 14); // Cached
|
|
36396
36406
|
*
|
|
36397
|
-
* instance.clear(); // Clear cache for current context
|
|
36407
|
+
* instance.clear(); // Clear all cache entries for current context
|
|
36398
36408
|
*
|
|
36399
36409
|
* const result3 = instance.run("BTCUSDT", 14); // Recomputed
|
|
36400
36410
|
* ```
|
|
36401
36411
|
*/
|
|
36402
36412
|
this.clear = () => {
|
|
36403
|
-
const
|
|
36404
|
-
|
|
36413
|
+
const contextKey = CREATE_KEY_FN(bt.methodContextService.context.strategyName, bt.methodContextService.context.exchangeName, bt.methodContextService.context.frameName, bt.executionContextService.context.backtest);
|
|
36414
|
+
const prefix = `${contextKey}:`;
|
|
36415
|
+
for (const key of this._cacheMap.keys()) {
|
|
36416
|
+
if (key.startsWith(prefix)) {
|
|
36417
|
+
this._cacheMap.delete(key);
|
|
36418
|
+
}
|
|
36419
|
+
}
|
|
36405
36420
|
};
|
|
36406
36421
|
}
|
|
36407
36422
|
}
|
|
@@ -36426,7 +36441,7 @@ class CacheUtils {
|
|
|
36426
36441
|
* Memoized function to get or create CacheInstance for a function.
|
|
36427
36442
|
* Each function gets its own isolated cache instance.
|
|
36428
36443
|
*/
|
|
36429
|
-
this._getInstance = memoize(([run]) => run, (run, interval) => new CacheInstance(run, interval));
|
|
36444
|
+
this._getInstance = memoize(([run]) => run, (run, interval, key) => new CacheInstance(run, interval, key));
|
|
36430
36445
|
/**
|
|
36431
36446
|
* Wrap a function with caching based on timeframe intervals.
|
|
36432
36447
|
*
|
|
@@ -36434,8 +36449,10 @@ class CacheUtils {
|
|
|
36434
36449
|
* and invalidates based on the specified candle interval.
|
|
36435
36450
|
*
|
|
36436
36451
|
* @template T - Function type to cache
|
|
36452
|
+
* @template K - Key type for argument-based caching
|
|
36437
36453
|
* @param run - Function to wrap with caching
|
|
36438
|
-
* @param interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
36454
|
+
* @param context.interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
36455
|
+
* @param context.key - Optional key generator function for argument-based caching
|
|
36439
36456
|
* @returns Wrapped function with automatic caching
|
|
36440
36457
|
*
|
|
36441
36458
|
* @example
|
|
@@ -36445,9 +36462,17 @@ class CacheUtils {
|
|
|
36445
36462
|
* return result;
|
|
36446
36463
|
* };
|
|
36447
36464
|
*
|
|
36448
|
-
*
|
|
36449
|
-
* const
|
|
36450
|
-
*
|
|
36465
|
+
* // Without key - single cache entry per context
|
|
36466
|
+
* const cachedCalculate = Cache.fn(calculateIndicator, { interval: "15m" });
|
|
36467
|
+
*
|
|
36468
|
+
* // With key - separate cache entries per symbol
|
|
36469
|
+
* const cachedCalculate = Cache.fn(calculateIndicator, {
|
|
36470
|
+
* interval: "15m",
|
|
36471
|
+
* key: ([symbol]) => symbol,
|
|
36472
|
+
* });
|
|
36473
|
+
* const result1 = cachedCalculate("BTCUSDT", 14); // Computed
|
|
36474
|
+
* const result2 = cachedCalculate("ETHUSDT", 14); // Computed (different key)
|
|
36475
|
+
* const result3 = cachedCalculate("BTCUSDT", 14); // Cached (same key, same interval)
|
|
36451
36476
|
* ```
|
|
36452
36477
|
*/
|
|
36453
36478
|
this.fn = (run, context) => {
|
|
@@ -36455,7 +36480,7 @@ class CacheUtils {
|
|
|
36455
36480
|
context,
|
|
36456
36481
|
});
|
|
36457
36482
|
const wrappedFn = (...args) => {
|
|
36458
|
-
const instance = this._getInstance(run, context.interval);
|
|
36483
|
+
const instance = this._getInstance(run, context.interval, context.key);
|
|
36459
36484
|
return instance.run(...args).value;
|
|
36460
36485
|
};
|
|
36461
36486
|
return wrappedFn;
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -13901,8 +13901,10 @@ declare class CacheUtils {
|
|
|
13901
13901
|
* and invalidates based on the specified candle interval.
|
|
13902
13902
|
*
|
|
13903
13903
|
* @template T - Function type to cache
|
|
13904
|
+
* @template K - Key type for argument-based caching
|
|
13904
13905
|
* @param run - Function to wrap with caching
|
|
13905
|
-
* @param interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
13906
|
+
* @param context.interval - Candle interval for cache invalidation (e.g., "1m", "1h")
|
|
13907
|
+
* @param context.key - Optional key generator function for argument-based caching
|
|
13906
13908
|
* @returns Wrapped function with automatic caching
|
|
13907
13909
|
*
|
|
13908
13910
|
* @example
|
|
@@ -13912,13 +13914,22 @@ declare class CacheUtils {
|
|
|
13912
13914
|
* return result;
|
|
13913
13915
|
* };
|
|
13914
13916
|
*
|
|
13915
|
-
*
|
|
13916
|
-
* const
|
|
13917
|
-
*
|
|
13917
|
+
* // Without key - single cache entry per context
|
|
13918
|
+
* const cachedCalculate = Cache.fn(calculateIndicator, { interval: "15m" });
|
|
13919
|
+
*
|
|
13920
|
+
* // With key - separate cache entries per symbol
|
|
13921
|
+
* const cachedCalculate = Cache.fn(calculateIndicator, {
|
|
13922
|
+
* interval: "15m",
|
|
13923
|
+
* key: ([symbol]) => symbol,
|
|
13924
|
+
* });
|
|
13925
|
+
* const result1 = cachedCalculate("BTCUSDT", 14); // Computed
|
|
13926
|
+
* const result2 = cachedCalculate("ETHUSDT", 14); // Computed (different key)
|
|
13927
|
+
* const result3 = cachedCalculate("BTCUSDT", 14); // Cached (same key, same interval)
|
|
13918
13928
|
* ```
|
|
13919
13929
|
*/
|
|
13920
|
-
fn: <T extends Function>(run: T, context: {
|
|
13930
|
+
fn: <T extends Function, K = symbol>(run: T, context: {
|
|
13921
13931
|
interval: CandleInterval;
|
|
13932
|
+
key?: (args: Parameters<T>) => K;
|
|
13922
13933
|
}) => T;
|
|
13923
13934
|
/**
|
|
13924
13935
|
* Flush (remove) cached CacheInstance for a specific function or all functions.
|