backtest-kit 1.1.4 โ 1.1.6
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 +91 -38
- package/build/index.cjs +464 -31
- package/build/index.mjs +461 -32
- package/package.json +1 -1
- package/types.d.ts +1366 -1010
package/README.md
CHANGED
|
@@ -14,14 +14,15 @@
|
|
|
14
14
|
- ๐ **Async Generators** - Memory-efficient streaming for backtest and live execution
|
|
15
15
|
- ๐ **VWAP Pricing** - Volume-weighted average price from last 5 1m candles
|
|
16
16
|
- ๐ฏ **Signal Lifecycle** - Type-safe state machine (idle โ opened โ active โ closed)
|
|
17
|
-
-
|
|
17
|
+
- ๐ **Accurate PNL** - Calculation with fees (0.1%) and slippage (0.1%)
|
|
18
18
|
- ๐ง **Interval Throttling** - Prevents signal spam at strategy level
|
|
19
19
|
- โก **Memory Optimized** - Prototype methods + memoization + streaming
|
|
20
20
|
- ๐ **Flexible Architecture** - Plug your own exchanges and strategies
|
|
21
|
-
- ๐ **Markdown Reports** - Auto-generated trading reports with statistics (win rate, avg PNL)
|
|
21
|
+
- ๐ **Markdown Reports** - Auto-generated trading reports with statistics (win rate, avg PNL, Sharpe Ratio, Standard Deviation, Certainty Ratio, Expected Yearly Returns, Risk-Adjusted Returns)
|
|
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** - 45+ unit tests covering validation, PNL, callbacks, reports, and event system
|
|
25
26
|
|
|
26
27
|
## Installation
|
|
27
28
|
|
|
@@ -252,6 +253,75 @@ for await (const result of Live.run("BTCUSDT", {
|
|
|
252
253
|
}
|
|
253
254
|
```
|
|
254
255
|
|
|
256
|
+
### 7. Schema Reflection API (Optional)
|
|
257
|
+
|
|
258
|
+
Retrieve registered schemas at runtime for debugging, documentation, or building dynamic UIs:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
import {
|
|
262
|
+
addExchange,
|
|
263
|
+
addStrategy,
|
|
264
|
+
addFrame,
|
|
265
|
+
listExchanges,
|
|
266
|
+
listStrategies,
|
|
267
|
+
listFrames
|
|
268
|
+
} from "backtest-kit";
|
|
269
|
+
|
|
270
|
+
// Register schemas with notes
|
|
271
|
+
addExchange({
|
|
272
|
+
exchangeName: "binance",
|
|
273
|
+
note: "Binance cryptocurrency exchange with database backend",
|
|
274
|
+
getCandles: async (symbol, interval, since, limit) => [...],
|
|
275
|
+
formatPrice: async (symbol, price) => price.toFixed(2),
|
|
276
|
+
formatQuantity: async (symbol, quantity) => quantity.toFixed(8),
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
addStrategy({
|
|
280
|
+
strategyName: "sma-crossover",
|
|
281
|
+
note: "Simple moving average crossover strategy (50/200)",
|
|
282
|
+
interval: "5m",
|
|
283
|
+
getSignal: async (symbol) => ({...}),
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
addFrame({
|
|
287
|
+
frameName: "january-2024",
|
|
288
|
+
note: "Full month backtest for January 2024",
|
|
289
|
+
interval: "1m",
|
|
290
|
+
startDate: new Date("2024-01-01"),
|
|
291
|
+
endDate: new Date("2024-02-01"),
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// List all registered schemas
|
|
295
|
+
const exchanges = await listExchanges();
|
|
296
|
+
console.log("Available exchanges:", exchanges.map(e => ({
|
|
297
|
+
name: e.exchangeName,
|
|
298
|
+
note: e.note
|
|
299
|
+
})));
|
|
300
|
+
// Output: [{ name: "binance", note: "Binance cryptocurrency exchange..." }]
|
|
301
|
+
|
|
302
|
+
const strategies = await listStrategies();
|
|
303
|
+
console.log("Available strategies:", strategies.map(s => ({
|
|
304
|
+
name: s.strategyName,
|
|
305
|
+
note: s.note,
|
|
306
|
+
interval: s.interval
|
|
307
|
+
})));
|
|
308
|
+
// Output: [{ name: "sma-crossover", note: "Simple moving average...", interval: "5m" }]
|
|
309
|
+
|
|
310
|
+
const frames = await listFrames();
|
|
311
|
+
console.log("Available frames:", frames.map(f => ({
|
|
312
|
+
name: f.frameName,
|
|
313
|
+
note: f.note,
|
|
314
|
+
period: `${f.startDate.toISOString()} - ${f.endDate.toISOString()}`
|
|
315
|
+
})));
|
|
316
|
+
// Output: [{ name: "january-2024", note: "Full month backtest...", period: "2024-01-01..." }]
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**Use cases:**
|
|
320
|
+
- Generate documentation automatically from registered schemas
|
|
321
|
+
- Build admin dashboards showing available strategies and exchanges
|
|
322
|
+
- Create CLI tools with auto-completion based on registered schemas
|
|
323
|
+
- Validate configuration files against registered schemas
|
|
324
|
+
|
|
255
325
|
## Architecture Overview
|
|
256
326
|
|
|
257
327
|
The framework follows **clean architecture** with:
|
|
@@ -794,41 +864,6 @@ pnl% = (priceOpenWithCosts - priceCloseWithCosts) / priceOpenWithCosts * 100
|
|
|
794
864
|
6. **Live Trading Ready** - Full implementation with real-time progression
|
|
795
865
|
7. **Error Recovery** - Stateless process with disk-based state
|
|
796
866
|
|
|
797
|
-
## File Structure
|
|
798
|
-
|
|
799
|
-
```
|
|
800
|
-
src/
|
|
801
|
-
โโโ client/ # Pure business logic (no DI)
|
|
802
|
-
โ โโโ ClientStrategy.ts # Signal lifecycle + validation + persistence
|
|
803
|
-
โ โโโ ClientExchange.ts # VWAP calculation
|
|
804
|
-
โ โโโ ClientFrame.ts # Timeframe generation
|
|
805
|
-
โโโ classes/
|
|
806
|
-
โ โโโ Persist.ts # Atomic file persistence
|
|
807
|
-
โโโ function/ # High-level API
|
|
808
|
-
โ โโโ add.ts # addStrategy, addExchange, addFrame
|
|
809
|
-
โ โโโ exchange.ts # getCandles, getAveragePrice, getDate, getMode
|
|
810
|
-
โ โโโ run.ts # DEPRECATED - use logic services instead
|
|
811
|
-
โโโ interfaces/ # TypeScript interfaces
|
|
812
|
-
โ โโโ Strategy.interface.ts
|
|
813
|
-
โ โโโ Exchange.interface.ts
|
|
814
|
-
โ โโโ Frame.interface.ts
|
|
815
|
-
โโโ lib/
|
|
816
|
-
โ โโโ core/ # DI container
|
|
817
|
-
โ โโโ services/
|
|
818
|
-
โ โ โโโ base/ # LoggerService
|
|
819
|
-
โ โ โโโ context/ # ExecutionContext, MethodContext
|
|
820
|
-
โ โ โโโ connection/ # Client instance creators
|
|
821
|
-
โ โ โโโ global/ # Context wrappers
|
|
822
|
-
โ โ โโโ schema/ # Registry services
|
|
823
|
-
โ โ โโโ logic/
|
|
824
|
-
โ โ โโโ private/ # Async generator orchestration
|
|
825
|
-
โ โ โโโ BacktestLogicPrivateService.ts
|
|
826
|
-
โ โ โโโ LiveLogicPrivateService.ts
|
|
827
|
-
โ โโโ index.ts # Public API
|
|
828
|
-
โโโ helpers/
|
|
829
|
-
โโโ toProfitLossDto.ts # PNL calculation
|
|
830
|
-
```
|
|
831
|
-
|
|
832
867
|
## Advanced Examples
|
|
833
868
|
|
|
834
869
|
### Multi-Symbol Live Trading
|
|
@@ -856,6 +891,24 @@ await Promise.all(
|
|
|
856
891
|
);
|
|
857
892
|
```
|
|
858
893
|
|
|
894
|
+
### Backtest Progress Listener
|
|
895
|
+
|
|
896
|
+
```typescript
|
|
897
|
+
import { listenProgress, Backtest } from "backtest-kit";
|
|
898
|
+
|
|
899
|
+
listenProgress((event) => {
|
|
900
|
+
console.log(`Progress: ${(event.progress * 100).toFixed(2)}%`);
|
|
901
|
+
console.log(`${event.processedFrames} / ${event.totalFrames} frames`);
|
|
902
|
+
console.log(`Strategy: ${event.strategyName}, Symbol: ${event.symbol}`);
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
Backtest.background("BTCUSDT", {
|
|
906
|
+
strategyName: "my-strategy",
|
|
907
|
+
exchangeName: "binance",
|
|
908
|
+
frameName: "1d-backtest"
|
|
909
|
+
});
|
|
910
|
+
```
|
|
911
|
+
|
|
859
912
|
### Early Termination
|
|
860
913
|
|
|
861
914
|
**Using async generator with break:**
|