@quantform/core 0.7.21 → 0.7.24

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 (194) hide show
  1. package/lib/app.d.ts +12 -0
  2. package/lib/app.d.ts.map +1 -0
  3. package/lib/app.js +35 -0
  4. package/lib/cli/build.d.ts.map +1 -1
  5. package/lib/cli/build.js +8 -18
  6. package/lib/cli/index.js +3 -12
  7. package/lib/cli/internal/script.d.ts +1 -1
  8. package/lib/cli/internal/script.d.ts.map +1 -1
  9. package/lib/cli/internal/script.js +8 -28
  10. package/lib/cli/live.js +10 -22
  11. package/lib/cli/paper.js +10 -22
  12. package/lib/cli/replay.d.ts.map +1 -1
  13. package/lib/cli/replay.js +15 -26
  14. package/lib/index.d.ts +1 -6
  15. package/lib/index.d.ts.map +1 -1
  16. package/lib/index.js +1 -6
  17. package/lib/make-test-module.d.ts.map +1 -1
  18. package/lib/make-test-module.js +18 -20
  19. package/lib/module.d.ts.map +1 -1
  20. package/lib/module.js +9 -24
  21. package/lib/module.spec.js +8 -17
  22. package/lib/replay/use-replay-options.d.ts +5 -4
  23. package/lib/replay/use-replay-options.d.ts.map +1 -1
  24. package/lib/replay/use-replay-options.js +5 -1
  25. package/lib/replay/use-replay-scheduler.d.ts +7 -6
  26. package/lib/replay/use-replay-scheduler.d.ts.map +1 -1
  27. package/lib/replay/use-replay-scheduler.js +64 -70
  28. package/lib/replay/use-replay-storage-buffer.d.ts +3 -2
  29. package/lib/replay/use-replay-storage-buffer.d.ts.map +1 -1
  30. package/lib/replay/use-replay-storage-buffer.js +12 -23
  31. package/lib/replay/use-replay-storage-cursor.d.ts +9 -8
  32. package/lib/replay/use-replay-storage-cursor.d.ts.map +1 -1
  33. package/lib/replay/use-replay-storage-cursor.js +17 -25
  34. package/lib/replay/use-replay-storage.d.ts +5 -4
  35. package/lib/replay/use-replay-storage.d.ts.map +1 -1
  36. package/lib/replay/use-replay-storage.js +32 -39
  37. package/lib/session/use-session-storage.d.ts +1 -1
  38. package/lib/session/use-session-storage.d.ts.map +1 -1
  39. package/lib/session/use-session-storage.js +8 -5
  40. package/lib/shared/environment.js +1 -1
  41. package/lib/shared/index.d.ts +0 -1
  42. package/lib/shared/index.d.ts.map +1 -1
  43. package/lib/shared/index.js +0 -1
  44. package/lib/simulator/use-simulator.spec.js +17 -30
  45. package/lib/storage/in-memory/in-memory-storage.d.ts.map +1 -1
  46. package/lib/storage/in-memory/in-memory-storage.factory.js +2 -2
  47. package/lib/storage/in-memory/in-memory-storage.js +56 -55
  48. package/lib/storage/in-memory/in-memory-storage.spec.js +90 -100
  49. package/lib/storage/storage.d.ts +9 -8
  50. package/lib/storage/storage.d.ts.map +1 -1
  51. package/lib/storage/storage.js +8 -2
  52. package/lib/storage/use-cache.d.ts +1 -1
  53. package/lib/storage/use-cache.d.ts.map +1 -1
  54. package/lib/storage/use-cache.js +5 -5
  55. package/lib/storage/use-cache.spec.js +14 -25
  56. package/lib/storage/use-storage.d.ts +1 -1
  57. package/lib/storage/use-storage.d.ts.map +1 -1
  58. package/lib/storage/use-storage.js +9 -6
  59. package/lib/use-execution-mode.js +2 -2
  60. package/lib/use-hash.spec.js +3 -6
  61. package/lib/use-logger.d.ts +1 -1
  62. package/lib/use-logger.d.ts.map +1 -1
  63. package/lib/use-logger.js +10 -7
  64. package/lib/use-memo.spec.js +14 -25
  65. package/lib/use-socket.d.ts +3 -2
  66. package/lib/use-socket.d.ts.map +1 -1
  67. package/lib/use-socket.js +2 -2
  68. package/lib/use-timestamp.d.ts +14 -1
  69. package/lib/use-timestamp.d.ts.map +1 -1
  70. package/lib/use-timestamp.js +30 -3
  71. package/lib/with-request.d.ts +2 -1
  72. package/lib/with-request.d.ts.map +1 -1
  73. package/lib/with-request.js +4 -13
  74. package/package.json +6 -10
  75. package/src/app.ts +52 -0
  76. package/src/cli/build.ts +11 -6
  77. package/src/cli/internal/script.ts +25 -54
  78. package/src/cli/replay.ts +13 -2
  79. package/src/index.ts +1 -6
  80. package/src/make-test-module.ts +12 -2
  81. package/src/module.ts +0 -3
  82. package/src/replay/use-replay-options.ts +7 -3
  83. package/src/replay/use-replay-scheduler.ts +75 -67
  84. package/src/replay/use-replay-storage-buffer.ts +2 -1
  85. package/src/replay/use-replay-storage-cursor.ts +33 -28
  86. package/src/replay/use-replay-storage.ts +36 -27
  87. package/src/session/use-session-storage.ts +7 -5
  88. package/src/shared/index.ts +0 -1
  89. package/src/storage/in-memory/in-memory-storage.spec.ts +55 -54
  90. package/src/storage/in-memory/in-memory-storage.ts +24 -7
  91. package/src/storage/storage.ts +16 -7
  92. package/src/storage/use-cache.ts +4 -4
  93. package/src/storage/use-storage.ts +8 -6
  94. package/src/use-hash.spec.ts +3 -6
  95. package/src/use-logger.ts +9 -6
  96. package/src/use-socket.ts +5 -5
  97. package/src/use-timestamp.ts +41 -3
  98. package/src/with-request.ts +3 -3
  99. package/lib/asset/asset.d.ts +0 -41
  100. package/lib/asset/asset.d.ts.map +0 -1
  101. package/lib/asset/asset.js +0 -76
  102. package/lib/asset/asset.spec.d.ts +0 -2
  103. package/lib/asset/asset.spec.d.ts.map +0 -1
  104. package/lib/asset/asset.spec.js +0 -54
  105. package/lib/asset/index.d.ts +0 -2
  106. package/lib/asset/index.d.ts.map +0 -1
  107. package/lib/asset/index.js +0 -17
  108. package/lib/component/distinct-until-timesamp-changed.d.ts +0 -5
  109. package/lib/component/distinct-until-timesamp-changed.d.ts.map +0 -1
  110. package/lib/component/distinct-until-timesamp-changed.js +0 -9
  111. package/lib/component/error.d.ts +0 -17
  112. package/lib/component/error.d.ts.map +0 -1
  113. package/lib/component/error.js +0 -33
  114. package/lib/component/index.d.ts +0 -8
  115. package/lib/component/index.d.ts.map +0 -1
  116. package/lib/component/index.js +0 -23
  117. package/lib/component/ohlc-operator.d.ts +0 -11
  118. package/lib/component/ohlc-operator.d.ts.map +0 -1
  119. package/lib/component/ohlc-operator.js +0 -69
  120. package/lib/component/ohlc-operator.spec.d.ts +0 -2
  121. package/lib/component/ohlc-operator.spec.d.ts.map +0 -1
  122. package/lib/component/ohlc-operator.spec.js +0 -110
  123. package/lib/component/ohlc.d.ts +0 -12
  124. package/lib/component/ohlc.d.ts.map +0 -1
  125. package/lib/component/ohlc.js +0 -20
  126. package/lib/component/ohlc.spec.d.ts +0 -2
  127. package/lib/component/ohlc.spec.d.ts.map +0 -1
  128. package/lib/component/ohlc.spec.js +0 -25
  129. package/lib/component/timeframe.d.ts +0 -15
  130. package/lib/component/timeframe.d.ts.map +0 -1
  131. package/lib/component/timeframe.js +0 -21
  132. package/lib/core.d.ts +0 -3
  133. package/lib/core.d.ts.map +0 -1
  134. package/lib/core.js +0 -17
  135. package/lib/instrument/commission/commission.d.ts +0 -16
  136. package/lib/instrument/commission/commission.d.ts.map +0 -1
  137. package/lib/instrument/commission/commission.js +0 -28
  138. package/lib/instrument/commission/commission.spec.d.ts +0 -2
  139. package/lib/instrument/commission/commission.spec.d.ts.map +0 -1
  140. package/lib/instrument/commission/commission.spec.js +0 -30
  141. package/lib/instrument/index.d.ts +0 -3
  142. package/lib/instrument/index.d.ts.map +0 -1
  143. package/lib/instrument/index.js +0 -18
  144. package/lib/instrument/instrument.d.ts +0 -28
  145. package/lib/instrument/instrument.d.ts.map +0 -1
  146. package/lib/instrument/instrument.js +0 -53
  147. package/lib/instrument/instrument.spec.d.ts +0 -2
  148. package/lib/instrument/instrument.spec.d.ts.map +0 -1
  149. package/lib/instrument/instrument.spec.js +0 -51
  150. package/lib/operators.d.ts +0 -5
  151. package/lib/operators.d.ts.map +0 -1
  152. package/lib/operators.js +0 -16
  153. package/lib/shared/datetime.d.ts +0 -3
  154. package/lib/shared/datetime.d.ts.map +0 -1
  155. package/lib/shared/datetime.js +0 -7
  156. package/lib/strategy.d.ts +0 -15
  157. package/lib/strategy.d.ts.map +0 -1
  158. package/lib/strategy.js +0 -26
  159. package/lib/strategy.spec.d.ts +0 -2
  160. package/lib/strategy.spec.d.ts.map +0 -1
  161. package/lib/strategy.spec.js +0 -34
  162. package/lib/when-socket.d.ts +0 -8
  163. package/lib/when-socket.d.ts.map +0 -1
  164. package/lib/when-socket.js +0 -53
  165. package/lib/with-memo.d.ts +0 -5
  166. package/lib/with-memo.d.ts.map +0 -1
  167. package/lib/with-memo.js +0 -20
  168. package/lib/with-memo.spec.d.ts +0 -2
  169. package/lib/with-memo.spec.d.ts.map +0 -1
  170. package/lib/with-memo.spec.js +0 -47
  171. package/src/asset/asset.spec.ts +0 -70
  172. package/src/asset/asset.ts +0 -89
  173. package/src/asset/index.ts +0 -1
  174. package/src/component/distinct-until-timesamp-changed.ts +0 -11
  175. package/src/component/error.ts +0 -32
  176. package/src/component/index.ts +0 -7
  177. package/src/component/ohlc-operator.spec.ts +0 -125
  178. package/src/component/ohlc-operator.ts +0 -122
  179. package/src/component/ohlc.spec.ts +0 -30
  180. package/src/component/ohlc.ts +0 -18
  181. package/src/component/timeframe.ts +0 -17
  182. package/src/core.ts +0 -16
  183. package/src/instrument/commission/commission.spec.ts +0 -35
  184. package/src/instrument/commission/commission.ts +0 -27
  185. package/src/instrument/index.ts +0 -2
  186. package/src/instrument/instrument.spec.ts +0 -76
  187. package/src/instrument/instrument.ts +0 -65
  188. package/src/operators.ts +0 -18
  189. package/src/shared/datetime.ts +0 -5
  190. package/src/strategy.spec.ts +0 -42
  191. package/src/strategy.ts +0 -36
  192. package/src/when-socket.ts +0 -61
  193. package/src/with-memo.spec.ts +0 -46
  194. package/src/with-memo.ts +0 -33
