@barchart/portfolio-api-common 1.0.48 → 1.0.52
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 +39 -6
- package/lib/processing/PositionGroup.js +14 -8
- package/lib/processing/PositionGroupDefinition.js +6 -1
- package/lib/processing/PositionItem.js +13 -0
- package/package.json +1 -1
- package/test/SpecRunner.js +77 -20
- package/test/specs/processing/PositionContainerSpec.js +3 -3
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
const array = require('@barchart/common-js/lang/array'),
|
|
2
|
+
ComparatorBuilder = require('@barchart/common-js/collections/sorting/ComparatorBuilder'),
|
|
3
|
+
comparators = require('@barchart/common-js/collections/sorting/comparators'),
|
|
4
|
+
Currency = require('@barchart/common-js/lang/Currency'),
|
|
2
5
|
assert = require('@barchart/common-js/lang/assert'),
|
|
3
6
|
is = require('@barchart/common-js/lang/is'),
|
|
4
7
|
Tree = require('@barchart/common-js/collections/Tree');
|
|
@@ -49,8 +52,8 @@ module.exports = (() => {
|
|
|
49
52
|
let position = item.position;
|
|
50
53
|
let symbol = null;
|
|
51
54
|
|
|
52
|
-
if (position.instrument && position.instrument.symbol && position.instrument.barchart) {
|
|
53
|
-
symbol = position.instrument.barchart;
|
|
55
|
+
if (position.instrument && position.instrument.symbol && position.instrument.symbol.barchart) {
|
|
56
|
+
symbol = position.instrument.symbol.barchart;
|
|
54
57
|
|
|
55
58
|
if (!map.hasOwnProperty(symbol)) {
|
|
56
59
|
map[symbol] = [ ];
|
|
@@ -62,7 +65,7 @@ module.exports = (() => {
|
|
|
62
65
|
return map;
|
|
63
66
|
}, { });
|
|
64
67
|
|
|
65
|
-
this._definitions = definitions
|
|
68
|
+
this._definitions = definitions;
|
|
66
69
|
|
|
67
70
|
this._tree = new Tree();
|
|
68
71
|
|
|
@@ -77,17 +80,47 @@ module.exports = (() => {
|
|
|
77
80
|
const populatedGroups = array.batchBy(items, currentDefinition.keySelector).map((items) => {
|
|
78
81
|
const first = items[0];
|
|
79
82
|
|
|
80
|
-
return new PositionGroup(items, currentDefinition.descriptionSelector(first), currentDefinition.single && items.length === 1);
|
|
83
|
+
return new PositionGroup(items, currentDefinition.currencySelector(first), currentDefinition.descriptionSelector(first), currentDefinition.single && items.length === 1);
|
|
81
84
|
});
|
|
82
85
|
|
|
83
|
-
const missingGroups = array.difference(currentDefinition.requiredGroups, populatedGroups.map(group => group.description));
|
|
86
|
+
const missingGroups = array.difference(Object.keys(currentDefinition.requiredGroups), populatedGroups.map(group => group.description));
|
|
84
87
|
|
|
85
88
|
const empty = missingGroups.map((description) => {
|
|
86
|
-
return new PositionGroup([ ], description);
|
|
89
|
+
return new PositionGroup([ ], currentDefinition.requiredGroups[description].currency, description);
|
|
87
90
|
});
|
|
88
91
|
|
|
89
92
|
const compositeGroups = populatedGroups.concat(empty);
|
|
90
93
|
|
|
94
|
+
let builder;
|
|
95
|
+
|
|
96
|
+
if (currentDefinition.requiredGroups.length !== 0) {
|
|
97
|
+
const ordering = currentDefinition.requiredGroups.reduce((map, group, index) => {
|
|
98
|
+
map[group] = index;
|
|
99
|
+
|
|
100
|
+
return map;
|
|
101
|
+
}, { });
|
|
102
|
+
|
|
103
|
+
const getIndex = (description) => {
|
|
104
|
+
if (ordering.hasOwnProperty(description)) {
|
|
105
|
+
return ordering[description];
|
|
106
|
+
} else {
|
|
107
|
+
return Number.MAX_VALUE;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
112
|
+
return comparators.compareNumbers(getIndex(a.description), getIndex(b.description));
|
|
113
|
+
}).thenBy((a, b) => {
|
|
114
|
+
return comparators.compareStrings(a.description, b.description);
|
|
115
|
+
});
|
|
116
|
+
} else {
|
|
117
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
118
|
+
return comparators.compareStrings(a.description, b.description);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
compositeGroups.sort(builder.toComparator());
|
|
123
|
+
|
|
91
124
|
compositeGroups.forEach((group) => {
|
|
92
125
|
const child = tree.addChild(group);
|
|
93
126
|
|
|
@@ -11,9 +11,11 @@ module.exports = (() => {
|
|
|
11
11
|
* @public
|
|
12
12
|
*/
|
|
13
13
|
class PositionGroup {
|
|
14
|
-
constructor(items, description, single) {
|
|
15
|
-
this._description = description;
|
|
14
|
+
constructor(items, currency, description, single) {
|
|
16
15
|
this._items = items;
|
|
16
|
+
this._currency = currency;
|
|
17
|
+
|
|
18
|
+
this._description = description;
|
|
17
19
|
|
|
18
20
|
this._single = is.boolean(single) && single;
|
|
19
21
|
|
|
@@ -44,13 +46,21 @@ module.exports = (() => {
|
|
|
44
46
|
this._dataFormat.current = null;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
calculateVariablePriceData(this, item
|
|
49
|
+
calculateVariablePriceData(this, item);
|
|
48
50
|
});
|
|
49
51
|
});
|
|
50
52
|
|
|
51
53
|
calculateStaticData(this);
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
get items() {
|
|
57
|
+
return this._items;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get currency() {
|
|
61
|
+
return this._currency;
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
get description() {
|
|
55
65
|
return this._description;
|
|
56
66
|
}
|
|
@@ -59,10 +69,6 @@ module.exports = (() => {
|
|
|
59
69
|
return this._dataFormat;
|
|
60
70
|
}
|
|
61
71
|
|
|
62
|
-
get items() {
|
|
63
|
-
return this._items;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
72
|
get single() {
|
|
67
73
|
return this._single;
|
|
68
74
|
}
|
|
@@ -105,7 +111,7 @@ module.exports = (() => {
|
|
|
105
111
|
formatted.basis = format(updates.basis, Currency.USD);
|
|
106
112
|
}
|
|
107
113
|
|
|
108
|
-
function calculateVariablePriceData(group, item
|
|
114
|
+
function calculateVariablePriceData(group, item) {
|
|
109
115
|
|
|
110
116
|
}
|
|
111
117
|
|
|
@@ -8,11 +8,12 @@ module.exports = (() => {
|
|
|
8
8
|
* @public
|
|
9
9
|
*/
|
|
10
10
|
class PositionGroupDefinition {
|
|
11
|
-
constructor(name, keySelector, descriptionSelector, requiredGroups, single) {
|
|
11
|
+
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single) {
|
|
12
12
|
this._name = name;
|
|
13
13
|
|
|
14
14
|
this._keySelector = keySelector;
|
|
15
15
|
this._descriptionSelector = descriptionSelector;
|
|
16
|
+
this._currencySelector = currencySelector;
|
|
16
17
|
|
|
17
18
|
this._requiredGroups = requiredGroups || [ ];
|
|
18
19
|
this._single = is.boolean(single) && single;
|
|
@@ -30,6 +31,10 @@ module.exports = (() => {
|
|
|
30
31
|
return this._descriptionSelector;
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
get currencySelector() {
|
|
35
|
+
return this._currencySelector;
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
get requiredGroups() {
|
|
34
39
|
return this._requiredGroups;
|
|
35
40
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
2
|
+
Decimal = require('@barchart/common-js/lang/Decimal'),
|
|
2
3
|
Event = require('@barchart/common-js/messaging/Event'),
|
|
3
4
|
is = require('@barchart/common-js/lang/is');
|
|
4
5
|
|
|
@@ -21,6 +22,18 @@ module.exports = (() => {
|
|
|
21
22
|
|
|
22
23
|
const snapshot = this._position.snapshot;
|
|
23
24
|
|
|
25
|
+
this._data.basis = snapshot.basis || Decimal.ZERO;
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
let market;
|
|
29
|
+
|
|
30
|
+
if (position.previous) {
|
|
31
|
+
market = snapshot.open.multiply(position.previous);
|
|
32
|
+
} else {
|
|
33
|
+
market = snapshot.value;
|
|
34
|
+
}
|
|
35
|
+
*/
|
|
36
|
+
|
|
24
37
|
this._priceChangeEvent = new Event(this);
|
|
25
38
|
}
|
|
26
39
|
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -514,6 +514,9 @@ module.exports = (() => {
|
|
|
514
514
|
|
|
515
515
|
},{"@barchart/common-js/lang/Enum":14,"@barchart/common-js/lang/assert":16}],3:[function(require,module,exports){
|
|
516
516
|
const array = require('@barchart/common-js/lang/array'),
|
|
517
|
+
ComparatorBuilder = require('@barchart/common-js/collections/sorting/ComparatorBuilder'),
|
|
518
|
+
comparators = require('@barchart/common-js/collections/sorting/comparators'),
|
|
519
|
+
Currency = require('@barchart/common-js/lang/Currency'),
|
|
517
520
|
assert = require('@barchart/common-js/lang/assert'),
|
|
518
521
|
is = require('@barchart/common-js/lang/is'),
|
|
519
522
|
Tree = require('@barchart/common-js/collections/Tree');
|
|
@@ -564,8 +567,8 @@ module.exports = (() => {
|
|
|
564
567
|
let position = item.position;
|
|
565
568
|
let symbol = null;
|
|
566
569
|
|
|
567
|
-
if (position.instrument && position.instrument.symbol && position.instrument.barchart) {
|
|
568
|
-
symbol = position.instrument.barchart;
|
|
570
|
+
if (position.instrument && position.instrument.symbol && position.instrument.symbol.barchart) {
|
|
571
|
+
symbol = position.instrument.symbol.barchart;
|
|
569
572
|
|
|
570
573
|
if (!map.hasOwnProperty(symbol)) {
|
|
571
574
|
map[symbol] = [ ];
|
|
@@ -577,7 +580,7 @@ module.exports = (() => {
|
|
|
577
580
|
return map;
|
|
578
581
|
}, { });
|
|
579
582
|
|
|
580
|
-
this._definitions = definitions
|
|
583
|
+
this._definitions = definitions;
|
|
581
584
|
|
|
582
585
|
this._tree = new Tree();
|
|
583
586
|
|
|
@@ -592,17 +595,47 @@ module.exports = (() => {
|
|
|
592
595
|
const populatedGroups = array.batchBy(items, currentDefinition.keySelector).map((items) => {
|
|
593
596
|
const first = items[0];
|
|
594
597
|
|
|
595
|
-
return new PositionGroup(items, currentDefinition.descriptionSelector(first), currentDefinition.single && items.length === 1);
|
|
598
|
+
return new PositionGroup(items, currentDefinition.currencySelector(first), currentDefinition.descriptionSelector(first), currentDefinition.single && items.length === 1);
|
|
596
599
|
});
|
|
597
600
|
|
|
598
|
-
const missingGroups = array.difference(currentDefinition.requiredGroups, populatedGroups.map(group => group.description));
|
|
601
|
+
const missingGroups = array.difference(Object.keys(currentDefinition.requiredGroups), populatedGroups.map(group => group.description));
|
|
599
602
|
|
|
600
603
|
const empty = missingGroups.map((description) => {
|
|
601
|
-
return new PositionGroup([ ], description);
|
|
604
|
+
return new PositionGroup([ ], currentDefinition.requiredGroups[description].currency, description);
|
|
602
605
|
});
|
|
603
606
|
|
|
604
607
|
const compositeGroups = populatedGroups.concat(empty);
|
|
605
608
|
|
|
609
|
+
let builder;
|
|
610
|
+
|
|
611
|
+
if (currentDefinition.requiredGroups.length !== 0) {
|
|
612
|
+
const ordering = currentDefinition.requiredGroups.reduce((map, group, index) => {
|
|
613
|
+
map[group] = index;
|
|
614
|
+
|
|
615
|
+
return map;
|
|
616
|
+
}, { });
|
|
617
|
+
|
|
618
|
+
const getIndex = (description) => {
|
|
619
|
+
if (ordering.hasOwnProperty(description)) {
|
|
620
|
+
return ordering[description];
|
|
621
|
+
} else {
|
|
622
|
+
return Number.MAX_VALUE;
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
627
|
+
return comparators.compareNumbers(getIndex(a.description), getIndex(b.description));
|
|
628
|
+
}).thenBy((a, b) => {
|
|
629
|
+
return comparators.compareStrings(a.description, b.description);
|
|
630
|
+
});
|
|
631
|
+
} else {
|
|
632
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
633
|
+
return comparators.compareStrings(a.description, b.description);
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
compositeGroups.sort(builder.toComparator());
|
|
638
|
+
|
|
606
639
|
compositeGroups.forEach((group) => {
|
|
607
640
|
const child = tree.addChild(group);
|
|
608
641
|
|
|
@@ -651,7 +684,7 @@ module.exports = (() => {
|
|
|
651
684
|
return PositionContainer;
|
|
652
685
|
})();
|
|
653
686
|
|
|
654
|
-
},{"./PositionGroup":4,"./PositionGroupDefinition":5,"./PositionItem":6,"@barchart/common-js/collections/Tree":7,"@barchart/common-js/lang/array":15,"@barchart/common-js/lang/assert":16,"@barchart/common-js/lang/is":18}],4:[function(require,module,exports){
|
|
687
|
+
},{"./PositionGroup":4,"./PositionGroupDefinition":5,"./PositionItem":6,"@barchart/common-js/collections/Tree":7,"@barchart/common-js/collections/sorting/ComparatorBuilder":8,"@barchart/common-js/collections/sorting/comparators":9,"@barchart/common-js/lang/Currency":10,"@barchart/common-js/lang/array":15,"@barchart/common-js/lang/assert":16,"@barchart/common-js/lang/is":18}],4:[function(require,module,exports){
|
|
655
688
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
656
689
|
Currency = require('@barchart/common-js/lang/Currency'),
|
|
657
690
|
Decimal = require('@barchart/common-js/lang/Decimal'),
|
|
@@ -665,9 +698,11 @@ module.exports = (() => {
|
|
|
665
698
|
* @public
|
|
666
699
|
*/
|
|
667
700
|
class PositionGroup {
|
|
668
|
-
constructor(items, description, single) {
|
|
669
|
-
this._description = description;
|
|
701
|
+
constructor(items, currency, description, single) {
|
|
670
702
|
this._items = items;
|
|
703
|
+
this._currency = currency;
|
|
704
|
+
|
|
705
|
+
this._description = description;
|
|
671
706
|
|
|
672
707
|
this._single = is.boolean(single) && single;
|
|
673
708
|
|
|
@@ -698,13 +733,21 @@ module.exports = (() => {
|
|
|
698
733
|
this._dataFormat.current = null;
|
|
699
734
|
}
|
|
700
735
|
|
|
701
|
-
calculateVariablePriceData(this, item
|
|
736
|
+
calculateVariablePriceData(this, item);
|
|
702
737
|
});
|
|
703
738
|
});
|
|
704
739
|
|
|
705
740
|
calculateStaticData(this);
|
|
706
741
|
}
|
|
707
742
|
|
|
743
|
+
get items() {
|
|
744
|
+
return this._items;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
get currency() {
|
|
748
|
+
return this._currency;
|
|
749
|
+
}
|
|
750
|
+
|
|
708
751
|
get description() {
|
|
709
752
|
return this._description;
|
|
710
753
|
}
|
|
@@ -713,10 +756,6 @@ module.exports = (() => {
|
|
|
713
756
|
return this._dataFormat;
|
|
714
757
|
}
|
|
715
758
|
|
|
716
|
-
get items() {
|
|
717
|
-
return this._items;
|
|
718
|
-
}
|
|
719
|
-
|
|
720
759
|
get single() {
|
|
721
760
|
return this._single;
|
|
722
761
|
}
|
|
@@ -759,7 +798,7 @@ module.exports = (() => {
|
|
|
759
798
|
formatted.basis = format(updates.basis, Currency.USD);
|
|
760
799
|
}
|
|
761
800
|
|
|
762
|
-
function calculateVariablePriceData(group, item
|
|
801
|
+
function calculateVariablePriceData(group, item) {
|
|
763
802
|
|
|
764
803
|
}
|
|
765
804
|
|
|
@@ -777,11 +816,12 @@ module.exports = (() => {
|
|
|
777
816
|
* @public
|
|
778
817
|
*/
|
|
779
818
|
class PositionGroupDefinition {
|
|
780
|
-
constructor(name, keySelector, descriptionSelector, requiredGroups, single) {
|
|
819
|
+
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single) {
|
|
781
820
|
this._name = name;
|
|
782
821
|
|
|
783
822
|
this._keySelector = keySelector;
|
|
784
823
|
this._descriptionSelector = descriptionSelector;
|
|
824
|
+
this._currencySelector = currencySelector;
|
|
785
825
|
|
|
786
826
|
this._requiredGroups = requiredGroups || [ ];
|
|
787
827
|
this._single = is.boolean(single) && single;
|
|
@@ -799,6 +839,10 @@ module.exports = (() => {
|
|
|
799
839
|
return this._descriptionSelector;
|
|
800
840
|
}
|
|
801
841
|
|
|
842
|
+
get currencySelector() {
|
|
843
|
+
return this._currencySelector;
|
|
844
|
+
}
|
|
845
|
+
|
|
802
846
|
get requiredGroups() {
|
|
803
847
|
return this._requiredGroups;
|
|
804
848
|
}
|
|
@@ -813,6 +857,7 @@ module.exports = (() => {
|
|
|
813
857
|
|
|
814
858
|
},{"@barchart/common-js/lang/assert":16,"@barchart/common-js/lang/is":18}],6:[function(require,module,exports){
|
|
815
859
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
860
|
+
Decimal = require('@barchart/common-js/lang/Decimal'),
|
|
816
861
|
Event = require('@barchart/common-js/messaging/Event'),
|
|
817
862
|
is = require('@barchart/common-js/lang/is');
|
|
818
863
|
|
|
@@ -835,6 +880,18 @@ module.exports = (() => {
|
|
|
835
880
|
|
|
836
881
|
const snapshot = this._position.snapshot;
|
|
837
882
|
|
|
883
|
+
this._data.basis = snapshot.basis || Decimal.ZERO;
|
|
884
|
+
|
|
885
|
+
/*
|
|
886
|
+
let market;
|
|
887
|
+
|
|
888
|
+
if (position.previous) {
|
|
889
|
+
market = snapshot.open.multiply(position.previous);
|
|
890
|
+
} else {
|
|
891
|
+
market = snapshot.value;
|
|
892
|
+
}
|
|
893
|
+
*/
|
|
894
|
+
|
|
838
895
|
this._priceChangeEvent = new Event(this);
|
|
839
896
|
}
|
|
840
897
|
|
|
@@ -872,7 +929,7 @@ module.exports = (() => {
|
|
|
872
929
|
return PositionItem;
|
|
873
930
|
})();
|
|
874
931
|
|
|
875
|
-
},{"@barchart/common-js/lang/assert":16,"@barchart/common-js/lang/is":18,"@barchart/common-js/messaging/Event":19}],7:[function(require,module,exports){
|
|
932
|
+
},{"@barchart/common-js/lang/Decimal":12,"@barchart/common-js/lang/assert":16,"@barchart/common-js/lang/is":18,"@barchart/common-js/messaging/Event":19}],7:[function(require,module,exports){
|
|
876
933
|
'use strict';
|
|
877
934
|
|
|
878
935
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
@@ -5313,9 +5370,9 @@ describe('When a position container data is gathered', () => {
|
|
|
5313
5370
|
|
|
5314
5371
|
beforeEach(() => {
|
|
5315
5372
|
definitions = [
|
|
5316
|
-
new PositionGroupDefinition('Total', x => true, x => 'Total'),
|
|
5317
|
-
new PositionGroupDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name),
|
|
5318
|
-
new PositionGroupDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart)
|
|
5373
|
+
new PositionGroupDefinition('Total', x => true, x => 'Total', x => Currency.CAD),
|
|
5374
|
+
new PositionGroupDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
|
|
5375
|
+
new PositionGroupDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
|
|
5319
5376
|
];
|
|
5320
5377
|
|
|
5321
5378
|
try {
|
|
@@ -56,9 +56,9 @@ describe('When a position container data is gathered', () => {
|
|
|
56
56
|
|
|
57
57
|
beforeEach(() => {
|
|
58
58
|
definitions = [
|
|
59
|
-
new PositionGroupDefinition('Total', x => true, x => 'Total'),
|
|
60
|
-
new PositionGroupDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name),
|
|
61
|
-
new PositionGroupDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart)
|
|
59
|
+
new PositionGroupDefinition('Total', x => true, x => 'Total', x => Currency.CAD),
|
|
60
|
+
new PositionGroupDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
|
|
61
|
+
new PositionGroupDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
|
|
62
62
|
];
|
|
63
63
|
|
|
64
64
|
try {
|