backtest-kit 1.1.3 โ 1.1.5
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 +90 -52
- package/build/index.cjs +341 -54
- package/build/index.mjs +339 -56
- package/package.json +2 -1
- package/types.d.ts +232 -2
package/README.md
CHANGED
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
- ๐ **Flexible Architecture** - Plug your own exchanges and strategies
|
|
21
21
|
- ๐ **Markdown Reports** - Auto-generated trading reports with statistics (win rate, avg PNL)
|
|
22
22
|
- ๐ **Graceful Shutdown** - Live.background() waits for open positions to close before stopping
|
|
23
|
+
- ๐ **Strategy Dependency Injection** - addStrategy() enables DI pattern for trading strategies
|
|
24
|
+
- ๐ **Schema Reflection API** - listExchanges(), listStrategies(), listFrames() for runtime introspection
|
|
25
|
+
- ๐งช **Comprehensive Test Coverage** - 30+ unit tests covering validation, PNL, callbacks, reports, and event system
|
|
23
26
|
|
|
24
27
|
## Installation
|
|
25
28
|
|
|
@@ -250,6 +253,75 @@ for await (const result of Live.run("BTCUSDT", {
|
|
|
250
253
|
}
|
|
251
254
|
```
|
|
252
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
|
+
|
|
253
325
|
## Architecture Overview
|
|
254
326
|
|
|
255
327
|
The framework follows **clean architecture** with:
|
|
@@ -792,60 +864,8 @@ pnl% = (priceOpenWithCosts - priceCloseWithCosts) / priceOpenWithCosts * 100
|
|
|
792
864
|
6. **Live Trading Ready** - Full implementation with real-time progression
|
|
793
865
|
7. **Error Recovery** - Stateless process with disk-based state
|
|
794
866
|
|
|
795
|
-
## File Structure
|
|
796
|
-
|
|
797
|
-
```
|
|
798
|
-
src/
|
|
799
|
-
โโโ client/ # Pure business logic (no DI)
|
|
800
|
-
โ โโโ ClientStrategy.ts # Signal lifecycle + validation + persistence
|
|
801
|
-
โ โโโ ClientExchange.ts # VWAP calculation
|
|
802
|
-
โ โโโ ClientFrame.ts # Timeframe generation
|
|
803
|
-
โโโ classes/
|
|
804
|
-
โ โโโ Persist.ts # Atomic file persistence
|
|
805
|
-
โโโ function/ # High-level API
|
|
806
|
-
โ โโโ add.ts # addStrategy, addExchange, addFrame
|
|
807
|
-
โ โโโ exchange.ts # getCandles, getAveragePrice, getDate, getMode
|
|
808
|
-
โ โโโ run.ts # DEPRECATED - use logic services instead
|
|
809
|
-
โโโ interfaces/ # TypeScript interfaces
|
|
810
|
-
โ โโโ Strategy.interface.ts
|
|
811
|
-
โ โโโ Exchange.interface.ts
|
|
812
|
-
โ โโโ Frame.interface.ts
|
|
813
|
-
โโโ lib/
|
|
814
|
-
โ โโโ core/ # DI container
|
|
815
|
-
โ โโโ services/
|
|
816
|
-
โ โ โโโ base/ # LoggerService
|
|
817
|
-
โ โ โโโ context/ # ExecutionContext, MethodContext
|
|
818
|
-
โ โ โโโ connection/ # Client instance creators
|
|
819
|
-
โ โ โโโ global/ # Context wrappers
|
|
820
|
-
โ โ โโโ schema/ # Registry services
|
|
821
|
-
โ โ โโโ logic/
|
|
822
|
-
โ โ โโโ private/ # Async generator orchestration
|
|
823
|
-
โ โ โโโ BacktestLogicPrivateService.ts
|
|
824
|
-
โ โ โโโ LiveLogicPrivateService.ts
|
|
825
|
-
โ โโโ index.ts # Public API
|
|
826
|
-
โโโ helpers/
|
|
827
|
-
โโโ toProfitLossDto.ts # PNL calculation
|
|
828
|
-
```
|
|
829
|
-
|
|
830
867
|
## Advanced Examples
|
|
831
868
|
|
|
832
|
-
### Custom Persistence Adapter
|
|
833
|
-
|
|
834
|
-
```typescript
|
|
835
|
-
import { PersistSignalAdaper, PersistBase } from "backtest-kit";
|
|
836
|
-
|
|
837
|
-
class RedisPersist extends PersistBase {
|
|
838
|
-
async readValue(entityId) {
|
|
839
|
-
return JSON.parse(await redis.get(entityId));
|
|
840
|
-
}
|
|
841
|
-
async writeValue(entityId, entity) {
|
|
842
|
-
await redis.set(entityId, JSON.stringify(entity));
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
PersistSignalAdaper.usePersistSignalAdapter(RedisPersist);
|
|
847
|
-
```
|
|
848
|
-
|
|
849
869
|
### Multi-Symbol Live Trading
|
|
850
870
|
|
|
851
871
|
```typescript
|
|
@@ -871,6 +891,24 @@ await Promise.all(
|
|
|
871
891
|
);
|
|
872
892
|
```
|
|
873
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
|
+
|
|
874
912
|
### Early Termination
|
|
875
913
|
|
|
876
914
|
**Using async generator with break:**
|