@barchart/portfolio-api-common 1.2.88 → 1.2.92
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.
- package/lib/data/PositionSummaryFrame.js +23 -0
- package/lib/processing/PositionContainer.js +10 -10
- package/lib/processing/PositionGroup.js +40 -5
- package/lib/processing/PositionItem.js +13 -3
- package/lib/serialization/PositionSummaryDefinitionSchema.js +58 -0
- package/lib/serialization/PositionSummarySchema.js +1 -2
- package/package.json +1 -1
- package/test/SpecRunner.js +86 -18
|
@@ -86,6 +86,19 @@ module.exports = (() => {
|
|
|
86
86
|
return this._rangeCalculator(getFilteredTransactions(transactions));
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Returns the range which contains a given date and all subsequent ranges.
|
|
91
|
+
*
|
|
92
|
+
* @public
|
|
93
|
+
* @param {Day} date
|
|
94
|
+
* @return {Array.<PositionSummaryRange>}
|
|
95
|
+
*/
|
|
96
|
+
getRangesFromDate(date) {
|
|
97
|
+
const transaction = { date: date, snapshot: { open: Decimal.ONE } };
|
|
98
|
+
|
|
99
|
+
return this.getRanges([ transaction ]);
|
|
100
|
+
}
|
|
101
|
+
|
|
89
102
|
/**
|
|
90
103
|
* Returns the start date for a frame, a given number of periods ago.
|
|
91
104
|
*
|
|
@@ -158,6 +171,16 @@ module.exports = (() => {
|
|
|
158
171
|
* @property {Day} end
|
|
159
172
|
*/
|
|
160
173
|
|
|
174
|
+
/**
|
|
175
|
+
* The start and and date for a {@link PositionSummaryFrame} along with the frame type.
|
|
176
|
+
*
|
|
177
|
+
* @typedef PositionSummaryDefinition
|
|
178
|
+
* @type {Object}
|
|
179
|
+
* @property {Day} start
|
|
180
|
+
* @property {Day} end
|
|
181
|
+
* @property {PositionSummaryFrame} frame
|
|
182
|
+
*/
|
|
183
|
+
|
|
161
184
|
function getRange(start, end) {
|
|
162
185
|
return {
|
|
163
186
|
start: start,
|
|
@@ -42,7 +42,7 @@ module.exports = (() => {
|
|
|
42
42
|
* @param {Array.<Object>} portfolios - The portfolios.
|
|
43
43
|
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
44
44
|
* @param {Array.<Object>} summaries - The positions summaries (for all of the positions).
|
|
45
|
-
* @param {PositionSummaryFrame} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
45
|
+
* @param {PositionSummaryFrame=} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
46
46
|
*/
|
|
47
47
|
class PositionContainer {
|
|
48
48
|
constructor(definitions, portfolios, positions, summaries, frame) {
|
|
@@ -284,12 +284,12 @@ module.exports = (() => {
|
|
|
284
284
|
|
|
285
285
|
const existingBarchartSymbols = this.getPositionSymbols(false);
|
|
286
286
|
|
|
287
|
-
let
|
|
287
|
+
let similarPositionItem;
|
|
288
288
|
|
|
289
|
-
if (
|
|
290
|
-
|
|
289
|
+
if (extractSymbolForBarchart(position)) {
|
|
290
|
+
similarPositionItem = this._items.find(item => extractSymbolForBarchart(item.position) === extractSymbolForBarchart(position)) || null;
|
|
291
291
|
} else {
|
|
292
|
-
|
|
292
|
+
similarPositionItem = null;
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
removePositionItem.call(this, this._items.find(item => item.position.position === position.position));
|
|
@@ -339,13 +339,13 @@ module.exports = (() => {
|
|
|
339
339
|
this._positionSymbolAddedEvent.fire(addedBarchartSymbol);
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
if (
|
|
343
|
-
if (
|
|
344
|
-
item.setQuote(
|
|
342
|
+
if (similarPositionItem !== null) {
|
|
343
|
+
if (similarPositionItem.previousQuote) {
|
|
344
|
+
item.setQuote(similarPositionItem.previousQuote);
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
-
if (
|
|
348
|
-
item.setQuote(
|
|
347
|
+
if (similarPositionItem.quote) {
|
|
348
|
+
item.setQuote(similarPositionItem.quote);
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
351
|
|
|
@@ -130,6 +130,10 @@ module.exports = (() => {
|
|
|
130
130
|
this._dataActual.summaryTotalCurrent = null;
|
|
131
131
|
this._dataActual.summaryTotalPrevious = null;
|
|
132
132
|
this._dataActual.summaryTotalPrevious2 = null;
|
|
133
|
+
this._dataActual.endingPrevious = null;
|
|
134
|
+
this._dataActual.endingPrevious2 = null;
|
|
135
|
+
this._dataActual.endingChange = null;
|
|
136
|
+
this._dataActual.endingChangePercent = null;
|
|
133
137
|
this._dataActual.cashTotal = null;
|
|
134
138
|
|
|
135
139
|
this._dataFormat.currentPrice = null;
|
|
@@ -153,6 +157,10 @@ module.exports = (() => {
|
|
|
153
157
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
154
158
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
155
159
|
this._dataFormat.summaryTotalPrevious2Negative = false;
|
|
160
|
+
this._dataFormat.endingPrevious = null;
|
|
161
|
+
this._dataFormat.endingPrevious2 = null;
|
|
162
|
+
this._dataFormat.endingChange = null;
|
|
163
|
+
this._dataFormat.endingChangePercent = null;
|
|
156
164
|
this._dataFormat.cashTotal = null;
|
|
157
165
|
this._dataFormat.portfolioType = null;
|
|
158
166
|
|
|
@@ -388,8 +396,6 @@ module.exports = (() => {
|
|
|
388
396
|
return;
|
|
389
397
|
}
|
|
390
398
|
|
|
391
|
-
const descriptionSelector = this._definition.descriptionSelector;
|
|
392
|
-
|
|
393
399
|
this._description = PositionLevelDefinition.getDescriptionForPortfolioGroup(portfolio);
|
|
394
400
|
|
|
395
401
|
this._dataActual.description = this._description;
|
|
@@ -634,7 +640,7 @@ module.exports = (() => {
|
|
|
634
640
|
const translate = (item, value) => {
|
|
635
641
|
let translated;
|
|
636
642
|
|
|
637
|
-
if (item.currency !== currency) {
|
|
643
|
+
if (item.currency !== currency && !value.getIsZero()) {
|
|
638
644
|
translated = Rate.convert(value, item.currency, currency, ...rates);
|
|
639
645
|
} else {
|
|
640
646
|
translated = value;
|
|
@@ -651,6 +657,8 @@ module.exports = (() => {
|
|
|
651
657
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
|
|
652
658
|
updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
|
|
653
659
|
updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
|
|
660
|
+
updates.endingPrevious = updates.endingPrevious.add(translate(item, item.data.endingPrevious));
|
|
661
|
+
updates.endingPrevious2 = updates.endingPrevious2.add(translate(item, item.data.endingPrevious2));
|
|
654
662
|
|
|
655
663
|
if (item.position.instrument.type === InstrumentType.CASH) {
|
|
656
664
|
updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
|
|
@@ -665,6 +673,8 @@ module.exports = (() => {
|
|
|
665
673
|
summaryTotalCurrent: Decimal.ZERO,
|
|
666
674
|
summaryTotalPrevious: Decimal.ZERO,
|
|
667
675
|
summaryTotalPrevious2: Decimal.ZERO,
|
|
676
|
+
endingPrevious: Decimal.ZERO,
|
|
677
|
+
endingPrevious2: Decimal.ZERO,
|
|
668
678
|
cashTotal: Decimal.ZERO
|
|
669
679
|
});
|
|
670
680
|
|
|
@@ -675,6 +685,8 @@ module.exports = (() => {
|
|
|
675
685
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
676
686
|
actual.summaryTotalPrevious = updates.summaryTotalPrevious;
|
|
677
687
|
actual.summaryTotalPrevious2 = updates.summaryTotalPrevious2;
|
|
688
|
+
actual.endingPrevious = updates.endingPrevious;
|
|
689
|
+
actual.endingPrevious2 = updates.endingPrevious2;
|
|
678
690
|
actual.cashTotal = updates.cashTotal;
|
|
679
691
|
|
|
680
692
|
format.basis = formatCurrency(actual.basis, currency);
|
|
@@ -686,6 +698,8 @@ module.exports = (() => {
|
|
|
686
698
|
format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
|
|
687
699
|
format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
|
|
688
700
|
format.summaryTotalPrevious2Negative = updates.summaryTotalPrevious2.getIsNegative();
|
|
701
|
+
format.endingPrevious = formatCurrency(updates.endingPrevious, currency);
|
|
702
|
+
format.endingPrevious2 = formatCurrency(updates.endingPrevious2, currency);
|
|
689
703
|
format.cashTotal = formatCurrency(updates.cashTotal, currency);
|
|
690
704
|
|
|
691
705
|
calculateUnrealizedPercent(group);
|
|
@@ -735,7 +749,7 @@ module.exports = (() => {
|
|
|
735
749
|
const translate = (item, value) => {
|
|
736
750
|
let translated;
|
|
737
751
|
|
|
738
|
-
if (item.currency !== currency) {
|
|
752
|
+
if (item.currency !== currency && !value.getIsZero()) {
|
|
739
753
|
translated = Rate.convert(value, item.currency, currency, ...rates);
|
|
740
754
|
} else {
|
|
741
755
|
translated = value;
|
|
@@ -782,7 +796,25 @@ module.exports = (() => {
|
|
|
782
796
|
actual.unrealizedToday = updates.unrealizedToday;
|
|
783
797
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
784
798
|
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
785
|
-
|
|
799
|
+
|
|
800
|
+
let endingChange = updates.market.subtract(actual.endingPrevious);
|
|
801
|
+
let endingChangePercent;
|
|
802
|
+
|
|
803
|
+
if (actual.endingPrevious.getIsZero()) {
|
|
804
|
+
if (endingChange.getIsPositive()) {
|
|
805
|
+
endingChangePercent = Decimal.ONE;
|
|
806
|
+
} else if (endingChange.getIsNegative()) {
|
|
807
|
+
endingChangePercent = Decimal.NEGATIVE_ONE;
|
|
808
|
+
} else {
|
|
809
|
+
endingChangePercent = Decimal.ZERO;
|
|
810
|
+
}
|
|
811
|
+
} else {
|
|
812
|
+
endingChangePercent = endingChange.divide(actual.endingPrevious);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
actual.endingChange = endingChange;
|
|
816
|
+
actual.endingChangePercent = endingChangePercent;
|
|
817
|
+
|
|
786
818
|
format.market = formatCurrency(actual.market, currency);
|
|
787
819
|
|
|
788
820
|
if (updates.marketDirection.up || updates.marketDirection.down) {
|
|
@@ -802,6 +834,9 @@ module.exports = (() => {
|
|
|
802
834
|
format.total = formatCurrency(actual.total, currency);
|
|
803
835
|
format.totalNegative = actual.total.getIsNegative();
|
|
804
836
|
|
|
837
|
+
format.endingChange = formatCurrency(actual.endingChange, currency);
|
|
838
|
+
format.endingChangePercent = formatPercent(actual.endingChangePercent, 2);
|
|
839
|
+
|
|
805
840
|
calculateUnrealizedPercent(group);
|
|
806
841
|
}
|
|
807
842
|
|
|
@@ -65,6 +65,9 @@ module.exports = (() => {
|
|
|
65
65
|
this._data.summaryTotalPrevious = null;
|
|
66
66
|
this._data.summaryTotalPrevious2 = null;
|
|
67
67
|
|
|
68
|
+
this._data.endingPrevious = null;
|
|
69
|
+
this._data.endingPrevious2 = null;
|
|
70
|
+
|
|
68
71
|
this._data.realized = null;
|
|
69
72
|
this._data.income = null;
|
|
70
73
|
this._data.basisPrice = null;
|
|
@@ -380,9 +383,16 @@ module.exports = (() => {
|
|
|
380
383
|
|
|
381
384
|
data.income = snapshot.income;
|
|
382
385
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
+
const previousSummary1 = getPreviousSummary(previousSummaries, 1);
|
|
387
|
+
const previousSummary2 = getPreviousSummary(previousSummaries, 2);
|
|
388
|
+
const previousSummary3 = getPreviousSummary(previousSummaries, 3);
|
|
389
|
+
|
|
390
|
+
data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary, previousSummary1);
|
|
391
|
+
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
392
|
+
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
393
|
+
|
|
394
|
+
data.endingPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
395
|
+
data.endingPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
386
396
|
|
|
387
397
|
if (snapshot.open.getIsZero()) {
|
|
388
398
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const DataType = require('@barchart/common-js/serialization/json/DataType'),
|
|
2
|
+
Enum = require('@barchart/common-js/lang/Enum'),
|
|
3
|
+
Schema = require('@barchart/common-js/serialization/json/Schema'),
|
|
4
|
+
SchemaBuilder = require('@barchart/common-js/serialization/json/builders/SchemaBuilder');
|
|
5
|
+
|
|
6
|
+
const PositionSummaryFrame = require('./../data/PositionSummaryFrame');
|
|
7
|
+
|
|
8
|
+
module.exports = (() => {
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The schemas which can be used to represent position summary objects.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
* @extends {Enum}
|
|
16
|
+
*/
|
|
17
|
+
class PositionSummaryDefinitionSchema extends Enum {
|
|
18
|
+
constructor(schema) {
|
|
19
|
+
super(schema.name, schema.name);
|
|
20
|
+
|
|
21
|
+
this._schema = schema;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The actual {@link Schema}.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
* @returns {Schema}
|
|
29
|
+
*/
|
|
30
|
+
get schema() {
|
|
31
|
+
return this._schema;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The complete position summary definition schema.
|
|
36
|
+
*
|
|
37
|
+
* @static
|
|
38
|
+
* @public
|
|
39
|
+
* @returns {PositionSummaryDefinitionSchema}
|
|
40
|
+
*/
|
|
41
|
+
static get COMPLETE() {
|
|
42
|
+
return complete;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toString() {
|
|
46
|
+
return '[PositionSummaryDefinitionSchema]';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const complete = new PositionSummaryDefinitionSchema(SchemaBuilder.withName('complete')
|
|
51
|
+
.withField('start', DataType.DAY)
|
|
52
|
+
.withField('end', DataType.DAY)
|
|
53
|
+
.withField('frame', DataType.forEnum(PositionSummaryFrame, 'PositionSummaryFrame'))
|
|
54
|
+
.schema
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return PositionSummaryDefinitionSchema;
|
|
58
|
+
})();
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
DataType = require('@barchart/common-js/serialization/json/DataType'),
|
|
1
|
+
const DataType = require('@barchart/common-js/serialization/json/DataType'),
|
|
3
2
|
Enum = require('@barchart/common-js/lang/Enum'),
|
|
4
3
|
Schema = require('@barchart/common-js/serialization/json/Schema'),
|
|
5
4
|
SchemaBuilder = require('@barchart/common-js/serialization/json/builders/SchemaBuilder');
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -477,6 +477,19 @@ module.exports = (() => {
|
|
|
477
477
|
return this._rangeCalculator(getFilteredTransactions(transactions));
|
|
478
478
|
}
|
|
479
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Returns the range which contains a given date and all subsequent ranges.
|
|
482
|
+
*
|
|
483
|
+
* @public
|
|
484
|
+
* @param {Day} date
|
|
485
|
+
* @return {Array.<PositionSummaryRange>}
|
|
486
|
+
*/
|
|
487
|
+
getRangesFromDate(date) {
|
|
488
|
+
const transaction = { date: date, snapshot: { open: Decimal.ONE } };
|
|
489
|
+
|
|
490
|
+
return this.getRanges([ transaction ]);
|
|
491
|
+
}
|
|
492
|
+
|
|
480
493
|
/**
|
|
481
494
|
* Returns the start date for a frame, a given number of periods ago.
|
|
482
495
|
*
|
|
@@ -549,6 +562,16 @@ module.exports = (() => {
|
|
|
549
562
|
* @property {Day} end
|
|
550
563
|
*/
|
|
551
564
|
|
|
565
|
+
/**
|
|
566
|
+
* The start and and date for a {@link PositionSummaryFrame} along with the frame type.
|
|
567
|
+
*
|
|
568
|
+
* @typedef PositionSummaryDefinition
|
|
569
|
+
* @type {Object}
|
|
570
|
+
* @property {Day} start
|
|
571
|
+
* @property {Day} end
|
|
572
|
+
* @property {PositionSummaryFrame} frame
|
|
573
|
+
*/
|
|
574
|
+
|
|
552
575
|
function getRange(start, end) {
|
|
553
576
|
return {
|
|
554
577
|
start: start,
|
|
@@ -1421,7 +1444,7 @@ module.exports = (() => {
|
|
|
1421
1444
|
* @param {Array.<Object>} portfolios - The portfolios.
|
|
1422
1445
|
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
1423
1446
|
* @param {Array.<Object>} summaries - The positions summaries (for all of the positions).
|
|
1424
|
-
* @param {PositionSummaryFrame} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
1447
|
+
* @param {PositionSummaryFrame=} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
1425
1448
|
*/
|
|
1426
1449
|
class PositionContainer {
|
|
1427
1450
|
constructor(definitions, portfolios, positions, summaries, frame) {
|
|
@@ -1663,12 +1686,12 @@ module.exports = (() => {
|
|
|
1663
1686
|
|
|
1664
1687
|
const existingBarchartSymbols = this.getPositionSymbols(false);
|
|
1665
1688
|
|
|
1666
|
-
let
|
|
1689
|
+
let similarPositionItem;
|
|
1667
1690
|
|
|
1668
|
-
if (
|
|
1669
|
-
|
|
1691
|
+
if (extractSymbolForBarchart(position)) {
|
|
1692
|
+
similarPositionItem = this._items.find(item => extractSymbolForBarchart(item.position) === extractSymbolForBarchart(position)) || null;
|
|
1670
1693
|
} else {
|
|
1671
|
-
|
|
1694
|
+
similarPositionItem = null;
|
|
1672
1695
|
}
|
|
1673
1696
|
|
|
1674
1697
|
removePositionItem.call(this, this._items.find(item => item.position.position === position.position));
|
|
@@ -1718,13 +1741,13 @@ module.exports = (() => {
|
|
|
1718
1741
|
this._positionSymbolAddedEvent.fire(addedBarchartSymbol);
|
|
1719
1742
|
}
|
|
1720
1743
|
|
|
1721
|
-
if (
|
|
1722
|
-
if (
|
|
1723
|
-
item.setQuote(
|
|
1744
|
+
if (similarPositionItem !== null) {
|
|
1745
|
+
if (similarPositionItem.previousQuote) {
|
|
1746
|
+
item.setQuote(similarPositionItem.previousQuote);
|
|
1724
1747
|
}
|
|
1725
1748
|
|
|
1726
|
-
if (
|
|
1727
|
-
item.setQuote(
|
|
1749
|
+
if (similarPositionItem.quote) {
|
|
1750
|
+
item.setQuote(similarPositionItem.quote);
|
|
1728
1751
|
}
|
|
1729
1752
|
}
|
|
1730
1753
|
|
|
@@ -2515,6 +2538,10 @@ module.exports = (() => {
|
|
|
2515
2538
|
this._dataActual.summaryTotalCurrent = null;
|
|
2516
2539
|
this._dataActual.summaryTotalPrevious = null;
|
|
2517
2540
|
this._dataActual.summaryTotalPrevious2 = null;
|
|
2541
|
+
this._dataActual.endingPrevious = null;
|
|
2542
|
+
this._dataActual.endingPrevious2 = null;
|
|
2543
|
+
this._dataActual.endingChange = null;
|
|
2544
|
+
this._dataActual.endingChangePercent = null;
|
|
2518
2545
|
this._dataActual.cashTotal = null;
|
|
2519
2546
|
|
|
2520
2547
|
this._dataFormat.currentPrice = null;
|
|
@@ -2538,6 +2565,10 @@ module.exports = (() => {
|
|
|
2538
2565
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
2539
2566
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
2540
2567
|
this._dataFormat.summaryTotalPrevious2Negative = false;
|
|
2568
|
+
this._dataFormat.endingPrevious = null;
|
|
2569
|
+
this._dataFormat.endingPrevious2 = null;
|
|
2570
|
+
this._dataFormat.endingChange = null;
|
|
2571
|
+
this._dataFormat.endingChangePercent = null;
|
|
2541
2572
|
this._dataFormat.cashTotal = null;
|
|
2542
2573
|
this._dataFormat.portfolioType = null;
|
|
2543
2574
|
|
|
@@ -2773,8 +2804,6 @@ module.exports = (() => {
|
|
|
2773
2804
|
return;
|
|
2774
2805
|
}
|
|
2775
2806
|
|
|
2776
|
-
const descriptionSelector = this._definition.descriptionSelector;
|
|
2777
|
-
|
|
2778
2807
|
this._description = PositionLevelDefinition.getDescriptionForPortfolioGroup(portfolio);
|
|
2779
2808
|
|
|
2780
2809
|
this._dataActual.description = this._description;
|
|
@@ -3019,7 +3048,7 @@ module.exports = (() => {
|
|
|
3019
3048
|
const translate = (item, value) => {
|
|
3020
3049
|
let translated;
|
|
3021
3050
|
|
|
3022
|
-
if (item.currency !== currency) {
|
|
3051
|
+
if (item.currency !== currency && !value.getIsZero()) {
|
|
3023
3052
|
translated = Rate.convert(value, item.currency, currency, ...rates);
|
|
3024
3053
|
} else {
|
|
3025
3054
|
translated = value;
|
|
@@ -3036,6 +3065,8 @@ module.exports = (() => {
|
|
|
3036
3065
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
|
|
3037
3066
|
updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
|
|
3038
3067
|
updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
|
|
3068
|
+
updates.endingPrevious = updates.endingPrevious.add(translate(item, item.data.endingPrevious));
|
|
3069
|
+
updates.endingPrevious2 = updates.endingPrevious2.add(translate(item, item.data.endingPrevious2));
|
|
3039
3070
|
|
|
3040
3071
|
if (item.position.instrument.type === InstrumentType.CASH) {
|
|
3041
3072
|
updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
|
|
@@ -3050,6 +3081,8 @@ module.exports = (() => {
|
|
|
3050
3081
|
summaryTotalCurrent: Decimal.ZERO,
|
|
3051
3082
|
summaryTotalPrevious: Decimal.ZERO,
|
|
3052
3083
|
summaryTotalPrevious2: Decimal.ZERO,
|
|
3084
|
+
endingPrevious: Decimal.ZERO,
|
|
3085
|
+
endingPrevious2: Decimal.ZERO,
|
|
3053
3086
|
cashTotal: Decimal.ZERO
|
|
3054
3087
|
});
|
|
3055
3088
|
|
|
@@ -3060,6 +3093,8 @@ module.exports = (() => {
|
|
|
3060
3093
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3061
3094
|
actual.summaryTotalPrevious = updates.summaryTotalPrevious;
|
|
3062
3095
|
actual.summaryTotalPrevious2 = updates.summaryTotalPrevious2;
|
|
3096
|
+
actual.endingPrevious = updates.endingPrevious;
|
|
3097
|
+
actual.endingPrevious2 = updates.endingPrevious2;
|
|
3063
3098
|
actual.cashTotal = updates.cashTotal;
|
|
3064
3099
|
|
|
3065
3100
|
format.basis = formatCurrency(actual.basis, currency);
|
|
@@ -3071,6 +3106,8 @@ module.exports = (() => {
|
|
|
3071
3106
|
format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
|
|
3072
3107
|
format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
|
|
3073
3108
|
format.summaryTotalPrevious2Negative = updates.summaryTotalPrevious2.getIsNegative();
|
|
3109
|
+
format.endingPrevious = formatCurrency(updates.endingPrevious, currency);
|
|
3110
|
+
format.endingPrevious2 = formatCurrency(updates.endingPrevious2, currency);
|
|
3074
3111
|
format.cashTotal = formatCurrency(updates.cashTotal, currency);
|
|
3075
3112
|
|
|
3076
3113
|
calculateUnrealizedPercent(group);
|
|
@@ -3120,7 +3157,7 @@ module.exports = (() => {
|
|
|
3120
3157
|
const translate = (item, value) => {
|
|
3121
3158
|
let translated;
|
|
3122
3159
|
|
|
3123
|
-
if (item.currency !== currency) {
|
|
3160
|
+
if (item.currency !== currency && !value.getIsZero()) {
|
|
3124
3161
|
translated = Rate.convert(value, item.currency, currency, ...rates);
|
|
3125
3162
|
} else {
|
|
3126
3163
|
translated = value;
|
|
@@ -3167,7 +3204,25 @@ module.exports = (() => {
|
|
|
3167
3204
|
actual.unrealizedToday = updates.unrealizedToday;
|
|
3168
3205
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3169
3206
|
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
3170
|
-
|
|
3207
|
+
|
|
3208
|
+
let endingChange = updates.market.subtract(actual.endingPrevious);
|
|
3209
|
+
let endingChangePercent;
|
|
3210
|
+
|
|
3211
|
+
if (actual.endingPrevious.getIsZero()) {
|
|
3212
|
+
if (endingChange.getIsPositive()) {
|
|
3213
|
+
endingChangePercent = Decimal.ONE;
|
|
3214
|
+
} else if (endingChange.getIsNegative()) {
|
|
3215
|
+
endingChangePercent = Decimal.NEGATIVE_ONE;
|
|
3216
|
+
} else {
|
|
3217
|
+
endingChangePercent = Decimal.ZERO;
|
|
3218
|
+
}
|
|
3219
|
+
} else {
|
|
3220
|
+
endingChangePercent = endingChange.divide(actual.endingPrevious);
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
actual.endingChange = endingChange;
|
|
3224
|
+
actual.endingChangePercent = endingChangePercent;
|
|
3225
|
+
|
|
3171
3226
|
format.market = formatCurrency(actual.market, currency);
|
|
3172
3227
|
|
|
3173
3228
|
if (updates.marketDirection.up || updates.marketDirection.down) {
|
|
@@ -3187,6 +3242,9 @@ module.exports = (() => {
|
|
|
3187
3242
|
format.total = formatCurrency(actual.total, currency);
|
|
3188
3243
|
format.totalNegative = actual.total.getIsNegative();
|
|
3189
3244
|
|
|
3245
|
+
format.endingChange = formatCurrency(actual.endingChange, currency);
|
|
3246
|
+
format.endingChangePercent = formatPercent(actual.endingChangePercent, 2);
|
|
3247
|
+
|
|
3190
3248
|
calculateUnrealizedPercent(group);
|
|
3191
3249
|
}
|
|
3192
3250
|
|
|
@@ -3319,6 +3377,9 @@ module.exports = (() => {
|
|
|
3319
3377
|
this._data.summaryTotalPrevious = null;
|
|
3320
3378
|
this._data.summaryTotalPrevious2 = null;
|
|
3321
3379
|
|
|
3380
|
+
this._data.endingPrevious = null;
|
|
3381
|
+
this._data.endingPrevious2 = null;
|
|
3382
|
+
|
|
3322
3383
|
this._data.realized = null;
|
|
3323
3384
|
this._data.income = null;
|
|
3324
3385
|
this._data.basisPrice = null;
|
|
@@ -3634,9 +3695,16 @@ module.exports = (() => {
|
|
|
3634
3695
|
|
|
3635
3696
|
data.income = snapshot.income;
|
|
3636
3697
|
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3698
|
+
const previousSummary1 = getPreviousSummary(previousSummaries, 1);
|
|
3699
|
+
const previousSummary2 = getPreviousSummary(previousSummaries, 2);
|
|
3700
|
+
const previousSummary3 = getPreviousSummary(previousSummaries, 3);
|
|
3701
|
+
|
|
3702
|
+
data.summaryTotalCurrent = calculateSummaryTotal(item.currentSummary, previousSummary1);
|
|
3703
|
+
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
3704
|
+
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
3705
|
+
|
|
3706
|
+
data.endingPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
3707
|
+
data.endingPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
3640
3708
|
|
|
3641
3709
|
if (snapshot.open.getIsZero()) {
|
|
3642
3710
|
data.basisPrice = Decimal.ZERO;
|