@barchart/portfolio-api-common 1.2.130 → 1.2.134

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.
@@ -11,9 +11,10 @@ module.exports = (() => {
11
11
  *
12
12
  * @public
13
13
  * @extends {Enum}
14
+ * @param {String} code
14
15
  * @param {String} description
15
16
  * @param {String} alternateDescription
16
- * @param {String} code
17
+ * @param {Boolean} canExistEmpty
17
18
  * @param {Boolean} canReinvest
18
19
  * @param {Boolean} canShort
19
20
  * @param {Boolean} canSwitchDirection
@@ -25,10 +26,11 @@ module.exports = (() => {
25
26
  * @param {Function} generator
26
27
  */
27
28
  class InstrumentType extends Enum {
28
- constructor(code, description, alternateDescription, canReinvest, canShort, canSwitchDirection, usesSymbols, hasCorporateActions, closeFractional, roundQuantity, strictOrdering, generator) {
29
+ constructor(code, description, alternateDescription, canExistEmpty, canReinvest, canShort, canSwitchDirection, usesSymbols, hasCorporateActions, closeFractional, roundQuantity, strictOrdering, generator) {
29
30
  super(code, description);
30
31
 
31
32
  assert.argumentIsRequired(alternateDescription, 'alternateDescription', String);
33
+ assert.argumentIsRequired(canExistEmpty, 'canExistEmpty', Boolean);
32
34
  assert.argumentIsRequired(canReinvest, 'canReinvest', Boolean);
33
35
  assert.argumentIsRequired(canShort, 'canShort', Boolean);
34
36
  assert.argumentIsRequired(canSwitchDirection, 'canSwitchDirection', Boolean);
@@ -40,6 +42,8 @@ module.exports = (() => {
40
42
  assert.argumentIsRequired(generator, 'generator', Function);
41
43
 
42
44
  this._alternateDescription = alternateDescription;
45
+
46
+ this._canExistEmpty = canExistEmpty;
43
47
  this._canReinvest = canReinvest;
44
48
  this._canShort = canShort;
45
49
  this._canSwitchDirection = canSwitchDirection;
@@ -62,6 +66,16 @@ module.exports = (() => {
62
66
  return this._alternateDescription;
63
67
  }
64
68
 
69
+ /**
70
+ * Indicates if the position can exist without any associated transactions.
71
+ *
72
+ * @public
73
+ * @returns {Boolean}
74
+ */
75
+ get canExistEmpty() {
76
+ return this._canExistEmpty;
77
+ }
78
+
65
79
  /**
66
80
  * Indicates if the instrument type allows automatic reinvestment.
67
81
  *
@@ -242,10 +256,10 @@ module.exports = (() => {
242
256
  }
243
257
  }
244
258
 
245
- const cash = new InstrumentType('CASH', 'cash', 'Cash', false, false, true, false, false, false, false, false, (instrument) => `BARCHART-${instrument.type.code}-${instrument.currency.code}`);
246
- const equity = new InstrumentType('EQUITY', 'equity', 'Equities', true, true, false, true, true, true, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
247
- const fund = new InstrumentType('FUND', 'mutual fund', 'Funds', true, false, false, true, true, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
248
- const other = new InstrumentType('OTHER', 'other', 'Other', false, false, false, false, false, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${uuid.v4()}`);
259
+ const cash = new InstrumentType('CASH', 'cash', 'Cash', true, false, false, true, false, false, false, false, false, (instrument) => `BARCHART-${instrument.type.code}-${instrument.currency.code}`);
260
+ const equity = new InstrumentType('EQUITY', 'equity', 'Equities', false, true, true, false, true, true, true, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
261
+ const fund = new InstrumentType('FUND', 'mutual fund', 'Funds', false, true, false, false, true, true, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
262
+ const other = new InstrumentType('OTHER', 'other', 'Other', false, false, false, false, false, false, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${uuid.v4()}`);
249
263
 
250
264
  const map = { };
251
265
 
@@ -137,6 +137,9 @@ module.exports = (() => {
137
137
  this._dataActual.marketChange = null;
138
138
  this._dataActual.marketChangePercent = null;
139
139
  this._dataActual.cashTotal = null;
140
+ this._dataActual.periodDivisorCurrent = null;
141
+ this._dataActual.periodDivisorPrevious = null;
142
+ this._dataActual.periodDivisorPrevious2 = null;
140
143
 
141
144
  this._dataFormat.currentPrice = null;
142
145
  this._dataFormat.basis = null;
@@ -168,33 +171,25 @@ module.exports = (() => {
168
171
 
169
172
  this._dataActual.periodPrice = null;
170
173
  this._dataActual.periodPricePrevious = null;
171
- this._dataActual.periodRealized = null;
172
- this._dataActual.periodRealizedPrevious = null;
173
- this._dataActual.periodRealizedPrevious2 = null;
174
- this._dataActual.periodRealizedBasis = null;
175
- this._dataActual.periodRealizedBasisPrevious = null;
176
- this._dataActual.periodRealizedBasisPrevious2 = null;
177
- this._dataActual.periodUnrealized = null;
178
- this._dataActual.periodUnrealizedPrevious = null;
179
- this._dataActual.periodUnrealizedPrevious2 = null;
180
- this._dataActual.periodUnrealizedBasis = null;
181
- this._dataActual.periodUnrealizedBasisPrevious = null;
182
- this._dataActual.periodUnrealizedBasisPrevious2 = null;
183
- this._dataActual.periodIncome = null;
184
174
 
185
175
  this._dataFormat.periodPrice = null;
186
176
  this._dataFormat.periodPricePrevious = null;
177
+
178
+ this._dataActual.periodIncome = null;
179
+ this._dataActual.periodRealized = null;
180
+ this._dataActual.periodUnrealized = null;
181
+
182
+ this._dataFormat.periodIncome = null;
187
183
  this._dataFormat.periodRealized = null;
188
184
  this._dataFormat.periodUnrealized = null;
189
- this._dataFormat.periodIncome = null;
190
185
 
191
186
  this._dataActual.periodPercent = null;
192
- this._dataActual.periodPreviousPercent = null;
193
- this._dataActual.periodPrevious2Percent = null;
187
+ this._dataActual.periodPercentPrevious = null;
188
+ this._dataActual.periodPercentPrevious2 = null;
194
189
 
195
190
  this._dataFormat.periodPercent = null;
196
- this._dataFormat.periodPreviousPercent = null;
197
- this._dataFormat.periodPrevious2Percent = null;
191
+ this._dataFormat.periodPercentPrevious = null;
192
+ this._dataFormat.periodPercentPrevious2 = null;
198
193
 
199
194
  this._items.forEach((item) => {
200
195
  bindItem.call(this, item);
@@ -686,9 +681,9 @@ module.exports = (() => {
686
681
  updates.realized = updates.realized.add(translate(item, item.data.realized));
687
682
  updates.unrealized = updates.unrealized.add(translate(item, item.data.unrealized));
688
683
  updates.income = updates.income.add(translate(item, item.data.income));
689
- updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
690
- updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
691
- updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
684
+ updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.periodGain));
685
+ updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.periodGainPrevious));
686
+ updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.periodGainPrevious2));
692
687
  updates.marketPrevious = updates.marketPrevious.add(translate(item, item.data.marketPrevious));
693
688
  updates.marketPrevious2 = updates.marketPrevious2.add(translate(item, item.data.marketPrevious2));
694
689
 
@@ -700,6 +695,10 @@ module.exports = (() => {
700
695
  updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
701
696
  }
702
697
 
698
+ updates.periodDivisorCurrent = updates.periodDivisorCurrent.add(translate(item, item.data.periodDivisor));
699
+ updates.periodDivisorPrevious = updates.periodDivisorPrevious.add(translate(item, item.data.periodDivisorPrevious));
700
+ updates.periodDivisorPrevious2 = updates.periodDivisorPrevious2.add(translate(item, item.data.periodDivisorPrevious2));
701
+
703
702
  return updates;
704
703
  }, {
705
704
  basis: Decimal.ZERO,
@@ -715,6 +714,9 @@ module.exports = (() => {
715
714
  periodUnrealized: Decimal.ZERO,
716
715
  periodIncome: Decimal.ZERO,
717
716
  cashTotal: Decimal.ZERO,
717
+ periodDivisorCurrent: Decimal.ZERO,
718
+ periodDivisorPrevious: Decimal.ZERO,
719
+ periodDivisorPrevious2: Decimal.ZERO
718
720
  });
719
721
 
720
722
  actual.basis = updates.basis;
@@ -730,12 +732,16 @@ module.exports = (() => {
730
732
  actual.periodUnrealized = updates.periodUnrealized;
731
733
  actual.periodIncome = updates.periodIncome;
732
734
  actual.cashTotal = updates.cashTotal;
735
+ actual.periodDivisorCurrent = updates.periodDivisorCurrent;
736
+ actual.periodDivisorPrevious = updates.periodDivisorPrevious;
737
+ actual.periodDivisorPrevious2 = updates.periodDivisorPrevious2;
733
738
 
734
739
  format.basis = formatCurrency(actual.basis, currency);
735
740
  format.realized = formatCurrency(actual.realized, currency);
736
741
  format.unrealized = formatCurrency(actual.unrealized, currency);
737
742
  format.income = formatCurrency(actual.income, currency);
738
743
  format.summaryTotalCurrent = formatCurrency(updates.summaryTotalCurrent, currency);
744
+ format.summaryTotalCurrentNegative = updates.summaryTotalCurrent.getIsNegative();
739
745
  format.summaryTotalPrevious = formatCurrency(updates.summaryTotalPrevious, currency);
740
746
  format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
741
747
  format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
@@ -770,25 +776,9 @@ module.exports = (() => {
770
776
  format.periodPrice = formatCurrency(actual.periodPrice, currency);
771
777
  format.periodPricePrevious = formatCurrency(actual.periodPricePrevious, currency);
772
778
 
773
- actual.periodRealized = item.data.periodRealized;
774
- actual.periodRealizedPrevious = item.data.periodRealizedPrevious;
775
- actual.periodRealizedPrevious2 = item.data.periodRealizedPrevious2;
776
-
777
- actual.periodRealizedBasis = item.data.periodRealizedBasis;
778
- actual.periodRealizedBasisPrevious = item.data.periodRealizedBasisPrevious;
779
- actual.periodRealizedBasisPrevious2 = item.data.periodRealizedBasisPrevious2;
780
-
781
- actual.periodUnrealized = item.data.periodUnrealized;
782
- actual.periodUnrealizedPrevious = item.data.periodUnrealizedPrevious;
783
- actual.periodUnrealizedPrevious2 = item.data.periodUnrealizedPrevious2;
784
-
785
- actual.periodUnrealizedBasis = item.data.periodUnrealizedBasis;
786
- actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
787
- actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
788
-
789
- actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
790
- actual.periodPercentPrevious = calculatePeriodPercent(actual.summaryTotalPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedBasisPrevious);
791
- actual.periodPercentPrevious2 = calculatePeriodPercent(actual.summaryTotalPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedBasisPrevious2);
779
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodDivisorCurrent);
780
+ actual.periodPercentPrevious = calculatePeriodPercent(actual.summaryTotalPrevious, actual.periodDivisorPrevious);
781
+ actual.periodPercentPrevious2 = calculatePeriodPercent(actual.summaryTotalPrevious2, actual.periodDivisorPrevious2);
792
782
 
793
783
  format.periodPercent = formatPercent(actual.periodPercent, 2);
794
784
  format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
@@ -847,7 +837,7 @@ module.exports = (() => {
847
837
  updates.marketAbsolute = updates.marketAbsolute.add(translate(item, item.data.marketAbsolute));
848
838
  updates.unrealized = updates.unrealized.add(translate(item, item.data.unrealized));
849
839
  updates.unrealizedToday = updates.unrealizedToday.add(translate(item, item.data.unrealizedToday));
850
- updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
840
+ updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.periodGain));
851
841
 
852
842
  return updates;
853
843
  }, {
@@ -865,7 +855,7 @@ module.exports = (() => {
865
855
  marketDirection: { up: item.data.marketChange.getIsPositive(), down: item.data.marketChange.getIsNegative() },
866
856
  unrealized: actual.unrealized.add(translate(item, item.data.unrealizedChange)),
867
857
  unrealizedToday: actual.unrealizedToday.add(translate(item, item.data.unrealizedTodayChange)),
868
- summaryTotalCurrent: actual.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrentChange))
858
+ summaryTotalCurrent: actual.summaryTotalCurrent.add(translate(item, item.data.periodGainChange))
869
859
  };
870
860
  }
871
861
 
@@ -921,7 +911,7 @@ module.exports = (() => {
921
911
  if (group.single && item) {
922
912
  actual.periodUnrealized = item.data.periodUnrealized;
923
913
 
924
- actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
914
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodDivisorCurrent);
925
915
  format.periodPercent = formatPercent(actual.periodPercent, 2);
926
916
  }
927
917
  }
@@ -982,11 +972,8 @@ module.exports = (() => {
982
972
  }
983
973
  }
984
974
 
985
- function calculatePeriodPercent(periodSummaryTotal, realizedBasis, unrealizedBasis) {
986
- const numerator = periodSummaryTotal;
987
- const denominator = realizedBasis.add(unrealizedBasis);
988
-
989
- return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
975
+ function calculatePeriodPercent(periodSummaryTotal, periodDivisor) {
976
+ return periodDivisor.getIsZero() ? Decimal.ZERO : periodSummaryTotal.divide(periodDivisor);
990
977
  }
991
978
 
992
979
  const unchanged = { up: false, down: false };
@@ -62,12 +62,6 @@ module.exports = (() => {
62
62
  this._data.unrealized = null;
63
63
  this._data.unrealizedChange = null;
64
64
 
65
- this._data.summaryTotalCurrent = null;
66
- this._data.summaryTotalCurrentChange = null;
67
-
68
- this._data.summaryTotalPrevious = null;
69
- this._data.summaryTotalPrevious2 = null;
70
-
71
65
  this._data.marketPrevious = null;
72
66
  this._data.marketPrevious2 = null;
73
67
 
@@ -78,26 +72,24 @@ module.exports = (() => {
78
72
  this._data.income = null;
79
73
  this._data.basisPrice = null;
80
74
 
75
+ this._data.periodIncome = null;
81
76
  this._data.periodRealized = null;
82
- this._data.periodRealizedPrevious = null;
83
- this._data.periodRealizedPrevious2 = null;
77
+ this._data.periodUnrealized = null;
84
78
 
85
- this._data.periodRealizedBasis = null;
86
- this._data.periodRealizedBasisPrevious = null;
87
- this._data.periodRealizedBasisPrevious2 = null;
79
+ this._data.periodPrice = null;
80
+ this._data.periodPricePrevious = null;
88
81
 
89
- this._data.periodUnrealized = null;
90
- this._data.periodUnrealizedPrevious = null;
91
- this._data.periodUnrealizedPrevious2 = null;
82
+ this._data.periodGain = null;
83
+ this._data.periodGainChange = null;
92
84
 
93
- this._data.periodUnrealizedBasis = null;
94
- this._data.periodUnrealizedBasisPrevious = null;
95
- this._data.periodUnrealizedBasisPrevious2 = null;
85
+ this._data.periodGainPrevious = null;
86
+ this._data.periodGainPrevious2 = null;
96
87
 
97
- this._data.periodIncome = null;
88
+ this._data.periodDivisor = null;
89
+ this._data.periodDivisorChange = null;
98
90
 
99
- this._data.periodPrice = null;
100
- this._data.periodPricePrevious = null;
91
+ this._data.periodDivisorPrevious = null;
92
+ this._data.periodDivisorPrevious2 = null;
101
93
 
102
94
  this._data.newsExists = false;
103
95
  this._data.fundamental = { };
@@ -417,31 +409,21 @@ module.exports = (() => {
417
409
 
418
410
  data.income = snapshot.income;
419
411
 
420
- data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary, previousSummary1);
421
- data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
422
- data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
423
-
424
412
  data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
425
413
  data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
426
414
  data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
427
415
 
428
- data.periodRealized = calculatePeriodRealized(item.currentSummary, previousSummary1);
429
- data.periodRealizedPrevious = calculatePeriodRealized(previousSummary1, previousSummary2);
430
- data.periodRealizedPrevious2 = calculatePeriodRealized(previousSummary2, previousSummary3);
431
-
432
- data.periodRealizedBasis = calculatePeriodRealizedBasis(item.currentSummary, previousSummary1);
433
- data.periodRealizedBasisPrevious = calculatePeriodRealizedBasis(previousSummary1, previousSummary2);
434
- data.periodRealizedBasisPrevious2 = calculatePeriodRealizedBasis(previousSummary2, previousSummary3);
435
-
436
- data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary1);
437
- data.periodUnrealizedPrevious = calculatePeriodUnrealized(previousSummary1, previousSummary2);
438
- data.periodUnrealizedPrevious2 = calculatePeriodUnrealized(previousSummary2, previousSummary3);
439
-
440
- data.periodUnrealizedBasis = calculatePeriodUnrealizedBasis(item.currentSummary, previousSummary1);
441
- data.periodUnrealizedBasisPrevious = calculatePeriodUnrealizedBasis(previousSummary1, previousSummary2);
442
- data.periodUnrealizedBasisPrevious2 = calculatePeriodUnrealizedBasis(previousSummary2, previousSummary3);
443
-
444
- data.periodIncome = calculatePeriodIncome(item.currentSummary, previousSummary1);
416
+ data.periodIncome = currentSummary !== null ? currentSummary.period.income : Decimal.ZERO;
417
+ data.periodRealized = currentSummary !== null ? currentSummary.period.realized : Decimal.ZERO;
418
+ data.periodUnrealized = currentSummary !== null ? currentSummary.period.unrealized : Decimal.ZERO;
419
+
420
+ data.periodGain = calculatePeriodGain(currentSummary, previousSummary1);
421
+ data.periodGainPrevious = calculatePeriodGain(previousSummary1, previousSummary2);
422
+ data.periodGainPrevious2 = calculatePeriodGain(previousSummary2, previousSummary3);
423
+
424
+ data.periodDivisor = calculatePeriodDivisor(currentSummary, previousSummary1);
425
+ data.periodDivisorPrevious = calculatePeriodDivisor(previousSummary1, previousSummary2);
426
+ data.periodDivisorPrevious2 = calculatePeriodDivisor(previousSummary2, previousSummary3);
445
427
 
446
428
  if (snapshot.open.getIsZero()) {
447
429
  data.basisPrice = Decimal.ZERO;
@@ -465,7 +447,6 @@ module.exports = (() => {
465
447
  function calculatePriceData(item, price) {
466
448
  const position = item.position;
467
449
  const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
468
- const previousSummaries = item.previousSummaries;
469
450
 
470
451
  const data = item._data;
471
452
 
@@ -526,10 +507,9 @@ module.exports = (() => {
526
507
  data.unrealizedTodayChange = unrealizedTodayChange;
527
508
 
528
509
  const currentSummary = item.currentSummary;
510
+ const previousSummary = getPreviousSummary(item.previousSummaries, 1);
529
511
 
530
512
  if (currentSummary && position.instrument.type !== InstrumentType.CASH) {
531
- const previousSummary = getPreviousSummary(previousSummaries, 1);
532
-
533
513
  let priceToUse;
534
514
 
535
515
  if (price) {
@@ -543,8 +523,6 @@ module.exports = (() => {
543
523
  }
544
524
 
545
525
  if (priceToUse !== null) {
546
- const period = currentSummary.period;
547
-
548
526
  let unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
549
527
  let unrealizedChange;
550
528
 
@@ -554,115 +532,79 @@ module.exports = (() => {
554
532
  unrealizedChange = Decimal.ZERO;
555
533
  }
556
534
 
557
- let summaryTotalCurrent = period.realized.add(period.income).add(unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
558
- let summaryTotalCurrentChange;
535
+ data.unrealized = unrealized;
536
+ data.unrealizedChange = unrealizedChange;
559
537
 
560
- if (data.summaryTotalCurrent !== null) {
561
- summaryTotalCurrentChange = summaryTotalCurrent.subtract(data.summaryTotalCurrent);
538
+ let periodGain = calculatePeriodGain(currentSummary, previousSummary, priceToUse);
539
+ let periodGainChange;
540
+
541
+ if (data.periodGain !== null) {
542
+ periodGainChange = periodGain.subtract(data.periodGain);
562
543
  } else {
563
- summaryTotalCurrentChange = Decimal.ZERO;
544
+ periodGainChange = Decimal.ZERO;
564
545
  }
565
546
 
566
- data.summaryTotalCurrent = summaryTotalCurrent;
567
- data.summaryTotalCurrentChange = summaryTotalCurrentChange;
568
-
569
- data.unrealized = unrealized;
570
- data.unrealizedChange = unrealizedChange;
571
-
572
- data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary, data.unrealized);
573
- data.periodUnrealizedChange = unrealizedChange;
547
+ data.periodGain = periodGain;
548
+ data.periodGainChange = periodGainChange;
574
549
  } else {
575
- data.summaryTotalCurrentChange = Decimal.ZERO;
576
-
577
550
  data.unrealized = Decimal.ZERO;
578
551
  data.unrealizedChange = Decimal.ZERO;
579
552
 
580
- data.periodUnrealizedChange = Decimal.ZERO;
553
+ data.periodGainChange = Decimal.ZERO;
581
554
  }
582
555
  } else {
583
- data.summaryTotalCurrentChange = Decimal.ZERO;
584
-
585
556
  data.unrealized = Decimal.ZERO;
586
557
  data.unrealizedChange = Decimal.ZERO;
587
- }
588
- }
589
-
590
- function calculateSummaryTotal(currentSummary, previousSummary) {
591
- let returnRef;
592
-
593
- if (currentSummary) {
594
- const period = currentSummary.period;
595
558
 
596
- returnRef = period.realized.add(period.income).add(period.unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
597
- } else {
598
- returnRef = Decimal.ZERO;
559
+ data.periodGainChange = Decimal.ZERO;
599
560
  }
600
-
601
- return returnRef;
602
561
  }
603
562
 
604
- function calculatePeriodRealized(currentSummary, previousSummary) {
563
+ function calculatePeriodGain(currentSummary, previousSummary, overridePrice) {
605
564
  let returnRef;
606
565
 
607
566
  if (currentSummary) {
608
- const period = currentSummary.period;
567
+ let startValue;
609
568
 
610
- returnRef = period.realized;
611
- } else {
612
- returnRef = Decimal.ZERO;
613
- }
569
+ if (previousSummary) {
570
+ startValue = previousSummary.end.value;
571
+ } else {
572
+ startValue = Decimal.ZERO;
573
+ }
614
574
 
615
- return returnRef;
616
- }
575
+ let endValue;
617
576
 
618
- function calculatePeriodRealizedBasis(currentSummary, previousSummary) {
619
- let returnRef;
577
+ if (overridePrice) {
578
+ endValue = currentSummary.end.open.multiply(overridePrice);
579
+ } else {
580
+ endValue = currentSummary.end.value;
581
+ }
620
582
 
621
- if (currentSummary) {
622
- const period = currentSummary.period;
583
+ const valueChange = endValue.subtract(startValue);
584
+ const tradeChange = currentSummary.period.sells.subtract(currentSummary.period.buys);
585
+ const incomeChange = currentSummary.period.income;
623
586
 
624
- returnRef = period.sells.subtract(calculatePeriodRealized(currentSummary, previousSummary));
587
+ returnRef = valueChange.add(tradeChange).add(incomeChange);
625
588
  } else {
626
589
  returnRef = Decimal.ZERO;
627
590
  }
628
591
 
629
592
  return returnRef;
630
593
  }
631
-
632
- function calculatePeriodUnrealized(currentSummary, previousSummary, override) {
633
- let returnRef;
634
-
635
- if (currentSummary) {
636
- const period = currentSummary.period;
637
- const unrealized = override || period.unrealized;
638
-
639
- returnRef = unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
640
- } else {
641
- returnRef = Decimal.ZERO;
642
- }
643
594
 
644
- return returnRef;
645
- }
646
-
647
- function calculatePeriodUnrealizedBasis(currentSummary, previousSummary) {
595
+ function calculatePeriodDivisor(currentSummary, previousSummary) {
648
596
  let returnRef;
649
597
 
650
598
  if (currentSummary) {
651
- returnRef = currentSummary.end.basis.absolute();
652
- } else {
653
- returnRef = Decimal.ZERO;
654
- }
599
+ let startValue;
655
600
 
656
- return returnRef;
657
- }
658
-
659
- function calculatePeriodIncome(currentSummary, previousSummary) {
660
- let returnRef;
661
-
662
- if (currentSummary) {
663
- const period = currentSummary.period;
601
+ if (previousSummary) {
602
+ startValue = previousSummary.end.value;
603
+ } else {
604
+ startValue = Decimal.ZERO;
605
+ }
664
606
 
665
- returnRef = period.income;
607
+ returnRef = startValue.add(currentSummary.period.buys);
666
608
  } else {
667
609
  returnRef = Decimal.ZERO;
668
610
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.2.130",
3
+ "version": "1.2.134",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -12,9 +12,10 @@ module.exports = (() => {
12
12
  *
13
13
  * @public
14
14
  * @extends {Enum}
15
+ * @param {String} code
15
16
  * @param {String} description
16
17
  * @param {String} alternateDescription
17
- * @param {String} code
18
+ * @param {Boolean} canExistEmpty
18
19
  * @param {Boolean} canReinvest
19
20
  * @param {Boolean} canShort
20
21
  * @param {Boolean} canSwitchDirection
@@ -26,10 +27,11 @@ module.exports = (() => {
26
27
  * @param {Function} generator
27
28
  */
28
29
  class InstrumentType extends Enum {
29
- constructor(code, description, alternateDescription, canReinvest, canShort, canSwitchDirection, usesSymbols, hasCorporateActions, closeFractional, roundQuantity, strictOrdering, generator) {
30
+ constructor(code, description, alternateDescription, canExistEmpty, canReinvest, canShort, canSwitchDirection, usesSymbols, hasCorporateActions, closeFractional, roundQuantity, strictOrdering, generator) {
30
31
  super(code, description);
31
32
 
32
33
  assert.argumentIsRequired(alternateDescription, 'alternateDescription', String);
34
+ assert.argumentIsRequired(canExistEmpty, 'canExistEmpty', Boolean);
33
35
  assert.argumentIsRequired(canReinvest, 'canReinvest', Boolean);
34
36
  assert.argumentIsRequired(canShort, 'canShort', Boolean);
35
37
  assert.argumentIsRequired(canSwitchDirection, 'canSwitchDirection', Boolean);
@@ -41,6 +43,8 @@ module.exports = (() => {
41
43
  assert.argumentIsRequired(generator, 'generator', Function);
42
44
 
43
45
  this._alternateDescription = alternateDescription;
46
+
47
+ this._canExistEmpty = canExistEmpty;
44
48
  this._canReinvest = canReinvest;
45
49
  this._canShort = canShort;
46
50
  this._canSwitchDirection = canSwitchDirection;
@@ -63,6 +67,16 @@ module.exports = (() => {
63
67
  return this._alternateDescription;
64
68
  }
65
69
 
70
+ /**
71
+ * Indicates if the position can exist without any associated transactions.
72
+ *
73
+ * @public
74
+ * @returns {Boolean}
75
+ */
76
+ get canExistEmpty() {
77
+ return this._canExistEmpty;
78
+ }
79
+
66
80
  /**
67
81
  * Indicates if the instrument type allows automatic reinvestment.
68
82
  *
@@ -243,10 +257,10 @@ module.exports = (() => {
243
257
  }
244
258
  }
245
259
 
246
- const cash = new InstrumentType('CASH', 'cash', 'Cash', false, false, true, false, false, false, false, false, (instrument) => `BARCHART-${instrument.type.code}-${instrument.currency.code}`);
247
- const equity = new InstrumentType('EQUITY', 'equity', 'Equities', true, true, false, true, true, true, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
248
- const fund = new InstrumentType('FUND', 'mutual fund', 'Funds', true, false, false, true, true, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
249
- const other = new InstrumentType('OTHER', 'other', 'Other', false, false, false, false, false, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${uuid.v4()}`);
260
+ const cash = new InstrumentType('CASH', 'cash', 'Cash', true, false, false, true, false, false, false, false, false, (instrument) => `BARCHART-${instrument.type.code}-${instrument.currency.code}`);
261
+ const equity = new InstrumentType('EQUITY', 'equity', 'Equities', false, true, true, false, true, true, true, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
262
+ const fund = new InstrumentType('FUND', 'mutual fund', 'Funds', false, true, false, false, true, true, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
263
+ const other = new InstrumentType('OTHER', 'other', 'Other', false, false, false, false, false, false, false, true, true, (instrument) => `BARCHART-${instrument.type.code}-${uuid.v4()}`);
250
264
 
251
265
  const map = { };
252
266
 
@@ -2645,6 +2659,9 @@ module.exports = (() => {
2645
2659
  this._dataActual.marketChange = null;
2646
2660
  this._dataActual.marketChangePercent = null;
2647
2661
  this._dataActual.cashTotal = null;
2662
+ this._dataActual.periodDivisorCurrent = null;
2663
+ this._dataActual.periodDivisorPrevious = null;
2664
+ this._dataActual.periodDivisorPrevious2 = null;
2648
2665
 
2649
2666
  this._dataFormat.currentPrice = null;
2650
2667
  this._dataFormat.basis = null;
@@ -2676,33 +2693,25 @@ module.exports = (() => {
2676
2693
 
2677
2694
  this._dataActual.periodPrice = null;
2678
2695
  this._dataActual.periodPricePrevious = null;
2679
- this._dataActual.periodRealized = null;
2680
- this._dataActual.periodRealizedPrevious = null;
2681
- this._dataActual.periodRealizedPrevious2 = null;
2682
- this._dataActual.periodRealizedBasis = null;
2683
- this._dataActual.periodRealizedBasisPrevious = null;
2684
- this._dataActual.periodRealizedBasisPrevious2 = null;
2685
- this._dataActual.periodUnrealized = null;
2686
- this._dataActual.periodUnrealizedPrevious = null;
2687
- this._dataActual.periodUnrealizedPrevious2 = null;
2688
- this._dataActual.periodUnrealizedBasis = null;
2689
- this._dataActual.periodUnrealizedBasisPrevious = null;
2690
- this._dataActual.periodUnrealizedBasisPrevious2 = null;
2691
- this._dataActual.periodIncome = null;
2692
2696
 
2693
2697
  this._dataFormat.periodPrice = null;
2694
2698
  this._dataFormat.periodPricePrevious = null;
2699
+
2700
+ this._dataActual.periodIncome = null;
2701
+ this._dataActual.periodRealized = null;
2702
+ this._dataActual.periodUnrealized = null;
2703
+
2704
+ this._dataFormat.periodIncome = null;
2695
2705
  this._dataFormat.periodRealized = null;
2696
2706
  this._dataFormat.periodUnrealized = null;
2697
- this._dataFormat.periodIncome = null;
2698
2707
 
2699
2708
  this._dataActual.periodPercent = null;
2700
- this._dataActual.periodPreviousPercent = null;
2701
- this._dataActual.periodPrevious2Percent = null;
2709
+ this._dataActual.periodPercentPrevious = null;
2710
+ this._dataActual.periodPercentPrevious2 = null;
2702
2711
 
2703
2712
  this._dataFormat.periodPercent = null;
2704
- this._dataFormat.periodPreviousPercent = null;
2705
- this._dataFormat.periodPrevious2Percent = null;
2713
+ this._dataFormat.periodPercentPrevious = null;
2714
+ this._dataFormat.periodPercentPrevious2 = null;
2706
2715
 
2707
2716
  this._items.forEach((item) => {
2708
2717
  bindItem.call(this, item);
@@ -3194,9 +3203,9 @@ module.exports = (() => {
3194
3203
  updates.realized = updates.realized.add(translate(item, item.data.realized));
3195
3204
  updates.unrealized = updates.unrealized.add(translate(item, item.data.unrealized));
3196
3205
  updates.income = updates.income.add(translate(item, item.data.income));
3197
- updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
3198
- updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
3199
- updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
3206
+ updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.periodGain));
3207
+ updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.periodGainPrevious));
3208
+ updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.periodGainPrevious2));
3200
3209
  updates.marketPrevious = updates.marketPrevious.add(translate(item, item.data.marketPrevious));
3201
3210
  updates.marketPrevious2 = updates.marketPrevious2.add(translate(item, item.data.marketPrevious2));
3202
3211
 
@@ -3208,6 +3217,10 @@ module.exports = (() => {
3208
3217
  updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
3209
3218
  }
3210
3219
 
3220
+ updates.periodDivisorCurrent = updates.periodDivisorCurrent.add(translate(item, item.data.periodDivisor));
3221
+ updates.periodDivisorPrevious = updates.periodDivisorPrevious.add(translate(item, item.data.periodDivisorPrevious));
3222
+ updates.periodDivisorPrevious2 = updates.periodDivisorPrevious2.add(translate(item, item.data.periodDivisorPrevious2));
3223
+
3211
3224
  return updates;
3212
3225
  }, {
3213
3226
  basis: Decimal.ZERO,
@@ -3223,6 +3236,9 @@ module.exports = (() => {
3223
3236
  periodUnrealized: Decimal.ZERO,
3224
3237
  periodIncome: Decimal.ZERO,
3225
3238
  cashTotal: Decimal.ZERO,
3239
+ periodDivisorCurrent: Decimal.ZERO,
3240
+ periodDivisorPrevious: Decimal.ZERO,
3241
+ periodDivisorPrevious2: Decimal.ZERO
3226
3242
  });
3227
3243
 
3228
3244
  actual.basis = updates.basis;
@@ -3238,12 +3254,16 @@ module.exports = (() => {
3238
3254
  actual.periodUnrealized = updates.periodUnrealized;
3239
3255
  actual.periodIncome = updates.periodIncome;
3240
3256
  actual.cashTotal = updates.cashTotal;
3257
+ actual.periodDivisorCurrent = updates.periodDivisorCurrent;
3258
+ actual.periodDivisorPrevious = updates.periodDivisorPrevious;
3259
+ actual.periodDivisorPrevious2 = updates.periodDivisorPrevious2;
3241
3260
 
3242
3261
  format.basis = formatCurrency(actual.basis, currency);
3243
3262
  format.realized = formatCurrency(actual.realized, currency);
3244
3263
  format.unrealized = formatCurrency(actual.unrealized, currency);
3245
3264
  format.income = formatCurrency(actual.income, currency);
3246
3265
  format.summaryTotalCurrent = formatCurrency(updates.summaryTotalCurrent, currency);
3266
+ format.summaryTotalCurrentNegative = updates.summaryTotalCurrent.getIsNegative();
3247
3267
  format.summaryTotalPrevious = formatCurrency(updates.summaryTotalPrevious, currency);
3248
3268
  format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
3249
3269
  format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
@@ -3278,25 +3298,9 @@ module.exports = (() => {
3278
3298
  format.periodPrice = formatCurrency(actual.periodPrice, currency);
3279
3299
  format.periodPricePrevious = formatCurrency(actual.periodPricePrevious, currency);
3280
3300
 
3281
- actual.periodRealized = item.data.periodRealized;
3282
- actual.periodRealizedPrevious = item.data.periodRealizedPrevious;
3283
- actual.periodRealizedPrevious2 = item.data.periodRealizedPrevious2;
3284
-
3285
- actual.periodRealizedBasis = item.data.periodRealizedBasis;
3286
- actual.periodRealizedBasisPrevious = item.data.periodRealizedBasisPrevious;
3287
- actual.periodRealizedBasisPrevious2 = item.data.periodRealizedBasisPrevious2;
3288
-
3289
- actual.periodUnrealized = item.data.periodUnrealized;
3290
- actual.periodUnrealizedPrevious = item.data.periodUnrealizedPrevious;
3291
- actual.periodUnrealizedPrevious2 = item.data.periodUnrealizedPrevious2;
3292
-
3293
- actual.periodUnrealizedBasis = item.data.periodUnrealizedBasis;
3294
- actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
3295
- actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
3296
-
3297
- actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
3298
- actual.periodPercentPrevious = calculatePeriodPercent(actual.summaryTotalPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedBasisPrevious);
3299
- actual.periodPercentPrevious2 = calculatePeriodPercent(actual.summaryTotalPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedBasisPrevious2);
3301
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodDivisorCurrent);
3302
+ actual.periodPercentPrevious = calculatePeriodPercent(actual.summaryTotalPrevious, actual.periodDivisorPrevious);
3303
+ actual.periodPercentPrevious2 = calculatePeriodPercent(actual.summaryTotalPrevious2, actual.periodDivisorPrevious2);
3300
3304
 
3301
3305
  format.periodPercent = formatPercent(actual.periodPercent, 2);
3302
3306
  format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
@@ -3355,7 +3359,7 @@ module.exports = (() => {
3355
3359
  updates.marketAbsolute = updates.marketAbsolute.add(translate(item, item.data.marketAbsolute));
3356
3360
  updates.unrealized = updates.unrealized.add(translate(item, item.data.unrealized));
3357
3361
  updates.unrealizedToday = updates.unrealizedToday.add(translate(item, item.data.unrealizedToday));
3358
- updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
3362
+ updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.periodGain));
3359
3363
 
3360
3364
  return updates;
3361
3365
  }, {
@@ -3373,7 +3377,7 @@ module.exports = (() => {
3373
3377
  marketDirection: { up: item.data.marketChange.getIsPositive(), down: item.data.marketChange.getIsNegative() },
3374
3378
  unrealized: actual.unrealized.add(translate(item, item.data.unrealizedChange)),
3375
3379
  unrealizedToday: actual.unrealizedToday.add(translate(item, item.data.unrealizedTodayChange)),
3376
- summaryTotalCurrent: actual.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrentChange))
3380
+ summaryTotalCurrent: actual.summaryTotalCurrent.add(translate(item, item.data.periodGainChange))
3377
3381
  };
3378
3382
  }
3379
3383
 
@@ -3429,7 +3433,7 @@ module.exports = (() => {
3429
3433
  if (group.single && item) {
3430
3434
  actual.periodUnrealized = item.data.periodUnrealized;
3431
3435
 
3432
- actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
3436
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodDivisorCurrent);
3433
3437
  format.periodPercent = formatPercent(actual.periodPercent, 2);
3434
3438
  }
3435
3439
  }
@@ -3490,11 +3494,8 @@ module.exports = (() => {
3490
3494
  }
3491
3495
  }
3492
3496
 
3493
- function calculatePeriodPercent(periodSummaryTotal, realizedBasis, unrealizedBasis) {
3494
- const numerator = periodSummaryTotal;
3495
- const denominator = realizedBasis.add(unrealizedBasis);
3496
-
3497
- return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
3497
+ function calculatePeriodPercent(periodSummaryTotal, periodDivisor) {
3498
+ return periodDivisor.getIsZero() ? Decimal.ZERO : periodSummaryTotal.divide(periodDivisor);
3498
3499
  }
3499
3500
 
3500
3501
  const unchanged = { up: false, down: false };
@@ -3567,12 +3568,6 @@ module.exports = (() => {
3567
3568
  this._data.unrealized = null;
3568
3569
  this._data.unrealizedChange = null;
3569
3570
 
3570
- this._data.summaryTotalCurrent = null;
3571
- this._data.summaryTotalCurrentChange = null;
3572
-
3573
- this._data.summaryTotalPrevious = null;
3574
- this._data.summaryTotalPrevious2 = null;
3575
-
3576
3571
  this._data.marketPrevious = null;
3577
3572
  this._data.marketPrevious2 = null;
3578
3573
 
@@ -3583,26 +3578,24 @@ module.exports = (() => {
3583
3578
  this._data.income = null;
3584
3579
  this._data.basisPrice = null;
3585
3580
 
3581
+ this._data.periodIncome = null;
3586
3582
  this._data.periodRealized = null;
3587
- this._data.periodRealizedPrevious = null;
3588
- this._data.periodRealizedPrevious2 = null;
3583
+ this._data.periodUnrealized = null;
3589
3584
 
3590
- this._data.periodRealizedBasis = null;
3591
- this._data.periodRealizedBasisPrevious = null;
3592
- this._data.periodRealizedBasisPrevious2 = null;
3585
+ this._data.periodPrice = null;
3586
+ this._data.periodPricePrevious = null;
3593
3587
 
3594
- this._data.periodUnrealized = null;
3595
- this._data.periodUnrealizedPrevious = null;
3596
- this._data.periodUnrealizedPrevious2 = null;
3588
+ this._data.periodGain = null;
3589
+ this._data.periodGainChange = null;
3597
3590
 
3598
- this._data.periodUnrealizedBasis = null;
3599
- this._data.periodUnrealizedBasisPrevious = null;
3600
- this._data.periodUnrealizedBasisPrevious2 = null;
3591
+ this._data.periodGainPrevious = null;
3592
+ this._data.periodGainPrevious2 = null;
3601
3593
 
3602
- this._data.periodIncome = null;
3594
+ this._data.periodDivisor = null;
3595
+ this._data.periodDivisorChange = null;
3603
3596
 
3604
- this._data.periodPrice = null;
3605
- this._data.periodPricePrevious = null;
3597
+ this._data.periodDivisorPrevious = null;
3598
+ this._data.periodDivisorPrevious2 = null;
3606
3599
 
3607
3600
  this._data.newsExists = false;
3608
3601
  this._data.fundamental = { };
@@ -3922,31 +3915,21 @@ module.exports = (() => {
3922
3915
 
3923
3916
  data.income = snapshot.income;
3924
3917
 
3925
- data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary, previousSummary1);
3926
- data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
3927
- data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
3928
-
3929
3918
  data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
3930
3919
  data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
3931
3920
  data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
3932
3921
 
3933
- data.periodRealized = calculatePeriodRealized(item.currentSummary, previousSummary1);
3934
- data.periodRealizedPrevious = calculatePeriodRealized(previousSummary1, previousSummary2);
3935
- data.periodRealizedPrevious2 = calculatePeriodRealized(previousSummary2, previousSummary3);
3936
-
3937
- data.periodRealizedBasis = calculatePeriodRealizedBasis(item.currentSummary, previousSummary1);
3938
- data.periodRealizedBasisPrevious = calculatePeriodRealizedBasis(previousSummary1, previousSummary2);
3939
- data.periodRealizedBasisPrevious2 = calculatePeriodRealizedBasis(previousSummary2, previousSummary3);
3940
-
3941
- data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary1);
3942
- data.periodUnrealizedPrevious = calculatePeriodUnrealized(previousSummary1, previousSummary2);
3943
- data.periodUnrealizedPrevious2 = calculatePeriodUnrealized(previousSummary2, previousSummary3);
3922
+ data.periodIncome = currentSummary !== null ? currentSummary.period.income : Decimal.ZERO;
3923
+ data.periodRealized = currentSummary !== null ? currentSummary.period.realized : Decimal.ZERO;
3924
+ data.periodUnrealized = currentSummary !== null ? currentSummary.period.unrealized : Decimal.ZERO;
3944
3925
 
3945
- data.periodUnrealizedBasis = calculatePeriodUnrealizedBasis(item.currentSummary, previousSummary1);
3946
- data.periodUnrealizedBasisPrevious = calculatePeriodUnrealizedBasis(previousSummary1, previousSummary2);
3947
- data.periodUnrealizedBasisPrevious2 = calculatePeriodUnrealizedBasis(previousSummary2, previousSummary3);
3948
-
3949
- data.periodIncome = calculatePeriodIncome(item.currentSummary, previousSummary1);
3926
+ data.periodGain = calculatePeriodGain(currentSummary, previousSummary1);
3927
+ data.periodGainPrevious = calculatePeriodGain(previousSummary1, previousSummary2);
3928
+ data.periodGainPrevious2 = calculatePeriodGain(previousSummary2, previousSummary3);
3929
+
3930
+ data.periodDivisor = calculatePeriodDivisor(currentSummary, previousSummary1);
3931
+ data.periodDivisorPrevious = calculatePeriodDivisor(previousSummary1, previousSummary2);
3932
+ data.periodDivisorPrevious2 = calculatePeriodDivisor(previousSummary2, previousSummary3);
3950
3933
 
3951
3934
  if (snapshot.open.getIsZero()) {
3952
3935
  data.basisPrice = Decimal.ZERO;
@@ -3970,7 +3953,6 @@ module.exports = (() => {
3970
3953
  function calculatePriceData(item, price) {
3971
3954
  const position = item.position;
3972
3955
  const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
3973
- const previousSummaries = item.previousSummaries;
3974
3956
 
3975
3957
  const data = item._data;
3976
3958
 
@@ -4031,10 +4013,9 @@ module.exports = (() => {
4031
4013
  data.unrealizedTodayChange = unrealizedTodayChange;
4032
4014
 
4033
4015
  const currentSummary = item.currentSummary;
4016
+ const previousSummary = getPreviousSummary(item.previousSummaries, 1);
4034
4017
 
4035
4018
  if (currentSummary && position.instrument.type !== InstrumentType.CASH) {
4036
- const previousSummary = getPreviousSummary(previousSummaries, 1);
4037
-
4038
4019
  let priceToUse;
4039
4020
 
4040
4021
  if (price) {
@@ -4048,8 +4029,6 @@ module.exports = (() => {
4048
4029
  }
4049
4030
 
4050
4031
  if (priceToUse !== null) {
4051
- const period = currentSummary.period;
4052
-
4053
4032
  let unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
4054
4033
  let unrealizedChange;
4055
4034
 
@@ -4059,115 +4038,79 @@ module.exports = (() => {
4059
4038
  unrealizedChange = Decimal.ZERO;
4060
4039
  }
4061
4040
 
4062
- let summaryTotalCurrent = period.realized.add(period.income).add(unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
4063
- let summaryTotalCurrentChange;
4041
+ data.unrealized = unrealized;
4042
+ data.unrealizedChange = unrealizedChange;
4043
+
4044
+ let periodGain = calculatePeriodGain(currentSummary, previousSummary, priceToUse);
4045
+ let periodGainChange;
4064
4046
 
4065
- if (data.summaryTotalCurrent !== null) {
4066
- summaryTotalCurrentChange = summaryTotalCurrent.subtract(data.summaryTotalCurrent);
4047
+ if (data.periodGain !== null) {
4048
+ periodGainChange = periodGain.subtract(data.periodGain);
4067
4049
  } else {
4068
- summaryTotalCurrentChange = Decimal.ZERO;
4050
+ periodGainChange = Decimal.ZERO;
4069
4051
  }
4070
4052
 
4071
- data.summaryTotalCurrent = summaryTotalCurrent;
4072
- data.summaryTotalCurrentChange = summaryTotalCurrentChange;
4073
-
4074
- data.unrealized = unrealized;
4075
- data.unrealizedChange = unrealizedChange;
4076
-
4077
- data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary, data.unrealized);
4078
- data.periodUnrealizedChange = unrealizedChange;
4053
+ data.periodGain = periodGain;
4054
+ data.periodGainChange = periodGainChange;
4079
4055
  } else {
4080
- data.summaryTotalCurrentChange = Decimal.ZERO;
4081
-
4082
4056
  data.unrealized = Decimal.ZERO;
4083
4057
  data.unrealizedChange = Decimal.ZERO;
4084
4058
 
4085
- data.periodUnrealizedChange = Decimal.ZERO;
4059
+ data.periodGainChange = Decimal.ZERO;
4086
4060
  }
4087
4061
  } else {
4088
- data.summaryTotalCurrentChange = Decimal.ZERO;
4089
-
4090
4062
  data.unrealized = Decimal.ZERO;
4091
4063
  data.unrealizedChange = Decimal.ZERO;
4092
- }
4093
- }
4094
-
4095
- function calculateSummaryTotal(currentSummary, previousSummary) {
4096
- let returnRef;
4097
4064
 
4098
- if (currentSummary) {
4099
- const period = currentSummary.period;
4100
-
4101
- returnRef = period.realized.add(period.income).add(period.unrealized).subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
4102
- } else {
4103
- returnRef = Decimal.ZERO;
4065
+ data.periodGainChange = Decimal.ZERO;
4104
4066
  }
4105
-
4106
- return returnRef;
4107
4067
  }
4108
4068
 
4109
- function calculatePeriodRealized(currentSummary, previousSummary) {
4069
+ function calculatePeriodGain(currentSummary, previousSummary, overridePrice) {
4110
4070
  let returnRef;
4111
4071
 
4112
4072
  if (currentSummary) {
4113
- const period = currentSummary.period;
4073
+ let startValue;
4114
4074
 
4115
- returnRef = period.realized;
4116
- } else {
4117
- returnRef = Decimal.ZERO;
4118
- }
4075
+ if (previousSummary) {
4076
+ startValue = previousSummary.end.value;
4077
+ } else {
4078
+ startValue = Decimal.ZERO;
4079
+ }
4119
4080
 
4120
- return returnRef;
4121
- }
4081
+ let endValue;
4122
4082
 
4123
- function calculatePeriodRealizedBasis(currentSummary, previousSummary) {
4124
- let returnRef;
4083
+ if (overridePrice) {
4084
+ endValue = currentSummary.end.open.multiply(overridePrice);
4085
+ } else {
4086
+ endValue = currentSummary.end.value;
4087
+ }
4125
4088
 
4126
- if (currentSummary) {
4127
- const period = currentSummary.period;
4089
+ const valueChange = endValue.subtract(startValue);
4090
+ const tradeChange = currentSummary.period.sells.subtract(currentSummary.period.buys);
4091
+ const incomeChange = currentSummary.period.income;
4128
4092
 
4129
- returnRef = period.sells.subtract(calculatePeriodRealized(currentSummary, previousSummary));
4093
+ returnRef = valueChange.add(tradeChange).add(incomeChange);
4130
4094
  } else {
4131
4095
  returnRef = Decimal.ZERO;
4132
4096
  }
4133
4097
 
4134
4098
  return returnRef;
4135
4099
  }
4136
-
4137
- function calculatePeriodUnrealized(currentSummary, previousSummary, override) {
4138
- let returnRef;
4139
-
4140
- if (currentSummary) {
4141
- const period = currentSummary.period;
4142
- const unrealized = override || period.unrealized;
4143
4100
 
4144
- returnRef = unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
4145
- } else {
4146
- returnRef = Decimal.ZERO;
4147
- }
4148
-
4149
- return returnRef;
4150
- }
4151
-
4152
- function calculatePeriodUnrealizedBasis(currentSummary, previousSummary) {
4101
+ function calculatePeriodDivisor(currentSummary, previousSummary) {
4153
4102
  let returnRef;
4154
4103
 
4155
4104
  if (currentSummary) {
4156
- returnRef = currentSummary.end.basis.absolute();
4157
- } else {
4158
- returnRef = Decimal.ZERO;
4159
- }
4160
-
4161
- return returnRef;
4162
- }
4163
-
4164
- function calculatePeriodIncome(currentSummary, previousSummary) {
4165
- let returnRef;
4105
+ let startValue;
4166
4106
 
4167
- if (currentSummary) {
4168
- const period = currentSummary.period;
4107
+ if (previousSummary) {
4108
+ startValue = previousSummary.end.value;
4109
+ } else {
4110
+ startValue = Decimal.ZERO;
4111
+ }
4169
4112
 
4170
- returnRef = period.income;
4113
+ returnRef = startValue.add(currentSummary.period.buys);
4171
4114
  } else {
4172
4115
  returnRef = Decimal.ZERO;
4173
4116
  }