backtest-kit 1.0.2 → 1.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backtest-kit",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "A TypeScript library for trading system backtest",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
package/types.d.ts CHANGED
@@ -1,19 +1,6 @@
1
1
  import * as di_scoped from 'di-scoped';
2
2
  import * as functools_kit from 'functools-kit';
3
3
 
4
- interface IExecutionContext {
5
- when: Date;
6
- backtest: boolean;
7
- }
8
- declare const ExecutionContextService: (new () => {
9
- readonly context: IExecutionContext;
10
- }) & Omit<{
11
- new (context: IExecutionContext): {
12
- readonly context: IExecutionContext;
13
- };
14
- }, "prototype"> & di_scoped.IScopedClassRun<[context: IExecutionContext]>;
15
- type TExecutionContextService = InstanceType<typeof ExecutionContextService>;
16
-
17
4
  /**
18
5
  * Interface representing a logging mechanism for the swarm system.
19
6
  * Provides methods to record messages at different severity levels, used across components like agents, sessions, states, storage, swarms, history, embeddings, completions, and policies.
@@ -37,6 +24,22 @@ interface ILogger {
37
24
  info(topic: string, ...args: any[]): void;
38
25
  }
39
26
 
27
+ declare function setLogger(logger: ILogger): Promise<void>;
28
+
29
+ interface IExecutionContext {
30
+ symbol: string;
31
+ when: Date;
32
+ backtest: boolean;
33
+ }
34
+ declare const ExecutionContextService: (new () => {
35
+ readonly context: IExecutionContext;
36
+ }) & Omit<{
37
+ new (context: IExecutionContext): {
38
+ readonly context: IExecutionContext;
39
+ };
40
+ }, "prototype"> & di_scoped.IScopedClassRun<[context: IExecutionContext]>;
41
+ type TExecutionContextService = InstanceType<typeof ExecutionContextService>;
42
+
40
43
  type CandleInterval = "1m" | "3m" | "5m" | "15m" | "30m" | "1h" | "2h" | "4h" | "6h" | "8h";
41
44
  interface ICandleData {
42
45
  timestamp: number;
@@ -46,24 +49,32 @@ interface ICandleData {
46
49
  close: number;
47
50
  volume: number;
48
51
  }
49
- interface ICandleParams extends ICandleSchema {
52
+ interface IExchangeParams extends IExchangeSchema {
50
53
  logger: ILogger;
51
54
  execution: TExecutionContextService;
52
55
  }
53
- interface ICandleCallbacks {
56
+ interface IExchangeCallbacks {
54
57
  onCandleData: (symbol: string, interval: CandleInterval, since: Date, limit: number, data: ICandleData[]) => void;
55
58
  }
56
- interface ICandleSchema {
59
+ interface IExchangeSchema {
60
+ exchangeName: ExchangeName;
57
61
  getCandles: (symbol: string, interval: CandleInterval, since: Date, limit: number) => Promise<ICandleData[]>;
58
- callbacks?: Partial<ICandleCallbacks>;
62
+ formatQuantity: (symbol: string, quantity: number) => Promise<string>;
63
+ formatPrice: (symbol: string, price: number) => Promise<string>;
64
+ callbacks?: Partial<IExchangeCallbacks>;
59
65
  }
60
- interface ICandle {
66
+ interface IExchange {
61
67
  getCandles: (symbol: string, interval: CandleInterval, limit: number) => Promise<ICandleData[]>;
68
+ getNextCandles: (symbol: string, interval: CandleInterval, limit: number) => Promise<ICandleData[]>;
69
+ formatQuantity: (symbol: string, quantity: number) => Promise<string>;
70
+ formatPrice: (symbol: string, price: number) => Promise<string>;
62
71
  getAveragePrice: (symbol: string) => Promise<number>;
63
72
  }
73
+ type ExchangeName = string;
64
74
 
65
- interface ISignalData {
66
- id: string;
75
+ type SignalInterval = "1m" | "3m" | "5m" | "15m" | "30m" | "1h";
76
+ interface ISignalDto {
77
+ id?: string;
67
78
  position: "long" | "short";
68
79
  note: string;
69
80
  priceOpen: number;
@@ -72,12 +83,17 @@ interface ISignalData {
72
83
  minuteEstimatedTime: number;
73
84
  timestamp: number;
74
85
  }
86
+ interface ISignalRow extends ISignalDto {
87
+ id: string;
88
+ }
75
89
  interface IStrategyCallbacks {
76
- onOpen: (backtest: boolean, symbol: string, data: ISignalData) => void;
77
- onClose: (backtest: boolean, symbol: string, priceClose: number, data: ISignalData) => void;
90
+ onOpen: (backtest: boolean, symbol: string, data: ISignalRow) => void;
91
+ onClose: (backtest: boolean, symbol: string, priceClose: number, data: ISignalRow) => void;
78
92
  }
79
93
  interface IStrategySchema {
80
- getSignal: (symbol: string) => Promise<ISignalData | null>;
94
+ strategyName: StrategyName;
95
+ interval: SignalInterval;
96
+ getSignal: (symbol: string) => Promise<ISignalDto | null>;
81
97
  callbacks?: Partial<IStrategyCallbacks>;
82
98
  }
83
99
  type StrategyCloseReason = "time_expired" | "take_profit" | "stop_loss";
@@ -92,27 +108,51 @@ interface IStrategyTickResultIdle {
92
108
  }
93
109
  interface IStrategyTickResultOpened {
94
110
  action: "opened";
95
- signal: ISignalData;
111
+ signal: ISignalRow;
96
112
  }
97
113
  interface IStrategyTickResultActive {
98
114
  action: "active";
99
- signal: ISignalData;
115
+ signal: ISignalRow;
100
116
  currentPrice: number;
101
117
  }
102
118
  interface IStrategyTickResultClosed {
103
119
  action: "closed";
104
- signal: ISignalData;
120
+ signal: ISignalRow;
105
121
  currentPrice: number;
106
122
  closeReason: StrategyCloseReason;
123
+ closeTimestamp: number;
107
124
  pnl: IStrategyPnL;
108
125
  }
109
126
  type IStrategyTickResult = IStrategyTickResultIdle | IStrategyTickResultOpened | IStrategyTickResultActive | IStrategyTickResultClosed;
127
+ type IStrategyBacktestResult = IStrategyTickResultClosed;
110
128
  interface IStrategy {
111
129
  tick: (symbol: string) => Promise<IStrategyTickResult>;
130
+ backtest: (candles: ICandleData[]) => Promise<IStrategyBacktestResult>;
131
+ }
132
+ type StrategyName = string;
133
+
134
+ type FrameInterval = "1m" | "3m" | "5m" | "15m" | "30m" | "1h" | "2h" | "4h" | "6h" | "8h" | "12h" | "1d" | "3d";
135
+ interface IFrameParams extends IFrameSchema {
136
+ logger: ILogger;
137
+ }
138
+ interface IFrameCallbacks {
139
+ onTimeframe: (timeframe: Date[], startDate: Date, endDate: Date, interval: FrameInterval) => void;
140
+ }
141
+ interface IFrameSchema {
142
+ frameName: FrameName;
143
+ interval: FrameInterval;
144
+ startDate: Date;
145
+ endDate: Date;
146
+ callbacks?: Partial<IFrameCallbacks>;
112
147
  }
148
+ interface IFrame {
149
+ getTimeframe: (symbol: string) => Promise<Date[]>;
150
+ }
151
+ type FrameName = string;
113
152
 
114
153
  declare function addStrategy(strategySchema: IStrategySchema): void;
115
- declare function addCandle(candleSchema: ICandleSchema): void;
154
+ declare function addExchange(exchangeSchema: IExchangeSchema): void;
155
+ declare function addFrame(frameSchema: IFrameSchema): void;
116
156
 
117
157
  interface IBacktestResult {
118
158
  symbol: string;
@@ -139,78 +179,268 @@ declare function stopAll(): void;
139
179
 
140
180
  declare function getCandles(symbol: string, interval: CandleInterval, limit: number): Promise<ICandleData[]>;
141
181
  declare function getAveragePrice(symbol: string): Promise<number>;
182
+ declare function formatPrice(symbol: string, price: number): Promise<string>;
183
+ declare function formatQuantity(symbol: string, quantity: number): Promise<string>;
184
+ declare function getDate(): Promise<Date>;
185
+ declare function getMode(): Promise<"backtest" | "live">;
186
+
187
+ interface IMethodContext {
188
+ exchangeName: ExchangeName;
189
+ strategyName: StrategyName;
190
+ frameName: FrameName;
191
+ }
192
+ declare const MethodContextService: (new () => {
193
+ readonly context: IMethodContext;
194
+ }) & Omit<{
195
+ new (context: IMethodContext): {
196
+ readonly context: IMethodContext;
197
+ };
198
+ }, "prototype"> & di_scoped.IScopedClassRun<[context: IMethodContext]>;
199
+
200
+ declare const BASE_WAIT_FOR_INIT_SYMBOL: unique symbol;
201
+ interface ISignalData {
202
+ signalRow: ISignalRow | null;
203
+ }
204
+ type TPersistBase = InstanceType<typeof PersistBase>;
205
+ type TPersistBaseCtor<EntityName extends string = string, Entity extends IEntity = IEntity> = new (entityName: EntityName, baseDir: string) => IPersistBase<Entity>;
206
+ type EntityId = string | number;
207
+ interface IEntity {
208
+ }
209
+ interface IPersistBase<Entity extends IEntity = IEntity> {
210
+ waitForInit(initial: boolean): Promise<void>;
211
+ readValue(entityId: EntityId): Promise<Entity>;
212
+ hasValue(entityId: EntityId): Promise<boolean>;
213
+ writeValue(entityId: EntityId, entity: Entity): Promise<void>;
214
+ }
215
+ declare const PersistBase: {
216
+ new <EntityName extends string = string>(entityName: EntityName, baseDir?: string): {
217
+ _directory: string;
218
+ readonly entityName: EntityName;
219
+ readonly baseDir: string;
220
+ _getFilePath(entityId: EntityId): string;
221
+ waitForInit(initial: boolean): Promise<void>;
222
+ getCount(): Promise<number>;
223
+ readValue<T extends IEntity = IEntity>(entityId: EntityId): Promise<T>;
224
+ hasValue(entityId: EntityId): Promise<boolean>;
225
+ writeValue<T extends IEntity = IEntity>(entityId: EntityId, entity: T): Promise<void>;
226
+ removeValue(entityId: EntityId): Promise<void>;
227
+ removeAll(): Promise<void>;
228
+ values<T extends IEntity = IEntity>(): AsyncGenerator<T>;
229
+ keys(): AsyncGenerator<EntityId>;
230
+ filter<T extends IEntity = IEntity>(predicate: (value: T) => boolean): AsyncGenerator<T>;
231
+ take<T extends IEntity = IEntity>(total: number, predicate?: (value: T) => boolean): AsyncGenerator<T>;
232
+ [BASE_WAIT_FOR_INIT_SYMBOL]: (() => Promise<void>) & functools_kit.ISingleshotClearable;
233
+ [Symbol.asyncIterator](): AsyncIterableIterator<any>;
234
+ };
235
+ };
236
+ declare class PersistSignalUtils {
237
+ private PersistSignalFactory;
238
+ private getSignalStorage;
239
+ usePersistSignalAdapter(Ctor: TPersistBaseCtor<StrategyName, ISignalData>): void;
240
+ readSignalData: (strategyName: StrategyName, symbol: string) => Promise<ISignalRow | null>;
241
+ writeSignalData: (signalRow: ISignalRow | null, strategyName: StrategyName, symbol: string) => Promise<void>;
242
+ }
243
+ declare const PersistSignalAdaper: PersistSignalUtils;
244
+
245
+ declare class BacktestUtils {
246
+ run: (symbol: string, context: {
247
+ strategyName: string;
248
+ exchangeName: string;
249
+ frameName: string;
250
+ }) => AsyncGenerator<IStrategyTickResultClosed, void, unknown>;
251
+ }
252
+ declare const Backtest: BacktestUtils;
253
+
254
+ declare class LiveUtils {
255
+ run: (symbol: string, context: {
256
+ strategyName: string;
257
+ exchangeName: string;
258
+ frameName: string;
259
+ }) => AsyncGenerator<IStrategyTickResultOpened | IStrategyTickResultClosed, void, unknown>;
260
+ }
261
+ declare const Live: LiveUtils;
142
262
 
143
263
  declare class LoggerService implements ILogger {
264
+ private readonly methodContextService;
265
+ private readonly executionContextService;
144
266
  private _commonLogger;
267
+ private get methodContext();
268
+ private get executionContext();
145
269
  log: (topic: string, ...args: any[]) => Promise<void>;
146
270
  debug: (topic: string, ...args: any[]) => Promise<void>;
147
271
  info: (topic: string, ...args: any[]) => Promise<void>;
148
272
  setLogger: (logger: ILogger) => void;
149
273
  }
150
274
 
151
- declare class ClientCandle implements ICandle {
152
- readonly params: ICandleParams;
153
- constructor(params: ICandleParams);
154
- getCandles: (symbol: string, interval: CandleInterval, limit: number) => Promise<ICandleData[]>;
155
- getAveragePrice: (symbol: string) => Promise<number>;
275
+ declare class ClientExchange implements IExchange {
276
+ readonly params: IExchangeParams;
277
+ constructor(params: IExchangeParams);
278
+ getCandles(symbol: string, interval: CandleInterval, limit: number): Promise<ICandleData[]>;
279
+ getNextCandles(symbol: string, interval: CandleInterval, limit: number): Promise<ICandleData[]>;
280
+ getAveragePrice(symbol: string): Promise<number>;
281
+ formatQuantity(symbol: string, quantity: number): Promise<string>;
282
+ formatPrice(symbol: string, price: number): Promise<string>;
156
283
  }
157
284
 
158
- declare class CandleConnectionService implements ICandle {
285
+ declare class ExchangeConnectionService implements IExchange {
159
286
  private readonly loggerService;
160
287
  private readonly executionContextService;
161
- private readonly candleSchemaService;
162
- getCandle: ((symbol: string) => ClientCandle) & functools_kit.IClearableMemoize<string> & functools_kit.IControlMemoize<string, ClientCandle>;
288
+ private readonly exchangeSchemaService;
289
+ private readonly methodContextService;
290
+ getExchange: ((exchangeName: ExchangeName) => ClientExchange) & functools_kit.IClearableMemoize<string> & functools_kit.IControlMemoize<string, ClientExchange>;
163
291
  getCandles: (symbol: string, interval: CandleInterval, limit: number) => Promise<ICandleData[]>;
292
+ getNextCandles: (symbol: string, interval: CandleInterval, limit: number) => Promise<ICandleData[]>;
164
293
  getAveragePrice: (symbol: string) => Promise<number>;
294
+ formatPrice: (symbol: string, price: number) => Promise<string>;
295
+ formatQuantity: (symbol: string, quantity: number) => Promise<string>;
165
296
  }
166
297
 
167
- declare class CandleSchemaService {
298
+ declare class StrategyConnectionService implements IStrategy {
168
299
  private readonly loggerService;
169
- private _candleSchema;
170
- getSchema: () => ICandleSchema;
171
- addSchema: (candleSchema: ICandleSchema) => void;
300
+ private readonly executionContextService;
301
+ private readonly strategySchemaService;
302
+ private readonly exchangeConnectionService;
303
+ private readonly methodContextService;
304
+ private getStrategy;
305
+ tick: () => Promise<IStrategyTickResult>;
306
+ backtest: (candles: ICandleData[]) => Promise<IStrategyBacktestResult>;
172
307
  }
173
308
 
174
- declare class StrategySchemaService {
175
- private readonly loggerService;
176
- private _strategySchema;
177
- getSchema: () => IStrategySchema;
178
- addSchema: (strategySchema: IStrategySchema) => void;
309
+ declare class ClientFrame implements IFrame {
310
+ readonly params: IFrameParams;
311
+ constructor(params: IFrameParams);
312
+ getTimeframe: ((symbol: string) => Promise<Date[]>) & functools_kit.ISingleshotClearable;
179
313
  }
180
314
 
181
- declare class StrategyConnectionService implements IStrategy {
315
+ declare class FrameConnectionService implements IFrame {
182
316
  private readonly loggerService;
183
- private readonly executionContextService;
184
- private readonly strategySchemaService;
185
- private readonly candleConnectionService;
186
- private getStrategy;
187
- tick: (symbol: string) => Promise<IStrategyTickResult>;
317
+ private readonly frameSchemaService;
318
+ private readonly methodContextService;
319
+ getFrame: ((frameName: FrameName) => ClientFrame) & functools_kit.IClearableMemoize<string> & functools_kit.IControlMemoize<string, ClientFrame>;
320
+ getTimeframe: (symbol: string) => Promise<Date[]>;
188
321
  }
189
322
 
190
- declare class CandlePublicService {
323
+ declare class ExchangeGlobalService {
191
324
  private readonly loggerService;
192
- private readonly candleConnectionService;
325
+ private readonly exchangeConnectionService;
193
326
  getCandles: (symbol: string, interval: CandleInterval, limit: number, when: Date, backtest: boolean) => Promise<ICandleData[]>;
327
+ getNextCandles: (symbol: string, interval: CandleInterval, limit: number, when: Date, backtest: boolean) => Promise<ICandleData[]>;
194
328
  getAveragePrice: (symbol: string, when: Date, backtest: boolean) => Promise<number>;
329
+ formatPrice: (symbol: string, price: number, when: Date, backtest: boolean) => Promise<string>;
330
+ formatQuantity: (symbol: string, quantity: number, when: Date, backtest: boolean) => Promise<string>;
195
331
  }
196
332
 
197
- declare class StrategyPublicService {
333
+ declare class StrategyGlobalService {
198
334
  private readonly loggerService;
199
335
  private readonly strategyConnectionService;
200
336
  tick: (symbol: string, when: Date, backtest: boolean) => Promise<IStrategyTickResult>;
337
+ backtest: (symbol: string, candles: ICandleData[], when: Date, backtest: boolean) => Promise<IStrategyBacktestResult>;
338
+ }
339
+
340
+ declare class FrameGlobalService {
341
+ private readonly loggerService;
342
+ private readonly frameConnectionService;
343
+ getTimeframe: (symbol: string) => Promise<Date[]>;
344
+ }
345
+
346
+ declare class ExchangeSchemaService {
347
+ readonly loggerService: LoggerService;
348
+ private _registry;
349
+ register: (key: ExchangeName, value: IExchangeSchema) => void;
350
+ override: (key: ExchangeName, value: Partial<IExchangeSchema>) => IExchangeSchema;
351
+ get: (key: ExchangeName) => IExchangeSchema;
352
+ }
353
+
354
+ declare class StrategySchemaService {
355
+ readonly loggerService: LoggerService;
356
+ private _registry;
357
+ register: (key: StrategyName, value: IStrategySchema) => void;
358
+ override: (key: StrategyName, value: Partial<IStrategySchema>) => IStrategySchema;
359
+ get: (key: StrategyName) => IStrategySchema;
360
+ }
361
+
362
+ declare class FrameSchemaService {
363
+ private _registry;
364
+ register(key: FrameName, value: IFrameSchema): void;
365
+ override(key: FrameName, value: Partial<IFrameSchema>): void;
366
+ get(key: FrameName): IFrameSchema;
367
+ }
368
+
369
+ declare class BacktestLogicPrivateService {
370
+ private readonly loggerService;
371
+ private readonly strategyGlobalService;
372
+ private readonly exchangeGlobalService;
373
+ private readonly frameGlobalService;
374
+ run(symbol: string): AsyncGenerator<IStrategyTickResultClosed, void, unknown>;
375
+ }
376
+
377
+ declare class LiveLogicPrivateService {
378
+ private readonly loggerService;
379
+ private readonly strategyGlobalService;
380
+ run(symbol: string): AsyncGenerator<IStrategyTickResultOpened | IStrategyTickResultClosed, void, unknown>;
381
+ }
382
+
383
+ declare class BacktestLogicPublicService {
384
+ private readonly loggerService;
385
+ private readonly backtestLogicPrivateService;
386
+ run: (symbol: string, context: {
387
+ strategyName: string;
388
+ exchangeName: string;
389
+ frameName: string;
390
+ }) => AsyncGenerator<IStrategyTickResultClosed, void, unknown>;
391
+ }
392
+
393
+ declare class LiveLogicPublicService {
394
+ private readonly loggerService;
395
+ private readonly liveLogicPrivateService;
396
+ run: (symbol: string, context: {
397
+ strategyName: string;
398
+ exchangeName: string;
399
+ }) => AsyncGenerator<IStrategyTickResultOpened | IStrategyTickResultClosed, void, unknown>;
400
+ }
401
+
402
+ declare class LiveGlobalService {
403
+ private readonly loggerService;
404
+ private readonly liveLogicPublicService;
405
+ run: (symbol: string, context: {
406
+ strategyName: string;
407
+ exchangeName: string;
408
+ }) => AsyncGenerator<IStrategyTickResultOpened | IStrategyTickResultClosed, void, unknown>;
409
+ }
410
+
411
+ declare class BacktestGlobalService {
412
+ private readonly loggerService;
413
+ private readonly backtestLogicPublicService;
414
+ run: (symbol: string, context: {
415
+ strategyName: string;
416
+ exchangeName: string;
417
+ frameName: string;
418
+ }) => AsyncGenerator<IStrategyTickResultClosed, void, unknown>;
201
419
  }
202
420
 
203
421
  declare const backtest: {
204
- candlePublicService: CandlePublicService;
205
- strategyPublicService: StrategyPublicService;
206
- candleSchemaService: CandleSchemaService;
422
+ backtestLogicPublicService: BacktestLogicPublicService;
423
+ liveLogicPublicService: LiveLogicPublicService;
424
+ backtestLogicPrivateService: BacktestLogicPrivateService;
425
+ liveLogicPrivateService: LiveLogicPrivateService;
426
+ exchangeGlobalService: ExchangeGlobalService;
427
+ strategyGlobalService: StrategyGlobalService;
428
+ frameGlobalService: FrameGlobalService;
429
+ liveGlobalService: LiveGlobalService;
430
+ backtestGlobalService: BacktestGlobalService;
431
+ exchangeSchemaService: ExchangeSchemaService;
207
432
  strategySchemaService: StrategySchemaService;
208
- candleConnectionService: CandleConnectionService;
433
+ frameSchemaService: FrameSchemaService;
434
+ exchangeConnectionService: ExchangeConnectionService;
209
435
  strategyConnectionService: StrategyConnectionService;
436
+ frameConnectionService: FrameConnectionService;
210
437
  executionContextService: {
211
438
  readonly context: IExecutionContext;
212
439
  };
440
+ methodContextService: {
441
+ readonly context: IMethodContext;
442
+ };
213
443
  loggerService: LoggerService;
214
444
  };
215
445
 
216
- export { type CandleInterval, ExecutionContextService, type ICandleData, type ICandleSchema, type ISignalData, type IStrategyPnL, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, addCandle, addStrategy, backtest, getAveragePrice, getCandles, reduce, runBacktest, runBacktestGUI, startRun, stopAll, stopRun };
446
+ export { Backtest, type CandleInterval, 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, MethodContextService, PersistBase, PersistSignalAdaper, type SignalInterval, type TPersistBase, type TPersistBaseCtor, addExchange, addFrame, addStrategy, backtest, formatPrice, formatQuantity, getAveragePrice, getCandles, getDate, getMode, reduce, runBacktest, runBacktestGUI, setLogger, startRun, stopAll, stopRun };