@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.
- package/dist/adapter/backtester/backtester-adapter.d.ts +1 -2
- package/dist/adapter/backtester/backtester-adapter.js.map +1 -1
- package/dist/adapter/backtester/backtester-streamer.d.ts +2 -1
- package/dist/adapter/backtester/backtester-streamer.js +8 -7
- package/dist/adapter/backtester/backtester-streamer.js.map +1 -1
- package/dist/adapter/backtester/backtester-streamer.spec.js +9 -10
- package/dist/adapter/backtester/backtester-streamer.spec.js.map +1 -1
- package/dist/bin.d.ts +3 -4
- package/dist/bin.js +5 -5
- package/dist/bin.js.map +1 -1
- package/dist/ipc.d.ts +4 -12
- package/dist/ipc.js +46 -44
- package/dist/ipc.js.map +1 -1
- package/dist/ipc.spec.js +9 -9
- package/dist/ipc.spec.js.map +1 -1
- package/dist/session/session-descriptor.d.ts +6 -3
- package/dist/session/session.d.ts +1 -1
- package/dist/session/session.js +3 -4
- package/dist/session/session.js.map +1 -1
- package/dist/session/session.spec.js +1 -5
- package/dist/session/session.spec.js.map +1 -1
- package/dist/tests/backtester-adapter.spec.js +7 -8
- package/dist/tests/backtester-adapter.spec.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/adapter/backtester/backtester-adapter.ts +2 -3
- package/src/adapter/backtester/backtester-streamer.spec.ts +10 -6
- package/src/adapter/backtester/backtester-streamer.ts +8 -7
- package/src/bin.ts +17 -7
- package/src/ipc.spec.ts +9 -8
- package/src/ipc.ts +54 -70
- package/src/session/session-descriptor.ts +7 -4
- package/src/session/session.spec.ts +1 -5
- package/src/session/session.ts +3 -3
- 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
|
-
|
|
84
|
-
|
|
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
|
|
76
|
+
from?: number;
|
|
97
77
|
|
|
98
78
|
/**
|
|
99
79
|
* Due date of the feed in unix timestamp.
|
|
100
80
|
*/
|
|
101
|
-
to
|
|
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
|
|
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:
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
this.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
this.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
this.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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(
|
|
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(
|
|
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:
|
|
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 {
|
|
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
|
-
*
|
|
47
|
+
* Session additional options.
|
|
48
48
|
*/
|
|
49
|
-
|
|
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 => {
|
package/src/session/session.ts
CHANGED
|
@@ -57,7 +57,7 @@ export class Session {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
async awake(
|
|
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 (
|
|
71
|
-
this.subscription =
|
|
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(
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
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
|
|