@quantform/core 0.6.4 → 0.6.5

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 (91) hide show
  1. package/dist/adapter/adapter-aggregate.d.ts +2 -2
  2. package/dist/adapter/adapter-aggregate.d.ts.map +1 -1
  3. package/dist/adapter/adapter-aggregate.js +1 -2
  4. package/dist/adapter/adapter.d.ts +2 -2
  5. package/dist/adapter/adapter.d.ts.map +1 -1
  6. package/dist/adapter/backtester/backtester-adapter.d.ts +2 -2
  7. package/dist/adapter/backtester/backtester-adapter.d.ts.map +1 -1
  8. package/dist/adapter/paper/paper-adapter.d.ts +2 -2
  9. package/dist/adapter/paper/paper-adapter.d.ts.map +1 -1
  10. package/dist/cli/dev.js +2 -2
  11. package/dist/cli/pull.js +2 -2
  12. package/dist/cli/run.js +2 -2
  13. package/dist/cli/test.js +2 -2
  14. package/dist/domain/asset.d.ts +0 -4
  15. package/dist/domain/asset.d.ts.map +1 -1
  16. package/dist/domain/asset.js +0 -6
  17. package/dist/domain/balance.d.ts +0 -2
  18. package/dist/domain/balance.d.ts.map +1 -1
  19. package/dist/domain/balance.js +0 -4
  20. package/dist/domain/component.d.ts +0 -1
  21. package/dist/domain/component.d.ts.map +1 -1
  22. package/dist/domain/index.d.ts +2 -2
  23. package/dist/domain/index.d.ts.map +1 -1
  24. package/dist/domain/index.js +2 -2
  25. package/dist/domain/instrument.d.ts +0 -2
  26. package/dist/domain/instrument.d.ts.map +1 -1
  27. package/dist/domain/instrument.js +0 -4
  28. package/dist/domain/ohlc-operator.d.ts +11 -0
  29. package/dist/domain/ohlc-operator.d.ts.map +1 -0
  30. package/dist/domain/{candle-operator.js → ohlc-operator.js} +11 -11
  31. package/dist/domain/{candle.d.ts → ohlc.d.ts} +2 -2
  32. package/dist/domain/ohlc.d.ts.map +1 -0
  33. package/dist/domain/{candle.js → ohlc.js} +3 -3
  34. package/dist/domain/order.d.ts +0 -2
  35. package/dist/domain/order.d.ts.map +1 -1
  36. package/dist/domain/order.js +0 -4
  37. package/dist/domain/orderbook.d.ts +0 -2
  38. package/dist/domain/orderbook.d.ts.map +1 -1
  39. package/dist/domain/orderbook.js +0 -4
  40. package/dist/domain/position.d.ts +0 -2
  41. package/dist/domain/position.d.ts.map +1 -1
  42. package/dist/domain/position.js +0 -4
  43. package/dist/domain/session-builder.d.ts +1 -1
  44. package/dist/domain/session-builder.d.ts.map +1 -1
  45. package/dist/domain/session-builder.js +3 -2
  46. package/dist/domain/session.d.ts +2 -2
  47. package/dist/domain/session.d.ts.map +1 -1
  48. package/dist/domain/trade.d.ts +0 -2
  49. package/dist/domain/trade.d.ts.map +1 -1
  50. package/dist/domain/trade.js +0 -4
  51. package/dist/index.d.ts +24 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +63 -1
  54. package/dist/shared/logger.d.ts +1 -0
  55. package/dist/shared/logger.d.ts.map +1 -1
  56. package/dist/shared/logger.js +7 -4
  57. package/package.json +1 -1
  58. package/src/adapter/adapter-aggregate.ts +4 -6
  59. package/src/adapter/adapter.ts +3 -3
  60. package/src/adapter/backtester/backtester-adapter.ts +2 -2
  61. package/src/adapter/backtester/backtester-cursor.ts +1 -1
  62. package/src/adapter/paper/paper-adapter.ts +2 -2
  63. package/src/cli/dev.ts +2 -2
  64. package/src/cli/pull.ts +2 -2
  65. package/src/cli/run.ts +2 -2
  66. package/src/cli/test.ts +2 -2
  67. package/src/domain/asset.ts +0 -7
  68. package/src/domain/balance.ts +0 -5
  69. package/src/domain/component.ts +0 -1
  70. package/src/domain/index.ts +2 -2
  71. package/src/domain/instrument.ts +0 -5
  72. package/src/domain/ohlc-operator.spec.ts +126 -0
  73. package/src/domain/{candle-operator.ts → ohlc-operator.ts} +15 -15
  74. package/src/domain/{candle.spec.ts → ohlc.spec.ts} +6 -6
  75. package/src/domain/{candle.ts → ohlc.ts} +2 -2
  76. package/src/domain/order.ts +0 -5
  77. package/src/domain/orderbook.ts +0 -5
  78. package/src/domain/position.ts +0 -5
  79. package/src/domain/session-builder.ts +3 -3
  80. package/src/domain/session.ts +3 -3
  81. package/src/domain/trade.ts +0 -5
  82. package/src/index.ts +75 -1
  83. package/src/shared/logger.ts +6 -4
  84. package/dist/domain/candle-operator.d.ts +0 -11
  85. package/dist/domain/candle-operator.d.ts.map +0 -1
  86. package/dist/domain/candle.d.ts.map +0 -1
  87. package/dist/strategy.d.ts +0 -8
  88. package/dist/strategy.d.ts.map +0 -1
  89. package/dist/strategy.js +0 -44
  90. package/src/domain/candle-operator.spec.ts +0 -126
  91. package/src/strategy.ts +0 -47
