backtest-kit 1.3.0 → 1.3.1
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 +70 -6
- package/build/index.mjs +70 -6
- package/package.json +1 -1
- package/types.d.ts +27 -0
package/build/index.cjs
CHANGED
|
@@ -1625,6 +1625,9 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
|
1625
1625
|
if (!signal) {
|
|
1626
1626
|
return null;
|
|
1627
1627
|
}
|
|
1628
|
+
if (self._isStopped) {
|
|
1629
|
+
return null;
|
|
1630
|
+
}
|
|
1628
1631
|
// Если priceOpen указан - проверяем нужно ли ждать активации или открыть сразу
|
|
1629
1632
|
if (signal.priceOpen !== undefined) {
|
|
1630
1633
|
// КРИТИЧЕСКАЯ ПРОВЕРКА: достигнут ли priceOpen?
|
|
@@ -2351,6 +2354,14 @@ class ClientStrategy {
|
|
|
2351
2354
|
}
|
|
2352
2355
|
await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.strategyName, this.params.execution.context.symbol);
|
|
2353
2356
|
}
|
|
2357
|
+
/**
|
|
2358
|
+
* Retrieves the current pending signal.
|
|
2359
|
+
* If no signal is pending, returns null.
|
|
2360
|
+
* @returns Promise resolving to the pending signal or null.
|
|
2361
|
+
*/
|
|
2362
|
+
async getPendingSignal() {
|
|
2363
|
+
return this._pendingSignal;
|
|
2364
|
+
}
|
|
2354
2365
|
/**
|
|
2355
2366
|
* Performs a single tick of strategy execution.
|
|
2356
2367
|
*
|
|
@@ -2656,6 +2667,17 @@ class StrategyConnectionService {
|
|
|
2656
2667
|
callbacks,
|
|
2657
2668
|
});
|
|
2658
2669
|
});
|
|
2670
|
+
/**
|
|
2671
|
+
* Retrieves the currently active pending signal for the strategy.
|
|
2672
|
+
* If no active signal exists, returns null.
|
|
2673
|
+
* Used internally for monitoring TP/SL and time expiration.
|
|
2674
|
+
* @returns Promise resolving to pending signal or null
|
|
2675
|
+
*/
|
|
2676
|
+
this.getPendingSignal = async () => {
|
|
2677
|
+
this.loggerService.log("strategyConnectionService getPendingSignal");
|
|
2678
|
+
const strategy = await this.getStrategy(this.methodContextService.context.strategyName);
|
|
2679
|
+
return await strategy.getPendingSignal();
|
|
2680
|
+
};
|
|
2659
2681
|
/**
|
|
2660
2682
|
* Executes live trading tick for current strategy.
|
|
2661
2683
|
*
|
|
@@ -3558,6 +3580,31 @@ class StrategyGlobalService {
|
|
|
3558
3580
|
riskName &&
|
|
3559
3581
|
this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE);
|
|
3560
3582
|
});
|
|
3583
|
+
/**
|
|
3584
|
+
* Retrieves the currently active pending signal for the symbol.
|
|
3585
|
+
* If no active signal exists, returns null.
|
|
3586
|
+
* Used internally for monitoring TP/SL and time expiration.
|
|
3587
|
+
*
|
|
3588
|
+
* @param symbol - Trading pair symbol
|
|
3589
|
+
* @param when - Timestamp for tick evaluation
|
|
3590
|
+
* @param backtest - Whether running in backtest mode
|
|
3591
|
+
* @returns Promise resolving to pending signal or null
|
|
3592
|
+
*/
|
|
3593
|
+
this.getPendingSignal = async (symbol, when, backtest) => {
|
|
3594
|
+
this.loggerService.log("strategyGlobalService getPendingSignal", {
|
|
3595
|
+
symbol,
|
|
3596
|
+
when,
|
|
3597
|
+
backtest,
|
|
3598
|
+
});
|
|
3599
|
+
await this.validate(this.methodContextService.context.strategyName);
|
|
3600
|
+
return await ExecutionContextService.runInContext(async () => {
|
|
3601
|
+
return await this.strategyConnectionService.getPendingSignal();
|
|
3602
|
+
}, {
|
|
3603
|
+
symbol,
|
|
3604
|
+
when,
|
|
3605
|
+
backtest,
|
|
3606
|
+
});
|
|
3607
|
+
};
|
|
3561
3608
|
/**
|
|
3562
3609
|
* Checks signal status at a specific timestamp.
|
|
3563
3610
|
*
|
|
@@ -9485,22 +9532,39 @@ class LiveUtils {
|
|
|
9485
9532
|
context,
|
|
9486
9533
|
});
|
|
9487
9534
|
let isStopped = false;
|
|
9535
|
+
let isDone = false;
|
|
9488
9536
|
const task = async () => {
|
|
9489
9537
|
for await (const signal of this.run(symbol, context)) {
|
|
9490
9538
|
if (signal?.action === "closed" && isStopped) {
|
|
9491
9539
|
break;
|
|
9492
9540
|
}
|
|
9493
9541
|
}
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9542
|
+
if (!isDone) {
|
|
9543
|
+
await doneLiveSubject.next({
|
|
9544
|
+
exchangeName: context.exchangeName,
|
|
9545
|
+
strategyName: context.strategyName,
|
|
9546
|
+
backtest: false,
|
|
9547
|
+
symbol,
|
|
9548
|
+
});
|
|
9549
|
+
}
|
|
9550
|
+
isDone = true;
|
|
9500
9551
|
};
|
|
9501
9552
|
task().catch((error) => errorEmitter.next(new Error(functoolsKit.getErrorMessage(error))));
|
|
9502
9553
|
return () => {
|
|
9503
9554
|
backtest$1.strategyGlobalService.stop(context.strategyName);
|
|
9555
|
+
backtest$1.strategyGlobalService
|
|
9556
|
+
.getPendingSignal(symbol, new Date(), false)
|
|
9557
|
+
.then(async () => {
|
|
9558
|
+
if (!isDone) {
|
|
9559
|
+
await doneLiveSubject.next({
|
|
9560
|
+
exchangeName: context.exchangeName,
|
|
9561
|
+
strategyName: context.strategyName,
|
|
9562
|
+
backtest: false,
|
|
9563
|
+
symbol,
|
|
9564
|
+
});
|
|
9565
|
+
}
|
|
9566
|
+
isDone = true;
|
|
9567
|
+
});
|
|
9504
9568
|
isStopped = true;
|
|
9505
9569
|
};
|
|
9506
9570
|
};
|
package/build/index.mjs
CHANGED
|
@@ -1623,6 +1623,9 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
1623
1623
|
if (!signal) {
|
|
1624
1624
|
return null;
|
|
1625
1625
|
}
|
|
1626
|
+
if (self._isStopped) {
|
|
1627
|
+
return null;
|
|
1628
|
+
}
|
|
1626
1629
|
// Если priceOpen указан - проверяем нужно ли ждать активации или открыть сразу
|
|
1627
1630
|
if (signal.priceOpen !== undefined) {
|
|
1628
1631
|
// КРИТИЧЕСКАЯ ПРОВЕРКА: достигнут ли priceOpen?
|
|
@@ -2349,6 +2352,14 @@ class ClientStrategy {
|
|
|
2349
2352
|
}
|
|
2350
2353
|
await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.strategyName, this.params.execution.context.symbol);
|
|
2351
2354
|
}
|
|
2355
|
+
/**
|
|
2356
|
+
* Retrieves the current pending signal.
|
|
2357
|
+
* If no signal is pending, returns null.
|
|
2358
|
+
* @returns Promise resolving to the pending signal or null.
|
|
2359
|
+
*/
|
|
2360
|
+
async getPendingSignal() {
|
|
2361
|
+
return this._pendingSignal;
|
|
2362
|
+
}
|
|
2352
2363
|
/**
|
|
2353
2364
|
* Performs a single tick of strategy execution.
|
|
2354
2365
|
*
|
|
@@ -2654,6 +2665,17 @@ class StrategyConnectionService {
|
|
|
2654
2665
|
callbacks,
|
|
2655
2666
|
});
|
|
2656
2667
|
});
|
|
2668
|
+
/**
|
|
2669
|
+
* Retrieves the currently active pending signal for the strategy.
|
|
2670
|
+
* If no active signal exists, returns null.
|
|
2671
|
+
* Used internally for monitoring TP/SL and time expiration.
|
|
2672
|
+
* @returns Promise resolving to pending signal or null
|
|
2673
|
+
*/
|
|
2674
|
+
this.getPendingSignal = async () => {
|
|
2675
|
+
this.loggerService.log("strategyConnectionService getPendingSignal");
|
|
2676
|
+
const strategy = await this.getStrategy(this.methodContextService.context.strategyName);
|
|
2677
|
+
return await strategy.getPendingSignal();
|
|
2678
|
+
};
|
|
2657
2679
|
/**
|
|
2658
2680
|
* Executes live trading tick for current strategy.
|
|
2659
2681
|
*
|
|
@@ -3556,6 +3578,31 @@ class StrategyGlobalService {
|
|
|
3556
3578
|
riskName &&
|
|
3557
3579
|
this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE);
|
|
3558
3580
|
});
|
|
3581
|
+
/**
|
|
3582
|
+
* Retrieves the currently active pending signal for the symbol.
|
|
3583
|
+
* If no active signal exists, returns null.
|
|
3584
|
+
* Used internally for monitoring TP/SL and time expiration.
|
|
3585
|
+
*
|
|
3586
|
+
* @param symbol - Trading pair symbol
|
|
3587
|
+
* @param when - Timestamp for tick evaluation
|
|
3588
|
+
* @param backtest - Whether running in backtest mode
|
|
3589
|
+
* @returns Promise resolving to pending signal or null
|
|
3590
|
+
*/
|
|
3591
|
+
this.getPendingSignal = async (symbol, when, backtest) => {
|
|
3592
|
+
this.loggerService.log("strategyGlobalService getPendingSignal", {
|
|
3593
|
+
symbol,
|
|
3594
|
+
when,
|
|
3595
|
+
backtest,
|
|
3596
|
+
});
|
|
3597
|
+
await this.validate(this.methodContextService.context.strategyName);
|
|
3598
|
+
return await ExecutionContextService.runInContext(async () => {
|
|
3599
|
+
return await this.strategyConnectionService.getPendingSignal();
|
|
3600
|
+
}, {
|
|
3601
|
+
symbol,
|
|
3602
|
+
when,
|
|
3603
|
+
backtest,
|
|
3604
|
+
});
|
|
3605
|
+
};
|
|
3559
3606
|
/**
|
|
3560
3607
|
* Checks signal status at a specific timestamp.
|
|
3561
3608
|
*
|
|
@@ -9483,22 +9530,39 @@ class LiveUtils {
|
|
|
9483
9530
|
context,
|
|
9484
9531
|
});
|
|
9485
9532
|
let isStopped = false;
|
|
9533
|
+
let isDone = false;
|
|
9486
9534
|
const task = async () => {
|
|
9487
9535
|
for await (const signal of this.run(symbol, context)) {
|
|
9488
9536
|
if (signal?.action === "closed" && isStopped) {
|
|
9489
9537
|
break;
|
|
9490
9538
|
}
|
|
9491
9539
|
}
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9540
|
+
if (!isDone) {
|
|
9541
|
+
await doneLiveSubject.next({
|
|
9542
|
+
exchangeName: context.exchangeName,
|
|
9543
|
+
strategyName: context.strategyName,
|
|
9544
|
+
backtest: false,
|
|
9545
|
+
symbol,
|
|
9546
|
+
});
|
|
9547
|
+
}
|
|
9548
|
+
isDone = true;
|
|
9498
9549
|
};
|
|
9499
9550
|
task().catch((error) => errorEmitter.next(new Error(getErrorMessage(error))));
|
|
9500
9551
|
return () => {
|
|
9501
9552
|
backtest$1.strategyGlobalService.stop(context.strategyName);
|
|
9553
|
+
backtest$1.strategyGlobalService
|
|
9554
|
+
.getPendingSignal(symbol, new Date(), false)
|
|
9555
|
+
.then(async () => {
|
|
9556
|
+
if (!isDone) {
|
|
9557
|
+
await doneLiveSubject.next({
|
|
9558
|
+
exchangeName: context.exchangeName,
|
|
9559
|
+
strategyName: context.strategyName,
|
|
9560
|
+
backtest: false,
|
|
9561
|
+
symbol,
|
|
9562
|
+
});
|
|
9563
|
+
}
|
|
9564
|
+
isDone = true;
|
|
9565
|
+
});
|
|
9502
9566
|
isStopped = true;
|
|
9503
9567
|
};
|
|
9504
9568
|
};
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -825,6 +825,15 @@ interface IStrategy {
|
|
|
825
825
|
* @returns Promise resolving to tick result (idle | opened | active | closed)
|
|
826
826
|
*/
|
|
827
827
|
tick: (symbol: string) => Promise<IStrategyTickResult>;
|
|
828
|
+
/**
|
|
829
|
+
* Retrieves the currently active pending signal for the symbol.
|
|
830
|
+
* If no active signal exists, returns null.
|
|
831
|
+
* Used internally for monitoring TP/SL and time expiration.
|
|
832
|
+
*
|
|
833
|
+
* @param symbol
|
|
834
|
+
* @returns
|
|
835
|
+
*/
|
|
836
|
+
getPendingSignal: (symbol: string) => Promise<ISignalRow | null>;
|
|
828
837
|
/**
|
|
829
838
|
* Fast backtest using historical candles.
|
|
830
839
|
* Iterates through candles, calculates VWAP, checks TP/SL on each candle.
|
|
@@ -4718,6 +4727,13 @@ declare class StrategyConnectionService implements IStrategy {
|
|
|
4718
4727
|
* @returns Configured ClientStrategy instance
|
|
4719
4728
|
*/
|
|
4720
4729
|
private getStrategy;
|
|
4730
|
+
/**
|
|
4731
|
+
* Retrieves the currently active pending signal for the strategy.
|
|
4732
|
+
* If no active signal exists, returns null.
|
|
4733
|
+
* Used internally for monitoring TP/SL and time expiration.
|
|
4734
|
+
* @returns Promise resolving to pending signal or null
|
|
4735
|
+
*/
|
|
4736
|
+
getPendingSignal: () => Promise<ISignalRow | null>;
|
|
4721
4737
|
/**
|
|
4722
4738
|
* Executes live trading tick for current strategy.
|
|
4723
4739
|
*
|
|
@@ -5165,6 +5181,17 @@ declare class StrategyGlobalService {
|
|
|
5165
5181
|
* @returns Promise that resolves when validation is complete
|
|
5166
5182
|
*/
|
|
5167
5183
|
private validate;
|
|
5184
|
+
/**
|
|
5185
|
+
* Retrieves the currently active pending signal for the symbol.
|
|
5186
|
+
* If no active signal exists, returns null.
|
|
5187
|
+
* Used internally for monitoring TP/SL and time expiration.
|
|
5188
|
+
*
|
|
5189
|
+
* @param symbol - Trading pair symbol
|
|
5190
|
+
* @param when - Timestamp for tick evaluation
|
|
5191
|
+
* @param backtest - Whether running in backtest mode
|
|
5192
|
+
* @returns Promise resolving to pending signal or null
|
|
5193
|
+
*/
|
|
5194
|
+
getPendingSignal: (symbol: string, when: Date, backtest: boolean) => Promise<ISignalRow | null>;
|
|
5168
5195
|
/**
|
|
5169
5196
|
* Checks signal status at a specific timestamp.
|
|
5170
5197
|
*
|