@quantform/core 0.7.22 → 0.7.25
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/lib/app.d.ts +12 -0
- package/lib/app.d.ts.map +1 -0
- package/lib/app.js +35 -0
- package/lib/cli/build.d.ts.map +1 -1
- package/lib/cli/build.js +8 -18
- package/lib/cli/index.js +3 -12
- package/lib/cli/internal/script.d.ts +1 -1
- package/lib/cli/internal/script.d.ts.map +1 -1
- package/lib/cli/internal/script.js +8 -28
- package/lib/cli/live.js +10 -22
- package/lib/cli/paper.js +10 -22
- package/lib/cli/replay.d.ts.map +1 -1
- package/lib/cli/replay.js +15 -26
- package/lib/index.d.ts +1 -6
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -6
- package/lib/make-test-module.d.ts +1 -6
- package/lib/make-test-module.d.ts.map +1 -1
- package/lib/make-test-module.js +19 -30
- package/lib/module.d.ts.map +1 -1
- package/lib/module.js +9 -24
- package/lib/module.spec.js +8 -17
- package/lib/replay/use-replay-options.d.ts +5 -4
- package/lib/replay/use-replay-options.d.ts.map +1 -1
- package/lib/replay/use-replay-options.js +5 -1
- package/lib/replay/use-replay-scheduler.d.ts +7 -6
- package/lib/replay/use-replay-scheduler.d.ts.map +1 -1
- package/lib/replay/use-replay-scheduler.js +64 -70
- package/lib/replay/use-replay-storage-buffer.d.ts +3 -2
- package/lib/replay/use-replay-storage-buffer.d.ts.map +1 -1
- package/lib/replay/use-replay-storage-buffer.js +12 -23
- package/lib/replay/use-replay-storage-cursor.d.ts +9 -8
- package/lib/replay/use-replay-storage-cursor.d.ts.map +1 -1
- package/lib/replay/use-replay-storage-cursor.js +17 -25
- package/lib/replay/use-replay-storage.d.ts +5 -4
- package/lib/replay/use-replay-storage.d.ts.map +1 -1
- package/lib/replay/use-replay-storage.js +32 -39
- package/lib/session/use-session-storage.d.ts +1 -1
- package/lib/session/use-session-storage.d.ts.map +1 -1
- package/lib/session/use-session-storage.js +8 -5
- package/lib/shared/environment.js +1 -1
- package/lib/shared/index.d.ts +0 -1
- package/lib/shared/index.d.ts.map +1 -1
- package/lib/shared/index.js +0 -1
- package/lib/simulator/use-simulator.spec.js +17 -30
- package/lib/storage/in-memory/in-memory-storage.d.ts.map +1 -1
- package/lib/storage/in-memory/in-memory-storage.factory.js +2 -2
- package/lib/storage/in-memory/in-memory-storage.js +56 -55
- package/lib/storage/in-memory/in-memory-storage.spec.js +90 -100
- package/lib/storage/storage.d.ts +9 -8
- package/lib/storage/storage.d.ts.map +1 -1
- package/lib/storage/storage.js +8 -2
- package/lib/storage/use-cache.d.ts +1 -1
- package/lib/storage/use-cache.d.ts.map +1 -1
- package/lib/storage/use-cache.js +5 -5
- package/lib/storage/use-cache.spec.js +14 -25
- package/lib/storage/use-storage.d.ts +1 -1
- package/lib/storage/use-storage.d.ts.map +1 -1
- package/lib/storage/use-storage.js +9 -6
- package/lib/use-execution-mode.js +2 -2
- package/lib/use-hash.spec.js +3 -6
- package/lib/use-logger.d.ts +1 -1
- package/lib/use-logger.d.ts.map +1 -1
- package/lib/use-logger.js +10 -7
- package/lib/use-memo.spec.js +14 -25
- package/lib/use-socket.d.ts +3 -2
- package/lib/use-socket.d.ts.map +1 -1
- package/lib/use-socket.js +2 -2
- package/lib/use-timestamp.d.ts +14 -1
- package/lib/use-timestamp.d.ts.map +1 -1
- package/lib/use-timestamp.js +30 -3
- package/lib/with-request.d.ts +2 -1
- package/lib/with-request.d.ts.map +1 -1
- package/lib/with-request.js +4 -13
- package/package.json +6 -10
- package/src/app.ts +52 -0
- package/src/cli/build.ts +11 -6
- package/src/cli/internal/script.ts +25 -54
- package/src/cli/replay.ts +13 -2
- package/src/index.ts +1 -6
- package/src/make-test-module.ts +13 -21
- package/src/module.ts +0 -3
- package/src/replay/use-replay-options.ts +7 -3
- package/src/replay/use-replay-scheduler.ts +75 -67
- package/src/replay/use-replay-storage-buffer.ts +2 -1
- package/src/replay/use-replay-storage-cursor.ts +33 -28
- package/src/replay/use-replay-storage.ts +36 -27
- package/src/session/use-session-storage.ts +7 -5
- package/src/shared/index.ts +0 -1
- package/src/storage/in-memory/in-memory-storage.spec.ts +55 -54
- package/src/storage/in-memory/in-memory-storage.ts +24 -7
- package/src/storage/storage.ts +16 -7
- package/src/storage/use-cache.ts +4 -4
- package/src/storage/use-storage.ts +8 -6
- package/src/use-hash.spec.ts +3 -6
- package/src/use-logger.ts +9 -6
- package/src/use-socket.ts +5 -5
- package/src/use-timestamp.ts +41 -3
- package/src/with-request.ts +3 -3
- package/lib/asset/asset.d.ts +0 -41
- package/lib/asset/asset.d.ts.map +0 -1
- package/lib/asset/asset.js +0 -76
- package/lib/asset/asset.spec.d.ts +0 -2
- package/lib/asset/asset.spec.d.ts.map +0 -1
- package/lib/asset/asset.spec.js +0 -54
- package/lib/asset/index.d.ts +0 -2
- package/lib/asset/index.d.ts.map +0 -1
- package/lib/asset/index.js +0 -17
- package/lib/component/distinct-until-timesamp-changed.d.ts +0 -5
- package/lib/component/distinct-until-timesamp-changed.d.ts.map +0 -1
- package/lib/component/distinct-until-timesamp-changed.js +0 -9
- package/lib/component/error.d.ts +0 -17
- package/lib/component/error.d.ts.map +0 -1
- package/lib/component/error.js +0 -33
- package/lib/component/index.d.ts +0 -8
- package/lib/component/index.d.ts.map +0 -1
- package/lib/component/index.js +0 -23
- package/lib/component/ohlc-operator.d.ts +0 -11
- package/lib/component/ohlc-operator.d.ts.map +0 -1
- package/lib/component/ohlc-operator.js +0 -69
- package/lib/component/ohlc-operator.spec.d.ts +0 -2
- package/lib/component/ohlc-operator.spec.d.ts.map +0 -1
- package/lib/component/ohlc-operator.spec.js +0 -110
- package/lib/component/ohlc.d.ts +0 -12
- package/lib/component/ohlc.d.ts.map +0 -1
- package/lib/component/ohlc.js +0 -20
- package/lib/component/ohlc.spec.d.ts +0 -2
- package/lib/component/ohlc.spec.d.ts.map +0 -1
- package/lib/component/ohlc.spec.js +0 -25
- package/lib/component/timeframe.d.ts +0 -15
- package/lib/component/timeframe.d.ts.map +0 -1
- package/lib/component/timeframe.js +0 -21
- package/lib/core.d.ts +0 -3
- package/lib/core.d.ts.map +0 -1
- package/lib/core.js +0 -17
- package/lib/instrument/commission/commission.d.ts +0 -16
- package/lib/instrument/commission/commission.d.ts.map +0 -1
- package/lib/instrument/commission/commission.js +0 -28
- package/lib/instrument/commission/commission.spec.d.ts +0 -2
- package/lib/instrument/commission/commission.spec.d.ts.map +0 -1
- package/lib/instrument/commission/commission.spec.js +0 -30
- package/lib/instrument/index.d.ts +0 -3
- package/lib/instrument/index.d.ts.map +0 -1
- package/lib/instrument/index.js +0 -18
- package/lib/instrument/instrument.d.ts +0 -28
- package/lib/instrument/instrument.d.ts.map +0 -1
- package/lib/instrument/instrument.js +0 -53
- package/lib/instrument/instrument.spec.d.ts +0 -2
- package/lib/instrument/instrument.spec.d.ts.map +0 -1
- package/lib/instrument/instrument.spec.js +0 -51
- package/lib/operators.d.ts +0 -5
- package/lib/operators.d.ts.map +0 -1
- package/lib/operators.js +0 -16
- package/lib/shared/datetime.d.ts +0 -3
- package/lib/shared/datetime.d.ts.map +0 -1
- package/lib/shared/datetime.js +0 -7
- package/lib/strategy.d.ts +0 -15
- package/lib/strategy.d.ts.map +0 -1
- package/lib/strategy.js +0 -26
- package/lib/strategy.spec.d.ts +0 -2
- package/lib/strategy.spec.d.ts.map +0 -1
- package/lib/strategy.spec.js +0 -34
- package/lib/when-socket.d.ts +0 -8
- package/lib/when-socket.d.ts.map +0 -1
- package/lib/when-socket.js +0 -53
- package/lib/with-memo.d.ts +0 -5
- package/lib/with-memo.d.ts.map +0 -1
- package/lib/with-memo.js +0 -20
- package/lib/with-memo.spec.d.ts +0 -2
- package/lib/with-memo.spec.d.ts.map +0 -1
- package/lib/with-memo.spec.js +0 -47
- package/src/asset/asset.spec.ts +0 -70
- package/src/asset/asset.ts +0 -89
- package/src/asset/index.ts +0 -1
- package/src/component/distinct-until-timesamp-changed.ts +0 -11
- package/src/component/error.ts +0 -32
- package/src/component/index.ts +0 -7
- package/src/component/ohlc-operator.spec.ts +0 -125
- package/src/component/ohlc-operator.ts +0 -122
- package/src/component/ohlc.spec.ts +0 -30
- package/src/component/ohlc.ts +0 -18
- package/src/component/timeframe.ts +0 -17
- package/src/core.ts +0 -16
- package/src/instrument/commission/commission.spec.ts +0 -35
- package/src/instrument/commission/commission.ts +0 -27
- package/src/instrument/index.ts +0 -2
- package/src/instrument/instrument.spec.ts +0 -76
- package/src/instrument/instrument.ts +0 -65
- package/src/operators.ts +0 -18
- package/src/shared/datetime.ts +0 -5
- package/src/strategy.spec.ts +0 -42
- package/src/strategy.ts +0 -36
- package/src/when-socket.ts +0 -61
- package/src/with-memo.spec.ts +0 -46
- package/src/with-memo.ts +0 -33
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { d } from '@lib/shared';
|
|
2
2
|
import { eq, gt, lt, Storage } from '@lib/storage';
|
|
3
|
+
import { ns } from '@lib/use-timestamp';
|
|
3
4
|
|
|
4
5
|
import { InMemoryStorage } from './in-memory-storage';
|
|
5
6
|
|
|
@@ -27,26 +28,26 @@ describe(InMemoryStorage.name, () => {
|
|
|
27
28
|
const { sut } = fixtures;
|
|
28
29
|
|
|
29
30
|
const pricing = Storage.createObject('pricing', {
|
|
30
|
-
timestamp: '
|
|
31
|
+
timestamp: 'bigint',
|
|
31
32
|
rate: 'decimal'
|
|
32
33
|
});
|
|
33
34
|
|
|
34
35
|
await sut.save(pricing, [
|
|
35
|
-
{ timestamp: 1, rate: d(1) },
|
|
36
|
-
{ timestamp: 2, rate: d(2) },
|
|
37
|
-
{ timestamp: 3, rate: d(3) },
|
|
38
|
-
{ timestamp: 4, rate: d(4) },
|
|
39
|
-
{ timestamp: 5, rate: d(5) }
|
|
36
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
37
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
38
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
39
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
40
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
40
41
|
]);
|
|
41
42
|
|
|
42
43
|
const set = await sut.query(pricing, {});
|
|
43
44
|
|
|
44
45
|
expect(set).toEqual([
|
|
45
|
-
{ timestamp: 1, rate: d(1) },
|
|
46
|
-
{ timestamp: 2, rate: d(2) },
|
|
47
|
-
{ timestamp: 3, rate: d(3) },
|
|
48
|
-
{ timestamp: 4, rate: d(4) },
|
|
49
|
-
{ timestamp: 5, rate: d(5) }
|
|
46
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
47
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
48
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
49
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
50
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
50
51
|
]);
|
|
51
52
|
});
|
|
52
53
|
|
|
@@ -54,24 +55,24 @@ describe(InMemoryStorage.name, () => {
|
|
|
54
55
|
const { sut } = fixtures;
|
|
55
56
|
|
|
56
57
|
const pricing = Storage.createObject('pricing', {
|
|
57
|
-
timestamp: '
|
|
58
|
+
timestamp: 'bigint',
|
|
58
59
|
rate: 'decimal'
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
await sut.save(pricing, [
|
|
62
|
-
{ timestamp: 1, rate: d(1) },
|
|
63
|
-
{ timestamp: 2, rate: d(2) },
|
|
64
|
-
{ timestamp: 3, rate: d(3) },
|
|
65
|
-
{ timestamp: 4, rate: d(4) },
|
|
66
|
-
{ timestamp: 5, rate: d(5) }
|
|
63
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
64
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
65
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
66
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
67
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
67
68
|
]);
|
|
68
69
|
|
|
69
70
|
const set = await sut.query(pricing, { limit: 3 });
|
|
70
71
|
|
|
71
72
|
expect(set).toEqual([
|
|
72
|
-
{ timestamp: 1, rate: d(1) },
|
|
73
|
-
{ timestamp: 2, rate: d(2) },
|
|
74
|
-
{ timestamp: 3, rate: d(3) }
|
|
73
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
74
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
75
|
+
{ timestamp: ns(3), rate: d(3) }
|
|
75
76
|
]);
|
|
76
77
|
});
|
|
77
78
|
|
|
@@ -79,26 +80,26 @@ describe(InMemoryStorage.name, () => {
|
|
|
79
80
|
const { sut } = fixtures;
|
|
80
81
|
|
|
81
82
|
const pricing = Storage.createObject('pricing', {
|
|
82
|
-
timestamp: '
|
|
83
|
+
timestamp: 'bigint',
|
|
83
84
|
rate: 'decimal'
|
|
84
85
|
});
|
|
85
86
|
|
|
86
87
|
await sut.save(pricing, [
|
|
87
|
-
{ timestamp: 1, rate: d(1) },
|
|
88
|
-
{ timestamp: 2, rate: d(2) },
|
|
89
|
-
{ timestamp: 3, rate: d(3) },
|
|
90
|
-
{ timestamp: 4, rate: d(4) },
|
|
91
|
-
{ timestamp: 5, rate: d(5) }
|
|
88
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
89
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
90
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
91
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
92
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
92
93
|
]);
|
|
93
94
|
|
|
94
95
|
const set = await sut.query(pricing, { orderBy: 'DESC' });
|
|
95
96
|
|
|
96
97
|
expect(set).toEqual([
|
|
97
|
-
{ timestamp: 5, rate: d(5) },
|
|
98
|
-
{ timestamp: 4, rate: d(4) },
|
|
99
|
-
{ timestamp: 3, rate: d(3) },
|
|
100
|
-
{ timestamp: 2, rate: d(2) },
|
|
101
|
-
{ timestamp: 1, rate: d(1) }
|
|
98
|
+
{ timestamp: ns(5), rate: d(5) },
|
|
99
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
100
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
101
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
102
|
+
{ timestamp: ns(1), rate: d(1) }
|
|
102
103
|
]);
|
|
103
104
|
});
|
|
104
105
|
|
|
@@ -106,16 +107,16 @@ describe(InMemoryStorage.name, () => {
|
|
|
106
107
|
const { sut } = fixtures;
|
|
107
108
|
|
|
108
109
|
const pricing = Storage.createObject('pricing', {
|
|
109
|
-
timestamp: '
|
|
110
|
+
timestamp: 'bigint',
|
|
110
111
|
rate: 'decimal'
|
|
111
112
|
});
|
|
112
113
|
|
|
113
114
|
await sut.save(pricing, [
|
|
114
|
-
{ timestamp: 1, rate: d(1) },
|
|
115
|
-
{ timestamp: 2, rate: d(2) },
|
|
116
|
-
{ timestamp: 3, rate: d(3) },
|
|
117
|
-
{ timestamp: 4, rate: d(4) },
|
|
118
|
-
{ timestamp: 5, rate: d(5) }
|
|
115
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
116
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
117
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
118
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
119
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
119
120
|
]);
|
|
120
121
|
|
|
121
122
|
const set = await sut.query(pricing, {
|
|
@@ -124,23 +125,23 @@ describe(InMemoryStorage.name, () => {
|
|
|
124
125
|
}
|
|
125
126
|
});
|
|
126
127
|
|
|
127
|
-
expect(set).toEqual([{ timestamp: 4, rate: d(4) }]);
|
|
128
|
+
expect(set).toEqual([{ timestamp: ns(4), rate: d(4) }]);
|
|
128
129
|
});
|
|
129
130
|
|
|
130
131
|
test('save and read filtered lt data', async () => {
|
|
131
132
|
const { sut } = fixtures;
|
|
132
133
|
|
|
133
134
|
const pricing = Storage.createObject('pricing', {
|
|
134
|
-
timestamp: '
|
|
135
|
+
timestamp: 'bigint',
|
|
135
136
|
rate: 'decimal'
|
|
136
137
|
});
|
|
137
138
|
|
|
138
139
|
await sut.save(pricing, [
|
|
139
|
-
{ timestamp: 1, rate: d(1) },
|
|
140
|
-
{ timestamp: 2, rate: d(2) },
|
|
141
|
-
{ timestamp: 3, rate: d(3) },
|
|
142
|
-
{ timestamp: 4, rate: d(4) },
|
|
143
|
-
{ timestamp: 5, rate: d(5) }
|
|
140
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
141
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
142
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
143
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
144
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
144
145
|
]);
|
|
145
146
|
|
|
146
147
|
const set = await sut.query(pricing, {
|
|
@@ -150,8 +151,8 @@ describe(InMemoryStorage.name, () => {
|
|
|
150
151
|
});
|
|
151
152
|
|
|
152
153
|
expect(set).toEqual([
|
|
153
|
-
{ timestamp: 1, rate: d(1) },
|
|
154
|
-
{ timestamp: 2, rate: d(2) }
|
|
154
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
155
|
+
{ timestamp: ns(2), rate: d(2) }
|
|
155
156
|
]);
|
|
156
157
|
});
|
|
157
158
|
|
|
@@ -159,16 +160,16 @@ describe(InMemoryStorage.name, () => {
|
|
|
159
160
|
const { sut } = fixtures;
|
|
160
161
|
|
|
161
162
|
const pricing = Storage.createObject('pricing', {
|
|
162
|
-
timestamp: '
|
|
163
|
+
timestamp: 'bigint',
|
|
163
164
|
rate: 'decimal'
|
|
164
165
|
});
|
|
165
166
|
|
|
166
167
|
await sut.save(pricing, [
|
|
167
|
-
{ timestamp: 1, rate: d(1) },
|
|
168
|
-
{ timestamp: 2, rate: d(2) },
|
|
169
|
-
{ timestamp: 3, rate: d(3) },
|
|
170
|
-
{ timestamp: 4, rate: d(4) },
|
|
171
|
-
{ timestamp: 5, rate: d(5) }
|
|
168
|
+
{ timestamp: ns(1), rate: d(1) },
|
|
169
|
+
{ timestamp: ns(2), rate: d(2) },
|
|
170
|
+
{ timestamp: ns(3), rate: d(3) },
|
|
171
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
172
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
172
173
|
]);
|
|
173
174
|
|
|
174
175
|
const set = await sut.query(pricing, {
|
|
@@ -178,8 +179,8 @@ describe(InMemoryStorage.name, () => {
|
|
|
178
179
|
});
|
|
179
180
|
|
|
180
181
|
expect(set).toEqual([
|
|
181
|
-
{ timestamp: 4, rate: d(4) },
|
|
182
|
-
{ timestamp: 5, rate: d(5) }
|
|
182
|
+
{ timestamp: ns(4), rate: d(4) },
|
|
183
|
+
{ timestamp: ns(5), rate: d(5) }
|
|
183
184
|
]);
|
|
184
185
|
});
|
|
185
186
|
});
|
|
@@ -29,18 +29,35 @@ export class InMemoryStorage implements Storage {
|
|
|
29
29
|
|
|
30
30
|
switch (expression?.type) {
|
|
31
31
|
case 'eq':
|
|
32
|
-
set = set.filter(it => it[prop]
|
|
32
|
+
set = set.filter(it => it[prop] == expression.value);
|
|
33
33
|
break;
|
|
34
34
|
case 'gt':
|
|
35
|
-
set = set.filter(it =>
|
|
35
|
+
set = set.filter(it => {
|
|
36
|
+
const value = it[prop];
|
|
37
|
+
|
|
38
|
+
return typeof value === 'bigint'
|
|
39
|
+
? BigInt(value) > expression.value
|
|
40
|
+
: Number(value) > Number(expression.value);
|
|
41
|
+
});
|
|
36
42
|
break;
|
|
37
43
|
case 'lt':
|
|
38
|
-
set = set.filter(it =>
|
|
44
|
+
set = set.filter(it => {
|
|
45
|
+
const value = it[prop];
|
|
46
|
+
|
|
47
|
+
return typeof value === 'bigint'
|
|
48
|
+
? BigInt(value) < expression.value
|
|
49
|
+
: Number(value) < Number(expression.value);
|
|
50
|
+
});
|
|
39
51
|
break;
|
|
40
52
|
case 'between':
|
|
41
|
-
set = set.filter(
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
set = set.filter(it => {
|
|
54
|
+
const value = it[prop];
|
|
55
|
+
|
|
56
|
+
return typeof value === 'bigint'
|
|
57
|
+
? BigInt(value) > expression.min && BigInt(value) < expression.max
|
|
58
|
+
: Number(value) > Number(expression.min) &&
|
|
59
|
+
Number(value) < Number(expression.max);
|
|
60
|
+
});
|
|
44
61
|
break;
|
|
45
62
|
}
|
|
46
63
|
}
|
|
@@ -71,7 +88,7 @@ export class InMemoryStorage implements Storage {
|
|
|
71
88
|
buffer.push(document);
|
|
72
89
|
}
|
|
73
90
|
|
|
74
|
-
buffer.sort((lhs, rhs) => lhs.timestamp - rhs.timestamp);
|
|
91
|
+
buffer.sort((lhs, rhs) => Number(lhs.timestamp - rhs.timestamp));
|
|
75
92
|
}
|
|
76
93
|
|
|
77
94
|
clear() {
|
package/src/storage/storage.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { decimal } from '@lib/shared';
|
|
2
|
+
import { Timestamp } from '@lib/use-timestamp';
|
|
2
3
|
|
|
3
|
-
type Types = string | number | decimal;
|
|
4
|
+
type Types = string | number | bigint | decimal;
|
|
4
5
|
|
|
5
6
|
export const eq = <T extends Types>(value: T) => ({ type: 'eq' as const, value });
|
|
6
|
-
export const gt = <T extends number>(value: T) => ({
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export const gt = <T extends number | bigint>(value: T) => ({
|
|
8
|
+
type: 'gt' as const,
|
|
9
|
+
value
|
|
10
|
+
});
|
|
11
|
+
export const lt = <T extends number | bigint>(value: T) => ({
|
|
12
|
+
type: 'lt' as const,
|
|
13
|
+
value
|
|
14
|
+
});
|
|
15
|
+
export const between = <T extends number | bigint>(min: T, max: T) => ({
|
|
9
16
|
type: 'between' as const,
|
|
10
17
|
min,
|
|
11
18
|
max
|
|
12
19
|
});
|
|
13
20
|
|
|
14
|
-
export type QueryObject = Record<string, Types> & { timestamp:
|
|
21
|
+
export type QueryObject = Record<string, Types> & { timestamp: Timestamp<'ns'> };
|
|
15
22
|
export type QueryObjectType<T extends QueryObject> = {
|
|
16
23
|
discriminator: string;
|
|
17
24
|
type: {
|
|
@@ -34,17 +41,19 @@ export type Query<T extends QueryObject> = {
|
|
|
34
41
|
offset?: number;
|
|
35
42
|
};
|
|
36
43
|
|
|
37
|
-
export type QueryMappingType = 'number' | 'string' | 'decimal';
|
|
44
|
+
export type QueryMappingType = 'number' | 'bigint' | 'string' | 'decimal';
|
|
38
45
|
export type InferQueryObject<T> = T extends QueryObjectType<infer U>
|
|
39
46
|
? {
|
|
40
47
|
[key in keyof T['type']]: T['type'][key] extends 'number'
|
|
41
48
|
? number
|
|
49
|
+
: T['type'][key] extends 'bigint'
|
|
50
|
+
? bigint
|
|
42
51
|
: T['type'][key] extends 'string'
|
|
43
52
|
? string
|
|
44
53
|
: T['type'][key] extends 'decimal'
|
|
45
54
|
? decimal
|
|
46
55
|
: never;
|
|
47
|
-
} & { timestamp:
|
|
56
|
+
} & { timestamp: Timestamp<'ns'> }
|
|
48
57
|
: never;
|
|
49
58
|
|
|
50
59
|
export abstract class Storage {
|
package/src/storage/use-cache.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { from, map, Observable, of, switchMap } from 'rxjs';
|
|
2
2
|
|
|
3
|
-
import { now } from '@lib/shared';
|
|
4
3
|
import { useStorage } from '@lib/storage/use-storage';
|
|
5
4
|
import { dependency, useHash } from '@lib/use-hash';
|
|
5
|
+
import { now } from '@lib/use-timestamp';
|
|
6
6
|
|
|
7
7
|
import { eq, gt, Storage } from './storage';
|
|
8
8
|
|
|
9
9
|
const object = Storage.createObject('keyValue', {
|
|
10
|
-
timestamp: '
|
|
10
|
+
timestamp: 'bigint',
|
|
11
11
|
forKey: 'string',
|
|
12
12
|
rawJson: 'string'
|
|
13
13
|
});
|
|
@@ -15,7 +15,7 @@ const object = Storage.createObject('keyValue', {
|
|
|
15
15
|
export const useCache = <T>(
|
|
16
16
|
calculateValue: Observable<T>,
|
|
17
17
|
dependencies: dependency[],
|
|
18
|
-
ttl
|
|
18
|
+
ttl = BigInt(60 * 60 * 24 * 1000000)
|
|
19
19
|
): Observable<T> => {
|
|
20
20
|
const storage = useStorage(['cache']);
|
|
21
21
|
const key = useHash(dependencies);
|
|
@@ -24,7 +24,7 @@ export const useCache = <T>(
|
|
|
24
24
|
return from(
|
|
25
25
|
storage.query(object, {
|
|
26
26
|
where: {
|
|
27
|
-
timestamp: gt(timestamp - ttl),
|
|
27
|
+
timestamp: gt(timestamp - BigInt(ttl)),
|
|
28
28
|
forKey: eq(key)
|
|
29
29
|
},
|
|
30
30
|
limit: 1,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { dependency, useHash } from '@lib/use-hash';
|
|
2
|
-
import {
|
|
2
|
+
import { useMemo } from '@lib/use-memo';
|
|
3
3
|
|
|
4
4
|
import { useStorageFactory } from './use-storage-factory';
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export function useStorage(dependencies: dependency[]) {
|
|
7
|
+
return useMemo(() => {
|
|
8
|
+
const key = useHash(dependencies);
|
|
9
|
+
const factory = useStorageFactory();
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
});
|
|
11
|
+
return factory.for(key);
|
|
12
|
+
}, [dependencies]);
|
|
13
|
+
}
|
package/src/use-hash.spec.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { assetOf } from './asset';
|
|
2
|
-
import { instrumentOf } from './instrument';
|
|
3
1
|
import { dependency, useHash } from './use-hash';
|
|
4
2
|
|
|
5
3
|
describe(useHash.name, () => {
|
|
6
4
|
it.each<[dependency[], string]>([
|
|
7
|
-
[[
|
|
8
|
-
[[
|
|
9
|
-
[[
|
|
10
|
-
[[instrumentOf('binance:btc-usdt'), 123], 'binance:btc-usdt/123']
|
|
5
|
+
[['binance:btc'], 'binance:btc'],
|
|
6
|
+
[['binance:btc', 'test'], 'binance:btc/test'],
|
|
7
|
+
[['binance:btc-usdt', 123], 'binance:btc-usdt/123']
|
|
11
8
|
])('hash list of dependencies from %p to %p', (dependencies, hashed) => {
|
|
12
9
|
const hash = useHash(dependencies);
|
|
13
10
|
|
package/src/use-logger.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
|
|
3
3
|
import { Dependency, useContext } from './module';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { useMemo } from './use-memo';
|
|
5
|
+
import { convert, useTimestamp } from './use-timestamp';
|
|
6
6
|
|
|
7
7
|
const token = Symbol('logger');
|
|
8
8
|
|
|
@@ -28,7 +28,7 @@ export class ConsoleLoggerFactory implements ILoggerFactory {
|
|
|
28
28
|
for(context: string, tint?: string): ILogger {
|
|
29
29
|
const prefix = () =>
|
|
30
30
|
`${chalk.hex(tint ?? this.colorize(context))(
|
|
31
|
-
new Date(useTimestamp()).toISOString()
|
|
31
|
+
new Date(Number(convert(useTimestamp().timestamp, 'ns', 'ms'))).toISOString()
|
|
32
32
|
)} ${chalk.hex(tint ?? this.colorize(context))(context)}`;
|
|
33
33
|
|
|
34
34
|
return {
|
|
@@ -69,6 +69,9 @@ export class ConsoleLoggerFactory implements ILoggerFactory {
|
|
|
69
69
|
/**
|
|
70
70
|
*
|
|
71
71
|
*/
|
|
72
|
-
export
|
|
73
|
-
|
|
74
|
-
)
|
|
72
|
+
export function useLogger(context: string, tint?: string) {
|
|
73
|
+
return useMemo(
|
|
74
|
+
() => useContext<ILoggerFactory>(token).for(context, tint),
|
|
75
|
+
[context, tint]
|
|
76
|
+
);
|
|
77
|
+
}
|
package/src/use-socket.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { defer, Observable, of, ReplaySubject } from 'rxjs';
|
|
|
2
2
|
import { WebSocket } from 'ws';
|
|
3
3
|
|
|
4
4
|
import { useLogger } from './use-logger';
|
|
5
|
-
import { useTimestamp } from './use-timestamp';
|
|
5
|
+
import { Timestamp, useTimestamp } from './use-timestamp';
|
|
6
6
|
|
|
7
7
|
export function useSocket(
|
|
8
8
|
url: string,
|
|
@@ -32,14 +32,14 @@ export function useSocket(
|
|
|
32
32
|
* Observes socket events and handles connection health monitoring via ping/pong
|
|
33
33
|
* @returns observable emitting message events with timestamps and parsed payloads
|
|
34
34
|
*/
|
|
35
|
-
watch(): Observable<{ timestamp:
|
|
35
|
+
watch(): Observable<{ timestamp: Timestamp<'ns'>; payload: unknown }> {
|
|
36
36
|
let isAlive = false;
|
|
37
37
|
let interval: NodeJS.Timeout | undefined;
|
|
38
38
|
|
|
39
39
|
return new Observable(stream => {
|
|
40
40
|
socket.onmessage = it =>
|
|
41
41
|
stream.next({
|
|
42
|
-
|
|
42
|
+
...useTimestamp(),
|
|
43
43
|
payload: JSON.parse(it.data as string)
|
|
44
44
|
});
|
|
45
45
|
socket.onerror = it => {
|
|
@@ -80,13 +80,13 @@ export function useSocket(
|
|
|
80
80
|
});
|
|
81
81
|
},
|
|
82
82
|
|
|
83
|
-
send(message: { payload: unknown }): Observable<{ timestamp:
|
|
83
|
+
send(message: { payload: unknown }): Observable<{ timestamp: Timestamp<'ns'> }> {
|
|
84
84
|
return defer(() => {
|
|
85
85
|
debug('sent', url, message.payload);
|
|
86
86
|
|
|
87
87
|
socket.send(JSON.stringify(message.payload));
|
|
88
88
|
|
|
89
|
-
return of(
|
|
89
|
+
return of(useTimestamp());
|
|
90
90
|
});
|
|
91
91
|
},
|
|
92
92
|
|
package/src/use-timestamp.ts
CHANGED
|
@@ -2,12 +2,50 @@ import { useExecutionMode } from '@lib/use-execution-mode';
|
|
|
2
2
|
|
|
3
3
|
import { useReplayScheduler } from './replay';
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export type Unit = 'ns' | 'us' | 'ms' | 's';
|
|
6
|
+
|
|
7
|
+
export type Timestamp<Unit> = bigint & { readonly __unit: Unit };
|
|
8
|
+
|
|
9
|
+
export function now(): Timestamp<'ns'> {
|
|
10
|
+
return process.hrtime.bigint() as Timestamp<'ns'>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const ns = (value: bigint | number): Timestamp<'ns'> =>
|
|
14
|
+
BigInt(value) as Timestamp<'ns'>;
|
|
15
|
+
export const us = (value: bigint | number): Timestamp<'us'> =>
|
|
16
|
+
BigInt(value) as Timestamp<'us'>;
|
|
17
|
+
export const ms = (value: bigint | number): Timestamp<'ms'> =>
|
|
18
|
+
BigInt(value) as Timestamp<'ms'>;
|
|
19
|
+
export const s = (value: bigint | number): Timestamp<'s'> =>
|
|
20
|
+
BigInt(value) as Timestamp<'s'>;
|
|
21
|
+
|
|
22
|
+
const factors = {
|
|
23
|
+
ns: 1n,
|
|
24
|
+
us: 1_000n,
|
|
25
|
+
ms: 1_000_000n,
|
|
26
|
+
s: 1_000_000_000n
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
export function convert<F extends Unit, T extends Unit>(
|
|
30
|
+
value: Timestamp<F>,
|
|
31
|
+
from: F,
|
|
32
|
+
to: T
|
|
33
|
+
): Timestamp<T> {
|
|
34
|
+
const ns = BigInt(value) * factors[from];
|
|
35
|
+
|
|
36
|
+
return BigInt(ns / factors[to]) as Timestamp<T>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function add<U extends Unit>(a: Timestamp<U>, b: Timestamp<U>): Timestamp<U> {
|
|
40
|
+
return (a + b) as Timestamp<U>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function useTimestamp(): { timestamp: Timestamp<'ns'> } {
|
|
6
44
|
const { isReplay } = useExecutionMode();
|
|
7
45
|
|
|
8
46
|
if (isReplay) {
|
|
9
|
-
return useReplayScheduler().timestamp();
|
|
47
|
+
return { timestamp: useReplayScheduler().timestamp() };
|
|
10
48
|
}
|
|
11
49
|
|
|
12
|
-
return
|
|
50
|
+
return { timestamp: now() };
|
|
13
51
|
}
|
package/src/with-request.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
|
|
|
3
3
|
import { request } from 'undici';
|
|
4
4
|
|
|
5
5
|
import { useLogger } from './use-logger';
|
|
6
|
-
import { useTimestamp } from './use-timestamp';
|
|
6
|
+
import { Timestamp, useTimestamp } from './use-timestamp';
|
|
7
7
|
|
|
8
8
|
export type RequestMethod =
|
|
9
9
|
| 'GET'
|
|
@@ -35,7 +35,7 @@ export function withRequest({
|
|
|
35
35
|
}) {
|
|
36
36
|
const { error, debug } = useLogger(withRequest.name);
|
|
37
37
|
|
|
38
|
-
return new Observable<{ timestamp:
|
|
38
|
+
return new Observable<{ timestamp: Timestamp<'ns'>; payload: unknown }>(subscriber => {
|
|
39
39
|
const correlationId = randomUUID();
|
|
40
40
|
|
|
41
41
|
debug('requesting', { correlationId, method, url, headers, body });
|
|
@@ -64,7 +64,7 @@ export function withRequest({
|
|
|
64
64
|
|
|
65
65
|
subscriber.error(new RequestNetworkError(statusCode));
|
|
66
66
|
} else {
|
|
67
|
-
subscriber.next({
|
|
67
|
+
subscriber.next({ ...useTimestamp(), payload: json });
|
|
68
68
|
}
|
|
69
69
|
})
|
|
70
70
|
.catch((e: Error) => {
|
package/lib/asset/asset.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { decimal } from '../shared';
|
|
2
|
-
export declare const AssetSelectorSeparator = ":";
|
|
3
|
-
export declare class MissingAssetError extends Error {
|
|
4
|
-
constructor(asset: AssetSelector);
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Supposed to query specific @see Asset based on string notation.
|
|
8
|
-
*/
|
|
9
|
-
export declare class AssetSelector {
|
|
10
|
-
readonly id: string;
|
|
11
|
-
readonly name: string;
|
|
12
|
-
readonly adapterName: string;
|
|
13
|
-
constructor(name: string, adapterName: string);
|
|
14
|
-
toString(): string;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Creates @see AssetSelector based on unified string notation.
|
|
18
|
-
*/
|
|
19
|
-
export declare function assetOf(selector: string): AssetSelector;
|
|
20
|
-
/**
|
|
21
|
-
* Represents a security that you can trade or hold in your wallet.
|
|
22
|
-
* For example, you can combine two trading assets to create a trading instrument.
|
|
23
|
-
*/
|
|
24
|
-
export declare class Asset extends AssetSelector {
|
|
25
|
-
readonly scale: number;
|
|
26
|
-
readonly tickSize: decimal;
|
|
27
|
-
constructor(name: string, adapterName: string, scale: number);
|
|
28
|
-
/**
|
|
29
|
-
* Formats a number to string with fixed number of decimal places.
|
|
30
|
-
*/
|
|
31
|
-
fixed(number: decimal): string;
|
|
32
|
-
/**
|
|
33
|
-
* Rounds down a number to the asset precision.
|
|
34
|
-
*/
|
|
35
|
-
floor(number: decimal): decimal;
|
|
36
|
-
/**
|
|
37
|
-
* Rounds up a number to the asset precision.
|
|
38
|
-
*/
|
|
39
|
-
ceil(number: decimal): decimal;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=asset.d.ts.map
|
package/lib/asset/asset.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/asset/asset.ts"],"names":[],"mappings":"AACA,OAAO,EAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAEzC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,KAAK,EAAE,aAAa;CAGjC;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAc7C,QAAQ;CAGT;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAQvD;AAED;;;GAGG;AACH,qBAAa,KAAM,SAAQ,aAAa;aAGyB,KAAK,EAAE,MAAM;IAF5E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAEf,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAkB,KAAK,EAAE,MAAM;IAU5E;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM;IAI9B;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;IAI/B;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAG/B"}
|
package/lib/asset/asset.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Asset = exports.assetOf = exports.AssetSelector = exports.MissingAssetError = exports.AssetSelectorSeparator = void 0;
|
|
4
|
-
const component_1 = require("../component");
|
|
5
|
-
const shared_1 = require("../shared");
|
|
6
|
-
exports.AssetSelectorSeparator = ':';
|
|
7
|
-
class MissingAssetError extends Error {
|
|
8
|
-
constructor(asset) {
|
|
9
|
-
super(`Missing asset: ${asset}`);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.MissingAssetError = MissingAssetError;
|
|
13
|
-
/**
|
|
14
|
-
* Supposed to query specific @see Asset based on string notation.
|
|
15
|
-
*/
|
|
16
|
-
class AssetSelector {
|
|
17
|
-
constructor(name, adapterName) {
|
|
18
|
-
if (!(name === null || name === void 0 ? void 0 : name.length)) {
|
|
19
|
-
throw new component_1.InvalidArgumentsError({ name });
|
|
20
|
-
}
|
|
21
|
-
if (!(adapterName === null || adapterName === void 0 ? void 0 : adapterName.length)) {
|
|
22
|
-
throw new component_1.InvalidArgumentsError({ adapterName });
|
|
23
|
-
}
|
|
24
|
-
this.name = name.toLowerCase();
|
|
25
|
-
this.adapterName = adapterName.toLowerCase();
|
|
26
|
-
this.id = `${this.adapterName}${exports.AssetSelectorSeparator}${this.name}`;
|
|
27
|
-
}
|
|
28
|
-
toString() {
|
|
29
|
-
return this.id;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
exports.AssetSelector = AssetSelector;
|
|
33
|
-
/**
|
|
34
|
-
* Creates @see AssetSelector based on unified string notation.
|
|
35
|
-
*/
|
|
36
|
-
function assetOf(selector) {
|
|
37
|
-
const [adapterName, name, ...rest] = selector.split(exports.AssetSelectorSeparator);
|
|
38
|
-
if (!adapterName || !name || rest.length) {
|
|
39
|
-
throw new component_1.InvalidAssetSelectorError(selector);
|
|
40
|
-
}
|
|
41
|
-
return new AssetSelector(name, adapterName);
|
|
42
|
-
}
|
|
43
|
-
exports.assetOf = assetOf;
|
|
44
|
-
/**
|
|
45
|
-
* Represents a security that you can trade or hold in your wallet.
|
|
46
|
-
* For example, you can combine two trading assets to create a trading instrument.
|
|
47
|
-
*/
|
|
48
|
-
class Asset extends AssetSelector {
|
|
49
|
-
constructor(name, adapterName, scale) {
|
|
50
|
-
super(name, adapterName);
|
|
51
|
-
this.scale = scale;
|
|
52
|
-
if (scale && (scale < 0 || Number.isNaN(scale))) {
|
|
53
|
-
throw new component_1.InvalidArgumentsError({ scale });
|
|
54
|
-
}
|
|
55
|
-
this.tickSize = (0, shared_1.d)(1.0).div(Math.pow(10, this.scale));
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Formats a number to string with fixed number of decimal places.
|
|
59
|
-
*/
|
|
60
|
-
fixed(number) {
|
|
61
|
-
return number.toFixed(this.scale);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Rounds down a number to the asset precision.
|
|
65
|
-
*/
|
|
66
|
-
floor(number) {
|
|
67
|
-
return number.toFloor(this.scale);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Rounds up a number to the asset precision.
|
|
71
|
-
*/
|
|
72
|
-
ceil(number) {
|
|
73
|
-
return number.toCeil(this.scale);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
exports.Asset = Asset;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asset.spec.d.ts","sourceRoot":"","sources":["../../src/asset/asset.spec.ts"],"names":[],"mappings":""}
|