@quantform/core 0.3.243 → 0.3.246

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.
Files changed (35) hide show
  1. package/dist/adapter/backtester/backtester-adapter.d.ts +1 -2
  2. package/dist/adapter/backtester/backtester-adapter.js.map +1 -1
  3. package/dist/adapter/backtester/backtester-streamer.d.ts +2 -1
  4. package/dist/adapter/backtester/backtester-streamer.js +8 -7
  5. package/dist/adapter/backtester/backtester-streamer.js.map +1 -1
  6. package/dist/adapter/backtester/backtester-streamer.spec.js +9 -10
  7. package/dist/adapter/backtester/backtester-streamer.spec.js.map +1 -1
  8. package/dist/bin.d.ts +3 -4
  9. package/dist/bin.js +5 -5
  10. package/dist/bin.js.map +1 -1
  11. package/dist/ipc.d.ts +4 -12
  12. package/dist/ipc.js +46 -44
  13. package/dist/ipc.js.map +1 -1
  14. package/dist/ipc.spec.js +9 -9
  15. package/dist/ipc.spec.js.map +1 -1
  16. package/dist/session/session-descriptor.d.ts +6 -3
  17. package/dist/session/session.d.ts +1 -1
  18. package/dist/session/session.js +3 -4
  19. package/dist/session/session.js.map +1 -1
  20. package/dist/session/session.spec.js +1 -5
  21. package/dist/session/session.spec.js.map +1 -1
  22. package/dist/tests/backtester-adapter.spec.js +7 -8
  23. package/dist/tests/backtester-adapter.spec.js.map +1 -1
  24. package/dist/tsconfig.tsbuildinfo +1 -1
  25. package/package.json +1 -1
  26. package/src/adapter/backtester/backtester-adapter.ts +2 -3
  27. package/src/adapter/backtester/backtester-streamer.spec.ts +10 -6
  28. package/src/adapter/backtester/backtester-streamer.ts +8 -7
  29. package/src/bin.ts +17 -7
  30. package/src/ipc.spec.ts +9 -8
  31. package/src/ipc.ts +54 -70
  32. package/src/session/session-descriptor.ts +7 -4
  33. package/src/session/session.spec.ts +1 -5
  34. package/src/session/session.ts +3 -3
  35. package/src/tests/backtester-adapter.spec.ts +11 -7
