@barchart/portfolio-api-common 1.0.262 → 1.0.266

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.
@@ -185,7 +185,137 @@ module.exports = (() => {
185
185
  return InstrumentType;
186
186
  })();
187
187
 
188
- },{"@barchart/common-js/lang/Enum":19,"@barchart/common-js/lang/assert":22,"uuid":28}],2:[function(require,module,exports){
188
+ },{"@barchart/common-js/lang/Enum":21,"@barchart/common-js/lang/assert":24,"uuid":30}],2:[function(require,module,exports){
189
+ const assert = require('@barchart/common-js/lang/assert'),
190
+ Decimal = require('@barchart/common-js/lang/Decimal'),
191
+ Enum = require('@barchart/common-js/lang/Enum');
192
+
193
+ module.exports = (() => {
194
+ 'use strict';
195
+
196
+ /**
197
+ * Describes a position size -- positive values are long, negative values
198
+ * are short and zero values are even.
199
+ *
200
+ * @public
201
+ * @extends {Enum}
202
+ * @param {String} code
203
+ * @param {String} description
204
+ * @param {sign} sign
205
+ */
206
+ class PositionDirection extends Enum {
207
+ constructor(code, description, sign) {
208
+ super(code, description);
209
+
210
+ assert.argumentIsRequired(sign, 'sign', String);
211
+
212
+ this._sign = sign;
213
+ }
214
+
215
+ /**
216
+ * A description of the positiveness or negativeness of the size of the
217
+ * position.
218
+ *
219
+ * @public
220
+ * @returns {String}
221
+ */
222
+ get sign() {
223
+ return this._sign;
224
+ }
225
+
226
+ /**
227
+ * Indicates if the position size is positive (i.e. is {@link PositionDirection.LONG}).
228
+ *
229
+ * @public
230
+ * @returns {boolean}
231
+ */
232
+ get positive() {
233
+ return this === long;
234
+ }
235
+
236
+ /**
237
+ * Indicates if the position size is negative (i.e. is {@link PositionDirection.SHORT}).
238
+ *
239
+ * @public
240
+ * @returns {boolean}
241
+ */
242
+ get negative() {
243
+ return this === short;
244
+ }
245
+
246
+ /**
247
+ * Indicates if the position size is zero (i.e. is {@link PositionDirection.EVEN}).
248
+ *
249
+ * @public
250
+ * @returns {boolean}
251
+ */
252
+ get closed() {
253
+ return this === even;
254
+ }
255
+
256
+ /**
257
+ * A positive quantity position.
258
+ *
259
+ * @public
260
+ * @static
261
+ * @returns {PositionDirection}
262
+ */
263
+ static get LONG() {
264
+ return long;
265
+ }
266
+
267
+ /**
268
+ * A positive quantity position.
269
+ *
270
+ * @public
271
+ * @static
272
+ * @returns {PositionDirection}
273
+ */
274
+ static get SHORT() {
275
+ return short;
276
+ }
277
+
278
+ /**
279
+ * A zero quantity position.
280
+ *
281
+ * @public
282
+ * @static
283
+ * @returns {PositionDirection}
284
+ */
285
+ static get EVEN() {
286
+ return even;
287
+ }
288
+
289
+ /**
290
+ * Given an open quantity, returns a {@link PositionDirection} that
291
+ * describes the quantity.
292
+ *
293
+ * @public
294
+ * @static
295
+ * @param {Decimal} open
296
+ * @returns {PositionDirection}
297
+ */
298
+ static for(open) {
299
+ assert.argumentIsRequired(open, 'open', Decimal, 'Decimal');
300
+
301
+ if (open.getIsPositive()) {
302
+ return long;
303
+ } else if (open.getIsNegative()) {
304
+ return short;
305
+ } else {
306
+ return even;
307
+ }
308
+ }
309
+ }
310
+
311
+ const long = new PositionDirection('LONG', 'Long', 'positive');
312
+ const short = new PositionDirection('SHORT', 'Short', 'negative');
313
+ const even = new PositionDirection('EVEN', 'Even', 'zero');
314
+
315
+ return PositionDirection;
316
+ })();
317
+
318
+ },{"@barchart/common-js/lang/Decimal":19,"@barchart/common-js/lang/Enum":21,"@barchart/common-js/lang/assert":24}],3:[function(require,module,exports){
189
319
  const array = require('@barchart/common-js/lang/array'),
190
320
  assert = require('@barchart/common-js/lang/assert'),
191
321
  Day = require('@barchart/common-js/lang/Day'),
@@ -208,18 +338,34 @@ module.exports = (() => {
208
338
  * @param {Function} descriptionCalculator
209
339
  */
210
340
  class PositionSummaryFrame extends Enum {
211
- constructor(code, description, rangeCalculator, startDateCalculator, descriptionCalculator) {
341
+ constructor(code, description, unique, rangeCalculator, startDateCalculator, descriptionCalculator) {
212
342
  super(code, description);
213
343
 
344
+ assert.argumentIsRequired(unique, 'unique', Boolean);
345
+
214
346
  assert.argumentIsRequired(rangeCalculator, 'rangeCalculator', Function);
215
347
  assert.argumentIsRequired(startDateCalculator, 'startDateCalculator', Function);
216
348
  assert.argumentIsRequired(descriptionCalculator, 'descriptionCalculator', Function);
217
349
 
350
+ this._unique = unique;
351
+
218
352
  this._rangeCalculator = rangeCalculator;
219
353
  this._startDateCalculator = startDateCalculator;
220
354
  this._descriptionCalculator = descriptionCalculator;
221
355
  }
222
356
 
357
+ /**
358
+ * If true, only one summary, of the given type, can exist for a
359
+ * position. If false, multiple summaries, of the given type, can
360
+ * exist for a position.
361
+ *
362
+ * @public
363
+ * @return {Boolean}
364
+ */
365
+ get unique() {
366
+ return this._unique;
367
+ }
368
+
223
369
  /**
224
370
  * Returns a human-readable description of the frame, given
225
371
  * start and end dates.
@@ -317,10 +463,10 @@ module.exports = (() => {
317
463
  }
318
464
  }
319
465
 
320
- const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges, getYearlyStartDate, getYearlyRangeDescription);
321
- const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges, getQuarterlyStartDate, getQuarterlyRangeDescription);
322
- const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges, getMonthlyStartDate, getMonthlyRangeDescription);
323
- const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges, getYearToDateStartDate, getYearToDateRangeDescription);
466
+ const yearly = new PositionSummaryFrame('YEARLY', 'year', false, getYearlyRanges, getYearlyStartDate, getYearlyRangeDescription);
467
+ const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', false, getQuarterlyRanges, getQuarterlyStartDate, getQuarterlyRangeDescription);
468
+ const monthly = new PositionSummaryFrame('MONTH', 'month', false, getMonthlyRanges, getMonthlyStartDate, getMonthlyRangeDescription);
469
+ const ytd = new PositionSummaryFrame('YTD', 'year-to-date', true, getYearToDateRanges, getYearToDateStartDate, getYearToDateRangeDescription);
324
470
 
325
471
  /**
326
472
  * The start and and date for a {@link PositionSummaryFrame}
@@ -442,7 +588,7 @@ module.exports = (() => {
442
588
  return PositionSummaryFrame;
443
589
  })();
444
590
 
445
- },{"@barchart/common-js/lang/Day":16,"@barchart/common-js/lang/Decimal":17,"@barchart/common-js/lang/Enum":19,"@barchart/common-js/lang/array":21,"@barchart/common-js/lang/assert":22,"@barchart/common-js/lang/is":24}],3:[function(require,module,exports){
591
+ },{"@barchart/common-js/lang/Day":18,"@barchart/common-js/lang/Decimal":19,"@barchart/common-js/lang/Enum":21,"@barchart/common-js/lang/array":23,"@barchart/common-js/lang/assert":24,"@barchart/common-js/lang/is":26}],4:[function(require,module,exports){
446
592
  const assert = require('@barchart/common-js/lang/assert'),
447
593
  Enum = require('@barchart/common-js/lang/Enum');
448
594
 
@@ -809,7 +955,205 @@ module.exports = (() => {
809
955
  return TransactionType;
810
956
  })();
811
957
 
812
- },{"@barchart/common-js/lang/Enum":19,"@barchart/common-js/lang/assert":22}],4:[function(require,module,exports){
958
+ },{"@barchart/common-js/lang/Enum":21,"@barchart/common-js/lang/assert":24}],5:[function(require,module,exports){
959
+ const assert = require('@barchart/common-js/lang/assert'),
960
+ array = require('@barchart/common-js/lang/array')
961
+
962
+ const InstrumentType = require('./InstrumentType'),
963
+ PositionDirection = require('./PositionDirection'),
964
+ TransactionType = require('./TransactionType');
965
+
966
+ module.exports = (() => {
967
+ 'use strict';
968
+
969
+ /**
970
+ * Static utilities for validating transactions.
971
+ *
972
+ * @public
973
+ */
974
+ class TransactionValidator {
975
+ constructor() {
976
+
977
+ }
978
+
979
+ /**
980
+ * Given a set of transaction, ensures that sequence numbers and dates
981
+ * are properly ordered.
982
+ *
983
+ * @public
984
+ * @static
985
+ * @param {Array.<Object>} transactions
986
+ * @param {Boolean=} partial - If true, sequence validation starts with the array's first transaction.
987
+ * @return {boolean}
988
+ */
989
+ static validateOrder(transactions, partial) {
990
+ assert.argumentIsArray(transactions, 'transactions');
991
+ assert.argumentIsOptional(partial, 'partial', Boolean);
992
+
993
+ let startSequence;
994
+
995
+ if (partial && transactions.length !== 0) {
996
+ startSequence = array.first(transactions).sequence;
997
+ } else {
998
+ startSequence = 1;
999
+ }
1000
+
1001
+ return transactions.every((t, i) => t.sequence === (i + startSequence) && (i === 0 || !t.date.getIsBefore(transactions[i - 1].date)));
1002
+ }
1003
+
1004
+ /**
1005
+ * Given an instrument type, returns all valid transaction types.
1006
+ *
1007
+ * @static
1008
+ * @public
1009
+ * @param {InstrumentType} instrumentType
1010
+ * @param {Boolean=} userInitiated
1011
+ * @pararm {PositionDirection=} currentDirection
1012
+ * @return {Array.<TransactionType>}
1013
+ */
1014
+ static getTransactionTypesFor(instrumentType, userInitiated, currentDirection) {
1015
+ assert.argumentIsRequired(instrumentType, 'instrumentType', InstrumentType, 'InstrumentType');
1016
+ assert.argumentIsOptional(userInitiated, 'userInitiated', Boolean);
1017
+
1018
+ let valid = validTransactionTypes[instrumentType.code] || [ ];
1019
+
1020
+ if (userInitiated) {
1021
+ valid = valid.filter(data => data.user === userInitiated);
1022
+ }
1023
+
1024
+ if (currentDirection) {
1025
+ valid = valid.filter(data => data.directions.some(d => d === currentDirection));
1026
+ }
1027
+
1028
+ return valid.map(d => d.type);
1029
+ }
1030
+
1031
+ /**
1032
+ * Checks to see if an transaction type is applicable to an instrument type.
1033
+ *
1034
+ * @static
1035
+ * @public
1036
+ * @param {InstrumentType} instrumentType
1037
+ * @param {TransactionType} transactionType
1038
+ * @param {Boolean=} userInitiated
1039
+ * @return {Boolean}
1040
+ */
1041
+ static validateTransactionType(instrumentType, transactionType, userInitiated) {
1042
+ assert.argumentIsRequired(transactionType, 'transactionType', TransactionType, 'TransactionType');
1043
+
1044
+ const transactionTypes = TransactionValidator.getTransactionTypesFor(instrumentType, userInitiated);
1045
+
1046
+ return transactionTypes.some(t => t === transactionType);
1047
+ }
1048
+
1049
+ /**
1050
+ * Checks to see if a position for a given instrument type can exist in
1051
+ * the given direction.
1052
+ *
1053
+ * @static
1054
+ * @public
1055
+ * @param {InstrumentType} instrumentType
1056
+ * @param {PositionDirection} direction
1057
+ * @return {Boolean}
1058
+ */
1059
+ static validateDirection(instrumentType, direction) {
1060
+ assert.argumentIsRequired(instrumentType, 'instrumentType', InstrumentType, 'InstrumentType');
1061
+ assert.argumentIsRequired(direction, 'direction', PositionDirection, 'PositionDirection');
1062
+
1063
+ return validDirections[instrumentType.code].some(d => d === direction);
1064
+ }
1065
+
1066
+ /**
1067
+ * Checks to see if the position switches direction and if the direction switch
1068
+ * is valid.
1069
+ *
1070
+ * @static
1071
+ * @public
1072
+ * @param {InstrumentType} instrumentType
1073
+ * @param {PositionDirection|null|undefined} currentDirection
1074
+ * @param {PositionDirection} proposedDirection
1075
+ * @return {Boolean}
1076
+ */
1077
+ static validateDirectionSwitch(instrumentType, currentDirection, proposedDirection) {
1078
+ return currentDirection === null || instrumentType.canSwitchDirection || (currentDirection.closed || proposedDirection.closed || currentDirection.positive === proposedDirection.positive);
1079
+ }
1080
+
1081
+ toString() {
1082
+ return '[TransactionValidator]';
1083
+ }
1084
+ }
1085
+
1086
+ const validTransactionTypes = { };
1087
+
1088
+ function associateTypes(instrumentType, transactionType, userInitiated, directions) {
1089
+ const instrumentTypeCode = instrumentType.code;
1090
+
1091
+ if (!validTransactionTypes.hasOwnProperty(instrumentTypeCode)) {
1092
+ validTransactionTypes[instrumentTypeCode] = [ ];
1093
+ }
1094
+
1095
+ validTransactionTypes[instrumentTypeCode].push({ type: transactionType, user: userInitiated, directions: directions || [ PositionDirection.LONG, PositionDirection.SHORT, PositionDirection.EVEN ] });
1096
+ }
1097
+
1098
+ associateTypes(InstrumentType.EQUITY, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
1099
+ associateTypes(InstrumentType.EQUITY, TransactionType.SELL, true, [ PositionDirection.LONG ]);
1100
+ associateTypes(InstrumentType.EQUITY, TransactionType.SELL_SHORT, true, [ PositionDirection.SHORT, PositionDirection.EVEN ]);
1101
+ associateTypes(InstrumentType.EQUITY, TransactionType.BUY_SHORT, true, [ PositionDirection.SHORT ]);
1102
+ associateTypes(InstrumentType.EQUITY, TransactionType.FEE, true, [ PositionDirection.LONG, PositionDirection.SHORT ]);
1103
+ associateTypes(InstrumentType.EQUITY, TransactionType.DIVIDEND, false);
1104
+ associateTypes(InstrumentType.EQUITY, TransactionType.DIVIDEND_REINVEST, false);
1105
+ associateTypes(InstrumentType.EQUITY, TransactionType.DIVIDEND_STOCK, false);
1106
+ associateTypes(InstrumentType.EQUITY, TransactionType.SPLIT, false);
1107
+
1108
+ associateTypes(InstrumentType.FUND, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
1109
+ associateTypes(InstrumentType.FUND, TransactionType.SELL, true, [ PositionDirection.LONG ]);
1110
+ associateTypes(InstrumentType.FUND, TransactionType.FEE, true, [ PositionDirection.LONG ]);
1111
+ associateTypes(InstrumentType.FUND, TransactionType.FEE_UNITS, false);
1112
+ associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_CASH, false);
1113
+ associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_FUND, false);
1114
+
1115
+ associateTypes(InstrumentType.OTHER, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
1116
+ associateTypes(InstrumentType.OTHER, TransactionType.SELL, true, [ PositionDirection.LONG ]);
1117
+ associateTypes(InstrumentType.OTHER, TransactionType.INCOME, true, [ PositionDirection.LONG ]);
1118
+ associateTypes(InstrumentType.OTHER, TransactionType.FEE, true, [ PositionDirection.LONG ]);
1119
+ associateTypes(InstrumentType.OTHER, TransactionType.VALUATION, true, [ PositionDirection.LONG ]);
1120
+
1121
+ associateTypes(InstrumentType.CASH, TransactionType.DEPOSIT, true);
1122
+ associateTypes(InstrumentType.CASH, TransactionType.WITHDRAWAL, true);
1123
+ associateTypes(InstrumentType.CASH, TransactionType.FEE, true);
1124
+ associateTypes(InstrumentType.CASH, TransactionType.DEBIT, false);
1125
+ associateTypes(InstrumentType.CASH, TransactionType.CREDIT, false);
1126
+
1127
+ const validDirections = { };
1128
+
1129
+ function associateDirections(instrumentType, positionDirection) {
1130
+ const instrumentTypeCode = instrumentType.code;
1131
+
1132
+ if (!validDirections.hasOwnProperty(instrumentTypeCode)) {
1133
+ validDirections[instrumentTypeCode] = [ ];
1134
+ }
1135
+
1136
+ validDirections[instrumentTypeCode].push(positionDirection);
1137
+ }
1138
+
1139
+ associateDirections(InstrumentType.EQUITY, PositionDirection.EVEN);
1140
+ associateDirections(InstrumentType.EQUITY, PositionDirection.LONG);
1141
+ associateDirections(InstrumentType.EQUITY, PositionDirection.SHORT);
1142
+
1143
+ associateDirections(InstrumentType.FUND, PositionDirection.EVEN);
1144
+ associateDirections(InstrumentType.FUND, PositionDirection.LONG);
1145
+
1146
+ associateDirections(InstrumentType.OTHER, PositionDirection.EVEN);
1147
+ associateDirections(InstrumentType.OTHER, PositionDirection.LONG);
1148
+
1149
+ associateDirections(InstrumentType.CASH, PositionDirection.EVEN);
1150
+ associateDirections(InstrumentType.CASH, PositionDirection.LONG);
1151
+ associateDirections(InstrumentType.CASH, PositionDirection.SHORT);
1152
+
1153
+ return TransactionValidator;
1154
+ })();
1155
+
1156
+ },{"./InstrumentType":1,"./PositionDirection":2,"./TransactionType":4,"@barchart/common-js/lang/array":23,"@barchart/common-js/lang/assert":24}],6:[function(require,module,exports){
813
1157
  const array = require('@barchart/common-js/lang/array'),
814
1158
  assert = require('@barchart/common-js/lang/assert'),
815
1159
  ComparatorBuilder = require('@barchart/common-js/collections/sorting/ComparatorBuilder'),
@@ -1136,6 +1480,8 @@ module.exports = (() => {
1136
1480
  this._positionSymbolAddedEvent.fire(addedBarchartSymbol);
1137
1481
  }
1138
1482
  });
1483
+
1484
+ recalculatePercentages.call(this);
1139
1485
  }
1140
1486
 
1141
1487
  /**
@@ -1149,6 +1495,8 @@ module.exports = (() => {
1149
1495
  assert.argumentIsRequired(position.position, 'position.position', String);
1150
1496
 
1151
1497
  removePositionItem.call(this, this._items.find((item) => item.position.position === position.position));
1498
+
1499
+ recalculatePercentages.call(this);
1152
1500
  }
1153
1501
 
1154
1502
  /**
@@ -1196,6 +1544,8 @@ module.exports = (() => {
1196
1544
  if (this._symbols.hasOwnProperty(symbol)) {
1197
1545
  this._symbols[symbol].forEach(item => item.setQuote(quote));
1198
1546
  }
1547
+
1548
+ recalculatePercentages.call(this);
1199
1549
  }
1200
1550
 
1201
1551
  /**
@@ -1239,7 +1589,9 @@ module.exports = (() => {
1239
1589
  this._forexQuotes[index] = rate;
1240
1590
  }
1241
1591
 
1242
- Object.keys(this._trees).forEach(key => this._trees[key].walk(group => group.setForexRate(rate), true, false));
1592
+ Object.keys(this._trees).forEach(key => this._trees[key].walk(group => group.setForexRates(this._forexQuotes), true, false));
1593
+
1594
+ recalculatePercentages.call(this);
1243
1595
  }
1244
1596
 
1245
1597
  /**
@@ -1551,12 +1903,6 @@ module.exports = (() => {
1551
1903
  }
1552
1904
  }
1553
1905
  }));
1554
-
1555
- addGroupBinding.call(this, group, group.registerMarketPercentChangeHandler(() => {
1556
- if (!groupTree.getIsRoot()) {
1557
- groupTree.getParent().walk((childGroup) => childGroup.refreshMarketPercent());
1558
- }
1559
- }));
1560
1906
  }
1561
1907
 
1562
1908
  function createGroups(parentTree, items, treeDefinition, levelDefinitions, overrideRequiredGroups) {
@@ -1564,6 +1910,8 @@ module.exports = (() => {
1564
1910
  return;
1565
1911
  }
1566
1912
 
1913
+ const rates = this._forexQuotes;
1914
+
1567
1915
  const levelDefinition = levelDefinitions[0];
1568
1916
 
1569
1917
  const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
@@ -1571,7 +1919,7 @@ module.exports = (() => {
1571
1919
  const items = populatedObjects[key];
1572
1920
  const first = items[0];
1573
1921
 
1574
- list.push(new PositionGroup(this, levelDefinition, items, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.aggregateCash));
1922
+ list.push(new PositionGroup(levelDefinition, items, rates, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.aggregateCash));
1575
1923
 
1576
1924
  return list;
1577
1925
  }, [ ]);
@@ -1584,7 +1932,7 @@ module.exports = (() => {
1584
1932
  });
1585
1933
 
1586
1934
  const empty = missingGroups.map((group) => {
1587
- return new PositionGroup(this, levelDefinition, [ ], group.currency, group.key, group.description);
1935
+ return new PositionGroup(levelDefinition, [ ], rates, group.currency, group.key, group.description);
1588
1936
  });
1589
1937
 
1590
1938
  const compositeGroups = populatedGroups.concat(empty);
@@ -1624,6 +1972,9 @@ module.exports = (() => {
1624
1972
 
1625
1973
  this._nodes[group.id] = childTree;
1626
1974
 
1975
+ group.setParentGroup(this.getParentGroup(group));
1976
+ group.setPortfolioGroup(this.getParentGroupForPortfolio(group));
1977
+
1627
1978
  initializeGroupObservers.call(this, childTree, treeDefinition);
1628
1979
 
1629
1980
  createGroups.call(this, childTree, group.items, treeDefinition, array.dropLeft(levelDefinitions));
@@ -1764,10 +2115,16 @@ module.exports = (() => {
1764
2115
  groupNodeToSever.walk(group => delete this._nodes[group.id], false, true);
1765
2116
  }
1766
2117
 
2118
+ function recalculatePercentages() {
2119
+ Object.keys(this._trees).forEach((key) => {
2120
+ this._trees[key].walk(group => group.refreshMarketPercent(), false, false);
2121
+ });
2122
+ }
2123
+
1767
2124
  return PositionContainer;
1768
2125
  })();
1769
2126
 
1770
- },{"./../data/PositionSummaryFrame":2,"./PositionGroup":5,"./PositionItem":6,"./definitions/PositionLevelDefinition":7,"./definitions/PositionLevelType":8,"./definitions/PositionTreeDefinition":9,"@barchart/common-js/collections/Tree":11,"@barchart/common-js/collections/sorting/ComparatorBuilder":12,"@barchart/common-js/collections/sorting/comparators":13,"@barchart/common-js/collections/specialized/DisposableStack":14,"@barchart/common-js/lang/Currency":15,"@barchart/common-js/lang/Decimal":17,"@barchart/common-js/lang/Rate":20,"@barchart/common-js/lang/array":21,"@barchart/common-js/lang/assert":22,"@barchart/common-js/lang/is":24,"@barchart/common-js/messaging/Event":26}],5:[function(require,module,exports){
2127
+ },{"./../data/PositionSummaryFrame":3,"./PositionGroup":7,"./PositionItem":8,"./definitions/PositionLevelDefinition":9,"./definitions/PositionLevelType":10,"./definitions/PositionTreeDefinition":11,"@barchart/common-js/collections/Tree":13,"@barchart/common-js/collections/sorting/ComparatorBuilder":14,"@barchart/common-js/collections/sorting/comparators":15,"@barchart/common-js/collections/specialized/DisposableStack":16,"@barchart/common-js/lang/Currency":17,"@barchart/common-js/lang/Decimal":19,"@barchart/common-js/lang/Rate":22,"@barchart/common-js/lang/array":23,"@barchart/common-js/lang/assert":24,"@barchart/common-js/lang/is":26,"@barchart/common-js/messaging/Event":28}],7:[function(require,module,exports){
1771
2128
  const array = require('@barchart/common-js/lang/array'),
1772
2129
  assert = require('@barchart/common-js/lang/assert'),
1773
2130
  Currency = require('@barchart/common-js/lang/Currency'),
@@ -1803,13 +2160,17 @@ module.exports = (() => {
1803
2160
  * @param {Boolean=} aggregateCash
1804
2161
  */
1805
2162
  class PositionGroup {
1806
- constructor(container, definition, items, currency, key, description, aggregateCash) {
2163
+ constructor(definition, items, rates, currency, key, description, aggregateCash) {
1807
2164
  this._id = counter++;
1808
2165
 
1809
2166
  this._definition = definition;
1810
- this._container = container;
1811
2167
 
1812
2168
  this._items = items;
2169
+ this._rates = rates;
2170
+
2171
+ this._parentGroup = null;
2172
+ this._portfolioGroup = null;
2173
+
1813
2174
  this._currency = currency || Currency.CAD;
1814
2175
  this._bypassCurrencyTranslation = false;
1815
2176
 
@@ -1823,7 +2184,6 @@ module.exports = (() => {
1823
2184
  this._suspended = false;
1824
2185
  this._showClosedPositions = false;
1825
2186
 
1826
- this._marketPercentChangeEvent = new Event(this);
1827
2187
  this._groupExcludedChangeEvent = new Event(this);
1828
2188
  this._showClosedPositionsChangeEvent = new Event(this);
1829
2189
 
@@ -2036,6 +2396,40 @@ module.exports = (() => {
2036
2396
  return this._excluded;
2037
2397
  }
2038
2398
 
2399
+ /**
2400
+ * Sets the immediate parent group (allowing for calculation of relative
2401
+ * percentages).
2402
+ *
2403
+ * @public
2404
+ * @param {PortfolioGroup} group
2405
+ */
2406
+ setParentGroup(group) {
2407
+ assert.argumentIsOptional(group, 'group', PositionGroup, 'PositionGroup');
2408
+
2409
+ if (this._parentGroup !== null) {
2410
+ throw new Error('The parent group has already been set.');
2411
+ }
2412
+
2413
+ this._parentGroup = group;
2414
+ }
2415
+
2416
+ /**
2417
+ * Sets the nearest parent group for a portfolio (allowing for calculation
2418
+ * of relative percentages).
2419
+ *
2420
+ * @public
2421
+ * @param {PortfolioGroup} group
2422
+ */
2423
+ setPortfolioGroup(group) {
2424
+ assert.argumentIsOptional(group, 'group', PositionGroup, 'PositionGroup');
2425
+
2426
+ if (this._portfolioGroup !== null) {
2427
+ throw new Error('The portfolio group has already been set.');
2428
+ }
2429
+
2430
+ this._portfolioGroup = group;
2431
+ }
2432
+
2039
2433
  /**
2040
2434
  * Adds a new {@link PositionItem} to the group.
2041
2435
  *
@@ -2081,9 +2475,11 @@ module.exports = (() => {
2081
2475
  * Causes aggregated data to be recalculated using a new exchange rate.
2082
2476
  *
2083
2477
  * @public
2084
- * @param {Rate} rate
2478
+ * @param {Array.<Rate>} rate
2085
2479
  */
2086
- setForexRate(rate) {
2480
+ setForexRates(rates) {
2481
+ this._rates = rates;
2482
+
2087
2483
  if (!this._bypassCurrencyTranslation) {
2088
2484
  this.refresh();
2089
2485
  }
@@ -2171,10 +2567,8 @@ module.exports = (() => {
2171
2567
  return;
2172
2568
  }
2173
2569
 
2174
- const rates = this._container.getForexQuotes();
2175
-
2176
- calculateStaticData(this, rates);
2177
- calculatePriceData(this, rates, null, true);
2570
+ calculateStaticData(this, this._rates);
2571
+ calculatePriceData(this, this._rates, null, true);
2178
2572
  }
2179
2573
 
2180
2574
  /**
@@ -2184,7 +2578,7 @@ module.exports = (() => {
2184
2578
  * @public
2185
2579
  */
2186
2580
  refreshMarketPercent() {
2187
- calculateMarketPercent(this, this._container.getForexQuotes(), true);
2581
+ calculateMarketPercent(this, this._rates, this._parentGroup, this._portfolioGroup);
2188
2582
  }
2189
2583
 
2190
2584
  /**
@@ -2197,17 +2591,6 @@ module.exports = (() => {
2197
2591
  return this._items.length === 0;
2198
2592
  }
2199
2593
 
2200
- /**
2201
- * Adds an observer for change in the market percentage of the group.
2202
- *
2203
- * @public
2204
- * @param {Function} handler
2205
- * @return {Disposable}
2206
- */
2207
- registerMarketPercentChangeHandler(handler) {
2208
- return this._marketPercentChangeEvent.register(handler);
2209
- }
2210
-
2211
2594
  /**
2212
2595
  * Adds an observer for changes to the exclusion of the group
2213
2596
  * from higher level aggregations.
@@ -2262,10 +2645,10 @@ module.exports = (() => {
2262
2645
  this._dataFormat.currentPrice = null;
2263
2646
  }
2264
2647
 
2265
- calculatePriceData(this, this._container.getForexQuotes(), sender, false);
2648
+ calculatePriceData(this, this._rates, sender, false);
2266
2649
  });
2267
2650
 
2268
- let fundamentalBinding = item.registerFundamentalDataChangeHandler((data, sender) => {
2651
+ let fundamentalBinding = item.registerFundamentalDataChangeHandler((data) => {
2269
2652
  if (this._single) {
2270
2653
  this._dataFormat.fundamental = data;
2271
2654
  } else {
@@ -2316,13 +2699,13 @@ module.exports = (() => {
2316
2699
  let newsBinding = Disposable.getEmpty();
2317
2700
 
2318
2701
  if (this._single) {
2319
- newsBinding = item.registerNewsExistsChangeHandler((exists, sender) => {
2702
+ newsBinding = item.registerNewsExistsChangeHandler((exists) => {
2320
2703
  this._dataActual.newsExists = exists;
2321
2704
  this._dataFormat.newsExists = exists;
2322
2705
  });
2323
2706
  }
2324
2707
 
2325
- this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio, sender) => {
2708
+ this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio) => {
2326
2709
  const descriptionSelector = this._definition.descriptionSelector;
2327
2710
 
2328
2711
  this._description = descriptionSelector(this._items[0]);
@@ -2571,12 +2954,11 @@ module.exports = (() => {
2571
2954
 
2572
2955
  format.total = formatCurrency(actual.total, currency);
2573
2956
  format.totalNegative = actual.total.getIsNegative();
2574
-
2575
- calculateMarketPercent(group, rates, false);
2957
+
2576
2958
  calculateUnrealizedPercent(group);
2577
2959
  }
2578
2960
 
2579
- function calculateMarketPercent(group, rates, silent) {
2961
+ function calculateMarketPercent(group, rates, parentGroup, portfolioGroup) {
2580
2962
  if (group.suspended) {
2581
2963
  return;
2582
2964
  }
@@ -2585,12 +2967,10 @@ module.exports = (() => {
2585
2967
  const format = group._dataFormat;
2586
2968
  const excluded = group._excluded;
2587
2969
 
2588
- const portfolioParent = group._container.getParentGroupForPortfolio(group);
2589
-
2590
2970
  const calculatePercent = (parent) => {
2591
2971
  let marketPercent;
2592
2972
 
2593
- if (parent !== null && !excluded) {
2973
+ if (parent && !excluded) {
2594
2974
  const parentData = parent._dataActual;
2595
2975
 
2596
2976
  if (parentData.marketAbsolute !== null && !parentData.marketAbsolute.getIsZero()) {
@@ -2613,14 +2993,15 @@ module.exports = (() => {
2613
2993
  return marketPercent;
2614
2994
  };
2615
2995
 
2616
- actual.marketPercent = calculatePercent(group._container.getParentGroup(group));
2996
+ actual.marketPercent = calculatePercent(parentGroup);
2617
2997
  format.marketPercent = formatPercent(actual.marketPercent, 2);
2618
2998
 
2619
- actual.marketPercentPortfolio = calculatePercent(group._container.getParentGroupForPortfolio(group));
2620
- format.marketPercentPortfolio = formatPercent(actual.marketPercentPortfolio, 2);
2621
-
2622
- if (!silent) {
2623
- group._marketPercentChangeEvent.fire(group);
2999
+ if (parentGroup === portfolioGroup) {
3000
+ actual.marketPercentPortfolio = actual.marketPercent;
3001
+ format.marketPercentPortfolio = format.marketPercent;
3002
+ } else {
3003
+ actual.marketPercentPortfolio = calculatePercent(portfolioGroup);
3004
+ format.marketPercentPortfolio = formatPercent(actual.marketPercentPortfolio, 2);
2624
3005
  }
2625
3006
  }
2626
3007
 
@@ -2642,7 +3023,7 @@ module.exports = (() => {
2642
3023
  return PositionGroup;
2643
3024
  })();
2644
3025
 
2645
- },{"./../data/InstrumentType":1,"./definitions/PositionLevelDefinition":7,"./definitions/PositionLevelType":8,"@barchart/common-js/collections/specialized/DisposableStack":14,"@barchart/common-js/lang/Currency":15,"@barchart/common-js/lang/Decimal":17,"@barchart/common-js/lang/Disposable":18,"@barchart/common-js/lang/Rate":20,"@barchart/common-js/lang/array":21,"@barchart/common-js/lang/assert":22,"@barchart/common-js/lang/formatter":23,"@barchart/common-js/lang/is":24,"@barchart/common-js/messaging/Event":26}],6:[function(require,module,exports){
3026
+ },{"./../data/InstrumentType":1,"./definitions/PositionLevelDefinition":9,"./definitions/PositionLevelType":10,"@barchart/common-js/collections/specialized/DisposableStack":16,"@barchart/common-js/lang/Currency":17,"@barchart/common-js/lang/Decimal":19,"@barchart/common-js/lang/Disposable":20,"@barchart/common-js/lang/Rate":22,"@barchart/common-js/lang/array":23,"@barchart/common-js/lang/assert":24,"@barchart/common-js/lang/formatter":25,"@barchart/common-js/lang/is":26,"@barchart/common-js/messaging/Event":28}],8:[function(require,module,exports){
2646
3027
  const assert = require('@barchart/common-js/lang/assert'),
2647
3028
  Currency = require('@barchart/common-js/lang/Currency'),
2648
3029
  Decimal = require('@barchart/common-js/lang/Decimal'),
@@ -3102,7 +3483,7 @@ module.exports = (() => {
3102
3483
  return PositionItem;
3103
3484
  })();
3104
3485
 
3105
- },{"./../data/InstrumentType":1,"@barchart/common-js/lang/Currency":15,"@barchart/common-js/lang/Decimal":17,"@barchart/common-js/lang/Disposable":18,"@barchart/common-js/lang/assert":22,"@barchart/common-js/lang/is":24,"@barchart/common-js/messaging/Event":26}],7:[function(require,module,exports){
3486
+ },{"./../data/InstrumentType":1,"@barchart/common-js/lang/Currency":17,"@barchart/common-js/lang/Decimal":19,"@barchart/common-js/lang/Disposable":20,"@barchart/common-js/lang/assert":24,"@barchart/common-js/lang/is":26,"@barchart/common-js/messaging/Event":28}],9:[function(require,module,exports){
3106
3487
  const assert = require('@barchart/common-js/lang/assert'),
3107
3488
  Currency = require('@barchart/common-js/lang/Currency'),
3108
3489
  is = require('@barchart/common-js/lang/is');
@@ -3381,7 +3762,7 @@ module.exports = (() => {
3381
3762
  return PositionLevelDefinition;
3382
3763
  })();
3383
3764
 
3384
- },{"./../../data/InstrumentType":1,"./PositionLevelType":8,"@barchart/common-js/lang/Currency":15,"@barchart/common-js/lang/assert":22,"@barchart/common-js/lang/is":24}],8:[function(require,module,exports){
3765
+ },{"./../../data/InstrumentType":1,"./PositionLevelType":10,"@barchart/common-js/lang/Currency":17,"@barchart/common-js/lang/assert":24,"@barchart/common-js/lang/is":26}],10:[function(require,module,exports){
3385
3766
  const Enum = require('@barchart/common-js/lang/Enum');
3386
3767
 
3387
3768
  module.exports = (() => {
@@ -3412,7 +3793,7 @@ module.exports = (() => {
3412
3793
  return PositionLevelType;
3413
3794
  })();
3414
3795
 
3415
- },{"@barchart/common-js/lang/Enum":19}],9:[function(require,module,exports){
3796
+ },{"@barchart/common-js/lang/Enum":21}],11:[function(require,module,exports){
3416
3797
  const assert = require('@barchart/common-js/lang/assert');
3417
3798
 
3418
3799
  const PositionLevelDefinition = require('./PositionLevelDefinition');
@@ -3483,7 +3864,7 @@ module.exports = (() => {
3483
3864
  return PositionTreeDefinitions;
3484
3865
  })();
3485
3866
 
3486
- },{"./PositionLevelDefinition":7,"@barchart/common-js/lang/assert":22}],10:[function(require,module,exports){
3867
+ },{"./PositionLevelDefinition":9,"@barchart/common-js/lang/assert":24}],12:[function(require,module,exports){
3487
3868
  'use strict';
3488
3869
 
3489
3870
  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; }; }();
@@ -3615,7 +3996,7 @@ module.exports = function () {
3615
3996
  return Stack;
3616
3997
  }();
3617
3998
 
3618
- },{"./../lang/assert":22}],11:[function(require,module,exports){
3999
+ },{"./../lang/assert":24}],13:[function(require,module,exports){
3619
4000
  'use strict';
3620
4001
 
3621
4002
  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; }; }();
@@ -3985,7 +4366,7 @@ module.exports = function () {
3985
4366
  return Tree;
3986
4367
  }();
3987
4368
 
3988
- },{"./../lang/is":24}],12:[function(require,module,exports){
4369
+ },{"./../lang/is":26}],14:[function(require,module,exports){
3989
4370
  'use strict';
3990
4371
 
3991
4372
  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; }; }();
@@ -4129,7 +4510,7 @@ module.exports = function () {
4129
4510
  return ComparatorBuilder;
4130
4511
  }();
4131
4512
 
4132
- },{"./../../lang/assert":22,"./comparators":13}],13:[function(require,module,exports){
4513
+ },{"./../../lang/assert":24,"./comparators":15}],15:[function(require,module,exports){
4133
4514
  'use strict';
4134
4515
 
4135
4516
  var assert = require('./../../lang/assert');
@@ -4204,7 +4585,7 @@ module.exports = function () {
4204
4585
  };
4205
4586
  }();
4206
4587
 
4207
- },{"./../../lang/assert":22}],14:[function(require,module,exports){
4588
+ },{"./../../lang/assert":24}],16:[function(require,module,exports){
4208
4589
  'use strict';
4209
4590
 
4210
4591
  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; }; }();
@@ -4312,7 +4693,7 @@ module.exports = function () {
4312
4693
  return DisposableStack;
4313
4694
  }();
4314
4695
 
4315
- },{"./../../lang/Disposable":18,"./../../lang/assert":22,"./../../lang/is":24,"./../Stack":10}],15:[function(require,module,exports){
4696
+ },{"./../../lang/Disposable":20,"./../../lang/assert":24,"./../../lang/is":26,"./../Stack":12}],17:[function(require,module,exports){
4316
4697
  'use strict';
4317
4698
 
4318
4699
  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; }; }();
@@ -4455,7 +4836,7 @@ module.exports = function () {
4455
4836
  return Currency;
4456
4837
  }();
4457
4838
 
4458
- },{"./Enum":19,"./assert":22,"./is":24}],16:[function(require,module,exports){
4839
+ },{"./Enum":21,"./assert":24,"./is":26}],18:[function(require,module,exports){
4459
4840
  'use strict';
4460
4841
 
4461
4842
  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; }; }();
@@ -5008,7 +5389,7 @@ module.exports = function () {
5008
5389
  return Day;
5009
5390
  }();
5010
5391
 
5011
- },{"./../collections/sorting/ComparatorBuilder":12,"./../collections/sorting/comparators":13,"./assert":22,"./is":24}],17:[function(require,module,exports){
5392
+ },{"./../collections/sorting/ComparatorBuilder":14,"./../collections/sorting/comparators":15,"./assert":24,"./is":26}],19:[function(require,module,exports){
5012
5393
  'use strict';
5013
5394
 
5014
5395
  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; }; }();
@@ -5616,7 +5997,7 @@ module.exports = function () {
5616
5997
  return Decimal;
5617
5998
  }();
5618
5999
 
5619
- },{"./Enum":19,"./assert":22,"./is":24,"big.js":27}],18:[function(require,module,exports){
6000
+ },{"./Enum":21,"./assert":24,"./is":26,"big.js":29}],20:[function(require,module,exports){
5620
6001
  'use strict';
5621
6002
 
5622
6003
  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; }; }();
@@ -5765,7 +6146,7 @@ module.exports = function () {
5765
6146
  return Disposable;
5766
6147
  }();
5767
6148
 
5768
- },{"./assert":22}],19:[function(require,module,exports){
6149
+ },{"./assert":24}],21:[function(require,module,exports){
5769
6150
  'use strict';
5770
6151
 
5771
6152
  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; }; }();
@@ -5907,7 +6288,7 @@ module.exports = function () {
5907
6288
  return Enum;
5908
6289
  }();
5909
6290
 
5910
- },{"./assert":22}],20:[function(require,module,exports){
6291
+ },{"./assert":24}],22:[function(require,module,exports){
5911
6292
  'use strict';
5912
6293
 
5913
6294
  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; }; }();
@@ -6162,7 +6543,7 @@ module.exports = function () {
6162
6543
  return Rate;
6163
6544
  }();
6164
6545
 
6165
- },{"./Currency":15,"./Decimal":17,"./assert":22,"./memoize":25}],21:[function(require,module,exports){
6546
+ },{"./Currency":17,"./Decimal":19,"./assert":24,"./memoize":27}],23:[function(require,module,exports){
6166
6547
  'use strict';
6167
6548
 
6168
6549
  var assert = require('./assert'),
@@ -6563,7 +6944,7 @@ module.exports = function () {
6563
6944
  };
6564
6945
  }();
6565
6946
 
6566
- },{"./assert":22,"./is":24}],22:[function(require,module,exports){
6947
+ },{"./assert":24,"./is":26}],24:[function(require,module,exports){
6567
6948
  'use strict';
6568
6949
 
6569
6950
  var is = require('./is');
@@ -6711,7 +7092,7 @@ module.exports = function () {
6711
7092
  };
6712
7093
  }();
6713
7094
 
6714
- },{"./is":24}],23:[function(require,module,exports){
7095
+ },{"./is":26}],25:[function(require,module,exports){
6715
7096
  'use strict';
6716
7097
 
6717
7098
  module.exports = function () {
@@ -6776,7 +7157,7 @@ module.exports = function () {
6776
7157
  };
6777
7158
  }();
6778
7159
 
6779
- },{}],24:[function(require,module,exports){
7160
+ },{}],26:[function(require,module,exports){
6780
7161
  'use strict';
6781
7162
 
6782
7163
  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; };
@@ -6999,7 +7380,7 @@ module.exports = function () {
6999
7380
  };
7000
7381
  }();
7001
7382
 
7002
- },{}],25:[function(require,module,exports){
7383
+ },{}],27:[function(require,module,exports){
7003
7384
  'use strict';
7004
7385
 
7005
7386
  var assert = require('./assert'),
@@ -7072,7 +7453,7 @@ module.exports = function () {
7072
7453
  };
7073
7454
  }();
7074
7455
 
7075
- },{"./assert":22,"./is":24}],26:[function(require,module,exports){
7456
+ },{"./assert":24,"./is":26}],28:[function(require,module,exports){
7076
7457
  'use strict';
7077
7458
 
7078
7459
  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; }; }();
@@ -7244,7 +7625,7 @@ module.exports = function () {
7244
7625
  return Event;
7245
7626
  }();
7246
7627
 
7247
- },{"./../lang/Disposable":18,"./../lang/assert":22}],27:[function(require,module,exports){
7628
+ },{"./../lang/Disposable":20,"./../lang/assert":24}],29:[function(require,module,exports){
7248
7629
  /*
7249
7630
  * big.js v5.0.3
7250
7631
  * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic.
@@ -8185,7 +8566,7 @@ module.exports = function () {
8185
8566
  }
8186
8567
  })(this);
8187
8568
 
8188
- },{}],28:[function(require,module,exports){
8569
+ },{}],30:[function(require,module,exports){
8189
8570
  var v1 = require('./v1');
8190
8571
  var v4 = require('./v4');
8191
8572
 
@@ -8195,7 +8576,7 @@ uuid.v4 = v4;
8195
8576
 
8196
8577
  module.exports = uuid;
8197
8578
 
8198
- },{"./v1":31,"./v4":32}],29:[function(require,module,exports){
8579
+ },{"./v1":33,"./v4":34}],31:[function(require,module,exports){
8199
8580
  /**
8200
8581
  * Convert array of 16 byte values to UUID string format of the form:
8201
8582
  * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
@@ -8220,7 +8601,7 @@ function bytesToUuid(buf, offset) {
8220
8601
 
8221
8602
  module.exports = bytesToUuid;
8222
8603
 
8223
- },{}],30:[function(require,module,exports){
8604
+ },{}],32:[function(require,module,exports){
8224
8605
  (function (global){
8225
8606
  // Unique ID creation requires a high quality random # generator. In the
8226
8607
  // browser this is a little complicated due to unknown quality of Math.random()
@@ -8257,7 +8638,7 @@ if (!rng) {
8257
8638
  module.exports = rng;
8258
8639
 
8259
8640
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
8260
- },{}],31:[function(require,module,exports){
8641
+ },{}],33:[function(require,module,exports){
8261
8642
  var rng = require('./lib/rng');
8262
8643
  var bytesToUuid = require('./lib/bytesToUuid');
8263
8644
 
@@ -8359,7 +8740,7 @@ function v1(options, buf, offset) {
8359
8740
 
8360
8741
  module.exports = v1;
8361
8742
 
8362
- },{"./lib/bytesToUuid":29,"./lib/rng":30}],32:[function(require,module,exports){
8743
+ },{"./lib/bytesToUuid":31,"./lib/rng":32}],34:[function(require,module,exports){
8363
8744
  var rng = require('./lib/rng');
8364
8745
  var bytesToUuid = require('./lib/bytesToUuid');
8365
8746
 
@@ -8390,7 +8771,7 @@ function v4(options, buf, offset) {
8390
8771
 
8391
8772
  module.exports = v4;
8392
8773
 
8393
- },{"./lib/bytesToUuid":29,"./lib/rng":30}],33:[function(require,module,exports){
8774
+ },{"./lib/bytesToUuid":31,"./lib/rng":32}],35:[function(require,module,exports){
8394
8775
  const Day = require('@barchart/common-js/lang/Day'),
8395
8776
  Decimal = require('@barchart/common-js/lang/Decimal');
8396
8777
 
@@ -8561,7 +8942,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
8561
8942
  });
8562
8943
  });
8563
8944
 
8564
- describe('and yearly position summary ranges are processed for a transaction set closed in 2016, but has after-the-face superfluous valuations in 2017 and 2018', () => {
8945
+ describe('and yearly position summary ranges are processed for a transaction set closed in 2016, but has after-the-fact superfluous valuations in 2017 and 2018', () => {
8565
8946
  let ranges;
8566
8947
 
8567
8948
  beforeEach(() => {
@@ -8747,7 +9128,60 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
8747
9128
  });
8748
9129
  });
8749
9130
 
8750
- },{"./../../../lib/data/PositionSummaryFrame":2,"./../../../lib/data/TransactionType":3,"@barchart/common-js/lang/Day":16,"@barchart/common-js/lang/Decimal":17}],34:[function(require,module,exports){
9131
+ },{"./../../../lib/data/PositionSummaryFrame":3,"./../../../lib/data/TransactionType":4,"@barchart/common-js/lang/Day":18,"@barchart/common-js/lang/Decimal":19}],36:[function(require,module,exports){
9132
+ const Day = require('@barchart/common-js/lang/Day');
9133
+
9134
+ const TransactionValidator = require('./../../../lib/data/TransactionValidator');
9135
+
9136
+ describe('When validating transaction order', () => {
9137
+ 'use strict';
9138
+
9139
+ const build = (sequence, day) => {
9140
+ return { sequence: sequence, date: Day.parse(day) };
9141
+ };
9142
+
9143
+ it('An array of zero transactions should be valid', () => {
9144
+ expect(TransactionValidator.validateOrder([])).toEqual(true);
9145
+ });
9146
+
9147
+ it('An array of transactions with ordered sequences, on the same day should be valid', () => {
9148
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(2, '2018-04-30'), build(3, '2018-04-30') ])).toEqual(true);
9149
+ });
9150
+
9151
+ it('An array of transactions with ordered sequences, on the sequential days should be valid', () => {
9152
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(2, '2018-05-01'), build(3, '2018-05-02') ])).toEqual(true);
9153
+ });
9154
+
9155
+ it('An array of transactions with ordered sequences (starting after one), on the same day should not be valid', () => {
9156
+ expect(TransactionValidator.validateOrder([ build(3, '2018-04-30'), build(4, '2018-04-30'), build(5, '2018-04-30') ])).toEqual(false);
9157
+ });
9158
+
9159
+ it('An array of transactions with duplicate sequences, on the same day should not be valid', () => {
9160
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(1, '2018-04-30') ])).toEqual(false);
9161
+ });
9162
+
9163
+ it('An array of transactions with with a gap in sequences, on the same day should not be valid', () => {
9164
+ expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(3, '2018-04-30') ])).toEqual(false);
9165
+ });
9166
+
9167
+ it('An array of transactions with with a reversed sequences, on the same subsequent days should not be valid', () => {
9168
+ expect(TransactionValidator.validateOrder([ build(2, '2018-04-30'), build(1, '2018-05-01') ])).toEqual(false);
9169
+ });
9170
+
9171
+ it('An array of transactions with ordered sequences, on the reversed days should not be valid', () => {
9172
+ expect(TransactionValidator.validateOrder([ build(1, '2018-05-02'), build(2, '2018-05-01'), build(3, '2018-04-30') ])).toEqual(false);
9173
+ });
9174
+
9175
+ it('A partial array of transactions with ordered sequences (starting after one), on the same day should be valid', () => {
9176
+ expect(TransactionValidator.validateOrder([ build(3, '2018-04-30'), build(4, '2018-04-30'), build(5, '2018-04-30') ], true)).toEqual(true);
9177
+ });
9178
+
9179
+ it('A partial array of transactions with gap in sequences (starting after one), on the same day should be not valid', () => {
9180
+ expect(TransactionValidator.validateOrder([ build(3, '2018-04-30'), build(5, '2018-04-30'), build(6, '2018-04-30') ], true)).toEqual(false);
9181
+ });
9182
+ });
9183
+
9184
+ },{"./../../../lib/data/TransactionValidator":5,"@barchart/common-js/lang/Day":18}],37:[function(require,module,exports){
8751
9185
  const Currency = require('@barchart/common-js/lang/Currency'),
8752
9186
  Decimal = require('@barchart/common-js/lang/Decimal');
8753
9187
 
@@ -8857,4 +9291,4 @@ describe('When a position container data is gathered', () => {
8857
9291
  });
8858
9292
  });
8859
9293
 
8860
- },{"./../../../lib/data/InstrumentType":1,"./../../../lib/processing/PositionContainer":4,"./../../../lib/processing/definitions/PositionLevelDefinition":7,"./../../../lib/processing/definitions/PositionLevelType":8,"./../../../lib/processing/definitions/PositionTreeDefinition":9,"@barchart/common-js/lang/Currency":15,"@barchart/common-js/lang/Decimal":17}]},{},[33,34]);
9294
+ },{"./../../../lib/data/InstrumentType":1,"./../../../lib/processing/PositionContainer":6,"./../../../lib/processing/definitions/PositionLevelDefinition":9,"./../../../lib/processing/definitions/PositionLevelType":10,"./../../../lib/processing/definitions/PositionTreeDefinition":11,"@barchart/common-js/lang/Currency":17,"@barchart/common-js/lang/Decimal":19}]},{},[35,36,37]);