package/lib/strategy.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- import { Dependency } from './module';
3
- export type Descriptor = () => Observable<unknown>;
4
- export declare let before: (descriptor: Descriptor) => void;
5
- export declare let behavior: (descriptor: Descriptor) => void;
6
- export declare let after: (descriptor: Descriptor) => void;
7
- export declare function strategy(descriptor: () => Dependency[]): {
8
- dependencies: Dependency[];
9
- description: {
10
- before: Descriptor[];
11
- behavior: Descriptor[];
12
- after: Descriptor[];
13
- };
14
- };
15
- //# sourceMappingURL=strategy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../src/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAM,MAAM,MAAM,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;AAEnD,eAAO,IAAI,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;AACpD,eAAO,IAAI,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;AACtD,eAAO,IAAI,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;AAEnD,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,UAAU,EAAE;;;;;;;EAyBtD"}
package/lib/strategy.js DELETED
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.strategy = exports.after = exports.behavior = exports.before = void 0;
4
- const rxjs_1 = require("rxjs");
5
- function strategy(descriptor) {
6
- const description = {
7
- before: Array.of(),
8
- behavior: Array.of(),
9
- after: Array.of()
10
- };
11
- exports.before = descriptor => description.before.push(descriptor);
12
- exports.behavior = descriptor => description.behavior.push(descriptor);
13
- exports.after = descriptor => description.after.push(descriptor);
14
- const dependencies = descriptor();
15
- if (!description.before.length) {
16
- description.before.push(() => (0, rxjs_1.of)(true));
17
- }
18
- if (!description.after.length) {
19
- description.after.push(() => (0, rxjs_1.of)(true));
20
- }
21
- return {
22
- dependencies,
23
- description
24
- };
25
- }
26
- exports.strategy = strategy;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=strategy.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy.spec.d.ts","sourceRoot":"","sources":["../src/strategy.spec.ts"],"names":[],"mappings":""}
@@ -1,34 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const rxjs_1 = require("rxjs");
4
- const strategy_1 = require("./strategy");
5
- describe(strategy_1.strategy.name, () => {
6
- let fixtures;
7
- beforeEach(() => {
8
- fixtures = getFixtures();
9
- });
10
- test('happy path', () => {
11
- const sut = (0, strategy_1.strategy)(() => {
12
- (0, strategy_1.before)(() => (0, rxjs_1.of)('before'));
13
- (0, strategy_1.behavior)(() => (0, rxjs_1.of)('behavior 1'));
14
- (0, strategy_1.behavior)(() => (0, rxjs_1.of)('behavior 2'));
15
- (0, strategy_1.after)(() => (0, rxjs_1.of)('after'));
16
- return fixtures.given.dependencies();
17
- });
18
- expect(sut.dependencies).toEqual(expect.arrayContaining(fixtures.given.dependencies()));
19
- expect(sut.description).toEqual({
20
- before: [expect.any(Function)],
21
- behavior: [expect.any(Function), expect.any(Function)],
22
- after: [expect.any(Function)]
23
- });
24
- });
25
- });
26
- function getFixtures() {
27
- return {
28
- given: {
29
- dependencies() {
30
- return [];
31
- }
32
- }
33
- };
34
- }
@@ -1,8 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- export declare function whenSocket(url: string, options?: {
3
- pingInterval?: number;
4
- }): [Observable<{
5
- timestamp: number;
6
- payload: unknown;
7
- }>, (message: unknown) => void];
8
- //# sourceMappingURL=when-socket.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"when-socket.d.ts","sourceRoot":"","sources":["../src/when-socket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAMlC,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAA2B,GAC1D,CAAC,UAAU,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,CAmDnF"}
@@ -1,53 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.whenSocket = void 0;
4
- const rxjs_1 = require("rxjs");
5
- const ws_1 = require("ws");
6
- const use_logger_1 = require("./use-logger");
7
- const use_timestamp_1 = require("./use-timestamp");
8
- function whenSocket(url, options = { pingInterval: 5000 }) {
9
- const { debug } = (0, use_logger_1.useLogger)('whenSocket');
10
- const message = new rxjs_1.Observable(stream => {
11
- const socket = new ws_1.WebSocket(url);
12
- let isAlive = false;
13
- let interval;
14
- socket.onmessage = it => stream.next({ timestamp: (0, use_timestamp_1.useTimestamp)(), payload: JSON.parse(it.data) });
15
- socket.onerror = it => {
16
- clearInterval(interval);
17
- debug('errored', url);
18
- stream.error(it);
19
- };
20
- socket.onclose = () => {
21
- debug('closed', url);
22
- clearInterval(interval);
23
- stream.error();
24
- };
25
- socket.onopen = () => {
26
- debug('opened', url);
27
- isAlive = true;
28
- interval = setInterval(() => {
29
- if (isAlive) {
30
- isAlive = false;
31
- socket.ping();
32
- }
33
- else {
34
- socket.terminate();
35
- clearInterval(interval);
36
- }
37
- }, options.pingInterval);
38
- socket.on('pong', () => {
39
- isAlive = true;
40
- });
41
- socket.on('ping', () => {
42
- isAlive = true;
43
- socket.pong();
44
- });
45
- };
46
- return () => {
47
- socket.terminate();
48
- clearInterval(interval);
49
- };
50
- });
51
- return [message, (message) => JSON.stringify(message)];
52
- }
53
- exports.whenSocket = whenSocket;
@@ -1,5 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- import { dependency } from './use-hash';
3
- export declare function withMemo<T extends Array<dependency>, U>(fn: (...args: T) => U): (...args: T) => U;
4
- export declare function withMemo<T extends Array<dependency>, U>(fn: (...args: T) => Observable<U>): (...args: T) => Observable<U>;
5
- //# sourceMappingURL=with-memo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"with-memo.d.ts","sourceRoot":"","sources":["../src/with-memo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,UAAU,EAAe,MAAM,MAAM,CAAC;AAK7D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,EACrD,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,GACpB,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;AACrB,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,EACrD,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,GAChC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC"}
package/lib/with-memo.js DELETED
@@ -1,20 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withMemo = void 0;
4
- const rxjs_1 = require("rxjs");
5
- const uuid_1 = require("uuid");
6
- const module_1 = require("./module");
7
- const operators_1 = require("./operators");
8
- const use_memo_1 = require("./use-memo");
9
- function withMemo(fn) {
10
- (0, module_1.throwWithContext)();
11
- const uniqueId = (0, uuid_1.v4)();
12
- return (...args) => (0, use_memo_1.useMemo)(() => {
13
- const value = fn(...args);
14
- if ((0, rxjs_1.isObservable)(value)) {
15
- return value.pipe((0, operators_1.asReadonly)(), (0, rxjs_1.shareReplay)(1));
16
- }
17
- return value;
18
- }, [uniqueId, ...args]);
19
- }
20
- exports.withMemo = withMemo;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=with-memo.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"with-memo.spec.d.ts","sourceRoot":"","sources":["../src/with-memo.spec.ts"],"names":[],"mappings":""}
@@ -1,47 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const make_test_module_1 = require("./make-test-module");
13
- const instrument_1 = require("./instrument");
14
- const with_memo_1 = require("./with-memo");
15
- describe(with_memo_1.withMemo.name, () => {
16
- let fixtures;
17
- beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
18
- fixtures = yield getFixtures();
19
- }));
20
- test('memorize same values for same arguments', () => {
21
- const { act, getValue } = fixtures;
22
- act(() => {
23
- const value1 = getValue((0, instrument_1.instrumentOf)('binance:btc-usdt'));
24
- const value2 = getValue((0, instrument_1.instrumentOf)('binance:btc-usdt'));
25
- expect(Object.is(value1, value2)).toBeTruthy();
26
- });
27
- });
28
- test('memorize different values for different arguments', () => {
29
- const { act, getValue } = fixtures;
30
- act(() => {
31
- const value1 = getValue((0, instrument_1.instrumentOf)('binance:btc-usdt'));
32
- const value2 = getValue((0, instrument_1.instrumentOf)('binance:btc-busd'));
33
- expect(value1).toEqual('binance:btc-usdt');
34
- expect(value2).toEqual('binance:btc-busd');
35
- });
36
- });
37
- });
38
- function getFixtures() {
39
- return __awaiter(this, void 0, void 0, function* () {
40
- const { act } = yield (0, make_test_module_1.makeTestModule)([]);
41
- const getValue = (0, with_memo_1.withMemo)((instrument) => instrument.id);
42
- return {
43
- act,
44
- getValue: act(() => (instrument) => getValue(instrument))
45
- };
46
- });
47
- }
@@ -1,70 +0,0 @@
1
- import { Asset, assetOf, AssetSelector } from '@lib/component';
2
- import { d } from '@lib/shared';
3
-
4
- describe(Asset.name, () => {
5
- test('should construct a new asset', () => {
6
- const sut = new Asset('abc', 'xyz', 4);
7
-
8
- expect(sut.name).toEqual('abc');
9
- expect(sut.adapterName).toEqual('xyz');
10
- expect(sut.scale).toEqual(4);
11
- expect(sut.tickSize).toEqual(d(0.0001));
12
- expect(sut.floor(d(1.1234567))).toEqual(d(1.1234));
13
- expect(sut.ceil(d(1.1234567))).toEqual(d(1.1235));
14
- expect(sut.id).toEqual('xyz:abc');
15
- });
16
-
17
- test('should throw for missing asset name', () => {
18
- const fn = () => new Asset('xyz', '', 5);
19
-
20
- expect(fn).toThrowError();
21
- });
22
-
23
- test('should throw for missing adapter name', () => {
24
- const fn = () => new Asset('', 'xyz', 5);
25
-
26
- expect(fn).toThrowError();
27
- });
28
- });
29
-
30
- describe(AssetSelector.name, () => {
31
- test('should construct a new asset selector from unified string', () => {
32
- const sut = assetOf('xyz:abc');
33
-
34
- expect(sut.name).toEqual('abc');
35
- expect(sut.adapterName).toEqual('xyz');
36
- expect(sut.id).toEqual('xyz:abc');
37
- });
38
-
39
- test('should instantiate proper asset selector capital case', () => {
40
- const sut = assetOf('XYZ:ABC');
41
-
42
- expect(sut.name).toEqual('abc');
43
- expect(sut.adapterName).toEqual('xyz');
44
- expect(sut.id).toEqual('xyz:abc');
45
- });
46
-
47
- test('should throw invalid format message for missing separator', () => {
48
- const fn = () => assetOf('xyzabc');
49
-
50
- expect(fn).toThrowError();
51
- });
52
-
53
- test('should throw for multiple separators', () => {
54
- const fn = () => assetOf('xyz:abc:');
55
-
56
- expect(fn).toThrowError();
57
- });
58
-
59
- test('should throw for missing asset name', () => {
60
- const fn = () => assetOf('xyz:');
61
-
62
- expect(fn).toThrowError();
63
- });
64
-
65
- test('should throw for missing adapter name', () => {
66
- const fn = () => assetOf(':abc');
67
-
68
- expect(fn).toThrowError();
69
- });
70
- });
@@ -1,89 +0,0 @@
1
- import { InvalidArgumentsError, InvalidAssetSelectorError } from '@lib/component';
2
- import { d, decimal } from '@lib/shared';
3
-
4
- export const AssetSelectorSeparator = ':';
5
-
6
- export class MissingAssetError extends Error {
7
- constructor(asset: AssetSelector) {
8
- super(`Missing asset: ${asset}`);
9
- }
10
- }
11
-
12
- /**
13
- * Supposed to query specific @see Asset based on string notation.
14
- */
15
- export class AssetSelector {
16
- readonly id: string;
17
- readonly name: string;
18
- readonly adapterName: string;
19
-
20
- constructor(name: string, adapterName: string) {
21
- if (!name?.length) {
22
- throw new InvalidArgumentsError({ name });
23
- }
24
-
25
- if (!adapterName?.length) {
26
- throw new InvalidArgumentsError({ adapterName });
27
- }
28
-
29
- this.name = name.toLowerCase();
30
- this.adapterName = adapterName.toLowerCase();
31
- this.id = `${this.adapterName}${AssetSelectorSeparator}${this.name}`;
32
- }
33
-
34
- toString() {
35
- return this.id;
36
- }
37
- }
38
-
39
- /**
40
- * Creates @see AssetSelector based on unified string notation.
41
- */
42
- export function assetOf(selector: string): AssetSelector {
43
- const [adapterName, name, ...rest] = selector.split(AssetSelectorSeparator);
44
-
45
- if (!adapterName || !name || rest.length) {
46
- throw new InvalidAssetSelectorError(selector);
47
- }
48
-
49
- return new AssetSelector(name, adapterName);
50
- }
51
-
52
- /**
53
- * Represents a security that you can trade or hold in your wallet.
54
- * For example, you can combine two trading assets to create a trading instrument.
55
- */
56
- export class Asset extends AssetSelector {
57
- readonly tickSize: decimal;
58
-
59
- constructor(name: string, adapterName: string, public readonly scale: number) {
60
- super(name, adapterName);
61
-
62
- if (scale && (scale < 0 || Number.isNaN(scale))) {
63
- throw new InvalidArgumentsError({ scale });
64
- }
65
-
66
- this.tickSize = d(1.0).div(Math.pow(10, this.scale));
67
- }
68
-
69
- /**
70
- * Formats a number to string with fixed number of decimal places.
71
- */
72
- fixed(number: decimal): string {
73
- return number.toFixed(this.scale);
74
- }
75
-
76
- /**
77
- * Rounds down a number to the asset precision.
78
- */
79
- floor(number: decimal): decimal {
80
- return number.toFloor(this.scale);
81
- }
82
-
83
- /**
84
- * Rounds up a number to the asset precision.
85
- */
86
- ceil(number: decimal): decimal {
87
- return number.toCeil(this.scale);
88
- }
89
- }
@@ -1 +0,0 @@
1
- export * from '@lib/asset/asset';
@@ -1,11 +0,0 @@
1
- import { filter, Observable, tap } from 'rxjs';
2
-
3
- export function distinctUntilTimestampChanged<T extends { timestamp: number }>() {
4
- let prevTimestamp: number | undefined;
5
-
6
- return (stream: Observable<T>) =>
7
- stream.pipe(
8
- filter(it => prevTimestamp === undefined || it.timestamp > prevTimestamp),
9
- tap(it => (prevTimestamp = it.timestamp))
10
- );
11
- }
@@ -1,32 +0,0 @@
1
- import { decimal } from '@lib/shared';
2
-
3
- export class InsufficientFundsError extends Error {
4
- constructor(assetName: string, requiredAmount: decimal, availableAmount: decimal) {
5
- super(
6
- `insufficient funds of ${assetName} has: ${availableAmount.toString()} requires: ${requiredAmount.toString()}`
7
- );
8
- }
9
- }
10
-
11
- export class InvalidArgumentsError extends Error {
12
- constructor(argName: Record<string, unknown>) {
13
- super(`invalid arguments: ${argName}`);
14
- }
15
- }
16
-
17
- export class InvalidAssetSelectorError extends Error {
18
- constructor(selector: string) {
19
- super(`invalid asset selector: ${selector}`);
20
- }
21
- }
22
- export class InvalidInstrumentSelectorError extends Error {
23
- constructor(selector: string) {
24
- super(`invalid instrument selector: ${selector}`);
25
- }
26
- }
27
-
28
- export class AdapterMismatchError extends Error {
29
- constructor() {
30
- super('adapters must be the same');
31
- }
32
- }
@@ -1,7 +0,0 @@
1
- export * from '@lib/asset';
2
- export * from '@lib/component/error';
3
- export * from '@lib/component/ohlc';
4
- export * from '@lib/component/ohlc-operator';
5
- export * from '@lib/instrument';
6
- export * from '@lib/component/timeframe';
7
- export * from '@lib/component/distinct-until-timesamp-changed';
@@ -1,125 +0,0 @@
1
- import { from } from 'rxjs';
2
-
3
- import { mergeOhlc, Ohlc, ohlc, ohlcCompleted } from '@lib/component';
4
- import { d } from '@lib/shared';
5
-
6
- describe(ohlc.name, () => {
7
- test('should aggregate and pipe ohlc updates', done => {
8
- const input$ = from([
9
- { timestamp: 1, rate: d(1) },
10
- { timestamp: 2, rate: d(2) },
11
- { timestamp: 3, rate: d(3) },
12
- { timestamp: 4, rate: d.Zero },
13
- { timestamp: 5, rate: d(7) },
14
- { timestamp: 6, rate: d(8) }
15
- ]);
16
-
17
- const output = [
18
- new Ohlc(0, d(1), d(1), d(1), d(1)),
19
- new Ohlc(0, d(1), d(2), d(1), d(2)),
20
- new Ohlc(0, d(1), d(3), d(1), d(3)),
21
- new Ohlc(0, d(1), d(3), d.Zero, d.Zero),
22
- new Ohlc(5, d.Zero, d(7), d(7), d(7)),
23
- new Ohlc(5, d.Zero, d(8), d(7), d(8))
24
- ].reverse();
25
-
26
- input$.pipe(ohlc(5, it => it.rate)).subscribe({
27
- next: it => {
28
- expect(it).toEqual(output.pop());
29
- if (output.length === 0) {
30
- done();
31
- }
32
- }
33
- });
34
- });
35
- });
36
-
37
- describe(ohlcCompleted.name, () => {
38
- test('should aggregate and pipe distinct completed ohlc', done => {
39
- const input$ = from([
40
- { timestamp: 1, rate: d(1) },
41
- { timestamp: 2, rate: d(2) },
42
- { timestamp: 3, rate: d(3) },
43
- { timestamp: 4, rate: d.Zero },
44
- { timestamp: 5, rate: d(7) },
45
- { timestamp: 6, rate: d(8) }
46
- ]);
47
-
48
- input$
49
- .pipe(
50
- ohlc(5, it => it.rate),
51
- ohlcCompleted()
52
- )
53
- .subscribe({
54
- next: it => {
55
- expect(it).toEqual(new Ohlc(0, d(1), d(3), d.Zero, d.Zero));
56
- done();
57
- }
58
- });
59
- });
60
- });
61
-
62
- describe(mergeOhlc.name, () => {
63
- test('should pipe and merge ohlc from history', done => {
64
- const history$ = from([
65
- new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
66
- new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
67
- new Ohlc(3, d(3), d(3.5), d(2.5), d(4))
68
- ]);
69
-
70
- const input$ = from([
71
- { timestamp: 3, rate: d(5) },
72
- { timestamp: 4, rate: d(3) },
73
- { timestamp: 5, rate: d(4) }
74
- ]);
75
-
76
- const output = [
77
- new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
78
- new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
79
- new Ohlc(3, d(3), d(5), d(2.5), d(5)),
80
- new Ohlc(4, d(5), d(3), d(3), d(3)),
81
- new Ohlc(5, d(3), d(4), d(4), d(4))
82
- ].reverse();
83
-
84
- input$.pipe(mergeOhlc(1, it => it.rate, history$)).subscribe({
85
- next: it => {
86
- expect(it).toEqual(output.pop());
87
- if (output.length === 0) {
88
- done();
89
- }
90
- }
91
- });
92
- });
93
-
94
- test('should pipe and not merge ohlc from history', done => {
95
- const history$ = from([
96
- new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
97
- new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
98
- new Ohlc(3, d(3), d(3.5), d(2.5), d(4))
99
- ]);
100
-
101
- const input$ = from([
102
- { timestamp: 4, rate: d(5) },
103
- { timestamp: 5, rate: d(3) },
104
- { timestamp: 6, rate: d(4) }
105
- ]);
106
-
107
- const output = [
108
- new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
109
- new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
110
- new Ohlc(3, d(3), d(3.5), d(2.5), d(4)),
111
- new Ohlc(4, d(4), d(5), d(5), d(5)),
112
- new Ohlc(5, d(5), d(3), d(3), d(3)),
113
- new Ohlc(6, d(3), d(4), d(4), d(4))
114
- ].reverse();
115
-
116
- input$.pipe(mergeOhlc(1, it => it.rate, history$)).subscribe({
117
- next: it => {
118
- expect(it).toEqual(output.pop());
119
- if (output.length === 0) {
120
- done();
121
- }
122
- }
123
- });
124
- });
125
- });