@quantform/core 0.3.239 → 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 (71) hide show
  1. package/dist/adapter/adapter-aggregate.js +5 -5
  2. package/dist/adapter/adapter-aggregate.js.map +1 -1
  3. package/dist/adapter/backtester/backtester-adapter.d.ts +1 -2
  4. package/dist/adapter/backtester/backtester-adapter.js.map +1 -1
  5. package/dist/adapter/backtester/backtester-streamer.d.ts +2 -1
  6. package/dist/adapter/backtester/backtester-streamer.js +8 -7
  7. package/dist/adapter/backtester/backtester-streamer.js.map +1 -1
  8. package/dist/adapter/backtester/backtester-streamer.spec.js +9 -10
  9. package/dist/adapter/backtester/backtester-streamer.spec.js.map +1 -1
  10. package/dist/adapter/paper/paper-adapter.js +2 -2
  11. package/dist/adapter/paper/paper-adapter.js.map +1 -1
  12. package/dist/bin.d.ts +3 -5
  13. package/dist/bin.js +6 -12
  14. package/dist/bin.js.map +1 -1
  15. package/dist/domain/asset.d.ts +3 -3
  16. package/dist/domain/asset.js +8 -8
  17. package/dist/domain/asset.js.map +1 -1
  18. package/dist/domain/asset.spec.js +4 -4
  19. package/dist/domain/asset.spec.js.map +1 -1
  20. package/dist/domain/instrument.d.ts +1 -1
  21. package/dist/domain/instrument.js +6 -6
  22. package/dist/domain/instrument.js.map +1 -1
  23. package/dist/domain/instrument.spec.js +7 -7
  24. package/dist/domain/instrument.spec.js.map +1 -1
  25. package/dist/domain/orderbook.d.ts +0 -1
  26. package/dist/ipc.d.ts +10 -16
  27. package/dist/ipc.js +82 -68
  28. package/dist/ipc.js.map +1 -1
  29. package/dist/ipc.spec.js +24 -8
  30. package/dist/ipc.spec.js.map +1 -1
  31. package/dist/session/session-descriptor.d.ts +6 -3
  32. package/dist/session/session.d.ts +2 -2
  33. package/dist/session/session.js +10 -11
  34. package/dist/session/session.js.map +1 -1
  35. package/dist/session/session.spec.js +1 -5
  36. package/dist/session/session.spec.js.map +1 -1
  37. package/dist/shared/index.d.ts +1 -0
  38. package/dist/shared/index.js +1 -0
  39. package/dist/shared/index.js.map +1 -1
  40. package/dist/shared/task.d.ts +6 -0
  41. package/dist/shared/task.js +25 -0
  42. package/dist/shared/task.js.map +1 -0
  43. package/dist/store/event/store-instrument.event.js +1 -1
  44. package/dist/store/event/store-instrument.event.js.map +1 -1
  45. package/dist/store/event/store-order.event.js +0 -8
  46. package/dist/store/event/store-order.event.js.map +1 -1
  47. package/dist/tests/backtester-adapter.spec.js +7 -8
  48. package/dist/tests/backtester-adapter.spec.js.map +1 -1
  49. package/dist/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +2 -1
  51. package/src/adapter/adapter-aggregate.ts +5 -5
  52. package/src/adapter/backtester/backtester-adapter.ts +2 -3
  53. package/src/adapter/backtester/backtester-streamer.spec.ts +10 -6
  54. package/src/adapter/backtester/backtester-streamer.ts +8 -7
  55. package/src/adapter/paper/paper-adapter.ts +2 -2
  56. package/src/bin.ts +17 -18
  57. package/src/domain/asset.spec.ts +4 -4
  58. package/src/domain/asset.ts +9 -9
  59. package/src/domain/instrument.spec.ts +7 -7
  60. package/src/domain/instrument.ts +6 -6
  61. package/src/domain/orderbook.ts +1 -1
  62. package/src/ipc.spec.ts +36 -8
  63. package/src/ipc.ts +99 -88
  64. package/src/session/session-descriptor.ts +7 -4
  65. package/src/session/session.spec.ts +1 -5
  66. package/src/session/session.ts +11 -11
  67. package/src/shared/index.ts +1 -0
  68. package/src/shared/task.ts +30 -0
  69. package/src/store/event/store-instrument.event.ts +1 -1
  70. package/src/store/event/store-order.event.ts +0 -12
  71. package/src/tests/backtester-adapter.spec.ts +11 -7
