@barchart/portfolio-api-common 1.2.73 → 1.2.77

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.
@@ -370,6 +370,21 @@ module.exports = (() => {
370
370
  return array.unique(symbols);
371
371
  }
372
372
 
373
+ setPositionLock(position) {
374
+ if (position) {
375
+ assert.argumentIsRequired(position, 'position', Object);
376
+ assert.argumentIsRequired(position.position, 'position.position', String);
377
+
378
+ const item = this._items.find((i) => i.position.position === position.position);
379
+
380
+ if (item) {
381
+ const locked = is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
382
+
383
+ item.setPositionLock(locked);
384
+ }
385
+ }
386
+ }
387
+
373
388
  /**
374
389
  * Performs a batch update of both position quotes and forex quotes,
375
390
  * triggering updates to position(s) and data aggregation(s).
@@ -717,6 +732,8 @@ module.exports = (() => {
717
732
  });
718
733
  }
719
734
  }
735
+
736
+ recalculatePercentages.call(this);
720
737
  }));
721
738
  }
722
739
 
@@ -72,6 +72,7 @@ module.exports = (() => {
72
72
  this._dataFormat.description = this._description;
73
73
  this._dataFormat.hide = false;
74
74
  this._dataFormat.invalid = false;
75
+ this._dataFormat.locked = false;
75
76
  this._dataFormat.newsExists = false;
76
77
  this._dataFormat.quantity = null;
77
78
  this._dataFormat.basisPrice = null;
@@ -541,12 +542,17 @@ module.exports = (() => {
541
542
  });
542
543
 
543
544
  let newsBinding = Disposable.getEmpty();
545
+ let lockedBinding = Disposable.getEmpty();
544
546
 
545
547
  if (this._single) {
546
548
  newsBinding = item.registerNewsExistsChangeHandler((exists) => {
547
549
  this._dataActual.newsExists = exists;
548
550
  this._dataFormat.newsExists = exists;
549
551
  });
552
+
553
+ lockedBinding = item.registerLockChangeHandler((locked) => {
554
+ this._dataFormat.locked = locked;
555
+ });
550
556
  }
551
557
 
552
558
  this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio) => {
@@ -558,14 +564,16 @@ module.exports = (() => {
558
564
  this._dataFormat.description = this._description;
559
565
  }));
560
566
 
567
+ this._disposeStack.push(fundamentalBinding);
561
568
  this._disposeStack.push(quoteBinding);
569
+ this._disposeStack.push(lockedBinding);
562
570
  this._disposeStack.push(newsBinding);
563
- this._disposeStack.push(fundamentalBinding);
564
571
 
565
572
  this._disposeStack.push(item.registerPositionItemDisposeHandler(() => {
573
+ fundamentalBinding.dispose();
566
574
  quoteBinding.dispose();
567
575
  newsBinding.dispose();
568
- fundamentalBinding.dispose();
576
+ lockedBinding.dispose();
569
577
 
570
578
  array.remove(this._items, i => i === item);
571
579
  array.remove(this._excludedItems, i => i === item);
@@ -692,6 +700,7 @@ module.exports = (() => {
692
700
  format.basisPrice = formatCurrency(actual.basisPrice, currency);
693
701
 
694
702
  format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
703
+ format.locked = definition.type === PositionLevelType.POSITION && item.data.locked;
695
704
  }
696
705
 
697
706
  const groupItems = group._items;
@@ -70,13 +70,15 @@ module.exports = (() => {
70
70
 
71
71
  this._data.newsExists = false;
72
72
  this._data.fundamental = { };
73
+ this._data.locked = is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
73
74
 
74
75
  calculateStaticData(this);
75
76
  calculatePriceData(this, null);
76
77
 
77
78
  this._quoteChangedEvent = new Event(this);
78
79
  this._newsExistsChangedEvent = new Event(this);
79
- this._fundamentalDataChangeEvent = new Event(this);
80
+ this._fundamentalDataChangedEvent = new Event(this);
81
+ this._lockChangedEvent = new Event(this);
80
82
  this._portfolioChangedEvent = new Event(this);
81
83
  this._positionItemDisposeEvent = new Event(this);
82
84
  }
@@ -204,6 +206,25 @@ module.exports = (() => {
204
206
  }
205
207
  }
206
208
 
209
+ /**
210
+ * Sets a flag which indicates if news article(s) exist for the encapsulated position's
211
+ * symbol.
212
+ *
213
+ * @public
214
+ * @param {Boolean} value
215
+ */
216
+ setNewsArticleExists(value) {
217
+ assert.argumentIsRequired(value, 'value', Boolean);
218
+
219
+ if (this.getIsDisposed()) {
220
+ return;
221
+ }
222
+
223
+ if (this._data.newsExists !== value) {
224
+ this._newsExistsChangedEvent.fire(this._data.newsExists = value);
225
+ }
226
+ }
227
+
207
228
  /**
208
229
  * Sets fundamental data for the position.
209
230
  *
@@ -217,25 +238,24 @@ module.exports = (() => {
217
238
  return;
218
239
  }
219
240
 
220
- this._fundamentalDataChangeEvent.fire(this._data.fundamental = data);
241
+ this._fundamentalDataChangedEvent.fire(this._data.fundamental = data);
221
242
  }
222
243
 
223
244
  /**
224
- * Sets a flag which indicates if news article(s) exist for the encapsulated position's
225
- * symbol.
245
+ * Sets position lock status.
226
246
  *
227
247
  * @public
228
248
  * @param {Boolean} value
229
249
  */
230
- setNewsArticleExists(value) {
250
+ setPositionLock(value) {
231
251
  assert.argumentIsRequired(value, 'value', Boolean);
232
252
 
233
253
  if (this.getIsDisposed()) {
234
254
  return;
235
255
  }
236
256
 
237
- if (this._data.newsExists !== value) {
238
- this._newsExistsChangedEvent.fire(this._data.newsExists = value);
257
+ if (this._data.locked !== value) {
258
+ this._lockChangedEvent.fire(this._data.locked = value);
239
259
  }
240
260
  }
241
261
 
@@ -251,6 +271,17 @@ module.exports = (() => {
251
271
  return this._quoteChangedEvent.register(handler);
252
272
  }
253
273
 
274
+ /**
275
+ * Registers an observer changes to the status of news existence.
276
+ *
277
+ * @public
278
+ * @param {Function} handler
279
+ * @returns {Disposable}
280
+ */
281
+ registerNewsExistsChangeHandler(handler) {
282
+ return this._newsExistsChangedEvent.register(handler);
283
+ }
284
+
254
285
  /**
255
286
  * Registers an observer for fundamental data changes.
256
287
  *
@@ -259,18 +290,18 @@ module.exports = (() => {
259
290
  * @returns {Disposable}
260
291
  */
261
292
  registerFundamentalDataChangeHandler(handler) {
262
- return this._fundamentalDataChangeEvent.register(handler);
293
+ return this._fundamentalDataChangedEvent.register(handler);
263
294
  }
264
295
 
265
296
  /**
266
- * Registers an observer changes to the status of news existence.
297
+ * Registers an observer for position lock changes.
267
298
  *
268
299
  * @public
269
300
  * @param {Function} handler
270
301
  * @returns {Disposable}
271
302
  */
272
- registerNewsExistsChangeHandler(handler) {
273
- return this._newsExistsChangedEvent.register(handler);
303
+ registerLockChangeHandler(handler) {
304
+ return this._lockChangedEvent.register(handler);
274
305
  }
275
306
 
276
307
  /**
@@ -300,7 +331,8 @@ module.exports = (() => {
300
331
 
301
332
  this._quoteChangedEvent.clear();
302
333
  this._newsExistsChangedEvent.clear();
303
- this._fundamentalDataChangeEvent.clear();
334
+ this._fundamentalDataChangedEvent.clear();
335
+ this._lockChangedEvent.clear();
304
336
  this._portfolioChangedEvent.clear();
305
337
  this._positionItemDisposeEvent.clear();
306
338
  }
@@ -102,6 +102,7 @@ module.exports = (() => {
102
102
  .withField('legacy.portfolio', DataType.STRING, true)
103
103
  .withField('legacy.position', DataType.STRING, true)
104
104
  .withField('system.version', DataType.NUMBER, true)
105
+ .withField('system.locked', DataType.BOOLEAN, true)
105
106
  .withField('root', DataType.STRING, true)
106
107
  .schema
107
108
  );
@@ -131,6 +132,7 @@ module.exports = (() => {
131
132
  .withField('snapshot.basis', DataType.DECIMAL)
132
133
  .withField('snapshot.income', DataType.DECIMAL)
133
134
  .withField('snapshot.value', DataType.DECIMAL)
135
+ .withField('system.locked', DataType.BOOLEAN, true)
134
136
  .withField('previous', DataType.NUMBER, true)
135
137
  .schema
136
138
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.2.73",
3
+ "version": "1.2.77",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -1749,6 +1749,21 @@ module.exports = (() => {
1749
1749
  return array.unique(symbols);
1750
1750
  }
1751
1751
 
1752
+ setPositionLock(position) {
1753
+ if (position) {
1754
+ assert.argumentIsRequired(position, 'position', Object);
1755
+ assert.argumentIsRequired(position.position, 'position.position', String);
1756
+
1757
+ const item = this._items.find((i) => i.position.position === position.position);
1758
+
1759
+ if (item) {
1760
+ const locked = is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
1761
+
1762
+ item.setPositionLock(locked);
1763
+ }
1764
+ }
1765
+ }
1766
+
1752
1767
  /**
1753
1768
  * Performs a batch update of both position quotes and forex quotes,
1754
1769
  * triggering updates to position(s) and data aggregation(s).
@@ -2096,6 +2111,8 @@ module.exports = (() => {
2096
2111
  });
2097
2112
  }
2098
2113
  }
2114
+
2115
+ recalculatePercentages.call(this);
2099
2116
  }));
2100
2117
  }
2101
2118
 
@@ -2393,6 +2410,7 @@ module.exports = (() => {
2393
2410
  this._dataFormat.description = this._description;
2394
2411
  this._dataFormat.hide = false;
2395
2412
  this._dataFormat.invalid = false;
2413
+ this._dataFormat.locked = false;
2396
2414
  this._dataFormat.newsExists = false;
2397
2415
  this._dataFormat.quantity = null;
2398
2416
  this._dataFormat.basisPrice = null;
@@ -2862,12 +2880,17 @@ module.exports = (() => {
2862
2880
  });
2863
2881
 
2864
2882
  let newsBinding = Disposable.getEmpty();
2883
+ let lockedBinding = Disposable.getEmpty();
2865
2884
 
2866
2885
  if (this._single) {
2867
2886
  newsBinding = item.registerNewsExistsChangeHandler((exists) => {
2868
2887
  this._dataActual.newsExists = exists;
2869
2888
  this._dataFormat.newsExists = exists;
2870
2889
  });
2890
+
2891
+ lockedBinding = item.registerLockChangeHandler((locked) => {
2892
+ this._dataFormat.locked = locked;
2893
+ });
2871
2894
  }
2872
2895
 
2873
2896
  this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio) => {
@@ -2879,14 +2902,16 @@ module.exports = (() => {
2879
2902
  this._dataFormat.description = this._description;
2880
2903
  }));
2881
2904
 
2905
+ this._disposeStack.push(fundamentalBinding);
2882
2906
  this._disposeStack.push(quoteBinding);
2907
+ this._disposeStack.push(lockedBinding);
2883
2908
  this._disposeStack.push(newsBinding);
2884
- this._disposeStack.push(fundamentalBinding);
2885
2909
 
2886
2910
  this._disposeStack.push(item.registerPositionItemDisposeHandler(() => {
2911
+ fundamentalBinding.dispose();
2887
2912
  quoteBinding.dispose();
2888
2913
  newsBinding.dispose();
2889
- fundamentalBinding.dispose();
2914
+ lockedBinding.dispose();
2890
2915
 
2891
2916
  array.remove(this._items, i => i === item);
2892
2917
  array.remove(this._excludedItems, i => i === item);
@@ -3013,6 +3038,7 @@ module.exports = (() => {
3013
3038
  format.basisPrice = formatCurrency(actual.basisPrice, currency);
3014
3039
 
3015
3040
  format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
3041
+ format.locked = definition.type === PositionLevelType.POSITION && item.data.locked;
3016
3042
  }
3017
3043
 
3018
3044
  const groupItems = group._items;
@@ -3251,13 +3277,15 @@ module.exports = (() => {
3251
3277
 
3252
3278
  this._data.newsExists = false;
3253
3279
  this._data.fundamental = { };
3280
+ this._data.locked = is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
3254
3281
 
3255
3282
  calculateStaticData(this);
3256
3283
  calculatePriceData(this, null);
3257
3284
 
3258
3285
  this._quoteChangedEvent = new Event(this);
3259
3286
  this._newsExistsChangedEvent = new Event(this);
3260
- this._fundamentalDataChangeEvent = new Event(this);
3287
+ this._fundamentalDataChangedEvent = new Event(this);
3288
+ this._lockChangedEvent = new Event(this);
3261
3289
  this._portfolioChangedEvent = new Event(this);
3262
3290
  this._positionItemDisposeEvent = new Event(this);
3263
3291
  }
@@ -3385,6 +3413,25 @@ module.exports = (() => {
3385
3413
  }
3386
3414
  }
3387
3415
 
3416
+ /**
3417
+ * Sets a flag which indicates if news article(s) exist for the encapsulated position's
3418
+ * symbol.
3419
+ *
3420
+ * @public
3421
+ * @param {Boolean} value
3422
+ */
3423
+ setNewsArticleExists(value) {
3424
+ assert.argumentIsRequired(value, 'value', Boolean);
3425
+
3426
+ if (this.getIsDisposed()) {
3427
+ return;
3428
+ }
3429
+
3430
+ if (this._data.newsExists !== value) {
3431
+ this._newsExistsChangedEvent.fire(this._data.newsExists = value);
3432
+ }
3433
+ }
3434
+
3388
3435
  /**
3389
3436
  * Sets fundamental data for the position.
3390
3437
  *
@@ -3398,25 +3445,24 @@ module.exports = (() => {
3398
3445
  return;
3399
3446
  }
3400
3447
 
3401
- this._fundamentalDataChangeEvent.fire(this._data.fundamental = data);
3448
+ this._fundamentalDataChangedEvent.fire(this._data.fundamental = data);
3402
3449
  }
3403
3450
 
3404
3451
  /**
3405
- * Sets a flag which indicates if news article(s) exist for the encapsulated position's
3406
- * symbol.
3452
+ * Sets position lock status.
3407
3453
  *
3408
3454
  * @public
3409
3455
  * @param {Boolean} value
3410
3456
  */
3411
- setNewsArticleExists(value) {
3457
+ setPositionLock(value) {
3412
3458
  assert.argumentIsRequired(value, 'value', Boolean);
3413
3459
 
3414
3460
  if (this.getIsDisposed()) {
3415
3461
  return;
3416
3462
  }
3417
3463
 
3418
- if (this._data.newsExists !== value) {
3419
- this._newsExistsChangedEvent.fire(this._data.newsExists = value);
3464
+ if (this._data.locked !== value) {
3465
+ this._lockChangedEvent.fire(this._data.locked = value);
3420
3466
  }
3421
3467
  }
3422
3468
 
@@ -3432,6 +3478,17 @@ module.exports = (() => {
3432
3478
  return this._quoteChangedEvent.register(handler);
3433
3479
  }
3434
3480
 
3481
+ /**
3482
+ * Registers an observer changes to the status of news existence.
3483
+ *
3484
+ * @public
3485
+ * @param {Function} handler
3486
+ * @returns {Disposable}
3487
+ */
3488
+ registerNewsExistsChangeHandler(handler) {
3489
+ return this._newsExistsChangedEvent.register(handler);
3490
+ }
3491
+
3435
3492
  /**
3436
3493
  * Registers an observer for fundamental data changes.
3437
3494
  *
@@ -3440,18 +3497,18 @@ module.exports = (() => {
3440
3497
  * @returns {Disposable}
3441
3498
  */
3442
3499
  registerFundamentalDataChangeHandler(handler) {
3443
- return this._fundamentalDataChangeEvent.register(handler);
3500
+ return this._fundamentalDataChangedEvent.register(handler);
3444
3501
  }
3445
3502
 
3446
3503
  /**
3447
- * Registers an observer changes to the status of news existence.
3504
+ * Registers an observer for position lock changes.
3448
3505
  *
3449
3506
  * @public
3450
3507
  * @param {Function} handler
3451
3508
  * @returns {Disposable}
3452
3509
  */
3453
- registerNewsExistsChangeHandler(handler) {
3454
- return this._newsExistsChangedEvent.register(handler);
3510
+ registerLockChangeHandler(handler) {
3511
+ return this._lockChangedEvent.register(handler);
3455
3512
  }
3456
3513
 
3457
3514
  /**
@@ -3481,7 +3538,8 @@ module.exports = (() => {
3481
3538
 
3482
3539
  this._quoteChangedEvent.clear();
3483
3540
  this._newsExistsChangedEvent.clear();
3484
- this._fundamentalDataChangeEvent.clear();
3541
+ this._fundamentalDataChangedEvent.clear();
3542
+ this._lockChangedEvent.clear();
3485
3543
  this._portfolioChangedEvent.clear();
3486
3544
  this._positionItemDisposeEvent.clear();
3487
3545
  }
@@ -5920,12 +5978,11 @@ module.exports = function () {
5920
5978
  }
5921
5979
 
5922
5980
  /**
5923
- * Converts a string (which matches the output of {@link Day#format} into
5924
- * a {@link Day} instance.
5981
+ * Clones a {@link Day} instance.
5925
5982
  *
5926
5983
  * @public
5927
5984
  * @static
5928
- * @param {String} value
5985
+ * @param {Day} value
5929
5986
  * @returns {Day}
5930
5987
  */
5931
5988
 
@@ -5966,6 +6023,24 @@ module.exports = function () {
5966
6023
  return this._day;
5967
6024
  }
5968
6025
  }], [{
6026
+ key: 'clone',
6027
+ value: function clone(value) {
6028
+ assert.argumentIsRequired(value, 'value', Day, 'Day');
6029
+
6030
+ return new Day(value.year, value.month, value.day);
6031
+ }
6032
+
6033
+ /**
6034
+ * Converts a string (which matches the output of {@link Day#format} into
6035
+ * a {@link Day} instance.
6036
+ *
6037
+ * @public
6038
+ * @static
6039
+ * @param {String} value
6040
+ * @returns {Day}
6041
+ */
6042
+
6043
+ }, {
5969
6044
  key: 'parse',
5970
6045
  value: function parse(value) {
5971
6046
  assert.argumentIsRequired(value, 'value', String);
@@ -6282,15 +6357,17 @@ module.exports = function () {
6282
6357
  *
6283
6358
  * @public
6284
6359
  * @param {Boolean=} approximate
6360
+ * @param {Number=} places
6285
6361
  * @returns {Boolean}
6286
6362
  */
6287
6363
 
6288
6364
  }, {
6289
6365
  key: 'getIsZero',
6290
- value: function getIsZero(approximate) {
6366
+ value: function getIsZero(approximate, places) {
6291
6367
  assert.argumentIsOptional(approximate, 'approximate', Boolean);
6368
+ assert.argumentIsOptional(places, 'places', Number);
6292
6369
 
6293
- return this._big.eq(zero) || is.boolean(approximate) && approximate && this.round(20, RoundingMode.NORMAL).getIsZero();
6370
+ return this._big.eq(zero) || is.boolean(approximate) && approximate && this.round(places || Big.DP, RoundingMode.NORMAL).getIsZero();
6294
6371
  }
6295
6372
 
6296
6373
  /**
@@ -6389,6 +6466,43 @@ module.exports = function () {
6389
6466
  return this._big.eq(getBig(other));
6390
6467
  }
6391
6468
 
6469
+ /**
6470
+ * Returns true if the current instance is an integer (i.e. has no decimal
6471
+ * component).
6472
+ *
6473
+ * @public
6474
+ * @return {Boolean}
6475
+ */
6476
+
6477
+ }, {
6478
+ key: 'getIsInteger',
6479
+ value: function getIsInteger() {
6480
+ return this.getIsEqual(this.round(0));
6481
+ }
6482
+
6483
+ /**
6484
+ * Returns the number of decimal places used.
6485
+ *
6486
+ * @public
6487
+ * @returns {Number}
6488
+ */
6489
+
6490
+ }, {
6491
+ key: 'getDecimalPlaces',
6492
+ value: function getDecimalPlaces() {
6493
+ var matches = this.toFixed().match(/-?\d*\.(\d*)/);
6494
+
6495
+ var returnVal = void 0;
6496
+
6497
+ if (matches === null) {
6498
+ returnVal = 0;
6499
+ } else {
6500
+ returnVal = matches[1].length;
6501
+ }
6502
+
6503
+ return returnVal;
6504
+ }
6505
+
6392
6506
  /**
6393
6507
  * Emits a floating point value that approximates the value of the current
6394
6508
  * instance.
@@ -6437,10 +6551,11 @@ module.exports = function () {
6437
6551
  }
6438
6552
 
6439
6553
  /**
6440
- * Parses the value emitted by {@link Decimal#toJSON}.
6554
+ * Clones a {@link Decimal} instance.
6441
6555
  *
6442
6556
  * @public
6443
- * @param {String} value
6557
+ * @static
6558
+ * @param {Decimal} value
6444
6559
  * @returns {Decimal}
6445
6560
  */
6446
6561
 
@@ -6450,6 +6565,22 @@ module.exports = function () {
6450
6565
  return '[Decimal]';
6451
6566
  }
6452
6567
  }], [{
6568
+ key: 'clone',
6569
+ value: function clone(value) {
6570
+ assert.argumentIsRequired(value, 'value', Decimal, 'Decimal');
6571
+
6572
+ return new Decimal(value._big);
6573
+ }
6574
+
6575
+ /**
6576
+ * Parses the value emitted by {@link Decimal#toJSON}.
6577
+ *
6578
+ * @public
6579
+ * @param {String} value
6580
+ * @returns {Decimal}
6581
+ */
6582
+
6583
+ }, {
6453
6584
  key: 'parse',
6454
6585
  value: function parse(value) {
6455
6586
  return new Decimal(value);
@@ -7471,10 +7602,11 @@ module.exports = function () {
7471
7602
  }
7472
7603
 
7473
7604
  /**
7474
- * Parses the value emitted by {@link Timestamp#toJSON}.
7605
+ * Clones a {@link Timestamp} instance.
7475
7606
  *
7476
7607
  * @public
7477
- * @param {Number} value
7608
+ * @static
7609
+ * @param {Timestamp} value
7478
7610
  * @returns {Timestamp}
7479
7611
  */
7480
7612
 
@@ -7510,6 +7642,22 @@ module.exports = function () {
7510
7642
  return this._moment;
7511
7643
  }
7512
7644
  }], [{
7645
+ key: 'clone',
7646
+ value: function clone(value) {
7647
+ assert.argumentIsRequired(value, 'value', Timestamp, 'Timestamp');
7648
+
7649
+ return new Timestamp(value._timestamp, value._timezone);
7650
+ }
7651
+
7652
+ /**
7653
+ * Parses the value emitted by {@link Timestamp#toJSON}.
7654
+ *
7655
+ * @public
7656
+ * @param {Number} value
7657
+ * @returns {Timestamp}
7658
+ */
7659
+
7660
+ }, {
7513
7661
  key: 'parse',
7514
7662
  value: function parse(value) {
7515
7663
  return new Timestamp(value);