@@ -14,7 +14,8 @@ function deposit(selector, amount) {
14
14
  exports.deposit = deposit;
15
15
  function period(from, to) {
16
16
  return (builder) => {
17
- builder.usePeriod(from.getTime(), to.getTime());
17
+ var _a;
18
+ builder.usePeriod(from.getTime(), (_a = to === null || to === void 0 ? void 0 : to.getTime()) !== null && _a !== void 0 ? _a : (0, shared_1.now)());
18
19
  };
19
20
  }
20
21
  exports.period = period;
@@ -56,7 +57,7 @@ class SessionBuilder {
56
57
  return this;
57
58
  }
58
59
  useBalance(selector, amount) {
59
- this.balance[selector.toString()] = amount;
60
+ this.balance[selector.id] = amount;
60
61
  return this;
61
62
  }
62
63
  usePeriod(from, to) {
@@ -1,6 +1,6 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { AdapterAggregate } from '../adapter/adapter-aggregate';
3
- import { AssetSelector, Balance, Candle, Instrument, InstrumentSelector, Order, Orderbook, Position, Trade } from '../domain';
3
+ import { AssetSelector, Balance, Instrument, InstrumentSelector, Ohlc, Order, Orderbook, Position, Trade } from '../domain';
4
4
  import { decimal } from '../shared';
5
5
  import { Measurement } from '../storage';
6
6
  import { Store } from '../store';
@@ -65,7 +65,7 @@ export declare class Session {
65
65
  positions(selector: InstrumentSelector): Observable<Readonly<Position[]>>;
66
66
  order(selector: InstrumentSelector): Observable<Readonly<Order>>;
67
67
  orders(selector: InstrumentSelector): Observable<Readonly<Order[]>>;
68
- history(selector: InstrumentSelector, timeframe: number, length: number): Observable<Readonly<Candle>>;
68
+ history(selector: InstrumentSelector, timeframe: number, length: number): Observable<Readonly<Ohlc>>;
69
69
  measure<T extends {
70
70
  timestamp: number;
71
71
  }>(spec: {
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/domain/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/domain/session.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,6 @@ export declare class Trade implements Component {
11
11
  rate: decimal;
12
12
  quantity: decimal;
13
13
  readonly id: string;
14
- readonly kind = "trade";
15
14
  constructor(timestamp: number, instrument: Instrument, rate: decimal, quantity: decimal);
16
- toString(): string;
17
15
  }
18
16
  //# sourceMappingURL=trade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trade.d.ts","sourceRoot":"","sources":["../../src/domain/trade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,qBAAa,KAAM,YAAW,SAAS;IAK5B,SAAS,EAAE,MAAM;aACR,UAAU,EAAE,UAAU;IAC/B,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,OAAO;IAP1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,WAAW;gBAGf,SAAS,EAAE,MAAM,EACR,UAAU,EAAE,UAAU,EAC/B,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,OAAO;IAK1B,QAAQ;CAGT"}
1
+ {"version":3,"file":"trade.d.ts","sourceRoot":"","sources":["../../src/domain/trade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,qBAAa,KAAM,YAAW,SAAS;IAI5B,SAAS,EAAE,MAAM;aACR,UAAU,EAAE,UAAU;IAC/B,IAAI,EAAE,OAAO;IACb,QAAQ,EAAE,OAAO;IAN1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAGX,SAAS,EAAE,MAAM,EACR,UAAU,EAAE,UAAU,EAC/B,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,OAAO;CAI3B"}
@@ -11,11 +11,7 @@ class Trade {
11
11
  this.instrument = instrument;
12
12
  this.rate = rate;
13
13
  this.quantity = quantity;
14
- this.kind = 'trade';
15
14
  this.id = instrument.id;
16
15
  }
17
- toString() {
18
- return this.instrument.toString();
19
- }
20
16
  }
21
17
  exports.Trade = Trade;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,30 @@
1
+ import { Observable } from 'rxjs';
2
+ import { Session, SessionBuilder, SessionFeature } from './domain';
1
3
  export * from './adapter';
2
4
  export * from './domain';
3
5
  export * from './shared';
4
6
  export * from './storage';
5
7
  export * from './store';
6
- export * from './strategy';
8
+ export declare type SessionHook = (session: Session) => Observable<any>;
9
+ /**
10
+ * Describes a single strategy logic
11
+ */
12
+ export declare let rule: (name: string | undefined, describe: SessionHook) => void;
13
+ /**
14
+ *
15
+ */
16
+ export declare let beforeAll: (describe: SessionHook) => void;
17
+ /**
18
+ *
19
+ * @param name
20
+ * @param describe
21
+ */
22
+ export declare function describe(name: string, describe: () => Array<SessionFeature>): void;
23
+ /**
24
+ *
25
+ * @param name
26
+ * @param builder
27
+ * @returns
28
+ */
29
+ export declare function spawn(name: string, builder: SessionBuilder): Promise<(session: Session) => Observable<any[]>>;
7
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,UAAU,EAAiB,MAAM,MAAM,CAAC;AAErE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACnE,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AAMxB,oBAAY,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,UAAU,CAAC,GAAG,CAAC,CAAC;AAEhE;;GAEG;AACH,eAAO,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;AAE3E;;GAEG;AACH,eAAO,IAAI,SAAS,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC,cAAc,CAAC,QAE3E;AAED;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,qBAyB9C,OAAO,wBAazB"}
package/dist/index.js CHANGED
@@ -13,10 +13,72 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
13
13
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
16
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.spawn = exports.describe = exports.beforeAll = exports.rule = void 0;
30
+ const chalk_1 = __importDefault(require("chalk"));
31
+ const rxjs_1 = require("rxjs");
17
32
  __exportStar(require("./adapter"), exports);
18
33
  __exportStar(require("./domain"), exports);
19
34
  __exportStar(require("./shared"), exports);
20
35
  __exportStar(require("./storage"), exports);
21
36
  __exportStar(require("./store"), exports);
22
- __exportStar(require("./strategy"), exports);
37
+ const shared_1 = require("./shared");
38
+ const registry = {};
39
+ /**
40
+ *
41
+ * @param name
42
+ * @param describe
43
+ */
44
+ function describe(name, describe) {
45
+ registry[name] = describe;
46
+ }
47
+ exports.describe = describe;
48
+ /**
49
+ *
50
+ * @param name
51
+ * @param builder
52
+ * @returns
53
+ */
54
+ function spawn(name, builder) {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ const describe = registry[name];
57
+ if (!describe) {
58
+ throw new Error(`missing strategy: ${name}`);
59
+ }
60
+ const ruleHooks = new Array();
61
+ const beforeAllHooks = new Array();
62
+ exports.beforeAll = (describe) => {
63
+ beforeAllHooks.push(describe);
64
+ };
65
+ exports.rule = (ruleName, describe) => {
66
+ if (ruleName) {
67
+ shared_1.Logger.info(name, `${chalk_1.default.italic(ruleName)} rule found`);
68
+ }
69
+ ruleHooks.push(describe);
70
+ };
71
+ for (const feature of describe()) {
72
+ feature(builder);
73
+ }
74
+ return (session) => {
75
+ const beforeAll$ = beforeAllHooks.map(it => it(session));
76
+ const rule$ = ruleHooks.map(it => it(session));
77
+ if (!beforeAll$.length) {
78
+ beforeAll$.push((0, rxjs_1.of)(true));
79
+ }
80
+ return (0, rxjs_1.forkJoin)(beforeAll$).pipe((0, rxjs_1.switchMap)(() => (0, rxjs_1.forkJoin)(rule$)), (0, rxjs_1.finalize)(() => session.dispose()));
81
+ };
82
+ });
83
+ }
84
+ exports.spawn = spawn;
@@ -3,5 +3,6 @@ export declare class Logger {
3
3
  static debug: (context: string, message: string) => void;
4
4
  static warn: (context: string, message: string) => void;
5
5
  static error: (context: string, error: unknown) => void;
6
+ static prefix: (context: string) => string;
6
7
  }
7
8
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/shared/logger.ts"],"names":[],"mappings":"AAiBA,qBAAa,MAAM;IACjB,OAAc,IAAI,YAAa,MAAM,WAAW,MAAM,UACO;IAE7D,OAAc,KAAK,YAAa,MAAM,WAAW,MAAM,UACO;IAE9D,OAAc,IAAI,YAAa,MAAM,WAAW,MAAM,UACO;IAE7D,OAAc,KAAK,YAAa,MAAM,SAAS,OAAO,UAQpD;CACH"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/shared/logger.ts"],"names":[],"mappings":"AAiBA,qBAAa,MAAM;IACjB,OAAc,IAAI,YAAa,MAAM,WAAW,MAAM,UACA;IAEtD,OAAc,KAAK,YAAa,MAAM,WAAW,MAAM,UACA;IAEvD,OAAc,IAAI,YAAa,MAAM,WAAW,MAAM,UACA;IAEtD,OAAc,KAAK,YAAa,MAAM,SAAS,OAAO,UAQpD;IAEF,OAAc,MAAM,YAAa,MAAM,YAAsC;CAC9E"}
@@ -2,6 +2,7 @@
2
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
+ var _a;
5
6
  Object.defineProperty(exports, "__esModule", { value: true });
6
7
  exports.Logger = void 0;
7
8
  const chalk_1 = __importDefault(require("chalk"));
@@ -18,13 +19,15 @@ const time = () => chalk_1.default.gray(new Date((0, datetime_1.now)()).toISOStr
18
19
  class Logger {
19
20
  }
20
21
  exports.Logger = Logger;
21
- Logger.info = (context, message) => console.info(`${time()} ${colorize(context)}: ${message}`);
22
- Logger.debug = (context, message) => console.debug(`${time()} ${colorize(context)}: ${message}`);
23
- Logger.warn = (context, message) => console.warn(`${time()} ${colorize(context)}: ${message}`);
22
+ _a = Logger;
23
+ Logger.info = (context, message) => console.info(`${_a.prefix(context)}: ${message}`);
24
+ Logger.debug = (context, message) => console.debug(`${_a.prefix(context)}: ${message}`);
25
+ Logger.warn = (context, message) => console.warn(`${_a.prefix(context)}: ${message}`);
24
26
  Logger.error = (context, error) => {
25
27
  let message = 'Unknown Error';
26
28
  if (error instanceof Error) {
27
29
  message = error.message;
28
30
  }
29
- console.error(`${time()} ${colorize(context)}: ${message}`);
31
+ console.error(`${_a.prefix(context)}: ${message}`);
30
32
  };
33
+ Logger.prefix = (context) => `${time()} ${colorize(context)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantform/core",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "license": "MIT",
5
5
  "author": "Mateusz Majchrzak",
6
6
  "description": "Node.js library for building systematic trading strategies in reactive way.",
@@ -1,4 +1,4 @@
1
- import { Candle, InstrumentSelector, Order } from '../domain';
1
+ import { InstrumentSelector, Ohlc, Order } from '../domain';
2
2
  import { Logger, timestamp } from '../shared';
3
3
  import { Cache } from '../storage';
4
4
  import { Store } from '../store';
@@ -18,7 +18,7 @@ export class AdapterAggregate {
18
18
  private readonly timeProvider: AdapterTimeProvider,
19
19
  private readonly store: Store,
20
20
  private readonly cache: Cache
21
- ) {}
21
+ ) { }
22
22
 
23
23
  /**
24
24
  * Returns adapter by name.
@@ -84,8 +84,6 @@ export class AdapterAggregate {
84
84
  }, {} as Record<string, InstrumentSelector[]>);
85
85
 
86
86
  for (const adapterName in grouped) {
87
- Logger.debug(adapterName, `subscribing for ${grouped[adapterName].join(', ')}`);
88
-
89
87
  try {
90
88
  await this.get(adapterName).subscribe(grouped[adapterName]);
91
89
  } catch (error) {
@@ -105,7 +103,7 @@ export class AdapterAggregate {
105
103
 
106
104
  Logger.debug(
107
105
  adapterName,
108
- `opening a new order on ${order.instrument.toString()} as ${order.id}`
106
+ `opening a new order on ${order.instrument.id} as ${order.id}`
109
107
  );
110
108
 
111
109
  try {
@@ -142,7 +140,7 @@ export class AdapterAggregate {
142
140
  instrument: InstrumentSelector,
143
141
  timeframe: number,
144
142
  length: number
145
- ): Promise<Candle[]> {
143
+ ): Promise<Ohlc[]> {
146
144
  try {
147
145
  return this.get(instrument.base.adapterName).history(instrument, timeframe, length);
148
146
  } catch (error) {
@@ -1,4 +1,4 @@
1
- import { Candle, InstrumentSelector, Order } from '../domain';
1
+ import { Ohlc, InstrumentSelector, Order } from '../domain';
2
2
  import { now, timestamp } from '../shared';
3
3
  import { Cache, StorageEvent } from '../storage';
4
4
  import { Store } from '../store';
@@ -32,7 +32,7 @@ export abstract class Adapter {
32
32
  return this.timeProvider.timestamp();
33
33
  }
34
34
 
35
- constructor(private readonly timeProvider: AdapterTimeProvider) {}
35
+ constructor(private readonly timeProvider: AdapterTimeProvider) { }
36
36
 
37
37
  /**
38
38
  * Setup an adapter.
@@ -70,7 +70,7 @@ export abstract class Adapter {
70
70
  instrument: InstrumentSelector,
71
71
  timeframe: number,
72
72
  length: number
73
- ): Promise<Candle[]>;
73
+ ): Promise<Ohlc[]>;
74
74
 
75
75
  abstract feed(
76
76
  instrument: InstrumentSelector,
@@ -1,4 +1,4 @@
1
- import { Candle, InstrumentSelector, Order } from '../../domain';
1
+ import { InstrumentSelector, Ohlc, Order } from '../../domain';
2
2
  import { timestamp } from '../../shared';
3
3
  import { InstrumentSubscriptionEvent, Store } from '../../store';
4
4
  import { Adapter } from '..';
@@ -71,7 +71,7 @@ export class BacktesterAdapter extends Adapter {
71
71
  instrument: InstrumentSelector,
72
72
  timeframe: number,
73
73
  length: number
74
- ): Promise<Candle[]> {
74
+ ): Promise<Ohlc[]> {
75
75
  this.streamer.stop();
76
76
 
77
77
  const response = await this.decoratedAdapter.history(instrument, timeframe, length);
@@ -12,7 +12,7 @@ export class BacktesterCursor {
12
12
  return this.page.length - this.pageIndex;
13
13
  }
14
14
 
15
- constructor(readonly instrument: InstrumentSelector, private readonly feed: Feed) { }
15
+ constructor(readonly instrument: InstrumentSelector, private readonly feed: Feed) {}
16
16
 
17
17
  peek(): StorageEvent | undefined {
18
18
  if (!this.page) {
@@ -1,4 +1,4 @@
1
- import { assetOf, Candle, InstrumentSelector, Order } from '../../domain';
1
+ import { assetOf, InstrumentSelector, Ohlc, Order } from '../../domain';
2
2
  import { d, decimal, timestamp } from '../../shared';
3
3
  import { BalancePatchEvent, Store } from '../../store';
4
4
  import { Adapter } from '..';
@@ -92,7 +92,7 @@ export class PaperAdapter extends Adapter {
92
92
  instrument: InstrumentSelector,
93
93
  timeframe: number,
94
94
  length: number
95
- ): Promise<Candle[]> {
95
+ ): Promise<Ohlc[]> {
96
96
  return this.decoratedAdapter.history(instrument, timeframe, length);
97
97
  }
98
98
 
package/src/cli/dev.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { join } from 'path';
2
2
 
3
+ import { spawn } from '..';
3
4
  import { SessionBuilder } from '../domain/session-builder';
4
5
  import { now } from '../shared';
5
- import { prepare } from '../strategy';
6
6
  import build from './build';
7
7
  import { buildDirectory } from './internal/workspace';
8
8
 
@@ -17,7 +17,7 @@ export default async function (name: string, options: any) {
17
17
  options.id ? Number(options.id) : now()
18
18
  );
19
19
 
20
- const rules = await prepare(name, builder);
20
+ const rules = await spawn(name, builder);
21
21
 
22
22
  const session = builder.paper();
23
23
  await session.awake();
package/src/cli/pull.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Presets, SingleBar } from 'cli-progress';
2
2
  import { join } from 'path';
3
3
 
4
+ import { spawn } from '..';
4
5
  import { instrumentOf } from '../domain';
5
6
  import { SessionBuilder } from '../domain/session-builder';
6
7
  import { now } from '../shared';
7
8
  import { Feed } from '../storage';
8
- import { prepare } from '../strategy';
9
9
  import build from './build';
10
10
  import { buildDirectory } from './internal/workspace';
11
11
 
@@ -19,7 +19,7 @@ export default async function (name: string, instrument: string, options: any) {
19
19
  options.id ? Number(options.id) : now()
20
20
  );
21
21
 
22
- await prepare(name, builder);
22
+ await spawn(name, builder);
23
23
 
24
24
  const session = builder.paper();
25
25
 
package/src/cli/run.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { join } from 'path';
2
2
 
3
+ import { spawn } from '..';
3
4
  import { SessionBuilder } from '../domain/session-builder';
4
5
  import { now } from '../shared';
5
- import { prepare } from '../strategy';
6
6
  import build from './build';
7
7
  import { buildDirectory } from './internal/workspace';
8
8
 
@@ -16,7 +16,7 @@ export default async function (name: string, options: any) {
16
16
  options.id ? Number(options.id) : now()
17
17
  );
18
18
 
19
- const rules = await prepare(name, builder);
19
+ const rules = await spawn(name, builder);
20
20
 
21
21
  const session = builder.live();
22
22
  await session.awake();
package/src/cli/test.ts CHANGED
@@ -2,7 +2,7 @@ import { join } from 'path';
2
2
 
3
3
  import { SessionBuilder } from '../domain/session-builder';
4
4
  import { Logger, now } from '../shared';
5
- import { prepare } from '../strategy';
5
+ import { spawn } from '..';
6
6
  import build from './build';
7
7
  import { buildDirectory } from './internal/workspace';
8
8
 
@@ -17,7 +17,7 @@ export default async function (name: string, options: any) {
17
17
  options.id ? Number(options.id) : now()
18
18
  );
19
19
 
20
- const rules = await prepare(name, builder);
20
+ const rules = await spawn(name, builder);
21
21
 
22
22
  const startTime = performance.now();
23
23
 
@@ -24,13 +24,6 @@ export class AssetSelector {
24
24
  this.adapterName = adapterName.toLowerCase();
25
25
  this.id = `${this.adapterName}${AssetSelectorSeparator}${this.name}`;
26
26
  }
27
-
28
- /**
29
- * Returns unified notation of the asset.
30
- */
31
- toString(): string {
32
- return this.id;
33
- }
34
27
  }
35
28
 
36
29
  /**
@@ -9,7 +9,6 @@ import { Position, PositionMode } from './position';
9
9
  */
10
10
  export class Balance implements Component {
11
11
  id: string;
12
- kind = 'balance';
13
12
 
14
13
  private locker: Record<string, decimal> = {};
15
14
  private available = d.Zero;
@@ -121,8 +120,4 @@ export class Balance implements Component {
121
120
  d.Zero
122
121
  );
123
122
  }
124
-
125
- toString() {
126
- return this.asset.toString();
127
- }
128
123
  }
@@ -2,6 +2,5 @@ import { timestamp } from '../shared';
2
2
 
3
3
  export interface Component {
4
4
  id: string;
5
- kind: string;
6
5
  timestamp: timestamp;
7
6
  }
@@ -2,8 +2,8 @@ export * from './asset';
2
2
  export * from './balance';
3
3
  export * from './balance-operator';
4
4
  export * from './error';
5
- export * from './candle';
6
- export * from './candle-operator';
5
+ export * from './ohlc';
6
+ export * from './ohlc-operator';
7
7
  export * from './commission';
8
8
  export * from './component';
9
9
  export * from './instrument';
@@ -16,17 +16,12 @@ export class InstrumentSelector {
16
16
 
17
17
  this.id = `${this.base.id}${InstrumentSelectorSeparator}${this.quote.name}`;
18
18
  }
19
-
20
- toString(): string {
21
- return this.id;
22
- }
23
19
  }
24
20
 
25
21
  /**
26
22
  * Represents trading market which is made up by two trading assets (base and quoted).
27
23
  */
28
24
  export class Instrument extends InstrumentSelector implements Component {
29
- readonly kind = 'instrument';
30
25
  readonly cross: Instrument | undefined;
31
26
  leverage: number | undefined = undefined;
32
27
 
@@ -0,0 +1,126 @@
1
+ import { from } from 'rxjs';
2
+
3
+ import { d } from '../shared';
4
+ import { Ohlc } from './ohlc';
5
+ import { mergeOhlc, ohlc, ohlcCompleted } from './ohlc-operator';
6
+
7
+ describe('ohlc', () => {
8
+ test('should aggregate and pipe ohlc updates', done => {
9
+ const input$ = from([
10
+ { timestamp: 1, rate: d(1) },
11
+ { timestamp: 2, rate: d(2) },
12
+ { timestamp: 3, rate: d(3) },
13
+ { timestamp: 4, rate: d.Zero },
14
+ { timestamp: 5, rate: d(7) },
15
+ { timestamp: 6, rate: d(8) }
16
+ ]);
17
+
18
+ const output = [
19
+ new Ohlc(0, d(1), d(1), d(1), d(1)),
20
+ new Ohlc(0, d(1), d(2), d(1), d(2)),
21
+ new Ohlc(0, d(1), d(3), d(1), d(3)),
22
+ new Ohlc(0, d(1), d(3), d.Zero, d.Zero),
23
+ new Ohlc(5, d.Zero, d(7), d(7), d(7)),
24
+ new Ohlc(5, d.Zero, d(8), d(7), d(8))
25
+ ].reverse();
26
+
27
+ input$.pipe(ohlc(5, it => it.rate)).subscribe({
28
+ next: it => {
29
+ expect(it).toEqual(output.pop());
30
+ if (output.length === 0) {
31
+ done();
32
+ }
33
+ }
34
+ });
35
+ });
36
+ });
37
+
38
+ describe('ohlcCompleted', () => {
39
+ test('should aggregate and pipe distinct completed ohlc', done => {
40
+ const input$ = from([
41
+ { timestamp: 1, rate: d(1) },
42
+ { timestamp: 2, rate: d(2) },
43
+ { timestamp: 3, rate: d(3) },
44
+ { timestamp: 4, rate: d.Zero },
45
+ { timestamp: 5, rate: d(7) },
46
+ { timestamp: 6, rate: d(8) }
47
+ ]);
48
+
49
+ input$
50
+ .pipe(
51
+ ohlc(5, it => it.rate),
52
+ ohlcCompleted()
53
+ )
54
+ .subscribe({
55
+ next: it => {
56
+ expect(it).toEqual(new Ohlc(0, d(1), d(3), d.Zero, d.Zero));
57
+ done();
58
+ }
59
+ });
60
+ });
61
+ });
62
+
63
+ describe('mergeOhlc', () => {
64
+ test('should pipe and merge ohlc from history', done => {
65
+ const history$ = from([
66
+ new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
67
+ new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
68
+ new Ohlc(3, d(3), d(3.5), d(2.5), d(4))
69
+ ]);
70
+
71
+ const input$ = from([
72
+ { timestamp: 3, rate: d(5) },
73
+ { timestamp: 4, rate: d(3) },
74
+ { timestamp: 5, rate: d(4) }
75
+ ]);
76
+
77
+ const output = [
78
+ new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
79
+ new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
80
+ new Ohlc(3, d(3), d(5), d(2.5), d(5)),
81
+ new Ohlc(4, d(5), d(3), d(3), d(3)),
82
+ new Ohlc(5, d(3), d(4), d(4), d(4))
83
+ ].reverse();
84
+
85
+ input$.pipe(mergeOhlc(1, it => it.rate, history$)).subscribe({
86
+ next: it => {
87
+ expect(it).toEqual(output.pop());
88
+ if (output.length === 0) {
89
+ done();
90
+ }
91
+ }
92
+ });
93
+ });
94
+
95
+ test('should pipe and not merge ohlc from history', done => {
96
+ const history$ = from([
97
+ new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
98
+ new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
99
+ new Ohlc(3, d(3), d(3.5), d(2.5), d(4))
100
+ ]);
101
+
102
+ const input$ = from([
103
+ { timestamp: 4, rate: d(5) },
104
+ { timestamp: 5, rate: d(3) },
105
+ { timestamp: 6, rate: d(4) }
106
+ ]);
107
+
108
+ const output = [
109
+ new Ohlc(1, d(1), d(1.5), d(0.5), d(2)),
110
+ new Ohlc(2, d(2), d(2.5), d(1.5), d(3)),
111
+ new Ohlc(3, d(3), d(3.5), d(2.5), d(4)),
112
+ new Ohlc(4, d(4), d(5), d(5), d(5)),
113
+ new Ohlc(5, d(5), d(3), d(3), d(3)),
114
+ new Ohlc(6, d(3), d(4), d(4), d(4))
115
+ ].reverse();
116
+
117
+ input$.pipe(mergeOhlc(1, it => it.rate, history$)).subscribe({
118
+ next: it => {
119
+ expect(it).toEqual(output.pop());
120
+ if (output.length === 0) {
121
+ done();
122
+ }
123
+ }
124
+ });
125
+ });
126
+ });