@barchart/portfolio-api-common 1.26.1 → 1.27.0

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.
@@ -662,6 +662,7 @@ module.exports = (() => {
662
662
  *
663
663
  * @public
664
664
  * @param {String} symbol
665
+ * @param {Boolean} display
665
666
  * @param {Object} data
666
667
  */
667
668
  setPositionFundamentalData(symbol, display, data) {
@@ -718,7 +719,7 @@ module.exports = (() => {
718
719
  */
719
720
  getGroup(name, keys) {
720
721
  assert.argumentIsRequired(name, 'name', String);
721
- assert.argumentIsArray(keys, 'keys', Number);
722
+ assert.argumentIsArray(keys, 'keys', String);
722
723
 
723
724
  return findNode(this._trees[name], keys).getValue();
724
725
  }
@@ -734,7 +735,7 @@ module.exports = (() => {
734
735
  */
735
736
  getGroups(name, keys) {
736
737
  assert.argumentIsRequired(name, 'name', String);
737
- assert.argumentIsArray(keys, 'keys', Number);
738
+ assert.argumentIsArray(keys, 'keys', String);
738
739
 
739
740
  return findNode(this._trees[name], keys).getChildren().map(node => node.getValue());
740
741
  }
@@ -743,7 +744,7 @@ module.exports = (() => {
743
744
  * Returns the immediate parent {@link PositionGroup} of a {@link PositionGroup}.
744
745
  *
745
746
  * @public
746
- * @param {PositionGroup} position
747
+ * @param {PositionGroup} group
747
748
  * @returns {PositionGroup|null}
748
749
  */
749
750
  getParentGroup(group) {
@@ -756,7 +757,7 @@ module.exports = (() => {
756
757
  * Returns the a parent {@link PositionGroup} which represents a portfolio.
757
758
  *
758
759
  * @public
759
- * @param {PositionGroup} position
760
+ * @param {PositionGroup} group
760
761
  * @returns {PositionGroup|null}
761
762
  */
762
763
  getParentGroupForPortfolio(group) {
@@ -265,7 +265,7 @@ module.exports = (() => {
265
265
  * The {@link PositionItem} instances which for which aggregated data is compiled.
266
266
  *
267
267
  * @public
268
- * @returns {Currency}
268
+ * @returns {PositionItem[]}
269
269
  */
270
270
  get items() {
271
271
  return this._items;
@@ -16,6 +16,7 @@ module.exports = (() => {
16
16
  *
17
17
  * @public
18
18
  * @param {String} name
19
+ * @param {PositionLevelType} type
19
20
  * @param {PositionLevelDefinition~keySelector} keySelector
20
21
  * @param {PositionLevelDefinition~descriptionSelector} descriptionSelector
21
22
  * @param {PositionLevelDefinition~currencySelector} currencySelector
@@ -173,6 +174,15 @@ module.exports = (() => {
173
174
  };
174
175
  }
175
176
 
177
+ /**
178
+ * Generates the key for a {@link PositionGroup}, representing a portfolio, held
179
+ * within a {@link PositionContainer}.
180
+ *
181
+ * @public
182
+ * @static
183
+ * @param {Object} portfolio
184
+ * @returns {String}
185
+ */
176
186
  static getKeyForPortfolioGroup(portfolio) {
177
187
  assert.argumentIsRequired(portfolio, 'portfolio', Object);
178
188
 
@@ -217,6 +227,16 @@ module.exports = (() => {
217
227
  };
218
228
  }
219
229
 
230
+ /**
231
+ * Generates the key for a {@link PositionGroup}, representing a grouping of positions
232
+ * by asset class, held within a {@link PositionContainer}.
233
+ *
234
+ * @public
235
+ * @static
236
+ * @param {InstrumentType} type
237
+ * @param {Currency} currency
238
+ * @returns {String}
239
+ */
220
240
  static getKeyForAssetClassGroup(type, currency) {
221
241
  assert.argumentIsRequired(type, 'type', InstrumentType, 'InstrumentType');
222
242
  assert.argumentIsRequired(currency, 'currency', Currency, 'Currency');
@@ -0,0 +1,98 @@
1
+ const assert = require('@barchart/common-js/lang/assert'),
2
+ is = require('@barchart/common-js/lang/is'),
3
+ promise = require('@barchart/common-js/lang/promise');
4
+
5
+ const EndpointBuilder = require('@barchart/common-js/api/http/builders/EndpointBuilder'),
6
+ ErrorInterceptor = require('@barchart/common-js/api/http/interceptors/ErrorInterceptor'),
7
+ Gateway = require('@barchart/common-js/api/http/Gateway'),
8
+ ProtocolType = require('@barchart/common-js/api/http/definitions/ProtocolType'),
9
+ ResponseInterceptor = require('@barchart/common-js/api/http/interceptors/ResponseInterceptor'),
10
+ VerbType = require('@barchart/common-js/api/http/definitions/VerbType');
11
+
12
+ module.exports = (() => {
13
+ 'use strict';
14
+
15
+ const MAXIMUM_WAIT_BEFORE_TIMEOUT_IN_MILLISECONDS = 3 * 1000;
16
+
17
+ const cache = { };
18
+
19
+ /**
20
+ * A utility that downloads instrument metadata (i.e. instrument "profile" data).
21
+ *
22
+ * @public
23
+ */
24
+ class InstrumentProvider {
25
+ constructor() {
26
+ }
27
+
28
+ /**
29
+ * Returns a promise for instrument metadata (i.e. "profile" data). If no instrument
30
+ * can be found with a matching symbol, the promise is rejected.
31
+ *
32
+ * @public
33
+ * @async
34
+ * @param {String} symbol
35
+ * @returns {Promise<Object>}
36
+ */
37
+ async getInstrument(symbol) {
38
+ return Promise.resolve()
39
+ .then(() => {
40
+ assert.argumentIsRequired(symbol, 'symbol', String);
41
+
42
+ return promise.timeout(Gateway.invoke(getInstrumentLookupEndpoint(), {symbol}), MAXIMUM_WAIT_BEFORE_TIMEOUT_IN_MILLISECONDS, 'instrument lookup')
43
+ .catch((e) => {
44
+ delete cache[symbol];
45
+
46
+ let message;
47
+
48
+ if (is.string(e) && e === 'timeout') {
49
+ message = `Instrument lookup for [ ${symbol} ] failed due to timed out`;
50
+ } else {
51
+ message = `Instrument lookup for [ ${symbol} ] failed due to an unspecified error`;
52
+ }
53
+
54
+ return Promise.reject(message);
55
+ }).then((result) => {
56
+ if (result.instrument === null) {
57
+ return Promise.reject(`Instrument lookup for [ ${symbol} ] failed, the instrument does not exist`);
58
+ }
59
+
60
+ return result;
61
+ });
62
+ });
63
+ }
64
+
65
+ toString() {
66
+ return '[InstrumentProvider]';
67
+ }
68
+ }
69
+
70
+ function buildInstrumentLookupEndpoint(host) {
71
+ return EndpointBuilder.for('query-instrument', 'query instrument')
72
+ .withVerb(VerbType.GET)
73
+ .withProtocol(ProtocolType.HTTPS)
74
+ .withHost(host)
75
+ .withPort(443)
76
+ .withPathBuilder((pb) => {
77
+ pb.withLiteralParameter('instruments', 'instruments')
78
+ .withVariableParameter('symbol', 'symbol', 'symbol');
79
+ })
80
+ .withResponseInterceptor(ResponseInterceptor.DATA)
81
+ .withErrorInterceptor(ErrorInterceptor.GENERAL)
82
+ .endpoint;
83
+ }
84
+
85
+ const instrumentLookupEndpoints = new Map();
86
+
87
+ function getInstrumentLookupEndpoint() {
88
+ const host = 'instruments-prod.aws.barchart.com';
89
+
90
+ if (!instrumentLookupEndpoints.has(host)) {
91
+ instrumentLookupEndpoints.set(host, buildInstrumentLookupEndpoint(host));
92
+ }
93
+
94
+ return instrumentLookupEndpoints.get(host);
95
+ }
96
+
97
+ return InstrumentProvider;
98
+ })();
@@ -0,0 +1,66 @@
1
+ const assert = require('@barchart/common-js/lang/assert'),
2
+ TimeMap = require('@barchart/common-js/collections/specialized/TimeMap');
3
+
4
+ const InstrumentProvider = require('./InstrumentProvider');
5
+
6
+ module.exports = (() => {
7
+ 'use strict';
8
+
9
+ const MAXIMUM_CACHE_AGE_IN_MILLISECONDS = 15 * 60 * 1000;
10
+
11
+ /**
12
+ * A caching layer on top of the {@link InstrumentProvider}.
13
+ *
14
+ * @public
15
+ * @param {InstrumentProvider} provider
16
+ * @param {Number} cacheDuration - The maximum number of milliseconds to cache an instrument.
17
+ */
18
+ class InstrumentProviderCache {
19
+ constructor(provider, cacheDuration) {
20
+ assert.argumentIsRequired(provider, 'provider', InstrumentProvider, 'InstrumentProvider');
21
+
22
+ this._provider = provider;
23
+ this._cache = new TimeMap(cacheDuration || MAXIMUM_CACHE_AGE_IN_MILLISECONDS);
24
+ }
25
+
26
+ /**
27
+ * Returns a promise for instrument metadata from an internal cache. If the instrument
28
+ * does not exist in the cache, or the data has expired, then a new request for the
29
+ * instrument is made using the {@link InstrumentProvider}.
30
+ *
31
+ * @public
32
+ * @async
33
+ * @param {String} symbol
34
+ * @returns {Promise<Object>}
35
+ */
36
+ async getInstrument(symbol) {
37
+ return Promise.resolve()
38
+ .then(() => {
39
+ assert.argumentIsRequired(symbol, 'symbol', String);
40
+
41
+ let promise = this._cache.get(symbol);
42
+
43
+ if (promise !== null) {
44
+ return promise;
45
+ }
46
+
47
+ promise = this._provider.getInstrument(symbol)
48
+ .then((profile) => {
49
+ if (profile) {
50
+ this._cache.put(symbol, promise);
51
+
52
+ return profile;
53
+ }
54
+ });
55
+
56
+ return promise;
57
+ });
58
+ }
59
+
60
+ toString() {
61
+ return '[InstrumentProviderCache]';
62
+ }
63
+ }
64
+
65
+ return InstrumentProviderCache;
66
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.26.1",
3
+ "version": "1.27.0",
4
4
  "description": "Common JavaScript code used by Barchart's Portfolio Service",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",