backtest-kit 1.1.6 โ 1.1.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/README.md +167 -30
- package/build/index.cjs +5 -5
- package/build/index.mjs +5 -5
- package/package.json +1 -1
- package/types.d.ts +8 -9
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Backtest Kit
|
|
1
|
+
# ๐งฟ Backtest Kit
|
|
2
2
|
|
|
3
3
|
> A production-ready TypeScript framework for backtesting and live trading strategies with crash-safe state persistence, signal validation, and memory-optimized architecture.
|
|
4
4
|
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
- ๐ **Graceful Shutdown** - Live.background() waits for open positions to close before stopping
|
|
23
23
|
- ๐ **Strategy Dependency Injection** - addStrategy() enables DI pattern for trading strategies
|
|
24
24
|
- ๐ **Schema Reflection API** - listExchanges(), listStrategies(), listFrames() for runtime introspection
|
|
25
|
-
- ๐งช **Comprehensive Test Coverage** -
|
|
25
|
+
- ๐งช **Comprehensive Test Coverage** - 50+ unit tests covering validation, PNL, callbacks, reports, and event system
|
|
26
|
+
- ๐พ **Zero Data Download** - Unlike Freqtrade, no need to download gigabytes of historical data - plug any data source (CCXT, database, API)
|
|
27
|
+
- ๐ **Safe Math & Robustness** - All metrics protected against NaN/Infinity with unsafe numeric checks, returns N/A for invalid calculations
|
|
26
28
|
|
|
27
29
|
## Installation
|
|
28
30
|
|
|
@@ -106,7 +108,7 @@ addStrategy({
|
|
|
106
108
|
interval: "5m", // Throttling: signals generated max once per 5 minutes
|
|
107
109
|
getSignal: async (symbol) => {
|
|
108
110
|
// Your signal generation logic
|
|
109
|
-
// Validation happens automatically (prices, TP/SL logic
|
|
111
|
+
// Validation happens automatically (prices, TP/SL logic)
|
|
110
112
|
return {
|
|
111
113
|
position: "long",
|
|
112
114
|
note: "BTC breakout",
|
|
@@ -114,14 +116,13 @@ addStrategy({
|
|
|
114
116
|
priceTakeProfit: 51000, // Must be > priceOpen for long
|
|
115
117
|
priceStopLoss: 49000, // Must be < priceOpen for long
|
|
116
118
|
minuteEstimatedTime: 60, // Signal duration in minutes
|
|
117
|
-
timestamp: Date.now(),
|
|
118
119
|
};
|
|
119
120
|
},
|
|
120
121
|
callbacks: {
|
|
121
|
-
onOpen: (
|
|
122
|
+
onOpen: (symbol, signal, currentPrice, backtest) => {
|
|
122
123
|
console.log(`[${backtest ? "BT" : "LIVE"}] Signal opened:`, signal.id);
|
|
123
124
|
},
|
|
124
|
-
onClose: (
|
|
125
|
+
onClose: (symbol, signal, priceClose, backtest) => {
|
|
125
126
|
console.log(`[${backtest ? "BT" : "LIVE"}] Signal closed:`, priceClose);
|
|
126
127
|
},
|
|
127
128
|
},
|
|
@@ -348,7 +349,6 @@ All signals are validated automatically before execution:
|
|
|
348
349
|
priceTakeProfit: 51000, // โ
51000 > 50000
|
|
349
350
|
priceStopLoss: 49000, // โ
49000 < 50000
|
|
350
351
|
minuteEstimatedTime: 60, // โ
positive
|
|
351
|
-
timestamp: Date.now(), // โ
positive
|
|
352
352
|
}
|
|
353
353
|
|
|
354
354
|
// โ Invalid long signal - throws error
|
|
@@ -465,7 +465,26 @@ const stopBacktest = Backtest.background("BTCUSDT", {
|
|
|
465
465
|
frameName: "1d-backtest"
|
|
466
466
|
});
|
|
467
467
|
|
|
468
|
-
//
|
|
468
|
+
// Get raw statistical data (Controller)
|
|
469
|
+
const stats = await Backtest.getData("my-strategy");
|
|
470
|
+
console.log(stats);
|
|
471
|
+
// Returns:
|
|
472
|
+
// {
|
|
473
|
+
// signalList: [...], // All closed signals
|
|
474
|
+
// totalSignals: 10,
|
|
475
|
+
// winCount: 7,
|
|
476
|
+
// lossCount: 3,
|
|
477
|
+
// winRate: 70.0, // Percentage (higher is better)
|
|
478
|
+
// avgPnl: 1.23, // Average PNL % (higher is better)
|
|
479
|
+
// totalPnl: 12.30, // Total PNL % (higher is better)
|
|
480
|
+
// stdDev: 2.45, // Standard deviation (lower is better)
|
|
481
|
+
// sharpeRatio: 0.50, // Risk-adjusted return (higher is better)
|
|
482
|
+
// annualizedSharpeRatio: 9.55, // Sharpe ร โ365 (higher is better)
|
|
483
|
+
// certaintyRatio: 1.75, // avgWin / |avgLoss| (higher is better)
|
|
484
|
+
// expectedYearlyReturns: 156 // Estimated yearly trades (higher is better)
|
|
485
|
+
// }
|
|
486
|
+
|
|
487
|
+
// Generate markdown report (View)
|
|
469
488
|
const markdown = await Backtest.getReport("my-strategy");
|
|
470
489
|
console.log(markdown);
|
|
471
490
|
|
|
@@ -476,29 +495,75 @@ await Backtest.dump("my-strategy");
|
|
|
476
495
|
await Backtest.dump("my-strategy", "./custom/path");
|
|
477
496
|
```
|
|
478
497
|
|
|
479
|
-
**
|
|
480
|
-
-
|
|
498
|
+
**getData() returns BacktestStatistics:**
|
|
499
|
+
- `signalList` - Array of all closed signals
|
|
500
|
+
- `totalSignals` - Total number of closed signals
|
|
501
|
+
- `winCount` / `lossCount` - Number of winning/losing trades
|
|
502
|
+
- `winRate` - Win percentage (higher is better)
|
|
503
|
+
- `avgPnl` - Average PNL percentage (higher is better)
|
|
504
|
+
- `totalPnl` - Total PNL percentage (higher is better)
|
|
505
|
+
- `stdDev` - Standard deviation / volatility (lower is better)
|
|
506
|
+
- `sharpeRatio` - Risk-adjusted return (higher is better)
|
|
507
|
+
- `annualizedSharpeRatio` - Sharpe Ratio ร โ365 (higher is better)
|
|
508
|
+
- `certaintyRatio` - avgWin / |avgLoss| (higher is better)
|
|
509
|
+
- `expectedYearlyReturns` - Estimated number of trades per year (higher is better)
|
|
510
|
+
|
|
511
|
+
**getReport() includes:**
|
|
512
|
+
- All metrics from getData() formatted as markdown
|
|
481
513
|
- All signal details (prices, TP/SL, PNL, duration, close reason)
|
|
482
514
|
- Timestamps for each signal
|
|
515
|
+
- "Higher is better" / "Lower is better" annotations
|
|
483
516
|
|
|
484
517
|
### Live Trading Reports
|
|
485
518
|
|
|
486
519
|
```typescript
|
|
487
520
|
import { Live } from "backtest-kit";
|
|
488
521
|
|
|
489
|
-
//
|
|
522
|
+
// Get raw statistical data (Controller)
|
|
523
|
+
const stats = await Live.getData("my-strategy");
|
|
524
|
+
console.log(stats);
|
|
525
|
+
// Returns:
|
|
526
|
+
// {
|
|
527
|
+
// eventList: [...], // All events (idle, opened, active, closed)
|
|
528
|
+
// totalEvents: 15,
|
|
529
|
+
// totalClosed: 5,
|
|
530
|
+
// winCount: 3,
|
|
531
|
+
// lossCount: 2,
|
|
532
|
+
// winRate: 60.0, // Percentage (higher is better)
|
|
533
|
+
// avgPnl: 1.23, // Average PNL % (higher is better)
|
|
534
|
+
// totalPnl: 6.15, // Total PNL % (higher is better)
|
|
535
|
+
// stdDev: 1.85, // Standard deviation (lower is better)
|
|
536
|
+
// sharpeRatio: 0.66, // Risk-adjusted return (higher is better)
|
|
537
|
+
// annualizedSharpeRatio: 12.61,// Sharpe ร โ365 (higher is better)
|
|
538
|
+
// certaintyRatio: 2.10, // avgWin / |avgLoss| (higher is better)
|
|
539
|
+
// expectedYearlyReturns: 365 // Estimated yearly trades (higher is better)
|
|
540
|
+
// }
|
|
541
|
+
|
|
542
|
+
// Generate markdown report (View)
|
|
490
543
|
const markdown = await Live.getReport("my-strategy");
|
|
491
544
|
|
|
492
545
|
// Save to disk (default: ./logs/live/my-strategy.md)
|
|
493
546
|
await Live.dump("my-strategy");
|
|
494
547
|
```
|
|
495
548
|
|
|
496
|
-
**
|
|
497
|
-
-
|
|
498
|
-
-
|
|
499
|
-
-
|
|
500
|
-
-
|
|
549
|
+
**getData() returns LiveStatistics:**
|
|
550
|
+
- `eventList` - Array of all events (idle, opened, active, closed)
|
|
551
|
+
- `totalEvents` - Total number of events
|
|
552
|
+
- `totalClosed` - Total number of closed signals
|
|
553
|
+
- `winCount` / `lossCount` - Number of winning/losing trades
|
|
554
|
+
- `winRate` - Win percentage (higher is better)
|
|
555
|
+
- `avgPnl` - Average PNL percentage (higher is better)
|
|
556
|
+
- `totalPnl` - Total PNL percentage (higher is better)
|
|
557
|
+
- `stdDev` - Standard deviation / volatility (lower is better)
|
|
558
|
+
- `sharpeRatio` - Risk-adjusted return (higher is better)
|
|
559
|
+
- `annualizedSharpeRatio` - Sharpe Ratio ร โ365 (higher is better)
|
|
560
|
+
- `certaintyRatio` - avgWin / |avgLoss| (higher is better)
|
|
561
|
+
- `expectedYearlyReturns` - Estimated number of trades per year (higher is better)
|
|
562
|
+
|
|
563
|
+
**getReport() includes:**
|
|
564
|
+
- All metrics from getData() formatted as markdown
|
|
501
565
|
- Signal-by-signal details with current state
|
|
566
|
+
- "Higher is better" / "Lower is better" annotations
|
|
502
567
|
|
|
503
568
|
**Report example:**
|
|
504
569
|
```markdown
|
|
@@ -506,8 +571,14 @@ await Live.dump("my-strategy");
|
|
|
506
571
|
|
|
507
572
|
Total events: 15
|
|
508
573
|
Closed signals: 5
|
|
509
|
-
Win rate: 60.00% (3W / 2L)
|
|
510
|
-
Average PNL: +1.23%
|
|
574
|
+
Win rate: 60.00% (3W / 2L) (higher is better)
|
|
575
|
+
Average PNL: +1.23% (higher is better)
|
|
576
|
+
Total PNL: +6.15% (higher is better)
|
|
577
|
+
Standard Deviation: 1.85% (lower is better)
|
|
578
|
+
Sharpe Ratio: 0.66 (higher is better)
|
|
579
|
+
Annualized Sharpe Ratio: 12.61 (higher is better)
|
|
580
|
+
Certainty Ratio: 2.10 (higher is better)
|
|
581
|
+
Expected Yearly Returns: 365 trades (higher is better)
|
|
511
582
|
|
|
512
583
|
| Timestamp | Action | Symbol | Signal ID | Position | ... | PNL (net) | Close Reason |
|
|
513
584
|
|-----------|--------|--------|-----------|----------|-----|-----------|--------------|
|
|
@@ -744,7 +815,7 @@ const quantity = await formatQuantity("BTCUSDT", 0.123456789);
|
|
|
744
815
|
#### Backtest API
|
|
745
816
|
|
|
746
817
|
```typescript
|
|
747
|
-
import { Backtest } from "backtest-kit";
|
|
818
|
+
import { Backtest, BacktestStatistics } from "backtest-kit";
|
|
748
819
|
|
|
749
820
|
// Stream backtest results
|
|
750
821
|
Backtest.run(
|
|
@@ -762,7 +833,10 @@ Backtest.background(
|
|
|
762
833
|
context: { strategyName, exchangeName, frameName }
|
|
763
834
|
): Promise<() => void> // Returns cancellation function
|
|
764
835
|
|
|
765
|
-
//
|
|
836
|
+
// Get raw statistical data (Controller)
|
|
837
|
+
Backtest.getData(strategyName: string): Promise<BacktestStatistics>
|
|
838
|
+
|
|
839
|
+
// Generate markdown report (View)
|
|
766
840
|
Backtest.getReport(strategyName: string): Promise<string>
|
|
767
841
|
|
|
768
842
|
// Save report to disk
|
|
@@ -772,7 +846,7 @@ Backtest.dump(strategyName: string, path?: string): Promise<void>
|
|
|
772
846
|
#### Live Trading API
|
|
773
847
|
|
|
774
848
|
```typescript
|
|
775
|
-
import { Live } from "backtest-kit";
|
|
849
|
+
import { Live, LiveStatistics } from "backtest-kit";
|
|
776
850
|
|
|
777
851
|
// Stream live results (infinite)
|
|
778
852
|
Live.run(
|
|
@@ -789,7 +863,10 @@ Live.background(
|
|
|
789
863
|
context: { strategyName, exchangeName }
|
|
790
864
|
): Promise<() => void> // Returns cancellation function
|
|
791
865
|
|
|
792
|
-
//
|
|
866
|
+
// Get raw statistical data (Controller)
|
|
867
|
+
Live.getData(strategyName: string): Promise<LiveStatistics>
|
|
868
|
+
|
|
869
|
+
// Generate markdown report (View)
|
|
793
870
|
Live.getReport(strategyName: string): Promise<string>
|
|
794
871
|
|
|
795
872
|
// Save report to disk
|
|
@@ -798,18 +875,58 @@ Live.dump(strategyName: string, path?: string): Promise<void>
|
|
|
798
875
|
|
|
799
876
|
## Type Definitions
|
|
800
877
|
|
|
878
|
+
### Statistics Types
|
|
879
|
+
|
|
880
|
+
```typescript
|
|
881
|
+
// Backtest statistics (exported from "backtest-kit")
|
|
882
|
+
interface BacktestStatistics {
|
|
883
|
+
signalList: IStrategyTickResultClosed[]; // All closed signals
|
|
884
|
+
totalSignals: number;
|
|
885
|
+
winCount: number;
|
|
886
|
+
lossCount: number;
|
|
887
|
+
winRate: number | null; // Win percentage (higher is better)
|
|
888
|
+
avgPnl: number | null; // Average PNL % (higher is better)
|
|
889
|
+
totalPnl: number | null; // Total PNL % (higher is better)
|
|
890
|
+
stdDev: number | null; // Standard deviation (lower is better)
|
|
891
|
+
sharpeRatio: number | null; // Risk-adjusted return (higher is better)
|
|
892
|
+
annualizedSharpeRatio: number | null; // Sharpe ร โ365 (higher is better)
|
|
893
|
+
certaintyRatio: number | null; // avgWin / |avgLoss| (higher is better)
|
|
894
|
+
expectedYearlyReturns: number | null; // Estimated yearly trades (higher is better)
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Live statistics (exported from "backtest-kit")
|
|
898
|
+
interface LiveStatistics {
|
|
899
|
+
eventList: TickEvent[]; // All events (idle, opened, active, closed)
|
|
900
|
+
totalEvents: number;
|
|
901
|
+
totalClosed: number;
|
|
902
|
+
winCount: number;
|
|
903
|
+
lossCount: number;
|
|
904
|
+
winRate: number | null; // Win percentage (higher is better)
|
|
905
|
+
avgPnl: number | null; // Average PNL % (higher is better)
|
|
906
|
+
totalPnl: number | null; // Total PNL % (higher is better)
|
|
907
|
+
stdDev: number | null; // Standard deviation (lower is better)
|
|
908
|
+
sharpeRatio: number | null; // Risk-adjusted return (higher is better)
|
|
909
|
+
annualizedSharpeRatio: number | null; // Sharpe ร โ365 (higher is better)
|
|
910
|
+
certaintyRatio: number | null; // avgWin / |avgLoss| (higher is better)
|
|
911
|
+
expectedYearlyReturns: number | null; // Estimated yearly trades (higher is better)
|
|
912
|
+
}
|
|
913
|
+
```
|
|
914
|
+
|
|
801
915
|
### Signal Data
|
|
802
916
|
|
|
803
917
|
```typescript
|
|
804
918
|
interface ISignalRow {
|
|
805
|
-
id: string;
|
|
919
|
+
id: string; // UUID v4 auto-generated
|
|
806
920
|
position: "long" | "short";
|
|
807
|
-
note
|
|
921
|
+
note?: string;
|
|
808
922
|
priceOpen: number;
|
|
809
923
|
priceTakeProfit: number;
|
|
810
924
|
priceStopLoss: number;
|
|
811
925
|
minuteEstimatedTime: number;
|
|
812
|
-
|
|
926
|
+
exchangeName: string;
|
|
927
|
+
strategyName: string;
|
|
928
|
+
timestamp: number; // Signal creation timestamp
|
|
929
|
+
symbol: string; // Trading pair (e.g., "BTCUSDT")
|
|
813
930
|
}
|
|
814
931
|
```
|
|
815
932
|
|
|
@@ -817,9 +934,27 @@ interface ISignalRow {
|
|
|
817
934
|
|
|
818
935
|
```typescript
|
|
819
936
|
type IStrategyTickResult =
|
|
820
|
-
| {
|
|
821
|
-
|
|
822
|
-
|
|
937
|
+
| {
|
|
938
|
+
action: "idle";
|
|
939
|
+
signal: null;
|
|
940
|
+
strategyName: string;
|
|
941
|
+
exchangeName: string;
|
|
942
|
+
currentPrice: number;
|
|
943
|
+
}
|
|
944
|
+
| {
|
|
945
|
+
action: "opened";
|
|
946
|
+
signal: ISignalRow;
|
|
947
|
+
strategyName: string;
|
|
948
|
+
exchangeName: string;
|
|
949
|
+
currentPrice: number;
|
|
950
|
+
}
|
|
951
|
+
| {
|
|
952
|
+
action: "active";
|
|
953
|
+
signal: ISignalRow;
|
|
954
|
+
currentPrice: number;
|
|
955
|
+
strategyName: string;
|
|
956
|
+
exchangeName: string;
|
|
957
|
+
}
|
|
823
958
|
| {
|
|
824
959
|
action: "closed";
|
|
825
960
|
signal: ISignalRow;
|
|
@@ -827,10 +962,12 @@ type IStrategyTickResult =
|
|
|
827
962
|
closeReason: "take_profit" | "stop_loss" | "time_expired";
|
|
828
963
|
closeTimestamp: number;
|
|
829
964
|
pnl: {
|
|
830
|
-
priceOpenWithCosts: number;
|
|
831
|
-
priceCloseWithCosts: number;
|
|
832
965
|
pnlPercentage: number;
|
|
966
|
+
priceOpen: number; // Entry price adjusted with slippage and fees
|
|
967
|
+
priceClose: number; // Exit price adjusted with slippage and fees
|
|
833
968
|
};
|
|
969
|
+
strategyName: string;
|
|
970
|
+
exchangeName: string;
|
|
834
971
|
};
|
|
835
972
|
```
|
|
836
973
|
|
package/build/index.cjs
CHANGED
|
@@ -1043,8 +1043,7 @@ class PersistSignalUtils {
|
|
|
1043
1043
|
const stateStorage = this.getSignalStorage(strategyName);
|
|
1044
1044
|
await stateStorage.waitForInit(isInitial);
|
|
1045
1045
|
if (await stateStorage.hasValue(symbol)) {
|
|
1046
|
-
|
|
1047
|
-
return signalRow;
|
|
1046
|
+
return await stateStorage.readValue(symbol);
|
|
1048
1047
|
}
|
|
1049
1048
|
return null;
|
|
1050
1049
|
};
|
|
@@ -1064,7 +1063,7 @@ class PersistSignalUtils {
|
|
|
1064
1063
|
const isInitial = !this.getSignalStorage.has(strategyName);
|
|
1065
1064
|
const stateStorage = this.getSignalStorage(strategyName);
|
|
1066
1065
|
await stateStorage.waitForInit(isInitial);
|
|
1067
|
-
await stateStorage.writeValue(symbol,
|
|
1066
|
+
await stateStorage.writeValue(symbol, signalRow);
|
|
1068
1067
|
};
|
|
1069
1068
|
}
|
|
1070
1069
|
/**
|
|
@@ -1206,6 +1205,7 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
|
1206
1205
|
}
|
|
1207
1206
|
const signalRow = {
|
|
1208
1207
|
id: functoolsKit.randomString(),
|
|
1208
|
+
priceOpen: await self.params.exchange.getAveragePrice(self.params.execution.context.symbol),
|
|
1209
1209
|
...signal,
|
|
1210
1210
|
symbol: self.params.execution.context.symbol,
|
|
1211
1211
|
exchangeName: self.params.method.context.exchangeName,
|
|
@@ -3997,8 +3997,8 @@ const ADD_FRAME_METHOD_NAME = "add.addFrame";
|
|
|
3997
3997
|
* timestamp: Date.now(),
|
|
3998
3998
|
* }),
|
|
3999
3999
|
* callbacks: {
|
|
4000
|
-
* onOpen: (
|
|
4001
|
-
* onClose: (
|
|
4000
|
+
* onOpen: (symbol, signal, currentPrice, backtest) => console.log("Signal opened"),
|
|
4001
|
+
* onClose: (symbol, signal, priceClose, backtest) => console.log("Signal closed"),
|
|
4002
4002
|
* },
|
|
4003
4003
|
* });
|
|
4004
4004
|
* ```
|
package/build/index.mjs
CHANGED
|
@@ -1041,8 +1041,7 @@ class PersistSignalUtils {
|
|
|
1041
1041
|
const stateStorage = this.getSignalStorage(strategyName);
|
|
1042
1042
|
await stateStorage.waitForInit(isInitial);
|
|
1043
1043
|
if (await stateStorage.hasValue(symbol)) {
|
|
1044
|
-
|
|
1045
|
-
return signalRow;
|
|
1044
|
+
return await stateStorage.readValue(symbol);
|
|
1046
1045
|
}
|
|
1047
1046
|
return null;
|
|
1048
1047
|
};
|
|
@@ -1062,7 +1061,7 @@ class PersistSignalUtils {
|
|
|
1062
1061
|
const isInitial = !this.getSignalStorage.has(strategyName);
|
|
1063
1062
|
const stateStorage = this.getSignalStorage(strategyName);
|
|
1064
1063
|
await stateStorage.waitForInit(isInitial);
|
|
1065
|
-
await stateStorage.writeValue(symbol,
|
|
1064
|
+
await stateStorage.writeValue(symbol, signalRow);
|
|
1066
1065
|
};
|
|
1067
1066
|
}
|
|
1068
1067
|
/**
|
|
@@ -1204,6 +1203,7 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
1204
1203
|
}
|
|
1205
1204
|
const signalRow = {
|
|
1206
1205
|
id: randomString(),
|
|
1206
|
+
priceOpen: await self.params.exchange.getAveragePrice(self.params.execution.context.symbol),
|
|
1207
1207
|
...signal,
|
|
1208
1208
|
symbol: self.params.execution.context.symbol,
|
|
1209
1209
|
exchangeName: self.params.method.context.exchangeName,
|
|
@@ -3995,8 +3995,8 @@ const ADD_FRAME_METHOD_NAME = "add.addFrame";
|
|
|
3995
3995
|
* timestamp: Date.now(),
|
|
3996
3996
|
* }),
|
|
3997
3997
|
* callbacks: {
|
|
3998
|
-
* onOpen: (
|
|
3999
|
-
* onClose: (
|
|
3998
|
+
* onOpen: (symbol, signal, currentPrice, backtest) => console.log("Signal opened"),
|
|
3999
|
+
* onClose: (symbol, signal, priceClose, backtest) => console.log("Signal closed"),
|
|
4000
4000
|
* },
|
|
4001
4001
|
* });
|
|
4002
4002
|
* ```
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -370,7 +370,7 @@ interface ISignalDto {
|
|
|
370
370
|
/** Human-readable description of signal reason */
|
|
371
371
|
note?: string;
|
|
372
372
|
/** Entry price for the position */
|
|
373
|
-
priceOpen
|
|
373
|
+
priceOpen?: number;
|
|
374
374
|
/** Take profit target price (must be > priceOpen for long, < priceOpen for short) */
|
|
375
375
|
priceTakeProfit: number;
|
|
376
376
|
/** Stop loss exit price (must be < priceOpen for long, > priceOpen for short) */
|
|
@@ -385,6 +385,8 @@ interface ISignalDto {
|
|
|
385
385
|
interface ISignalRow extends ISignalDto {
|
|
386
386
|
/** Unique signal identifier (UUID v4 auto-generated) */
|
|
387
387
|
id: string;
|
|
388
|
+
/** Entry price for the position */
|
|
389
|
+
priceOpen: number;
|
|
388
390
|
/** Unique exchange identifier for execution */
|
|
389
391
|
exchangeName: ExchangeName;
|
|
390
392
|
/** Unique strategy identifier for execution */
|
|
@@ -597,8 +599,8 @@ type StrategyName = string;
|
|
|
597
599
|
* timestamp: Date.now(),
|
|
598
600
|
* }),
|
|
599
601
|
* callbacks: {
|
|
600
|
-
* onOpen: (
|
|
601
|
-
* onClose: (
|
|
602
|
+
* onOpen: (symbol, signal, currentPrice, backtest) => console.log("Signal opened"),
|
|
603
|
+
* onClose: (symbol, signal, priceClose, backtest) => console.log("Signal closed"),
|
|
602
604
|
* },
|
|
603
605
|
* });
|
|
604
606
|
* ```
|
|
@@ -1593,10 +1595,7 @@ declare const BASE_WAIT_FOR_INIT_SYMBOL: unique symbol;
|
|
|
1593
1595
|
* Signal data stored in persistence layer.
|
|
1594
1596
|
* Contains nullable signal for atomic updates.
|
|
1595
1597
|
*/
|
|
1596
|
-
|
|
1597
|
-
/** Current signal state (null when no active signal) */
|
|
1598
|
-
signalRow: ISignalRow | null;
|
|
1599
|
-
}
|
|
1598
|
+
type SignalData = ISignalRow | null;
|
|
1600
1599
|
/**
|
|
1601
1600
|
* Type helper for PersistBase instance.
|
|
1602
1601
|
*/
|
|
@@ -1777,7 +1776,7 @@ declare class PersistSignalUtils {
|
|
|
1777
1776
|
* PersistSignalAdaper.usePersistSignalAdapter(RedisPersist);
|
|
1778
1777
|
* ```
|
|
1779
1778
|
*/
|
|
1780
|
-
usePersistSignalAdapter(Ctor: TPersistBaseCtor<StrategyName,
|
|
1779
|
+
usePersistSignalAdapter(Ctor: TPersistBaseCtor<StrategyName, SignalData>): void;
|
|
1781
1780
|
/**
|
|
1782
1781
|
* Reads persisted signal data for a strategy and symbol.
|
|
1783
1782
|
*
|
|
@@ -3092,4 +3091,4 @@ declare const backtest: {
|
|
|
3092
3091
|
loggerService: LoggerService;
|
|
3093
3092
|
};
|
|
3094
3093
|
|
|
3095
|
-
export { Backtest, type BacktestStatistics, type CandleInterval, type DoneContract, type EntityId, ExecutionContextService, type FrameInterval, type ICandleData, type IExchangeSchema, type IFrameSchema, type IPersistBase, type
|
|
3094
|
+
export { Backtest, type BacktestStatistics, type CandleInterval, type DoneContract, type EntityId, ExecutionContextService, type FrameInterval, type ICandleData, type IExchangeSchema, type IFrameSchema, type IPersistBase, type ISignalDto, type ISignalRow, type IStrategyPnL, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, Live, type LiveStatistics, MethodContextService, PersistBase, PersistSignalAdaper, type ProgressContract, type SignalData, type SignalInterval, type TPersistBase, type TPersistBaseCtor, addExchange, addFrame, addStrategy, formatPrice, formatQuantity, getAveragePrice, getCandles, getDate, getMode, backtest as lib, listExchanges, listFrames, listStrategies, listenDone, listenDoneOnce, listenError, listenProgress, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, setLogger };
|