@@ -18,11 +18,15 @@ describe('backtester streamer tests', () => {
18
18
  store.snapshot.universe.instrument[instrument.toString()] = instrument;
19
19
  store.snapshot.subscription.instrument[instrument.toString()] = instrument;
20
20
 
21
- const streamer = new BacktesterStreamer(store, feed, {
22
- balance: {},
23
- from: 0,
24
- to: 10,
25
- listener: {
21
+ const streamer = new BacktesterStreamer(
22
+ store,
23
+ feed,
24
+ {
25
+ balance: {},
26
+ from: 0,
27
+ to: 10
28
+ },
29
+ {
26
30
  onBacktestCompleted: () => {
27
31
  const trade = store.snapshot.trade[instrument.toString()];
28
32
 
@@ -34,7 +38,7 @@ describe('backtester streamer tests', () => {
34
38
  done();
35
39
  }
36
40
  }
37
- });
41
+ );
38
42
 
39
43
  feed
40
44
  .save(instrument, [
@@ -36,7 +36,8 @@ export class BacktesterStreamer {
36
36
  constructor(
37
37
  private readonly store: Store,
38
38
  private readonly feed: Feed,
39
- private readonly options: BacktesterOptions
39
+ private readonly options: BacktesterOptions,
40
+ private readonly listener?: BacktesterListener
40
41
  ) {
41
42
  this.timestamp = this.options.from;
42
43
  }
@@ -73,15 +74,15 @@ export class BacktesterStreamer {
73
74
  }
74
75
 
75
76
  if (this.sequence == 0) {
76
- if (this.options.listener.onBacktestStarted) {
77
- this.options.listener.onBacktestStarted(this);
77
+ if (this.listener.onBacktestStarted) {
78
+ this.listener.onBacktestStarted(this);
78
79
  }
79
80
  }
80
81
 
81
82
  while (await this.processNext()) {
82
83
  if (this.sequence % this.sequenceUpdateBatch == 0) {
83
- if (this.options.listener.onBacktestUpdated) {
84
- this.options.listener.onBacktestUpdated(this);
84
+ if (this.listener.onBacktestUpdated) {
85
+ this.listener.onBacktestUpdated(this);
85
86
  }
86
87
  }
87
88
 
@@ -90,8 +91,8 @@ export class BacktesterStreamer {
90
91
  }
91
92
  }
92
93
 
93
- if (this.options.listener.onBacktestCompleted) {
94
- this.options.listener.onBacktestCompleted(this);
94
+ if (this.listener.onBacktestCompleted) {
95
+ this.listener.onBacktestCompleted(this);
95
96
  }
96
97
  }
97
98
 
@@ -43,13 +43,13 @@ export class PaperAdapter extends Adapter {
43
43
  @handler(AdapterAccountCommand)
44
44
  onAccount(event: AdapterAccountCommand, context: AdapterContext) {
45
45
  let subscribed = Object.values(this.store.snapshot.subscription.asset).filter(
46
- it => it.exchange == this.name
46
+ it => it.adapter == this.name
47
47
  );
48
48
 
49
49
  for (const balance in this.options.balance) {
50
50
  const asset = assetOf(balance);
51
51
 
52
- if (asset.exchange != this.name) {
52
+ if (asset.adapter != this.name) {
53
53
  continue;
54
54
  }
55
55
 
package/src/bin.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  BacktesterAdapter,
3
- BacktesterOptions,
3
+ BacktesterListener,
4
4
  BacktesterStreamer
5
5
  } from './adapter/backtester';
6
6
  import { AdapterAggregate } from './adapter';
7
- import { PaperAdapter, PaperOptions } from './adapter/paper';
7
+ import { PaperAdapter } from './adapter/paper';
8
8
  import { Session, SessionDescriptor } from './session';
9
9
  import { Store } from './store';
10
10
 
@@ -16,15 +16,25 @@ import { Store } from './store';
16
16
  */
17
17
  export function backtest(
18
18
  descriptor: SessionDescriptor,
19
- options: BacktesterOptions
19
+ listener?: BacktesterListener
20
20
  ): [Session, BacktesterStreamer] {
21
21
  const store = new Store();
22
22
 
23
- const streamer = new BacktesterStreamer(store, descriptor.feed, options);
23
+ const streamer = new BacktesterStreamer(
24
+ store,
25
+ descriptor.feed,
26
+ descriptor.options.backtester,
27
+ listener
28
+ );
24
29
  const aggregate = new AdapterAggregate(
25
30
  store,
26
31
  descriptor.adapter.map(
27
- it => new PaperAdapter(new BacktesterAdapter(it, streamer), store, options)
32
+ it =>
33
+ new PaperAdapter(
34
+ new BacktesterAdapter(it, streamer),
35
+ store,
36
+ descriptor.options.backtester
37
+ )
28
38
  )
29
39
  );
30
40
 
@@ -37,12 +47,12 @@ export function backtest(
37
47
  * @param options backtest options.
38
48
  * @returns new session object.
39
49
  */
40
- export function paper(descriptor: SessionDescriptor, options: PaperOptions): Session {
50
+ export function paper(descriptor: SessionDescriptor): Session {
41
51
  const store = new Store();
42
52
 
43
53
  const aggregate = new AdapterAggregate(
44
54
  store,
45
- descriptor.adapter.map(it => new PaperAdapter(it, store, options))
55
+ descriptor.adapter.map(it => new PaperAdapter(it, store, descriptor.options.paper))
46
56
  );
47
57
 
48
58
  return new Session(store, aggregate, descriptor);
@@ -59,14 +69,3 @@ export function live(descriptor: SessionDescriptor): Session {
59
69
 
60
70
  return new Session(store, aggregate, descriptor);
61
71
  }
62
-
63
- /**
64
- * Starts a new idle session.
65
- * @param descriptor session descriptor.
66
- */
67
- export function idle(descriptor: SessionDescriptor): Session {
68
- const store = new Store();
69
- const aggregate = new AdapterAggregate(store, descriptor.adapter);
70
-
71
- return new Session(store, aggregate);
72
- }
@@ -5,7 +5,7 @@ describe('asset tests', () => {
5
5
  const sut = new Asset('abc', 'xyz', 4);
6
6
 
7
7
  expect(sut.name).toEqual('abc');
8
- expect(sut.exchange).toEqual('xyz');
8
+ expect(sut.adapter).toEqual('xyz');
9
9
  expect(sut.scale).toEqual(4);
10
10
  expect(sut.tickSize).toEqual(0.0001);
11
11
  expect(sut.fixed(1.1234567)).toEqual(1.1234);
@@ -20,7 +20,7 @@ describe('asset selector tests', () => {
20
20
  const sut = assetOf('xyz:abc');
21
21
 
22
22
  expect(sut.name).toEqual('abc');
23
- expect(sut.exchange).toEqual('xyz');
23
+ expect(sut.adapter).toEqual('xyz');
24
24
  expect(sut.toString()).toEqual('xyz:abc');
25
25
  });
26
26
 
@@ -28,7 +28,7 @@ describe('asset selector tests', () => {
28
28
  const sut = assetOf('XYZ:ABC');
29
29
 
30
30
  expect(sut.name).toEqual('abc');
31
- expect(sut.exchange).toEqual('xyz');
31
+ expect(sut.adapter).toEqual('xyz');
32
32
  expect(sut.toString()).toEqual('xyz:abc');
33
33
  });
34
34
 
@@ -56,7 +56,7 @@ describe('asset selector tests', () => {
56
56
  expect(fn).toThrow(Error);
57
57
  });
58
58
 
59
- test('should throw invalid format message for missing exchange name', () => {
59
+ test('should throw invalid format message for missing adapter name', () => {
60
60
  const fn = () => {
61
61
  assetOf(':abc');
62
62
  };
@@ -7,13 +7,13 @@ export class AssetSelector {
7
7
  private readonly id: string;
8
8
 
9
9
  readonly name: string;
10
- readonly exchange: string;
10
+ readonly adapter: string;
11
11
 
12
- constructor(name: string, exchange: string) {
12
+ constructor(name: string, adapter: string) {
13
13
  this.name = name.toLowerCase();
14
- this.exchange = exchange.toLowerCase();
14
+ this.adapter = adapter.toLowerCase();
15
15
 
16
- this.id = `${this.exchange}:${this.name}`;
16
+ this.id = `${this.adapter}:${this.name}`;
17
17
  }
18
18
 
19
19
  /**
@@ -35,13 +35,13 @@ export function assetOf(asset: string): AssetSelector {
35
35
  }
36
36
 
37
37
  const assetName = section[1];
38
- const exchangeName = section[0];
38
+ const adapterName = section[0];
39
39
 
40
- if (assetName.length == 0 || exchangeName.length == 0) {
40
+ if (assetName.length == 0 || adapterName.length == 0) {
41
41
  throw Error('invalid asset format');
42
42
  }
43
43
 
44
- return new AssetSelector(assetName, exchangeName);
44
+ return new AssetSelector(assetName, adapterName);
45
45
  }
46
46
 
47
47
  /**
@@ -51,8 +51,8 @@ export function assetOf(asset: string): AssetSelector {
51
51
  export class Asset extends AssetSelector {
52
52
  readonly tickSize: number;
53
53
 
54
- constructor(name: string, exchange: string, public readonly scale: number) {
55
- super(name, exchange);
54
+ constructor(name: string, adapter: string, public readonly scale: number) {
55
+ super(name, adapter);
56
56
 
57
57
  this.tickSize = 1.0 / Math.pow(10, this.scale);
58
58
  }
@@ -10,9 +10,9 @@ describe('instrument tests', () => {
10
10
  );
11
11
 
12
12
  expect(sut.base.name).toEqual('abc');
13
- expect(sut.base.exchange).toEqual('xyz');
13
+ expect(sut.base.adapter).toEqual('xyz');
14
14
  expect(sut.quote.name).toEqual('def');
15
- expect(sut.quote.exchange).toEqual('xyz');
15
+ expect(sut.quote.adapter).toEqual('xyz');
16
16
  expect(sut.toString()).toEqual('xyz:abc-def');
17
17
  });
18
18
  });
@@ -22,9 +22,9 @@ describe('instrument selector tests', () => {
22
22
  const sut = instrumentOf('xyz:abc-def');
23
23
 
24
24
  expect(sut.base.name).toEqual('abc');
25
- expect(sut.base.exchange).toEqual('xyz');
25
+ expect(sut.base.adapter).toEqual('xyz');
26
26
  expect(sut.quote.name).toEqual('def');
27
- expect(sut.quote.exchange).toEqual('xyz');
27
+ expect(sut.quote.adapter).toEqual('xyz');
28
28
  expect(sut.toString()).toEqual('xyz:abc-def');
29
29
  });
30
30
 
@@ -32,9 +32,9 @@ describe('instrument selector tests', () => {
32
32
  const sut = instrumentOf('XYZ:ABC-DEF');
33
33
 
34
34
  expect(sut.base.name).toEqual('abc');
35
- expect(sut.base.exchange).toEqual('xyz');
35
+ expect(sut.base.adapter).toEqual('xyz');
36
36
  expect(sut.quote.name).toEqual('def');
37
- expect(sut.quote.exchange).toEqual('xyz');
37
+ expect(sut.quote.adapter).toEqual('xyz');
38
38
  expect(sut.toString()).toEqual('xyz:abc-def');
39
39
  });
40
40
 
@@ -62,7 +62,7 @@ describe('instrument selector tests', () => {
62
62
  expect(fn).toThrow(Error);
63
63
  });
64
64
 
65
- test('should throw invalid format message for missing exchange name', () => {
65
+ test('should throw invalid format message for missing adapter name', () => {
66
66
  const fn = () => {
67
67
  assetOf(':abc-def');
68
68
  };
@@ -9,9 +9,9 @@ export class InstrumentSelector {
9
9
  readonly base: AssetSelector;
10
10
  readonly quote: AssetSelector;
11
11
 
12
- constructor(base: string, quote: string, exchange: string) {
13
- this.base = new AssetSelector(base.toLowerCase(), exchange.toLowerCase());
14
- this.quote = new AssetSelector(quote.toLowerCase(), exchange.toLowerCase());
12
+ constructor(base: string, quote: string, adapter: string) {
13
+ this.base = new AssetSelector(base.toLowerCase(), adapter.toLowerCase());
14
+ this.quote = new AssetSelector(quote.toLowerCase(), adapter.toLowerCase());
15
15
 
16
16
  this.id = `${this.base.toString()}-${this.quote.name}`;
17
17
  }
@@ -31,10 +31,10 @@ export class Instrument extends InstrumentSelector implements Component {
31
31
  leverage?: number = null;
32
32
 
33
33
  constructor(readonly base: Asset, readonly quote: Asset, readonly raw: string) {
34
- super(base.name, quote.name, base.exchange);
34
+ super(base.name, quote.name, base.adapter);
35
35
 
36
- if (base.exchange != quote.exchange) {
37
- throw new Error('Exchange mismatch!');
36
+ if (base.adapter != quote.adapter) {
37
+ throw new Error('Adapter mismatch!');
38
38
  }
39
39
  }
40
40
  }
@@ -11,7 +11,7 @@ export class Orderbook implements Component {
11
11
  bestAskQuantity: number;
12
12
  bestBidRate: number;
13
13
  bestBidQuantity: number;
14
- az;
14
+
15
15
  get midRate(): number {
16
16
  return this.instrument.quote.fixed((this.bestAskRate + this.bestBidRate) / 2);
17
17
  }
package/src/ipc.spec.ts CHANGED
@@ -9,10 +9,12 @@ import {
9
9
  } from './adapter';
10
10
  import { PaperAdapter, PaperSpotExecutor } from './adapter/paper';
11
11
  import { PaperExecutor } from './adapter/paper/executor/paper-executor';
12
- import { ipcSub, run } from './ipc';
12
+ import { run } from './ipc';
13
13
  import { Feed, InMemoryStorage } from './storage';
14
14
  import { instrumentOf } from './domain';
15
- import { handler } from './shared';
15
+ import { handler, task } from './shared';
16
+ import { EventEmitter } from 'events';
17
+ import { from, of, take, tap } from 'rxjs';
16
18
 
17
19
  class DefaultAdapter extends Adapter {
18
20
  name = 'default';
@@ -53,21 +55,21 @@ describe('ipc feed tests', () => {
53
55
  const session = await run(
54
56
  {
55
57
  adapter: [new DefaultAdapter()],
56
- feed: new Feed(new InMemoryStorage()),
57
- describe: (session: Session) => session.trade(instrumentOf('default:btc-usdt'))
58
+ feed: new Feed(new InMemoryStorage())
58
59
  },
59
60
  command
60
61
  );
61
62
 
62
- expect(session.descriptor).toBeUndefined();
63
+ //expect(session.descriptor).toBeUndefined();
63
64
  });
64
65
 
65
66
  test('should dispatch session started event', done => {
66
67
  const command = {
67
- type: 'paper',
68
- balance: { 'default:usd': 100 }
68
+ type: 'paper'
69
69
  };
70
70
 
71
+ const ipcSub = new EventEmitter();
72
+
71
73
  ipcSub.on('message', (message: any) => {
72
74
  expect(message.type).toBe('paper:started');
73
75
  done();
@@ -76,7 +78,33 @@ describe('ipc feed tests', () => {
76
78
  run(
77
79
  {
78
80
  adapter: [new DefaultAdapter()],
79
- describe: (session: Session) => session.trade(instrumentOf('default:btc-usdt'))
81
+ ipcSub,
82
+ options: {
83
+ paper: {
84
+ balance: { 'default:usd': 100 }
85
+ }
86
+ }
87
+ },
88
+ command
89
+ );
90
+ });
91
+
92
+ test('should execute user task', done => {
93
+ task('hello-world', session => {
94
+ return of(1).pipe(
95
+ take(1),
96
+ tap(() => done())
97
+ );
98
+ });
99
+
100
+ const command = {
101
+ type: 'task',
102
+ taskName: 'hello-world'
103
+ };
104
+
105
+ run(
106
+ {
107
+ adapter: [new DefaultAdapter()]
80
108
  },
81
109
  command
82
110
  );