@barchart/portfolio-api-common 1.0.96 → 1.0.97
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/formatters/TransactionFormatter.js +44 -32
- package/lib/processing/PositionContainer.js +119 -98
- package/lib/processing/definitions/PositionLevelDefinition.js +143 -0
- package/lib/processing/definitions/PositionTreeDefinition.js +52 -0
- package/package.json +1 -1
- package/test/SpecRunner.js +350 -176
- package/test/specs/processing/PositionContainerSpec.js +15 -11
- package/lib/processing/PositionGroupDefinition.js +0 -48
package/test/SpecRunner.js
CHANGED
|
@@ -116,7 +116,7 @@ module.exports = (() => {
|
|
|
116
116
|
return InstrumentType;
|
|
117
117
|
})();
|
|
118
118
|
|
|
119
|
-
},{"@barchart/common-js/lang/Enum":
|
|
119
|
+
},{"@barchart/common-js/lang/Enum":16,"@barchart/common-js/lang/assert":18}],2:[function(require,module,exports){
|
|
120
120
|
const array = require('@barchart/common-js/lang/array'),
|
|
121
121
|
assert = require('@barchart/common-js/lang/assert'),
|
|
122
122
|
Day = require('@barchart/common-js/lang/Day'),
|
|
@@ -373,7 +373,7 @@ module.exports = (() => {
|
|
|
373
373
|
return PositionSummaryFrame;
|
|
374
374
|
})();
|
|
375
375
|
|
|
376
|
-
},{"@barchart/common-js/lang/Day":
|
|
376
|
+
},{"@barchart/common-js/lang/Day":13,"@barchart/common-js/lang/Decimal":14,"@barchart/common-js/lang/Enum":16,"@barchart/common-js/lang/array":17,"@barchart/common-js/lang/assert":18,"@barchart/common-js/lang/is":20}],3:[function(require,module,exports){
|
|
377
377
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
378
378
|
Enum = require('@barchart/common-js/lang/Enum');
|
|
379
379
|
|
|
@@ -713,17 +713,20 @@ module.exports = (() => {
|
|
|
713
713
|
return TransactionType;
|
|
714
714
|
})();
|
|
715
715
|
|
|
716
|
-
},{"@barchart/common-js/lang/Enum":
|
|
716
|
+
},{"@barchart/common-js/lang/Enum":16,"@barchart/common-js/lang/assert":18}],4:[function(require,module,exports){
|
|
717
717
|
const array = require('@barchart/common-js/lang/array'),
|
|
718
|
+
assert = require('@barchart/common-js/lang/assert'),
|
|
718
719
|
ComparatorBuilder = require('@barchart/common-js/collections/sorting/ComparatorBuilder'),
|
|
719
720
|
comparators = require('@barchart/common-js/collections/sorting/comparators'),
|
|
720
721
|
Currency = require('@barchart/common-js/lang/Currency'),
|
|
721
|
-
assert = require('@barchart/common-js/lang/assert'),
|
|
722
722
|
is = require('@barchart/common-js/lang/is'),
|
|
723
723
|
Tree = require('@barchart/common-js/collections/Tree');
|
|
724
724
|
|
|
725
725
|
const PositionSummaryFrame = require('./../data/PositionSummaryFrame');
|
|
726
726
|
|
|
727
|
+
const PositionLevelDefinition = require('./definitions/PositionLevelDefinition'),
|
|
728
|
+
PositionTreeDefinition = require('./definitions/PositionTreeDefinition');
|
|
729
|
+
|
|
727
730
|
const PositionGroup = require('./PositionGroup'),
|
|
728
731
|
PositionItem = require('./PositionItem');
|
|
729
732
|
|
|
@@ -731,22 +734,32 @@ module.exports = (() => {
|
|
|
731
734
|
'use strict';
|
|
732
735
|
|
|
733
736
|
/**
|
|
737
|
+
* A container for positions which groups the positions into one or more
|
|
738
|
+
* trees for aggregation and display purposes. For example, perhaps a positions
|
|
739
|
+
* grouped first by asset class then by position is desired.
|
|
740
|
+
*
|
|
741
|
+
* Furthermore, the container performs aggregation (driven primarily by price
|
|
742
|
+
* changes) for each level of grouping in the internal tree(s).
|
|
743
|
+
*
|
|
734
744
|
* @public
|
|
745
|
+
* @param {Array.<PositionTreeDefinition>} definitions
|
|
746
|
+
* @param {Array.<Object>} portfolios
|
|
747
|
+
* @param {Array.<Object>} positions
|
|
748
|
+
* @param {Array.<Object>} summaries
|
|
735
749
|
*/
|
|
736
750
|
class PositionContainer {
|
|
737
|
-
constructor(portfolios, positions, summaries
|
|
738
|
-
|
|
739
|
-
|
|
751
|
+
constructor(definitions, portfolios, positions, summaries) {
|
|
752
|
+
assert.argumentIsArray(definitions, 'definitions', PositionTreeDefinition, 'PositionTreeDefinition');
|
|
753
|
+
assert.argumentIsArray(portfolios, 'portfolios');
|
|
754
|
+
assert.argumentIsArray(positions, 'positions');
|
|
755
|
+
assert.argumentIsArray(summaries, 'summaries');
|
|
740
756
|
|
|
741
|
-
const previousSummaryFrame =
|
|
757
|
+
const previousSummaryFrame = PositionSummaryFrame.YEARLY;
|
|
742
758
|
const previousSummaryRanges = previousSummaryFrame.getRecentRanges(0);
|
|
743
759
|
|
|
744
760
|
const currentSummaryFrame = PositionSummaryFrame.YTD;
|
|
745
761
|
const currentSummaryRange = array.last(currentSummaryFrame.getRecentRanges(0));
|
|
746
762
|
|
|
747
|
-
this._summaryDescriptionCurrent = previousSummaryFrame.describeRange(array.last(previousSummaryRanges));
|
|
748
|
-
this._summaryDescriptionPrevious = currentSummaryFrame.describeRange(currentSummaryRange);
|
|
749
|
-
|
|
750
763
|
this._portfolios = portfolios.reduce((map, portfolio) => {
|
|
751
764
|
map[portfolio.portfolio] = portfolio;
|
|
752
765
|
|
|
@@ -825,111 +838,101 @@ module.exports = (() => {
|
|
|
825
838
|
|
|
826
839
|
return map;
|
|
827
840
|
}, { });
|
|
841
|
+
|
|
842
|
+
this._trees = definitions.reduce((map, treeDefinition) => {
|
|
843
|
+
const tree = new Tree();
|
|
828
844
|
|
|
829
|
-
|
|
845
|
+
const createGroups = (currentTree, items, levelDefinitions) => {
|
|
846
|
+
if (levelDefinitions.length === 0) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
830
849
|
|
|
831
|
-
|
|
832
|
-
if (definitions.length === 0) {
|
|
833
|
-
return;
|
|
834
|
-
}
|
|
850
|
+
const parent = currentTree.getValue() || null;
|
|
835
851
|
|
|
836
|
-
|
|
852
|
+
const levelDefinition = levelDefinitions[0];
|
|
837
853
|
|
|
838
|
-
|
|
839
|
-
|
|
854
|
+
const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
|
|
855
|
+
const populatedGroups = Object.keys(populatedObjects).map(key => populatedObjects[key]).map((items) => {
|
|
856
|
+
const first = items[0];
|
|
840
857
|
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
const first = items[0];
|
|
858
|
+
return new PositionGroup(this, parent, items, levelDefinition.currencySelector(first), levelDefinition.descriptionSelector(first), levelDefinition.single && items.length === 1);
|
|
859
|
+
});
|
|
844
860
|
|
|
845
|
-
|
|
846
|
-
});
|
|
861
|
+
const missingGroups = array.difference(levelDefinition.requiredGroups.map(group => group.description), populatedGroups.map(group => group.description));
|
|
847
862
|
|
|
848
|
-
|
|
863
|
+
const empty = missingGroups.map((description) => {
|
|
864
|
+
return new PositionGroup(this, parent, [ ], levelDefinition.requiredGroups.find(group => group.description === description).currency, description);
|
|
865
|
+
});
|
|
849
866
|
|
|
850
|
-
|
|
851
|
-
return new PositionGroup(this, parent, [ ], currentDefinition.requiredGroups.find(group => group.description === description).currency, description);
|
|
852
|
-
});
|
|
867
|
+
const compositeGroups = populatedGroups.concat(empty);
|
|
853
868
|
|
|
854
|
-
|
|
869
|
+
let builder;
|
|
855
870
|
|
|
856
|
-
|
|
871
|
+
if (levelDefinition.requiredGroups.length !== 0) {
|
|
872
|
+
const ordering = levelDefinition.requiredGroups.reduce((map, group, index) => {
|
|
873
|
+
map[group.description] = index;
|
|
857
874
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
map[group.description] = index;
|
|
875
|
+
return map;
|
|
876
|
+
}, { });
|
|
861
877
|
|
|
862
|
-
|
|
863
|
-
|
|
878
|
+
const getIndex = (description) => {
|
|
879
|
+
if (ordering.hasOwnProperty(description)) {
|
|
880
|
+
return ordering[description];
|
|
881
|
+
} else {
|
|
882
|
+
return Number.MAX_VALUE;
|
|
883
|
+
}
|
|
884
|
+
};
|
|
864
885
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
886
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
887
|
+
return comparators.compareNumbers(getIndex(a.description), getIndex(b.description));
|
|
888
|
+
}).thenBy((a, b) => {
|
|
889
|
+
return comparators.compareStrings(a.description, b.description);
|
|
890
|
+
});
|
|
891
|
+
} else {
|
|
892
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
893
|
+
return comparators.compareStrings(a.description, b.description);
|
|
894
|
+
});
|
|
895
|
+
}
|
|
872
896
|
|
|
873
|
-
builder
|
|
874
|
-
return comparators.compareNumbers(getIndex(a.description), getIndex(b.description));
|
|
875
|
-
}).thenBy((a, b) => {
|
|
876
|
-
return comparators.compareStrings(a.description, b.description);
|
|
877
|
-
});
|
|
878
|
-
} else {
|
|
879
|
-
builder = ComparatorBuilder.startWith((a, b) => {
|
|
880
|
-
return comparators.compareStrings(a.description, b.description);
|
|
881
|
-
});
|
|
882
|
-
}
|
|
897
|
+
compositeGroups.sort(builder.toComparator());
|
|
883
898
|
|
|
884
|
-
|
|
899
|
+
compositeGroups.forEach((group) => {
|
|
900
|
+
const childTree = currentTree.addChild(group);
|
|
885
901
|
|
|
886
|
-
|
|
887
|
-
|
|
902
|
+
group.registerMarketPercentChangeHandler(() => {
|
|
903
|
+
currentTree.walk((childGroup) => childGroup.refreshMarketPercent());
|
|
904
|
+
});
|
|
888
905
|
|
|
889
|
-
|
|
890
|
-
this._tree.walk((childGroup) => childGroup.refreshMarketPercent());
|
|
906
|
+
createGroups(childTree, group.items, array.dropLeft(levelDefinitions));
|
|
891
907
|
});
|
|
908
|
+
};
|
|
892
909
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
910
|
+
createGroups(tree, this._items, treeDefinition.definitions);
|
|
911
|
+
|
|
912
|
+
map[treeDefinition.name] = tree;
|
|
896
913
|
|
|
897
|
-
|
|
914
|
+
return map;
|
|
915
|
+
}, { });
|
|
898
916
|
}
|
|
899
917
|
|
|
900
918
|
get defaultCurrency() {
|
|
901
919
|
return this._defaultCurrency;
|
|
902
920
|
}
|
|
903
921
|
|
|
904
|
-
|
|
905
|
-
return this._summaryDescriptionCurrent;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
getPreviousSummaryDescription() {
|
|
909
|
-
return this._summaryDescriptionPrevious;
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
startTransaction(executor) {
|
|
913
|
-
assert.argumentIsRequired(executor, 'executor', Function);
|
|
914
|
-
|
|
915
|
-
this._tree.walk(group => group.setSuspended(true), false, false);
|
|
916
|
-
|
|
917
|
-
executor(this);
|
|
918
|
-
|
|
919
|
-
this._tree.walk(group => group.setSuspended(false), false, false);
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
getSymbols() {
|
|
922
|
+
getPositionSymbols() {
|
|
923
923
|
return Object.keys(this._symbols);
|
|
924
924
|
}
|
|
925
925
|
|
|
926
|
-
|
|
927
|
-
|
|
926
|
+
setPositionPrice(symbol, price) {
|
|
927
|
+
assert.argumentIsOptional(symbol, 'symbol', String);
|
|
928
|
+
assert.argumentIsOptional(price, 'price', Number);
|
|
929
|
+
|
|
930
|
+
if (this._symbols.hasOwnProperty(symbol) && is.number(price)) {
|
|
928
931
|
this._symbols[symbol].forEach(item => item.setPrice(price));
|
|
929
932
|
}
|
|
930
933
|
}
|
|
931
934
|
|
|
932
|
-
|
|
935
|
+
getForexSymbols() {
|
|
933
936
|
const codes = Object.keys(this._currencies);
|
|
934
937
|
|
|
935
938
|
return codes.reduce((symbols, code) => {
|
|
@@ -941,28 +944,38 @@ module.exports = (() => {
|
|
|
941
944
|
}, [ ]);
|
|
942
945
|
}
|
|
943
946
|
|
|
944
|
-
|
|
947
|
+
setForexPrice(symbol, price) {
|
|
948
|
+
assert.argumentIsOptional(symbol, 'symbol', String);
|
|
949
|
+
assert.argumentIsOptional(price, 'price', Number);
|
|
945
950
|
|
|
951
|
+
return;
|
|
946
952
|
}
|
|
947
953
|
|
|
948
|
-
getGroup(keys) {
|
|
949
|
-
|
|
950
|
-
|
|
954
|
+
getGroup(name, keys) {
|
|
955
|
+
assert.argumentIsRequired(name, 'name', String);
|
|
956
|
+
assert.argumentIsArray(keys, 'keys', Number);
|
|
951
957
|
|
|
952
|
-
|
|
953
|
-
|
|
958
|
+
return findNode(this._trees[name], keys).getValue();
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
getGroups(name, keys) {
|
|
962
|
+
assert.argumentIsRequired(name, 'name', String);
|
|
963
|
+
assert.argumentIsArray(keys, 'keys', Number);
|
|
954
964
|
|
|
955
|
-
return node.getValue();
|
|
965
|
+
return findNode(this._trees[name], keys).getChildren().map(node => node.getValue());
|
|
956
966
|
}
|
|
957
967
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
968
|
+
startTransaction(name, executor) {
|
|
969
|
+
assert.argumentIsRequired(name, 'name', String);
|
|
970
|
+
assert.argumentIsRequired(executor, 'executor', Function);
|
|
961
971
|
|
|
962
|
-
|
|
963
|
-
|
|
972
|
+
assert.argumentIsRequired(executor, 'executor', Function);
|
|
973
|
+
|
|
974
|
+
this._trees[name].walk(group => group.setSuspended(true), false, false);
|
|
975
|
+
|
|
976
|
+
executor(this);
|
|
964
977
|
|
|
965
|
-
|
|
978
|
+
this._trees[name].walk(group => group.setSuspended(false), false, false);
|
|
966
979
|
}
|
|
967
980
|
|
|
968
981
|
toString() {
|
|
@@ -970,6 +983,14 @@ module.exports = (() => {
|
|
|
970
983
|
}
|
|
971
984
|
}
|
|
972
985
|
|
|
986
|
+
function findNode(tree, keys) {
|
|
987
|
+
return keys.reduce((tree, key) => {
|
|
988
|
+
tree = tree.findChild(group => group.description === key);
|
|
989
|
+
|
|
990
|
+
return tree;
|
|
991
|
+
}, tree);
|
|
992
|
+
}
|
|
993
|
+
|
|
973
994
|
function getSummaryArray(ranges) {
|
|
974
995
|
return ranges.map(range => null);
|
|
975
996
|
}
|
|
@@ -977,7 +998,7 @@ module.exports = (() => {
|
|
|
977
998
|
return PositionContainer;
|
|
978
999
|
})();
|
|
979
1000
|
|
|
980
|
-
},{"./../data/PositionSummaryFrame":2,"./PositionGroup":5,"./PositionItem":7,"@barchart/common-js/collections/Tree":
|
|
1001
|
+
},{"./../data/PositionSummaryFrame":2,"./PositionGroup":5,"./PositionItem":6,"./definitions/PositionLevelDefinition":7,"./definitions/PositionTreeDefinition":8,"@barchart/common-js/collections/Tree":9,"@barchart/common-js/collections/sorting/ComparatorBuilder":10,"@barchart/common-js/collections/sorting/comparators":11,"@barchart/common-js/lang/Currency":12,"@barchart/common-js/lang/array":17,"@barchart/common-js/lang/assert":18,"@barchart/common-js/lang/is":20}],5:[function(require,module,exports){
|
|
981
1002
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
982
1003
|
Currency = require('@barchart/common-js/lang/Currency'),
|
|
983
1004
|
Decimal = require('@barchart/common-js/lang/Decimal'),
|
|
@@ -1308,57 +1329,7 @@ module.exports = (() => {
|
|
|
1308
1329
|
return PositionGroup;
|
|
1309
1330
|
})();
|
|
1310
1331
|
|
|
1311
|
-
},{"@barchart/common-js/lang/Currency":
|
|
1312
|
-
const assert = require('@barchart/common-js/lang/assert'),
|
|
1313
|
-
is = require('@barchart/common-js/lang/is');
|
|
1314
|
-
|
|
1315
|
-
module.exports = (() => {
|
|
1316
|
-
'use strict';
|
|
1317
|
-
|
|
1318
|
-
/**
|
|
1319
|
-
* @public
|
|
1320
|
-
*/
|
|
1321
|
-
class PositionGroupDefinition {
|
|
1322
|
-
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single) {
|
|
1323
|
-
this._name = name;
|
|
1324
|
-
|
|
1325
|
-
this._keySelector = keySelector;
|
|
1326
|
-
this._descriptionSelector = descriptionSelector;
|
|
1327
|
-
this._currencySelector = currencySelector;
|
|
1328
|
-
|
|
1329
|
-
this._requiredGroups = requiredGroups || [ ];
|
|
1330
|
-
this._single = is.boolean(single) && single;
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
get name() {
|
|
1334
|
-
return this._name;
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
|
-
get keySelector() {
|
|
1338
|
-
return this._keySelector;
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
get descriptionSelector() {
|
|
1342
|
-
return this._descriptionSelector;
|
|
1343
|
-
}
|
|
1344
|
-
|
|
1345
|
-
get currencySelector() {
|
|
1346
|
-
return this._currencySelector;
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
get requiredGroups() {
|
|
1350
|
-
return this._requiredGroups;
|
|
1351
|
-
}
|
|
1352
|
-
|
|
1353
|
-
toString() {
|
|
1354
|
-
return '[PositionGroupDefinition]';
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
return PositionGroupDefinition;
|
|
1359
|
-
})();
|
|
1360
|
-
|
|
1361
|
-
},{"@barchart/common-js/lang/assert":17,"@barchart/common-js/lang/is":19}],7:[function(require,module,exports){
|
|
1332
|
+
},{"@barchart/common-js/lang/Currency":12,"@barchart/common-js/lang/Decimal":14,"@barchart/common-js/lang/assert":18,"@barchart/common-js/lang/formatter":19,"@barchart/common-js/lang/is":20,"@barchart/common-js/messaging/Event":21}],6:[function(require,module,exports){
|
|
1362
1333
|
const array = require('@barchart/common-js/lang/array'),
|
|
1363
1334
|
assert = require('@barchart/common-js/lang/assert'),
|
|
1364
1335
|
Decimal = require('@barchart/common-js/lang/Decimal'),
|
|
@@ -1582,7 +1553,206 @@ module.exports = (() => {
|
|
|
1582
1553
|
return PositionItem;
|
|
1583
1554
|
})();
|
|
1584
1555
|
|
|
1585
|
-
},{"./../data/InstrumentType":1,"@barchart/common-js/lang/Decimal":
|
|
1556
|
+
},{"./../data/InstrumentType":1,"@barchart/common-js/lang/Decimal":14,"@barchart/common-js/lang/array":17,"@barchart/common-js/lang/assert":18,"@barchart/common-js/lang/is":20,"@barchart/common-js/messaging/Event":21}],7:[function(require,module,exports){
|
|
1557
|
+
const assert = require('@barchart/common-js/lang/assert'),
|
|
1558
|
+
is = require('@barchart/common-js/lang/is');
|
|
1559
|
+
|
|
1560
|
+
module.exports = (() => {
|
|
1561
|
+
'use strict';
|
|
1562
|
+
|
|
1563
|
+
/**
|
|
1564
|
+
* Defines a grouping level within a tree of positions. A level could represent a
|
|
1565
|
+
* group of multiple positions (e.g. all equities or all positions for a portfolio).
|
|
1566
|
+
* Alternately, a level could also represent a single position.
|
|
1567
|
+
*
|
|
1568
|
+
* @public
|
|
1569
|
+
* @param {String} name
|
|
1570
|
+
* @param {PositionLevelDefinition~keySelector} keySelector
|
|
1571
|
+
* @param {PositionLevelDefinition~descriptionSelector} descriptionSelector
|
|
1572
|
+
* @param {PositionLevelDefinition~currencySelector} currencySelector
|
|
1573
|
+
* @param {Array.<String>=} requiredGroups
|
|
1574
|
+
* @param {Boolean=} single
|
|
1575
|
+
*/
|
|
1576
|
+
class PositionLevelDefinition {
|
|
1577
|
+
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single) {
|
|
1578
|
+
assert.argumentIsRequired(name, 'name', String);
|
|
1579
|
+
assert.argumentIsRequired(keySelector, 'keySelector', Function);
|
|
1580
|
+
assert.argumentIsRequired(descriptionSelector, 'descriptionSelector', Function);
|
|
1581
|
+
assert.argumentIsRequired(currencySelector, 'currencySelector', Function);
|
|
1582
|
+
|
|
1583
|
+
if (requiredGroups) {
|
|
1584
|
+
assert.argumentIsArray(requiredGroups, 'requiredGroups', String);
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
assert.argumentIsOptional(single, 'single', Boolean);
|
|
1588
|
+
|
|
1589
|
+
this._name = name;
|
|
1590
|
+
|
|
1591
|
+
this._keySelector = keySelector;
|
|
1592
|
+
this._descriptionSelector = descriptionSelector;
|
|
1593
|
+
this._currencySelector = currencySelector;
|
|
1594
|
+
|
|
1595
|
+
this._requiredGroups = requiredGroups || [ ];
|
|
1596
|
+
this._single = is.boolean(single) && single;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* The name of the grouping level.
|
|
1601
|
+
*
|
|
1602
|
+
* @public
|
|
1603
|
+
* @returns {String}
|
|
1604
|
+
*/
|
|
1605
|
+
get name() {
|
|
1606
|
+
return this._name;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
/**
|
|
1610
|
+
* A function, when given a {@link PositionItem} returns a string that is used
|
|
1611
|
+
* to group {@link PositionItem} instances into different groups.
|
|
1612
|
+
*
|
|
1613
|
+
* @public
|
|
1614
|
+
* @returns {PositionLevelDefinition~keySelector}
|
|
1615
|
+
*/
|
|
1616
|
+
get keySelector() {
|
|
1617
|
+
return this._keySelector;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
/**
|
|
1621
|
+
* A function, when given a {@link PositionItem} returns a string used to describe the
|
|
1622
|
+
* group.
|
|
1623
|
+
*
|
|
1624
|
+
* @public
|
|
1625
|
+
* @returns {PositionLevelDefinition~descriptionSelector}
|
|
1626
|
+
*/
|
|
1627
|
+
get descriptionSelector() {
|
|
1628
|
+
return this._descriptionSelector;
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
/**
|
|
1632
|
+
* A function, when given a {@link PositionItem} returns the {@link Currency} used to
|
|
1633
|
+
* display values for the group.
|
|
1634
|
+
*
|
|
1635
|
+
* @public
|
|
1636
|
+
* @returns {PositionLevelDefinition~currencySelector}
|
|
1637
|
+
*/
|
|
1638
|
+
get currencySelector() {
|
|
1639
|
+
return this._currencySelector;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
/**
|
|
1643
|
+
* Indicates the required groups (i.e. descriptions). The allows for the creation of empty
|
|
1644
|
+
* groups.
|
|
1645
|
+
*
|
|
1646
|
+
* @public
|
|
1647
|
+
* @returns {Array<String>}
|
|
1648
|
+
*/
|
|
1649
|
+
get requiredGroups() {
|
|
1650
|
+
return this._requiredGroups;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
/**
|
|
1654
|
+
* Indicates if the grouping level is meant to only contain a single item.
|
|
1655
|
+
*
|
|
1656
|
+
* @public
|
|
1657
|
+
* @returns {Boolean}
|
|
1658
|
+
*/
|
|
1659
|
+
get single() {
|
|
1660
|
+
return this._single;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
toString() {
|
|
1664
|
+
return '[PositionLevelDefinition]';
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
/**
|
|
1669
|
+
* A callback used to determine the eligibility for membership of a {@link PositionItem}
|
|
1670
|
+
* within a group.
|
|
1671
|
+
*
|
|
1672
|
+
* @public
|
|
1673
|
+
* @callback PositionLevelDefinition~keySelector
|
|
1674
|
+
* @param {PositionItem} session
|
|
1675
|
+
* @returns {String}
|
|
1676
|
+
*/
|
|
1677
|
+
|
|
1678
|
+
/**
|
|
1679
|
+
* A callback used to determine the human-readable name of a group. This function should
|
|
1680
|
+
* return the same value for any {@link PositionItem} in the group.
|
|
1681
|
+
*
|
|
1682
|
+
* @public
|
|
1683
|
+
* @callback PositionLevelDefinition~descriptionSelector
|
|
1684
|
+
* @param {PositionItem} session
|
|
1685
|
+
* @returns {String}
|
|
1686
|
+
*/
|
|
1687
|
+
|
|
1688
|
+
/**
|
|
1689
|
+
* A callback used to determine the display {@link Currency} for the group. This function should
|
|
1690
|
+
* return the same value for any {@link PositionItem} in the group.
|
|
1691
|
+
*
|
|
1692
|
+
* @public
|
|
1693
|
+
* @callback PositionLevelDefinition~currencySelector
|
|
1694
|
+
* @param {PositionItem} session
|
|
1695
|
+
* @returns {Currency}
|
|
1696
|
+
*/
|
|
1697
|
+
|
|
1698
|
+
return PositionLevelDefinition;
|
|
1699
|
+
})();
|
|
1700
|
+
|
|
1701
|
+
},{"@barchart/common-js/lang/assert":18,"@barchart/common-js/lang/is":20}],8:[function(require,module,exports){
|
|
1702
|
+
const assert = require('@barchart/common-js/lang/assert');
|
|
1703
|
+
|
|
1704
|
+
const PositionLevelDefinition = require('./PositionLevelDefinition');
|
|
1705
|
+
|
|
1706
|
+
module.exports = (() => {
|
|
1707
|
+
'use strict';
|
|
1708
|
+
|
|
1709
|
+
/**
|
|
1710
|
+
* Defines the structure for a tree of positions.
|
|
1711
|
+
*
|
|
1712
|
+
* @public
|
|
1713
|
+
* @param {String} name
|
|
1714
|
+
* @param {Array.<PositionLevelDefinition>} definitions
|
|
1715
|
+
*/
|
|
1716
|
+
class PositionTreeDefinitions {
|
|
1717
|
+
constructor(name, definitions) {
|
|
1718
|
+
assert.argumentIsRequired(name, 'name', String);
|
|
1719
|
+
assert.argumentIsArray(definitions, 'definitions', PositionLevelDefinition, 'PositionLevelDefinition');
|
|
1720
|
+
|
|
1721
|
+
this._name = name;
|
|
1722
|
+
this._definitions = definitions;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
/**
|
|
1726
|
+
* The name of the tree.
|
|
1727
|
+
*
|
|
1728
|
+
* @returns {String}
|
|
1729
|
+
*/
|
|
1730
|
+
get name() {
|
|
1731
|
+
return this._name;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
/**
|
|
1735
|
+
* An ordered list of {@link PositionLevelDefinitions} that describes the
|
|
1736
|
+
* levels of the tree. The first item represents the top-most level of the
|
|
1737
|
+
* tree (i.e. the children of the root node) and the last item represents the
|
|
1738
|
+
* bottom-most level of the tree (i.e. leaf nodes).
|
|
1739
|
+
*
|
|
1740
|
+
* @public
|
|
1741
|
+
* @returns {Array.<PositionTreeDefinition>}
|
|
1742
|
+
*/
|
|
1743
|
+
get definitions() {
|
|
1744
|
+
return this._definitions;
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
toString() {
|
|
1748
|
+
return '[PositionTreeDefinitions]';
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
return PositionTreeDefinitions;
|
|
1753
|
+
})();
|
|
1754
|
+
|
|
1755
|
+
},{"./PositionLevelDefinition":7,"@barchart/common-js/lang/assert":18}],9:[function(require,module,exports){
|
|
1586
1756
|
'use strict';
|
|
1587
1757
|
|
|
1588
1758
|
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; }; }();
|
|
@@ -1891,7 +2061,7 @@ module.exports = function () {
|
|
|
1891
2061
|
return Tree;
|
|
1892
2062
|
}();
|
|
1893
2063
|
|
|
1894
|
-
},{"./../lang/is":
|
|
2064
|
+
},{"./../lang/is":20}],10:[function(require,module,exports){
|
|
1895
2065
|
'use strict';
|
|
1896
2066
|
|
|
1897
2067
|
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; }; }();
|
|
@@ -2035,7 +2205,7 @@ module.exports = function () {
|
|
|
2035
2205
|
return ComparatorBuilder;
|
|
2036
2206
|
}();
|
|
2037
2207
|
|
|
2038
|
-
},{"./../../lang/assert":
|
|
2208
|
+
},{"./../../lang/assert":18,"./comparators":11}],11:[function(require,module,exports){
|
|
2039
2209
|
'use strict';
|
|
2040
2210
|
|
|
2041
2211
|
var assert = require('./../../lang/assert');
|
|
@@ -2110,7 +2280,7 @@ module.exports = function () {
|
|
|
2110
2280
|
};
|
|
2111
2281
|
}();
|
|
2112
2282
|
|
|
2113
|
-
},{"./../../lang/assert":
|
|
2283
|
+
},{"./../../lang/assert":18}],12:[function(require,module,exports){
|
|
2114
2284
|
'use strict';
|
|
2115
2285
|
|
|
2116
2286
|
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; }; }();
|
|
@@ -2253,7 +2423,7 @@ module.exports = function () {
|
|
|
2253
2423
|
return Currency;
|
|
2254
2424
|
}();
|
|
2255
2425
|
|
|
2256
|
-
},{"./Enum":
|
|
2426
|
+
},{"./Enum":16,"./assert":18,"./is":20}],13:[function(require,module,exports){
|
|
2257
2427
|
'use strict';
|
|
2258
2428
|
|
|
2259
2429
|
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; }; }();
|
|
@@ -2806,7 +2976,7 @@ module.exports = function () {
|
|
|
2806
2976
|
return Day;
|
|
2807
2977
|
}();
|
|
2808
2978
|
|
|
2809
|
-
},{"./../collections/sorting/ComparatorBuilder":
|
|
2979
|
+
},{"./../collections/sorting/ComparatorBuilder":10,"./../collections/sorting/comparators":11,"./assert":18,"./is":20}],14:[function(require,module,exports){
|
|
2810
2980
|
'use strict';
|
|
2811
2981
|
|
|
2812
2982
|
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; }; }();
|
|
@@ -3386,7 +3556,7 @@ module.exports = function () {
|
|
|
3386
3556
|
return Decimal;
|
|
3387
3557
|
}();
|
|
3388
3558
|
|
|
3389
|
-
},{"./Enum":
|
|
3559
|
+
},{"./Enum":16,"./assert":18,"./is":20,"big.js":22}],15:[function(require,module,exports){
|
|
3390
3560
|
'use strict';
|
|
3391
3561
|
|
|
3392
3562
|
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; }; }();
|
|
@@ -3535,7 +3705,7 @@ module.exports = function () {
|
|
|
3535
3705
|
return Disposable;
|
|
3536
3706
|
}();
|
|
3537
3707
|
|
|
3538
|
-
},{"./assert":
|
|
3708
|
+
},{"./assert":18}],16:[function(require,module,exports){
|
|
3539
3709
|
'use strict';
|
|
3540
3710
|
|
|
3541
3711
|
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; }; }();
|
|
@@ -3677,7 +3847,7 @@ module.exports = function () {
|
|
|
3677
3847
|
return Enum;
|
|
3678
3848
|
}();
|
|
3679
3849
|
|
|
3680
|
-
},{"./assert":
|
|
3850
|
+
},{"./assert":18}],17:[function(require,module,exports){
|
|
3681
3851
|
'use strict';
|
|
3682
3852
|
|
|
3683
3853
|
var assert = require('./assert'),
|
|
@@ -4058,7 +4228,7 @@ module.exports = function () {
|
|
|
4058
4228
|
};
|
|
4059
4229
|
}();
|
|
4060
4230
|
|
|
4061
|
-
},{"./assert":
|
|
4231
|
+
},{"./assert":18,"./is":20}],18:[function(require,module,exports){
|
|
4062
4232
|
'use strict';
|
|
4063
4233
|
|
|
4064
4234
|
var is = require('./is');
|
|
@@ -4206,7 +4376,7 @@ module.exports = function () {
|
|
|
4206
4376
|
};
|
|
4207
4377
|
}();
|
|
4208
4378
|
|
|
4209
|
-
},{"./is":
|
|
4379
|
+
},{"./is":20}],19:[function(require,module,exports){
|
|
4210
4380
|
'use strict';
|
|
4211
4381
|
|
|
4212
4382
|
module.exports = function () {
|
|
@@ -4271,7 +4441,7 @@ module.exports = function () {
|
|
|
4271
4441
|
};
|
|
4272
4442
|
}();
|
|
4273
4443
|
|
|
4274
|
-
},{}],
|
|
4444
|
+
},{}],20:[function(require,module,exports){
|
|
4275
4445
|
'use strict';
|
|
4276
4446
|
|
|
4277
4447
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
|
@@ -4494,7 +4664,7 @@ module.exports = function () {
|
|
|
4494
4664
|
};
|
|
4495
4665
|
}();
|
|
4496
4666
|
|
|
4497
|
-
},{}],
|
|
4667
|
+
},{}],21:[function(require,module,exports){
|
|
4498
4668
|
'use strict';
|
|
4499
4669
|
|
|
4500
4670
|
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; }; }();
|
|
@@ -4666,7 +4836,7 @@ module.exports = function () {
|
|
|
4666
4836
|
return Event;
|
|
4667
4837
|
}();
|
|
4668
4838
|
|
|
4669
|
-
},{"./../lang/Disposable":
|
|
4839
|
+
},{"./../lang/Disposable":15,"./../lang/assert":18}],22:[function(require,module,exports){
|
|
4670
4840
|
/*
|
|
4671
4841
|
* big.js v5.0.3
|
|
4672
4842
|
* A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic.
|
|
@@ -5607,7 +5777,7 @@ module.exports = function () {
|
|
|
5607
5777
|
}
|
|
5608
5778
|
})(this);
|
|
5609
5779
|
|
|
5610
|
-
},{}],
|
|
5780
|
+
},{}],23:[function(require,module,exports){
|
|
5611
5781
|
const Day = require('@barchart/common-js/lang/Day'),
|
|
5612
5782
|
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
5613
5783
|
|
|
@@ -5964,14 +6134,15 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
5964
6134
|
});
|
|
5965
6135
|
});
|
|
5966
6136
|
|
|
5967
|
-
},{"./../../../lib/data/PositionSummaryFrame":2,"./../../../lib/data/TransactionType":3,"@barchart/common-js/lang/Day":
|
|
6137
|
+
},{"./../../../lib/data/PositionSummaryFrame":2,"./../../../lib/data/TransactionType":3,"@barchart/common-js/lang/Day":13,"@barchart/common-js/lang/Decimal":14}],24:[function(require,module,exports){
|
|
5968
6138
|
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
5969
6139
|
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
5970
6140
|
|
|
5971
6141
|
const InstrumentType = require('./../../../lib/data/InstrumentType');
|
|
5972
6142
|
|
|
5973
6143
|
const PositionContainer = require('./../../../lib/processing/PositionContainer'),
|
|
5974
|
-
|
|
6144
|
+
PositionLevelDefinition = require('./../../../lib/processing/definitions/PositionLevelDefinition'),
|
|
6145
|
+
PositionTreeDefinition = require('./../../../lib/processing/definitions/PositionTreeDefinition');
|
|
5975
6146
|
|
|
5976
6147
|
describe('When a position container data is gathered', () => {
|
|
5977
6148
|
'use strict';
|
|
@@ -6025,48 +6196,51 @@ describe('When a position container data is gathered', () => {
|
|
|
6025
6196
|
});
|
|
6026
6197
|
|
|
6027
6198
|
describe('and a container is created grouping by total, portfolio, and instrument', () => {
|
|
6199
|
+
let name;
|
|
6028
6200
|
let definitions;
|
|
6029
6201
|
let container;
|
|
6030
6202
|
|
|
6031
6203
|
beforeEach(() => {
|
|
6032
6204
|
definitions = [
|
|
6033
|
-
new
|
|
6034
|
-
|
|
6035
|
-
|
|
6205
|
+
new PositionTreeDefinition(name = 'the only tree', [
|
|
6206
|
+
new PositionLevelDefinition('Total', x => true, x => 'Total', x => Currency.CAD),
|
|
6207
|
+
new PositionLevelDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
|
|
6208
|
+
new PositionLevelDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
|
|
6209
|
+
])
|
|
6036
6210
|
];
|
|
6037
6211
|
|
|
6038
6212
|
try {
|
|
6039
|
-
container = new PositionContainer(portfolios, positions, summaries
|
|
6213
|
+
container = new PositionContainer(definitions, portfolios, positions, summaries);
|
|
6040
6214
|
} catch (e) {
|
|
6041
6215
|
console.log(e);
|
|
6042
6216
|
}
|
|
6043
6217
|
});
|
|
6044
6218
|
|
|
6045
6219
|
it('the "Total" group should have two children groups', () => {
|
|
6046
|
-
expect(container.getGroups([ 'Total' ]).length).toEqual(2);
|
|
6220
|
+
expect(container.getGroups(name, [ 'Total' ]).length).toEqual(2);
|
|
6047
6221
|
});
|
|
6048
6222
|
|
|
6049
6223
|
it('the "Total" group should have three items', () => {
|
|
6050
|
-
expect(container.getGroup([ 'Total' ]).items.length).toEqual(3);
|
|
6224
|
+
expect(container.getGroup(name, [ 'Total' ]).items.length).toEqual(3);
|
|
6051
6225
|
});
|
|
6052
6226
|
|
|
6053
6227
|
it('The "a" portfolio group should have one child group', () => {
|
|
6054
|
-
expect(container.getGroups([ 'Total', 'a' ]).length).toEqual(1);
|
|
6228
|
+
expect(container.getGroups(name, [ 'Total', 'a' ]).length).toEqual(1);
|
|
6055
6229
|
});
|
|
6056
6230
|
|
|
6057
6231
|
it('the "a" portfolio group should have one item', () => {
|
|
6058
|
-
expect(container.getGroup([ 'Total', 'a' ]).items.length).toEqual(1);
|
|
6232
|
+
expect(container.getGroup(name, [ 'Total', 'a' ]).items.length).toEqual(1);
|
|
6059
6233
|
});
|
|
6060
6234
|
|
|
6061
6235
|
it('The "b" portfolio group should have two child groups', () => {
|
|
6062
|
-
expect(container.getGroups([ 'Total', 'b' ]).length).toEqual(2);
|
|
6236
|
+
expect(container.getGroups(name, [ 'Total', 'b' ]).length).toEqual(2);
|
|
6063
6237
|
});
|
|
6064
6238
|
|
|
6065
6239
|
it('the "b" portfolio group should have two items', () => {
|
|
6066
|
-
expect(container.getGroup([ 'Total', 'b' ]).items.length).toEqual(2);
|
|
6240
|
+
expect(container.getGroup(name, [ 'Total', 'b' ]).items.length).toEqual(2);
|
|
6067
6241
|
});
|
|
6068
6242
|
});
|
|
6069
6243
|
});
|
|
6070
6244
|
});
|
|
6071
6245
|
|
|
6072
|
-
},{"./../../../lib/data/InstrumentType":1,"./../../../lib/processing/PositionContainer":4,"./../../../lib/processing/
|
|
6246
|
+
},{"./../../../lib/data/InstrumentType":1,"./../../../lib/processing/PositionContainer":4,"./../../../lib/processing/definitions/PositionLevelDefinition":7,"./../../../lib/processing/definitions/PositionTreeDefinition":8,"@barchart/common-js/lang/Currency":12,"@barchart/common-js/lang/Decimal":14}]},{},[23,24]);
|