@barchart/portfolio-api-common 1.0.241 → 1.0.245
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/processing/PositionContainer.js +70 -7
- package/lib/processing/PositionGroup.js +31 -26
- package/package.json +1 -1
- package/test/SpecRunner.js +101 -33
|
@@ -132,7 +132,9 @@ module.exports = (() => {
|
|
|
132
132
|
this._forexQuotes = this._forexSymbols.map((symbol) => {
|
|
133
133
|
return Rate.fromPair(Decimal.ONE, symbol);
|
|
134
134
|
});
|
|
135
|
-
|
|
135
|
+
|
|
136
|
+
this._nodes = { };
|
|
137
|
+
|
|
136
138
|
this._trees = this._definitions.reduce((map, treeDefinition) => {
|
|
137
139
|
const tree = new Tree();
|
|
138
140
|
|
|
@@ -247,7 +249,7 @@ module.exports = (() => {
|
|
|
247
249
|
Object.keys(this._trees).forEach((key) => {
|
|
248
250
|
this._trees[key].walk((group, groupNode) => {
|
|
249
251
|
if (group.definition.type === PositionLevelType.PORTFOLIO && group.key === PositionLevelDefinition.getKeyForPortfolioGroup(portfolio)) {
|
|
250
|
-
|
|
252
|
+
severGroupNode.call(this, groupNode);
|
|
251
253
|
}
|
|
252
254
|
}, true, false);
|
|
253
255
|
});
|
|
@@ -510,6 +512,32 @@ module.exports = (() => {
|
|
|
510
512
|
return findNode(this._trees[name], keys).getChildren().map(node => node.getValue());
|
|
511
513
|
}
|
|
512
514
|
|
|
515
|
+
/**
|
|
516
|
+
* Returns the immediate parent {@link PositionGroup} of a {@link PositionGroup}.
|
|
517
|
+
*
|
|
518
|
+
* @public
|
|
519
|
+
* @param {PositionGroup} position
|
|
520
|
+
* @returns {PositionGroup|null}
|
|
521
|
+
*/
|
|
522
|
+
getParentGroup(group) {
|
|
523
|
+
assert.argumentIsRequired(group, 'group', PositionGroup, 'PositionGroup');
|
|
524
|
+
|
|
525
|
+
return findParentGroup.call(this, group, candidate => true);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Returns the a parent {@link PositionGroup} which represents a portfolio.
|
|
530
|
+
*
|
|
531
|
+
* @public
|
|
532
|
+
* @param {PositionGroup} position
|
|
533
|
+
* @returns {PositionGroup|null}
|
|
534
|
+
*/
|
|
535
|
+
getParentGroupForPortfolio(group) {
|
|
536
|
+
assert.argumentIsRequired(group, 'group', PositionGroup, 'PositionGroup');
|
|
537
|
+
|
|
538
|
+
return findParentGroup.call(this, group, candidate => candidate.definition.type === PositionLevelType.PORTFOLIO);
|
|
539
|
+
}
|
|
540
|
+
|
|
513
541
|
/**
|
|
514
542
|
* Returns all portfolios in the container.
|
|
515
543
|
*
|
|
@@ -536,6 +564,20 @@ module.exports = (() => {
|
|
|
536
564
|
});
|
|
537
565
|
}
|
|
538
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Returns a single position for a portfolio.
|
|
569
|
+
*
|
|
570
|
+
* @public
|
|
571
|
+
* @param {String} portfolio
|
|
572
|
+
* @param {String} position
|
|
573
|
+
* @return {Object|null}
|
|
574
|
+
*/
|
|
575
|
+
getPosition(portfolio, position) {
|
|
576
|
+
assert.argumentIsRequired(position, 'position', String);
|
|
577
|
+
|
|
578
|
+
return this.getPositions(portfolio).find(p => p.position === position) || null;
|
|
579
|
+
}
|
|
580
|
+
|
|
539
581
|
/**
|
|
540
582
|
* Pauses aggregation calculations during the processing of an action.
|
|
541
583
|
*
|
|
@@ -603,6 +645,22 @@ module.exports = (() => {
|
|
|
603
645
|
return keys.reduce((tree, key) => tree.findChild(group => group.key === key), tree);
|
|
604
646
|
}
|
|
605
647
|
|
|
648
|
+
function findParentGroup(group, predicate) {
|
|
649
|
+
const groupNode = this._nodes[group.id];
|
|
650
|
+
|
|
651
|
+
let returnRef = null;
|
|
652
|
+
|
|
653
|
+
if (groupNode) {
|
|
654
|
+
const resultNode = groupNode.findParent((candidateGroup, candidateNode) => !candidateNode.getIsRoot() && predicate(candidateGroup));
|
|
655
|
+
|
|
656
|
+
if (resultNode) {
|
|
657
|
+
returnRef = resultNode.getValue();
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
return returnRef;
|
|
662
|
+
}
|
|
663
|
+
|
|
606
664
|
function extractSymbolForBarchart(position) {
|
|
607
665
|
if (position.instrument && position.instrument.symbol && position.instrument.symbol.barchart) {
|
|
608
666
|
return position.instrument.symbol.barchart;
|
|
@@ -694,8 +752,6 @@ module.exports = (() => {
|
|
|
694
752
|
return;
|
|
695
753
|
}
|
|
696
754
|
|
|
697
|
-
const parent = parentTree.getValue() || null;
|
|
698
|
-
|
|
699
755
|
const levelDefinition = levelDefinitions[0];
|
|
700
756
|
|
|
701
757
|
const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
|
|
@@ -703,7 +759,7 @@ module.exports = (() => {
|
|
|
703
759
|
const items = populatedObjects[key];
|
|
704
760
|
const first = items[0];
|
|
705
761
|
|
|
706
|
-
list.push(new PositionGroup(this,
|
|
762
|
+
list.push(new PositionGroup(this, levelDefinition, items, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.aggregateCash));
|
|
707
763
|
|
|
708
764
|
return list;
|
|
709
765
|
}, [ ]);
|
|
@@ -716,7 +772,7 @@ module.exports = (() => {
|
|
|
716
772
|
});
|
|
717
773
|
|
|
718
774
|
const empty = missingGroups.map((group) => {
|
|
719
|
-
return new PositionGroup(this,
|
|
775
|
+
return new PositionGroup(this, levelDefinition, [ ], group.currency, group.key, group.description);
|
|
720
776
|
});
|
|
721
777
|
|
|
722
778
|
const compositeGroups = populatedGroups.concat(empty);
|
|
@@ -754,6 +810,8 @@ module.exports = (() => {
|
|
|
754
810
|
compositeGroups.forEach((group) => {
|
|
755
811
|
const childTree = parentTree.addChild(group);
|
|
756
812
|
|
|
813
|
+
this._nodes[group.id] = childTree;
|
|
814
|
+
|
|
757
815
|
initializeGroupObservers.call(this, childTree, treeDefinition);
|
|
758
816
|
|
|
759
817
|
createGroups.call(this, childTree, group.items, treeDefinition, array.dropLeft(levelDefinitions));
|
|
@@ -881,7 +939,7 @@ module.exports = (() => {
|
|
|
881
939
|
Object.keys(this._trees).forEach((key) => {
|
|
882
940
|
this._trees[key].walk((group, groupNode) => {
|
|
883
941
|
if (group.definition.type === PositionLevelType.POSITION && group.key === positionItem.position.position) {
|
|
884
|
-
|
|
942
|
+
severGroupNode.call(this, groupNode);
|
|
885
943
|
}
|
|
886
944
|
}, true, false);
|
|
887
945
|
});
|
|
@@ -889,5 +947,10 @@ module.exports = (() => {
|
|
|
889
947
|
positionItem.dispose();
|
|
890
948
|
}
|
|
891
949
|
|
|
950
|
+
function severGroupNode(groupNodeToSever) {
|
|
951
|
+
groupNodeToSever.sever();
|
|
952
|
+
groupNodeToSever.walk(group => delete this._nodes[group.id], false, true);
|
|
953
|
+
}
|
|
954
|
+
|
|
892
955
|
return PositionContainer;
|
|
893
956
|
})();
|
|
@@ -25,7 +25,6 @@ module.exports = (() => {
|
|
|
25
25
|
*
|
|
26
26
|
* @public
|
|
27
27
|
* @param {PositionContainer} container
|
|
28
|
-
* @param {PositionGroup|null} parent
|
|
29
28
|
* @param {LevelDefinition} definition
|
|
30
29
|
* @param {Array.<PositionItem>} items
|
|
31
30
|
* @param {Currency} currency
|
|
@@ -34,12 +33,11 @@ module.exports = (() => {
|
|
|
34
33
|
* @param {Boolean=} aggregateCash
|
|
35
34
|
*/
|
|
36
35
|
class PositionGroup {
|
|
37
|
-
constructor(container,
|
|
36
|
+
constructor(container, definition, items, currency, key, description, aggregateCash) {
|
|
38
37
|
this._id = counter++;
|
|
39
38
|
|
|
40
39
|
this._definition = definition;
|
|
41
40
|
this._container = container;
|
|
42
|
-
this._parent = parent || null;
|
|
43
41
|
|
|
44
42
|
this._items = items;
|
|
45
43
|
this._currency = currency || Currency.CAD;
|
|
@@ -122,6 +120,7 @@ module.exports = (() => {
|
|
|
122
120
|
this._dataActual.income = null;
|
|
123
121
|
this._dataActual.market = null;
|
|
124
122
|
this._dataActual.marketPercent = null;
|
|
123
|
+
this._dataActual.marketPercentPortfolio = null;
|
|
125
124
|
this._dataActual.unrealized = null;
|
|
126
125
|
this._dataActual.unrealizedToday = null;
|
|
127
126
|
this._dataActual.total = null;
|
|
@@ -137,6 +136,7 @@ module.exports = (() => {
|
|
|
137
136
|
this._dataFormat.income = null;
|
|
138
137
|
this._dataFormat.market = null;
|
|
139
138
|
this._dataFormat.marketPercent = null;
|
|
139
|
+
this._dataFormat.marketPercentPortfolio = null;
|
|
140
140
|
this._dataFormat.marketDirection = null;
|
|
141
141
|
this._dataFormat.unrealized = null;
|
|
142
142
|
this._dataFormat.unrealizedPercent = null;
|
|
@@ -146,7 +146,7 @@ module.exports = (() => {
|
|
|
146
146
|
this._dataFormat.total = null;
|
|
147
147
|
this._dataFormat.totalNegative = false;
|
|
148
148
|
this._dataFormat.summaryTotalCurrent = null;
|
|
149
|
-
this.
|
|
149
|
+
this._dataFormat.summaryTotalCurrentNegative = false;
|
|
150
150
|
this._dataFormat.summaryTotalPrevious = null;
|
|
151
151
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
152
152
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
@@ -670,7 +670,6 @@ module.exports = (() => {
|
|
|
670
670
|
return;
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
-
const parent = group._parent;
|
|
674
673
|
const currency = group.currency;
|
|
675
674
|
|
|
676
675
|
const actual = group._dataActual;
|
|
@@ -761,38 +760,44 @@ module.exports = (() => {
|
|
|
761
760
|
return;
|
|
762
761
|
}
|
|
763
762
|
|
|
764
|
-
const parent = group._parent;
|
|
765
|
-
const excluded = group._excluded;
|
|
766
|
-
|
|
767
763
|
const actual = group._dataActual;
|
|
768
764
|
const format = group._dataFormat;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
765
|
+
const excluded = group._excluded;
|
|
766
|
+
|
|
767
|
+
const portfolioParent = group._container.getParentGroupForPortfolio(group);
|
|
768
|
+
|
|
769
|
+
const calculatePercent = (parent) => {
|
|
770
|
+
let marketPercent;
|
|
771
|
+
|
|
772
|
+
if (parent !== null && !excluded) {
|
|
773
|
+
const parentData = parent._dataActual;
|
|
774
|
+
|
|
775
|
+
if (parentData.marketAbsolute !== null && !parentData.marketAbsolute.getIsZero()) {
|
|
776
|
+
let numerator;
|
|
774
777
|
|
|
775
|
-
|
|
776
|
-
|
|
778
|
+
if (group.currency !== parent.currency) {
|
|
779
|
+
numerator = Rate.convert(actual.marketAbsolute, group.currency, parent.currency, ...rates);
|
|
780
|
+
} else {
|
|
781
|
+
numerator = actual.marketAbsolute;
|
|
782
|
+
}
|
|
777
783
|
|
|
778
|
-
|
|
779
|
-
numerator = Rate.convert(actual.marketAbsolute, group.currency, parent.currency, ...rates);
|
|
784
|
+
marketPercent = numerator.divide(parentData.marketAbsolute);
|
|
780
785
|
} else {
|
|
781
|
-
|
|
786
|
+
marketPercent = null;
|
|
782
787
|
}
|
|
783
|
-
|
|
784
|
-
marketPercent = numerator.divide(parentData.marketAbsolute);
|
|
785
788
|
} else {
|
|
786
789
|
marketPercent = null;
|
|
787
790
|
}
|
|
788
|
-
} else {
|
|
789
|
-
marketPercent = null;
|
|
790
|
-
}
|
|
791
791
|
|
|
792
|
-
|
|
793
|
-
|
|
792
|
+
return marketPercent;
|
|
793
|
+
};
|
|
794
|
+
|
|
795
|
+
actual.marketPercent = calculatePercent(group._container.getParentGroup(group));
|
|
794
796
|
format.marketPercent = formatPercent(actual.marketPercent, 2);
|
|
795
|
-
|
|
797
|
+
|
|
798
|
+
actual.marketPercentPortfolio = calculatePercent(group._container.getParentGroupForPortfolio(group));
|
|
799
|
+
format.marketPercentPortfolio = formatPercent(actual.marketPercentPortfolio, 2);
|
|
800
|
+
|
|
796
801
|
if (!silent) {
|
|
797
802
|
group._marketPercentChangeEvent.fire(group);
|
|
798
803
|
}
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -931,7 +931,9 @@ module.exports = (() => {
|
|
|
931
931
|
this._forexQuotes = this._forexSymbols.map((symbol) => {
|
|
932
932
|
return Rate.fromPair(Decimal.ONE, symbol);
|
|
933
933
|
});
|
|
934
|
-
|
|
934
|
+
|
|
935
|
+
this._nodes = { };
|
|
936
|
+
|
|
935
937
|
this._trees = this._definitions.reduce((map, treeDefinition) => {
|
|
936
938
|
const tree = new Tree();
|
|
937
939
|
|
|
@@ -1046,7 +1048,7 @@ module.exports = (() => {
|
|
|
1046
1048
|
Object.keys(this._trees).forEach((key) => {
|
|
1047
1049
|
this._trees[key].walk((group, groupNode) => {
|
|
1048
1050
|
if (group.definition.type === PositionLevelType.PORTFOLIO && group.key === PositionLevelDefinition.getKeyForPortfolioGroup(portfolio)) {
|
|
1049
|
-
|
|
1051
|
+
severGroupNode.call(this, groupNode);
|
|
1050
1052
|
}
|
|
1051
1053
|
}, true, false);
|
|
1052
1054
|
});
|
|
@@ -1309,6 +1311,32 @@ module.exports = (() => {
|
|
|
1309
1311
|
return findNode(this._trees[name], keys).getChildren().map(node => node.getValue());
|
|
1310
1312
|
}
|
|
1311
1313
|
|
|
1314
|
+
/**
|
|
1315
|
+
* Returns the immediate parent {@link PositionGroup} of a {@link PositionGroup}.
|
|
1316
|
+
*
|
|
1317
|
+
* @public
|
|
1318
|
+
* @param {PositionGroup} position
|
|
1319
|
+
* @returns {PositionGroup|null}
|
|
1320
|
+
*/
|
|
1321
|
+
getParentGroup(group) {
|
|
1322
|
+
assert.argumentIsRequired(group, 'group', PositionGroup, 'PositionGroup');
|
|
1323
|
+
|
|
1324
|
+
return findParentGroup.call(this, group, candidate => true);
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
/**
|
|
1328
|
+
* Returns the a parent {@link PositionGroup} which represents a portfolio.
|
|
1329
|
+
*
|
|
1330
|
+
* @public
|
|
1331
|
+
* @param {PositionGroup} position
|
|
1332
|
+
* @returns {PositionGroup|null}
|
|
1333
|
+
*/
|
|
1334
|
+
getParentGroupForPortfolio(group) {
|
|
1335
|
+
assert.argumentIsRequired(group, 'group', PositionGroup, 'PositionGroup');
|
|
1336
|
+
|
|
1337
|
+
return findParentGroup.call(this, group, candidate => candidate.definition.type === PositionLevelType.PORTFOLIO);
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1312
1340
|
/**
|
|
1313
1341
|
* Returns all portfolios in the container.
|
|
1314
1342
|
*
|
|
@@ -1335,6 +1363,20 @@ module.exports = (() => {
|
|
|
1335
1363
|
});
|
|
1336
1364
|
}
|
|
1337
1365
|
|
|
1366
|
+
/**
|
|
1367
|
+
* Returns a single position for a portfolio.
|
|
1368
|
+
*
|
|
1369
|
+
* @public
|
|
1370
|
+
* @param {String} portfolio
|
|
1371
|
+
* @param {String} position
|
|
1372
|
+
* @return {Object|null}
|
|
1373
|
+
*/
|
|
1374
|
+
getPosition(portfolio, position) {
|
|
1375
|
+
assert.argumentIsRequired(position, 'position', String);
|
|
1376
|
+
|
|
1377
|
+
return this.getPositions(portfolio).find(p => p.position === position) || null;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1338
1380
|
/**
|
|
1339
1381
|
* Pauses aggregation calculations during the processing of an action.
|
|
1340
1382
|
*
|
|
@@ -1402,6 +1444,22 @@ module.exports = (() => {
|
|
|
1402
1444
|
return keys.reduce((tree, key) => tree.findChild(group => group.key === key), tree);
|
|
1403
1445
|
}
|
|
1404
1446
|
|
|
1447
|
+
function findParentGroup(group, predicate) {
|
|
1448
|
+
const groupNode = this._nodes[group.id];
|
|
1449
|
+
|
|
1450
|
+
let returnRef = null;
|
|
1451
|
+
|
|
1452
|
+
if (groupNode) {
|
|
1453
|
+
const resultNode = groupNode.findParent((candidateGroup, candidateNode) => !candidateNode.getIsRoot() && predicate(candidateGroup));
|
|
1454
|
+
|
|
1455
|
+
if (resultNode) {
|
|
1456
|
+
returnRef = resultNode.getValue();
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
return returnRef;
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1405
1463
|
function extractSymbolForBarchart(position) {
|
|
1406
1464
|
if (position.instrument && position.instrument.symbol && position.instrument.symbol.barchart) {
|
|
1407
1465
|
return position.instrument.symbol.barchart;
|
|
@@ -1493,8 +1551,6 @@ module.exports = (() => {
|
|
|
1493
1551
|
return;
|
|
1494
1552
|
}
|
|
1495
1553
|
|
|
1496
|
-
const parent = parentTree.getValue() || null;
|
|
1497
|
-
|
|
1498
1554
|
const levelDefinition = levelDefinitions[0];
|
|
1499
1555
|
|
|
1500
1556
|
const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
|
|
@@ -1502,7 +1558,7 @@ module.exports = (() => {
|
|
|
1502
1558
|
const items = populatedObjects[key];
|
|
1503
1559
|
const first = items[0];
|
|
1504
1560
|
|
|
1505
|
-
list.push(new PositionGroup(this,
|
|
1561
|
+
list.push(new PositionGroup(this, levelDefinition, items, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.aggregateCash));
|
|
1506
1562
|
|
|
1507
1563
|
return list;
|
|
1508
1564
|
}, [ ]);
|
|
@@ -1515,7 +1571,7 @@ module.exports = (() => {
|
|
|
1515
1571
|
});
|
|
1516
1572
|
|
|
1517
1573
|
const empty = missingGroups.map((group) => {
|
|
1518
|
-
return new PositionGroup(this,
|
|
1574
|
+
return new PositionGroup(this, levelDefinition, [ ], group.currency, group.key, group.description);
|
|
1519
1575
|
});
|
|
1520
1576
|
|
|
1521
1577
|
const compositeGroups = populatedGroups.concat(empty);
|
|
@@ -1553,6 +1609,8 @@ module.exports = (() => {
|
|
|
1553
1609
|
compositeGroups.forEach((group) => {
|
|
1554
1610
|
const childTree = parentTree.addChild(group);
|
|
1555
1611
|
|
|
1612
|
+
this._nodes[group.id] = childTree;
|
|
1613
|
+
|
|
1556
1614
|
initializeGroupObservers.call(this, childTree, treeDefinition);
|
|
1557
1615
|
|
|
1558
1616
|
createGroups.call(this, childTree, group.items, treeDefinition, array.dropLeft(levelDefinitions));
|
|
@@ -1680,7 +1738,7 @@ module.exports = (() => {
|
|
|
1680
1738
|
Object.keys(this._trees).forEach((key) => {
|
|
1681
1739
|
this._trees[key].walk((group, groupNode) => {
|
|
1682
1740
|
if (group.definition.type === PositionLevelType.POSITION && group.key === positionItem.position.position) {
|
|
1683
|
-
|
|
1741
|
+
severGroupNode.call(this, groupNode);
|
|
1684
1742
|
}
|
|
1685
1743
|
}, true, false);
|
|
1686
1744
|
});
|
|
@@ -1688,6 +1746,11 @@ module.exports = (() => {
|
|
|
1688
1746
|
positionItem.dispose();
|
|
1689
1747
|
}
|
|
1690
1748
|
|
|
1749
|
+
function severGroupNode(groupNodeToSever) {
|
|
1750
|
+
groupNodeToSever.sever();
|
|
1751
|
+
groupNodeToSever.walk(group => delete this._nodes[group.id], false, true);
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1691
1754
|
return PositionContainer;
|
|
1692
1755
|
})();
|
|
1693
1756
|
|
|
@@ -1719,7 +1782,6 @@ module.exports = (() => {
|
|
|
1719
1782
|
*
|
|
1720
1783
|
* @public
|
|
1721
1784
|
* @param {PositionContainer} container
|
|
1722
|
-
* @param {PositionGroup|null} parent
|
|
1723
1785
|
* @param {LevelDefinition} definition
|
|
1724
1786
|
* @param {Array.<PositionItem>} items
|
|
1725
1787
|
* @param {Currency} currency
|
|
@@ -1728,12 +1790,11 @@ module.exports = (() => {
|
|
|
1728
1790
|
* @param {Boolean=} aggregateCash
|
|
1729
1791
|
*/
|
|
1730
1792
|
class PositionGroup {
|
|
1731
|
-
constructor(container,
|
|
1793
|
+
constructor(container, definition, items, currency, key, description, aggregateCash) {
|
|
1732
1794
|
this._id = counter++;
|
|
1733
1795
|
|
|
1734
1796
|
this._definition = definition;
|
|
1735
1797
|
this._container = container;
|
|
1736
|
-
this._parent = parent || null;
|
|
1737
1798
|
|
|
1738
1799
|
this._items = items;
|
|
1739
1800
|
this._currency = currency || Currency.CAD;
|
|
@@ -1816,6 +1877,7 @@ module.exports = (() => {
|
|
|
1816
1877
|
this._dataActual.income = null;
|
|
1817
1878
|
this._dataActual.market = null;
|
|
1818
1879
|
this._dataActual.marketPercent = null;
|
|
1880
|
+
this._dataActual.marketPercentPortfolio = null;
|
|
1819
1881
|
this._dataActual.unrealized = null;
|
|
1820
1882
|
this._dataActual.unrealizedToday = null;
|
|
1821
1883
|
this._dataActual.total = null;
|
|
@@ -1831,6 +1893,7 @@ module.exports = (() => {
|
|
|
1831
1893
|
this._dataFormat.income = null;
|
|
1832
1894
|
this._dataFormat.market = null;
|
|
1833
1895
|
this._dataFormat.marketPercent = null;
|
|
1896
|
+
this._dataFormat.marketPercentPortfolio = null;
|
|
1834
1897
|
this._dataFormat.marketDirection = null;
|
|
1835
1898
|
this._dataFormat.unrealized = null;
|
|
1836
1899
|
this._dataFormat.unrealizedPercent = null;
|
|
@@ -1840,7 +1903,7 @@ module.exports = (() => {
|
|
|
1840
1903
|
this._dataFormat.total = null;
|
|
1841
1904
|
this._dataFormat.totalNegative = false;
|
|
1842
1905
|
this._dataFormat.summaryTotalCurrent = null;
|
|
1843
|
-
this.
|
|
1906
|
+
this._dataFormat.summaryTotalCurrentNegative = false;
|
|
1844
1907
|
this._dataFormat.summaryTotalPrevious = null;
|
|
1845
1908
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
1846
1909
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
@@ -2364,7 +2427,6 @@ module.exports = (() => {
|
|
|
2364
2427
|
return;
|
|
2365
2428
|
}
|
|
2366
2429
|
|
|
2367
|
-
const parent = group._parent;
|
|
2368
2430
|
const currency = group.currency;
|
|
2369
2431
|
|
|
2370
2432
|
const actual = group._dataActual;
|
|
@@ -2455,38 +2517,44 @@ module.exports = (() => {
|
|
|
2455
2517
|
return;
|
|
2456
2518
|
}
|
|
2457
2519
|
|
|
2458
|
-
const parent = group._parent;
|
|
2459
|
-
const excluded = group._excluded;
|
|
2460
|
-
|
|
2461
2520
|
const actual = group._dataActual;
|
|
2462
2521
|
const format = group._dataFormat;
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
if (parent !== null && !excluded) {
|
|
2467
|
-
const parentData = parent._dataActual;
|
|
2522
|
+
const excluded = group._excluded;
|
|
2523
|
+
|
|
2524
|
+
const portfolioParent = group._container.getParentGroupForPortfolio(group);
|
|
2468
2525
|
|
|
2469
|
-
|
|
2470
|
-
|
|
2526
|
+
const calculatePercent = (parent) => {
|
|
2527
|
+
let marketPercent;
|
|
2471
2528
|
|
|
2472
|
-
|
|
2473
|
-
|
|
2529
|
+
if (parent !== null && !excluded) {
|
|
2530
|
+
const parentData = parent._dataActual;
|
|
2531
|
+
|
|
2532
|
+
if (parentData.marketAbsolute !== null && !parentData.marketAbsolute.getIsZero()) {
|
|
2533
|
+
let numerator;
|
|
2534
|
+
|
|
2535
|
+
if (group.currency !== parent.currency) {
|
|
2536
|
+
numerator = Rate.convert(actual.marketAbsolute, group.currency, parent.currency, ...rates);
|
|
2537
|
+
} else {
|
|
2538
|
+
numerator = actual.marketAbsolute;
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
marketPercent = numerator.divide(parentData.marketAbsolute);
|
|
2474
2542
|
} else {
|
|
2475
|
-
|
|
2543
|
+
marketPercent = null;
|
|
2476
2544
|
}
|
|
2477
|
-
|
|
2478
|
-
marketPercent = numerator.divide(parentData.marketAbsolute);
|
|
2479
2545
|
} else {
|
|
2480
2546
|
marketPercent = null;
|
|
2481
2547
|
}
|
|
2482
|
-
} else {
|
|
2483
|
-
marketPercent = null;
|
|
2484
|
-
}
|
|
2485
2548
|
|
|
2486
|
-
|
|
2487
|
-
|
|
2549
|
+
return marketPercent;
|
|
2550
|
+
};
|
|
2551
|
+
|
|
2552
|
+
actual.marketPercent = calculatePercent(group._container.getParentGroup(group));
|
|
2488
2553
|
format.marketPercent = formatPercent(actual.marketPercent, 2);
|
|
2489
|
-
|
|
2554
|
+
|
|
2555
|
+
actual.marketPercentPortfolio = calculatePercent(group._container.getParentGroupForPortfolio(group));
|
|
2556
|
+
format.marketPercentPortfolio = formatPercent(actual.marketPercentPortfolio, 2);
|
|
2557
|
+
|
|
2490
2558
|
if (!silent) {
|
|
2491
2559
|
group._marketPercentChangeEvent.fire(group);
|
|
2492
2560
|
}
|