package/src/ipc.spec.ts CHANGED
@@ -55,8 +55,7 @@ describe('ipc feed tests', () => {
55
55
  const session = await run(
56
56
  {
57
57
  adapter: [new DefaultAdapter()],
58
- feed: new Feed(new InMemoryStorage()),
59
- describe: (session: Session) => session.trade(instrumentOf('default:btc-usdt'))
58
+ feed: new Feed(new InMemoryStorage())
60
59
  },
61
60
  command
62
61
  );
@@ -66,8 +65,7 @@ describe('ipc feed tests', () => {
66
65
 
67
66
  test('should dispatch session started event', done => {
68
67
  const command = {
69
- type: 'paper',
70
- balance: { 'default:usd': 100 }
68
+ type: 'paper'
71
69
  };
72
70
 
73
71
  const ipcSub = new EventEmitter();
@@ -80,8 +78,12 @@ describe('ipc feed tests', () => {
80
78
  run(
81
79
  {
82
80
  adapter: [new DefaultAdapter()],
83
- describe: (session: Session) => session.trade(instrumentOf('default:btc-usdt')),
84
- ipcSub
81
+ ipcSub,
82
+ options: {
83
+ paper: {
84
+ balance: { 'default:usd': 100 }
85
+ }
86
+ }
85
87
  },
86
88
  command
87
89
  );
@@ -102,8 +104,7 @@ describe('ipc feed tests', () => {
102
104
 
103
105
  run(
104
106
  {
105
- adapter: [new DefaultAdapter()],
106
- describe: (session: Session) => session.trade(instrumentOf('default:btc-usdt'))
107
+ adapter: [new DefaultAdapter()]
107
108
  },
108
109
  command
109
110
  );
package/src/ipc.ts CHANGED
@@ -5,7 +5,9 @@ import { Topic, event, handler } from './shared/topic';
5
5
  import { runTask, Logger } from './shared';
6
6
  import { backtest, live, paper } from './bin';
7
7
  import { BacktesterStreamer } from './adapter/backtester';
8
+ import { Observable } from 'rxjs';
8
9
  import { EventEmitter } from 'events';
10
+ import { join } from 'path';
9
11
  import minimist = require('minimist');
10
12
  import dotenv = require('dotenv');
11
13
 
@@ -46,12 +48,6 @@ export class IpcPaperCommand implements IpcCommand {
46
48
  * The optional session identifier.
47
49
  */
48
50
  id?: number;
49
-
50
- /**
51
- * Specifies trading balance, for example:
52
- * { "binance:usdt": 1000 }
53
- */
54
- balance: { [key: string]: number };
55
51
  }
56
52
 
57
53
  /**
@@ -60,22 +56,6 @@ export class IpcPaperCommand implements IpcCommand {
60
56
  @event
61
57
  export class IpcBacktestCommand implements IpcCommand {
62
58
  type = 'backtest';
63
-
64
- /**
65
- * Start date of the backtest in unix timestamp.
66
- */
67
- from: number;
68
-
69
- /**
70
- * Due date of the backtest in unix timestamp.
71
- */
72
- to: number;
73
-
74
- /**
75
- * Specifies trading balance, for example:
76
- * { "binance:usdt": 1000 }
77
- */
78
- balance: { [key: string]: number };
79
59
  }
80
60
 
81
61
  /**
@@ -93,12 +73,12 @@ export class IpcFeedCommand implements IpcCommand {
93
73
  /**
94
74
  * Start date of the feed in unix timestamp.
95
75
  */
96
- from: number;
76
+ from?: number;
97
77
 
98
78
  /**
99
79
  * Due date of the feed in unix timestamp.
100
80
  */
101
- to: number;
81
+ to?: number;
102
82
  }
103
83
 
104
84
  /**
@@ -121,13 +101,13 @@ class IpcSessionAccessor {
121
101
  session: Session;
122
102
  }
123
103
 
124
- export declare type SessionRunDescriptor = SessionDescriptor & { ipcSub?: EventEmitter };
104
+ export declare type IpcSessionDescriptor = SessionDescriptor & { ipcSub?: EventEmitter };
125
105
 
126
106
  /**
127
107
  * Inter process communication handler.
128
108
  */
129
109
  class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
130
- constructor(private readonly descriptor: SessionRunDescriptor) {
110
+ constructor(private readonly descriptor: IpcSessionDescriptor) {
131
111
  super();
132
112
  }
133
113
 
@@ -147,7 +127,7 @@ class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
147
127
  session: accessor.session.descriptor?.id
148
128
  });
149
129
 
150
- await accessor.session.awake();
130
+ await accessor.session.awake(this.describe());
151
131
  }
152
132
 
153
133
  /**
@@ -159,16 +139,14 @@ class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
159
139
  this.descriptor.id = command.id;
160
140
  }
161
141
 
162
- accessor.session = paper(this.descriptor, {
163
- balance: command.balance
164
- });
142
+ accessor.session = paper(this.descriptor);
165
143
 
166
144
  this.notify({
167
145
  type: 'paper:started',
168
146
  session: accessor.session.descriptor?.id
169
147
  });
170
148
 
171
- await accessor.session.awake();
149
+ await accessor.session.awake(this.describe());
172
150
  }
173
151
 
174
152
  /**
@@ -178,47 +156,42 @@ class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
178
156
  onBacktestMode(command: IpcBacktestCommand, accessor: IpcSessionAccessor) {
179
157
  return new Promise<void>(async resolve => {
180
158
  const [session, streamer] = backtest(this.descriptor, {
181
- from: command.from,
182
- to: command.to,
183
- balance: command.balance,
184
- listener: {
185
- onBacktestStarted: (streamer: BacktesterStreamer) => {
186
- this.notify({
187
- type: 'backtest:started',
188
- session: session.descriptor?.id,
189
- timestamp: streamer.timestamp,
190
- from: command.from,
191
- to: command.to
192
- });
193
- },
194
- onBacktestUpdated: (streamer: BacktesterStreamer) => {
195
- this.notify({
196
- type: 'backtest:updated',
197
- session: session.descriptor?.id,
198
- timestamp: streamer.timestamp,
199
- from: command.from,
200
- to: command.to
201
- });
202
- },
203
- onBacktestCompleted: async (streamer: BacktesterStreamer) => {
204
- await accessor.session.dispose();
205
-
206
- this.notify({
207
- type: 'backtest:completed',
208
- session: session.descriptor?.id,
209
- timestamp: streamer.timestamp,
210
- from: command.from,
211
- to: command.to
212
- });
213
-
214
- resolve();
215
- }
159
+ onBacktestStarted: (streamer: BacktesterStreamer) => {
160
+ this.notify({
161
+ type: 'backtest:started',
162
+ session: session.descriptor?.id,
163
+ timestamp: streamer.timestamp,
164
+ from: this.descriptor.options.backtester.from,
165
+ to: this.descriptor.options.backtester.to
166
+ });
167
+ },
168
+ onBacktestUpdated: (streamer: BacktesterStreamer) => {
169
+ this.notify({
170
+ type: 'backtest:updated',
171
+ session: session.descriptor?.id,
172
+ timestamp: streamer.timestamp,
173
+ from: this.descriptor.options.backtester.from,
174
+ to: this.descriptor.options.backtester.to
175
+ });
176
+ },
177
+ onBacktestCompleted: async (streamer: BacktesterStreamer) => {
178
+ await accessor.session.dispose();
179
+
180
+ this.notify({
181
+ type: 'backtest:completed',
182
+ session: session.descriptor?.id,
183
+ timestamp: streamer.timestamp,
184
+ from: this.descriptor.options.backtester.from,
185
+ to: this.descriptor.options.backtester.to
186
+ });
187
+
188
+ resolve();
216
189
  }
217
190
  });
218
191
 
219
192
  accessor.session = session;
220
193
 
221
- await accessor.session.awake();
194
+ await accessor.session.awake(this.describe());
222
195
  await streamer.tryContinue().catch(it => Logger.error(it));
223
196
  });
224
197
  }
@@ -231,7 +204,7 @@ class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
231
204
  accessor.session = accessor.session ?? live(this.descriptor);
232
205
  const instrument = instrumentOf(command.instrument);
233
206
 
234
- await accessor.session.awake(true);
207
+ await accessor.session.awake(undefined);
235
208
 
236
209
  this.notify({ type: 'feed:started' });
237
210
 
@@ -264,7 +237,7 @@ class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
264
237
  async onTask(query: IpcTaskCommand, accessor: IpcSessionAccessor) {
265
238
  accessor.session = accessor.session ?? live(this.descriptor);
266
239
 
267
- await accessor.session.awake(true);
240
+ await accessor.session.awake(undefined);
268
241
 
269
242
  this.notify({ type: 'task:started', taskName: query.taskName });
270
243
 
@@ -281,6 +254,17 @@ class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
281
254
  await accessor.session.dispose();
282
255
  }
283
256
 
257
+ describe(): (session: Session) => Observable<any> {
258
+ const pkg = require(join(process.cwd(), 'package.json'));
259
+ const describe = require(join(process.cwd(), pkg.main));
260
+
261
+ if (describe instanceof Function) {
262
+ return describe;
263
+ }
264
+
265
+ return undefined;
266
+ }
267
+
284
268
  /**
285
269
  * Sends a message to parent process.
286
270
  */
@@ -300,7 +284,7 @@ class IpcHandler extends Topic<{ type: string }, IpcSessionAccessor> {
300
284
  * @returns new session.
301
285
  */
302
286
  export async function run(
303
- descriptor: SessionRunDescriptor,
287
+ descriptor: IpcSessionDescriptor,
304
288
  ...commands: IpcCommand[]
305
289
  ): Promise<Session> {
306
290
  const handler = new IpcHandler(descriptor);
@@ -1,8 +1,8 @@
1
1
  import { Adapter } from '../adapter';
2
- import { Session } from '.';
3
2
  import { Measurement } from '../storage/measurement';
4
3
  import { Feed } from '../storage';
5
- import { Observable } from 'rxjs';
4
+ import { BacktesterOptions } from './../adapter/backtester';
5
+ import { PaperOptions } from './../adapter/paper';
6
6
 
7
7
  /**
8
8
  * Describes a single session.
@@ -44,7 +44,10 @@ export interface SessionDescriptor {
44
44
  measurement?: Measurement;
45
45
 
46
46
  /**
47
- * Describes your trading strategy.
47
+ * Session additional options.
48
48
  */
49
- describe?: (session: Session) => Observable<any>;
49
+ options?: {
50
+ backtester?: BacktesterOptions;
51
+ paper?: PaperOptions;
52
+ };
50
53
  }
@@ -13,11 +13,7 @@ describe('session tests', () => {
13
13
  };
14
14
 
15
15
  test('should trigger once', done => {
16
- const session = paper(descriptor, {
17
- balance: {
18
- ['binance:btc']: 1.23
19
- }
20
- });
16
+ const session = paper(descriptor);
21
17
 
22
18
  session.instruments().subscribe({
23
19
  next: it => {
@@ -57,7 +57,7 @@ export class Session {
57
57
  }
58
58
  }
59
59
 
60
- async awake(idle: boolean = false): Promise<void> {
60
+ async awake(describe: (session: Session) => Observable<any>): Promise<void> {
61
61
  if (this.initialized) {
62
62
  return;
63
63
  }
@@ -67,8 +67,8 @@ export class Session {
67
67
  // awake all adapters and synchronize trading accounts with store.
68
68
  await this.aggregate.awake(this.descriptor != null);
69
69
 
70
- if (!idle && this.descriptor?.describe) {
71
- this.subscription = this.descriptor.describe(this).subscribe();
70
+ if (describe) {
71
+ this.subscription = describe(this).subscribe();
72
72
  }
73
73
  }
74
74
 
@@ -63,13 +63,17 @@ describe('backtester adapter tests', () => {
63
63
  });
64
64
 
65
65
  test('should stream data from input array', done => {
66
- const streamer = new BacktesterStreamer(store, feed, {
67
- balance: {
68
- ['binance:usdt']: 1000
66
+ const streamer = new BacktesterStreamer(
67
+ store,
68
+ feed,
69
+ {
70
+ balance: {
71
+ ['binance:usdt']: 1000
72
+ },
73
+ from: 0,
74
+ to: 100
69
75
  },
70
- from: 0,
71
- to: 100,
72
- listener: {
76
+ {
73
77
  onBacktestCompleted: () => {
74
78
  expect(store.snapshot.timestamp).toEqual(1);
75
79
  expect(store.snapshot.trade[instrument.toString()].rate).toEqual(100);
@@ -78,7 +82,7 @@ describe('backtester adapter tests', () => {
78
82
  done();
79
83
  }
80
84
  }
81
- });
85
+ );
82
86
 
83
87
  feed.save(instrument, [new TradePatchEvent(instrument, 100, 10, 1)]);
84
88