@barchart/portfolio-api-common 1.2.55 → 1.2.59

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.
@@ -109,7 +109,7 @@ module.exports = (() => {
109
109
 
110
110
  /**
111
111
  * Indicates if fractional shares should be closed when the position
112
- * size is less than one.
112
+ * size is less than one (or some of the fractional shares are closed).
113
113
  *
114
114
  * @public
115
115
  * @returns {Boolean}
@@ -118,7 +118,6 @@ module.exports = (() => {
118
118
  return this._closeFractional;
119
119
  }
120
120
 
121
-
122
121
  /**
123
122
  * Generates an identifier for the instrument.
124
123
  *
@@ -26,10 +26,11 @@ module.exports = (() => {
26
26
  * @public
27
27
  * @static
28
28
  * @param {Array.<Object>} transactions
29
+ * @param {Boolean=} strict
29
30
  * @returns {Boolean}
30
31
  */
31
- static validateOrder(transactions) {
32
- return TransactionValidator.getInvalidIndex(transactions) < 0;
32
+ static validateOrder(transactions, strict) {
33
+ return TransactionValidator.getInvalidIndex(transactions, strict) < 0;
33
34
  }
34
35
 
35
36
  /**
@@ -77,12 +78,14 @@ module.exports = (() => {
77
78
  * @public
78
79
  * @static
79
80
  * @param {Array.<Object>} transactions
81
+ * @param {Boolean=} strict
80
82
  * @returns {Number}
81
83
  */
82
- static getInvalidIndex(transactions) {
84
+ static getInvalidIndex(transactions, strict) {
83
85
  assert.argumentIsArray(transactions, 'transactions');
86
+ assert.argumentIsOptional(strict, 'strict', Boolean);
84
87
 
85
- return transactions.findIndex((t, i, a) => t.sequence !== (i + 1) || (i !== 0 && t.date.getIsBefore(a[ i - 1 ].date)) || (i !== 0 && t.date.getIsEqual(a[i - 1].date) && t.type.sequence < a[i - 1].type.sequence));
88
+ return transactions.findIndex((t, i, a) => t.sequence !== (i + 1) || (i !== 0 && t.date.getIsBefore(a[ i - 1 ].date)) || (i !== 0 && is.boolean(strict) && strict && t.date.getIsEqual(a[i - 1].date) && t.type.sequence < a[i - 1].type.sequence));
86
89
  }
87
90
 
88
91
  /**
@@ -6,7 +6,6 @@ const array = require('@barchart/common-js/lang/array'),
6
6
  Decimal = require('@barchart/common-js/lang/Decimal'),
7
7
  DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
8
8
  Event = require('@barchart/common-js/messaging/Event'),
9
- is = require('@barchart/common-js/lang/is'),
10
9
  Rate = require('@barchart/common-js/lang/Rate'),
11
10
  Tree = require('@barchart/common-js/collections/Tree');
12
11
 
@@ -311,7 +311,6 @@ module.exports = (() => {
311
311
  }
312
312
 
313
313
  function calculateStaticData(item) {
314
- const portfolio = item.portfolio;
315
314
  const position = item.position;
316
315
  const snapshot = item.position.snapshot;
317
316
  const previousSummaries = item.previousSummaries;
@@ -335,9 +334,9 @@ module.exports = (() => {
335
334
 
336
335
  data.income = snapshot.income;
337
336
 
338
- data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary);
339
- data.summaryTotalPrevious = calculateSummaryTotal(getPreviousSummary(previousSummaries, 1));
340
- data.summaryTotalPrevious2 = calculateSummaryTotal(getPreviousSummary(previousSummaries, 2));
337
+ data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary, getPreviousSummary(previousSummaries, 1));
338
+ data.summaryTotalPrevious = calculateSummaryTotal(getPreviousSummary(previousSummaries, 1), getPreviousSummary(previousSummaries, 2));
339
+ data.summaryTotalPrevious2 = calculateSummaryTotal(getPreviousSummary(previousSummaries, 2), getPreviousSummary(previousSummaries, 3));
341
340
 
342
341
  if (snapshot.open.getIsZero()) {
343
342
  data.basisPrice = Decimal.ZERO;
@@ -349,6 +348,7 @@ module.exports = (() => {
349
348
  function calculatePriceData(item, price) {
350
349
  const position = item.position;
351
350
  const snapshot = item.position.snapshot;
351
+ const previousSummaries = item.previousSummaries;
352
352
 
353
353
  const data = item._data;
354
354
 
@@ -408,25 +408,27 @@ module.exports = (() => {
408
408
  data.unrealizedToday = unrealizedToday;
409
409
  data.unrealizedTodayChange = unrealizedTodayChange;
410
410
 
411
- const summary = item.currentSummary;
411
+ const currentSummary = item.currentSummary;
412
+
413
+ if (currentSummary && position.instrument.type !== InstrumentType.CASH) {
414
+ const previousSummary = getPreviousSummary(previousSummaries, 1);
412
415
 
413
- if (summary && position.instrument.type !== InstrumentType.CASH) {
414
416
  let priceToUse;
415
417
 
416
418
  if (price) {
417
419
  priceToUse = price;
418
420
  } else if (data.previousPrice) {
419
421
  priceToUse = new Decimal(data.previousPrice);
420
- } else if (!summary.end.open.getIsZero()) {
421
- priceToUse = summary.end.value.divide(summary.end.open);
422
+ } else if (!currentSummary.end.open.getIsZero()) {
423
+ priceToUse = currentSummary.end.value.divide(summary.end.open);
422
424
  } else {
423
425
  priceToUse = null;
424
426
  }
425
427
 
426
428
  if (priceToUse !== null) {
427
- const period = summary.period;
429
+ const period = currentSummary.period;
428
430
 
429
- let unrealized = summary.end.open.multiply(priceToUse).add(summary.end.basis);
431
+ let unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
430
432
  let unrealizedChange;
431
433
 
432
434
  if (data.unrealized !== null) {
@@ -435,7 +437,7 @@ module.exports = (() => {
435
437
  unrealizedChange = Decimal.ZERO;
436
438
  }
437
439
 
438
- let summaryTotalCurrent = period.realized.add(period.income).add(unrealized);
440
+ let summaryTotalCurrent = period.realized.add(period.income).add(unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
439
441
  let summaryTotalCurrentChange;
440
442
 
441
443
  if (data.summaryTotalCurrent !== null) {
@@ -463,13 +465,13 @@ module.exports = (() => {
463
465
  }
464
466
  }
465
467
 
466
- function calculateSummaryTotal(summary) {
468
+ function calculateSummaryTotal(currentSummary, previousSummary) {
467
469
  let returnRef;
468
470
 
469
- if (summary) {
470
- const period = summary.period;
471
+ if (currentSummary) {
472
+ const period = currentSummary.period;
471
473
 
472
- returnRef = period.realized.add(period.income).add(period.unrealized);
474
+ returnRef = period.realized.add(period.income).add(period.unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
473
475
  } else {
474
476
  returnRef = Decimal.ZERO;
475
477
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.2.55",
3
+ "version": "1.2.59",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -110,7 +110,7 @@ module.exports = (() => {
110
110
 
111
111
  /**
112
112
  * Indicates if fractional shares should be closed when the position
113
- * size is less than one.
113
+ * size is less than one (or some of the fractional shares are closed).
114
114
  *
115
115
  * @public
116
116
  * @returns {Boolean}
@@ -119,7 +119,6 @@ module.exports = (() => {
119
119
  return this._closeFractional;
120
120
  }
121
121
 
122
-
123
122
  /**
124
123
  * Generates an identifier for the instrument.
125
124
  *
@@ -1084,10 +1083,11 @@ module.exports = (() => {
1084
1083
  * @public
1085
1084
  * @static
1086
1085
  * @param {Array.<Object>} transactions
1086
+ * @param {Boolean=} strict
1087
1087
  * @returns {Boolean}
1088
1088
  */
1089
- static validateOrder(transactions) {
1090
- return TransactionValidator.getInvalidIndex(transactions) < 0;
1089
+ static validateOrder(transactions, strict) {
1090
+ return TransactionValidator.getInvalidIndex(transactions, strict) < 0;
1091
1091
  }
1092
1092
 
1093
1093
  /**
@@ -1135,12 +1135,14 @@ module.exports = (() => {
1135
1135
  * @public
1136
1136
  * @static
1137
1137
  * @param {Array.<Object>} transactions
1138
+ * @param {Boolean=} strict
1138
1139
  * @returns {Number}
1139
1140
  */
1140
- static getInvalidIndex(transactions) {
1141
+ static getInvalidIndex(transactions, strict) {
1141
1142
  assert.argumentIsArray(transactions, 'transactions');
1143
+ assert.argumentIsOptional(strict, 'strict', Boolean);
1142
1144
 
1143
- return transactions.findIndex((t, i, a) => t.sequence !== (i + 1) || (i !== 0 && t.date.getIsBefore(a[ i - 1 ].date)) || (i !== 0 && t.date.getIsEqual(a[i - 1].date) && t.type.sequence < a[i - 1].type.sequence));
1145
+ return transactions.findIndex((t, i, a) => t.sequence !== (i + 1) || (i !== 0 && t.date.getIsBefore(a[ i - 1 ].date)) || (i !== 0 && is.boolean(strict) && strict && t.date.getIsEqual(a[i - 1].date) && t.type.sequence < a[i - 1].type.sequence));
1144
1146
  }
1145
1147
 
1146
1148
  /**
@@ -1338,7 +1340,6 @@ const array = require('@barchart/common-js/lang/array'),
1338
1340
  Decimal = require('@barchart/common-js/lang/Decimal'),
1339
1341
  DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
1340
1342
  Event = require('@barchart/common-js/messaging/Event'),
1341
- is = require('@barchart/common-js/lang/is'),
1342
1343
  Rate = require('@barchart/common-js/lang/Rate'),
1343
1344
  Tree = require('@barchart/common-js/collections/Tree');
1344
1345
 
@@ -2272,7 +2273,7 @@ module.exports = (() => {
2272
2273
  return PositionContainer;
2273
2274
  })();
2274
2275
 
2275
- },{"./../data/PositionSummaryFrame":3,"./PositionGroup":7,"./PositionItem":8,"./definitions/PositionLevelDefinition":9,"./definitions/PositionLevelType":10,"./definitions/PositionTreeDefinition":11,"@barchart/common-js/collections/Tree":15,"@barchart/common-js/collections/sorting/ComparatorBuilder":16,"@barchart/common-js/collections/sorting/comparators":17,"@barchart/common-js/collections/specialized/DisposableStack":18,"@barchart/common-js/lang/Currency":20,"@barchart/common-js/lang/Decimal":22,"@barchart/common-js/lang/Rate":26,"@barchart/common-js/lang/array":28,"@barchart/common-js/lang/assert":29,"@barchart/common-js/lang/is":33,"@barchart/common-js/messaging/Event":35}],7:[function(require,module,exports){
2276
+ },{"./../data/PositionSummaryFrame":3,"./PositionGroup":7,"./PositionItem":8,"./definitions/PositionLevelDefinition":9,"./definitions/PositionLevelType":10,"./definitions/PositionTreeDefinition":11,"@barchart/common-js/collections/Tree":15,"@barchart/common-js/collections/sorting/ComparatorBuilder":16,"@barchart/common-js/collections/sorting/comparators":17,"@barchart/common-js/collections/specialized/DisposableStack":18,"@barchart/common-js/lang/Currency":20,"@barchart/common-js/lang/Decimal":22,"@barchart/common-js/lang/Rate":26,"@barchart/common-js/lang/array":28,"@barchart/common-js/lang/assert":29,"@barchart/common-js/messaging/Event":35}],7:[function(require,module,exports){
2276
2277
  const array = require('@barchart/common-js/lang/array'),
2277
2278
  assert = require('@barchart/common-js/lang/assert'),
2278
2279
  Currency = require('@barchart/common-js/lang/Currency'),
@@ -3446,7 +3447,6 @@ module.exports = (() => {
3446
3447
  }
3447
3448
 
3448
3449
  function calculateStaticData(item) {
3449
- const portfolio = item.portfolio;
3450
3450
  const position = item.position;
3451
3451
  const snapshot = item.position.snapshot;
3452
3452
  const previousSummaries = item.previousSummaries;
@@ -3470,9 +3470,9 @@ module.exports = (() => {
3470
3470
 
3471
3471
  data.income = snapshot.income;
3472
3472
 
3473
- data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary);
3474
- data.summaryTotalPrevious = calculateSummaryTotal(getPreviousSummary(previousSummaries, 1));
3475
- data.summaryTotalPrevious2 = calculateSummaryTotal(getPreviousSummary(previousSummaries, 2));
3473
+ data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary, getPreviousSummary(previousSummaries, 1));
3474
+ data.summaryTotalPrevious = calculateSummaryTotal(getPreviousSummary(previousSummaries, 1), getPreviousSummary(previousSummaries, 2));
3475
+ data.summaryTotalPrevious2 = calculateSummaryTotal(getPreviousSummary(previousSummaries, 2), getPreviousSummary(previousSummaries, 3));
3476
3476
 
3477
3477
  if (snapshot.open.getIsZero()) {
3478
3478
  data.basisPrice = Decimal.ZERO;
@@ -3484,6 +3484,7 @@ module.exports = (() => {
3484
3484
  function calculatePriceData(item, price) {
3485
3485
  const position = item.position;
3486
3486
  const snapshot = item.position.snapshot;
3487
+ const previousSummaries = item.previousSummaries;
3487
3488
 
3488
3489
  const data = item._data;
3489
3490
 
@@ -3543,25 +3544,27 @@ module.exports = (() => {
3543
3544
  data.unrealizedToday = unrealizedToday;
3544
3545
  data.unrealizedTodayChange = unrealizedTodayChange;
3545
3546
 
3546
- const summary = item.currentSummary;
3547
+ const currentSummary = item.currentSummary;
3548
+
3549
+ if (currentSummary && position.instrument.type !== InstrumentType.CASH) {
3550
+ const previousSummary = getPreviousSummary(previousSummaries, 1);
3547
3551
 
3548
- if (summary && position.instrument.type !== InstrumentType.CASH) {
3549
3552
  let priceToUse;
3550
3553
 
3551
3554
  if (price) {
3552
3555
  priceToUse = price;
3553
3556
  } else if (data.previousPrice) {
3554
3557
  priceToUse = new Decimal(data.previousPrice);
3555
- } else if (!summary.end.open.getIsZero()) {
3556
- priceToUse = summary.end.value.divide(summary.end.open);
3558
+ } else if (!currentSummary.end.open.getIsZero()) {
3559
+ priceToUse = currentSummary.end.value.divide(summary.end.open);
3557
3560
  } else {
3558
3561
  priceToUse = null;
3559
3562
  }
3560
3563
 
3561
3564
  if (priceToUse !== null) {
3562
- const period = summary.period;
3565
+ const period = currentSummary.period;
3563
3566
 
3564
- let unrealized = summary.end.open.multiply(priceToUse).add(summary.end.basis);
3567
+ let unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
3565
3568
  let unrealizedChange;
3566
3569
 
3567
3570
  if (data.unrealized !== null) {
@@ -3570,7 +3573,7 @@ module.exports = (() => {
3570
3573
  unrealizedChange = Decimal.ZERO;
3571
3574
  }
3572
3575
 
3573
- let summaryTotalCurrent = period.realized.add(period.income).add(unrealized);
3576
+ let summaryTotalCurrent = period.realized.add(period.income).add(unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
3574
3577
  let summaryTotalCurrentChange;
3575
3578
 
3576
3579
  if (data.summaryTotalCurrent !== null) {
@@ -3598,13 +3601,13 @@ module.exports = (() => {
3598
3601
  }
3599
3602
  }
3600
3603
 
3601
- function calculateSummaryTotal(summary) {
3604
+ function calculateSummaryTotal(currentSummary, previousSummary) {
3602
3605
  let returnRef;
3603
3606
 
3604
- if (summary) {
3605
- const period = summary.period;
3607
+ if (currentSummary) {
3608
+ const period = currentSummary.period;
3606
3609
 
3607
- returnRef = period.realized.add(period.income).add(period.unrealized);
3610
+ returnRef = period.realized.add(period.income).add(period.unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
3608
3611
  } else {
3609
3612
  returnRef = Decimal.ZERO;
3610
3613
  }
@@ -17249,8 +17252,12 @@ describe('When validating transaction order', () => {
17249
17252
  expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(2, '2018-04-30', TransactionType.DIVIDEND) ])).toEqual(true);
17250
17253
  });
17251
17254
 
17252
- it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, should not be valid', () => {
17253
- expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ])).toEqual(false);
17255
+ it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, in strict mode, should not be valid', () => {
17256
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ], true)).toEqual(false);
17257
+ });
17258
+
17259
+ it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, in non-strict mode, should be valid', () => {
17260
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ], false)).toEqual(true);
17254
17261
  });
17255
17262
 
17256
17263
  it('An array of transactions with ordered sequences, on the sequential days should be valid', () => {
@@ -22,8 +22,12 @@ describe('When validating transaction order', () => {
22
22
  expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(2, '2018-04-30', TransactionType.DIVIDEND) ])).toEqual(true);
23
23
  });
24
24
 
25
- it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, should not be valid', () => {
26
- expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ])).toEqual(false);
25
+ it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, in strict mode, should not be valid', () => {
26
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ], true)).toEqual(false);
27
+ });
28
+
29
+ it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, in non-strict mode, should be valid', () => {
30
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ], false)).toEqual(true);
27
31
  });
28
32
 
29
33
  it('An array of transactions with ordered sequences, on the sequential days should be valid', () => {