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 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:**