@barchart/portfolio-api-common 1.0.141 → 1.0.145

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.
@@ -4,6 +4,7 @@ const array = require('@barchart/common-js/lang/array'),
4
4
  comparators = require('@barchart/common-js/collections/sorting/comparators'),
5
5
  Currency = require('@barchart/common-js/lang/Currency'),
6
6
  Decimal = require('@barchart/common-js/lang/Decimal'),
7
+ DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
7
8
  is = require('@barchart/common-js/lang/is'),
8
9
  Rate = require('@barchart/common-js/lang/Rate'),
9
10
  Tree = require('@barchart/common-js/collections/Tree');
@@ -47,6 +48,18 @@ module.exports = (() => {
47
48
  const currentSummaryFrame = PositionSummaryFrame.YTD;
48
49
  const currentSummaryRange = array.last(currentSummaryFrame.getRecentRanges(0));
49
50
 
51
+ this._groupBindings = { };
52
+
53
+ const addGroupBinding = (group, dispoable) => {
54
+ const id = group.id;
55
+
56
+ if (!this._groupBindings.hasOwnProperty(id)) {
57
+ this._groupBindings[id] = new DisposableStack();
58
+ }
59
+
60
+ this._groupBindings[id].push(dispoable);
61
+ };
62
+
50
63
  this._portfolios = portfolios.reduce((map, portfolio) => {
51
64
  map[portfolio.portfolio] = portfolio;
52
65
 
@@ -214,12 +227,30 @@ module.exports = (() => {
214
227
 
215
228
  compositeGroups.sort(builder.toComparator());
216
229
 
230
+ const initializeGroupObservers = (group, groupTree) => {
231
+ addGroupBinding(group, group.registerGroupExcludedChangeHandler((excluded, sender) => {
232
+ groupTree.climb((parentGroup, parentTree) => {
233
+ let excludedItems = [ ];
234
+
235
+ currentTree.walk((childGroup, childTree) => {
236
+ if (childGroup.excluded) {
237
+ excludedItems = excludedItems.concat(childGroup.items);
238
+ }
239
+ }, false, false);
240
+
241
+ parentGroup.setExcludedItems(array.unique(excludedItems));
242
+ }, false);
243
+ }));
244
+ };
245
+
217
246
  compositeGroups.forEach((group) => {
218
247
  const childTree = currentTree.addChild(group);
219
248
 
220
- group.registerMarketPercentChangeHandler(() => {
249
+ initializeGroupObservers(group, childTree);
250
+
251
+ addGroupBinding(group, group.registerMarketPercentChangeHandler(() => {
221
252
  currentTree.walk((childGroup) => childGroup.refreshMarketPercent());
222
- });
253
+ }));
223
254
 
224
255
  createGroups(childTree, group.items, array.dropLeft(levelDefinitions));
225
256
  });
@@ -379,6 +410,7 @@ module.exports = (() => {
379
410
  /**
380
411
  * Returns a single level of grouping from one of the internal trees.
381
412
  *
413
+ * @public
382
414
  * @param {String} name
383
415
  * @param {Array.<String> keys
384
416
  * @returns {PositionGroup}
@@ -394,6 +426,7 @@ module.exports = (() => {
394
426
  * Returns all child groups from a level of grouping within one of
395
427
  * the internal trees.
396
428
  *
429
+ * @public
397
430
  * @param {String} name
398
431
  * @param {Array.<String> keys
399
432
  * @returns {Array.<PositionGroup>}
@@ -405,6 +438,13 @@ module.exports = (() => {
405
438
  return findNode(this._trees[name], keys).getChildren().map(node => node.getValue());
406
439
  }
407
440
 
441
+ /**
442
+ * Returns all positions for the given portfolio.
443
+ *
444
+ * @public
445
+ * @param {String} portfolio
446
+ * @return {Array.<Object>}
447
+ */
408
448
  getPositions(portfolio) {
409
449
  return this._items.reduce((positions, item) => {
410
450
  if (item.position.portfolio === portfolio) {
@@ -1,6 +1,8 @@
1
- const assert = require('@barchart/common-js/lang/assert'),
1
+ const array = require('@barchart/common-js/lang/array'),
2
+ assert = require('@barchart/common-js/lang/assert'),
2
3
  Currency = require('@barchart/common-js/lang/Currency'),
3
4
  Decimal = require('@barchart/common-js/lang/Decimal'),
5
+ DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
4
6
  Event = require('@barchart/common-js/messaging/Event'),
5
7
  formatter = require('@barchart/common-js/lang/formatter'),
6
8
  is = require('@barchart/common-js/lang/is'),
@@ -9,6 +11,8 @@ const assert = require('@barchart/common-js/lang/assert'),
9
11
  module.exports = (() => {
10
12
  'use strict';
11
13
 
14
+ let counter = 0;
15
+
12
16
  /**
13
17
  * A grouping of {@link PositionItem} instances. The group aggregates from across
14
18
  * all the positions and performs currency translation, as necessary.
@@ -24,6 +28,7 @@ module.exports = (() => {
24
28
  */
25
29
  class PositionGroup {
26
30
  constructor(container, parent, items, currency, key, description, single) {
31
+ this._id = counter++;
27
32
  this._container = container;
28
33
  this._parent = parent || null;
29
34
 
@@ -41,9 +46,15 @@ module.exports = (() => {
41
46
  this._showClosedPositions = false;
42
47
 
43
48
  this._marketPercentChangeEvent = new Event(this);
44
- this._excludedChangeEvent = new Event(this);
49
+ this._groupExcludedChangeEvent = new Event(this);
45
50
  this._showClosedPositionsChangeEvent = new Event(this);
46
51
 
52
+ this._disposeStack = new DisposableStack();
53
+
54
+ this._excludedItems = [ ];
55
+ this._excludedItemMap = { };
56
+ this._consideredItems = this._items;
57
+
47
58
  this._dataFormat = { };
48
59
  this._dataActual = { };
49
60
 
@@ -74,6 +85,15 @@ module.exports = (() => {
74
85
  this._dataFormat.fundamental = { };
75
86
  }
76
87
 
88
+ this._dataActual.quoteLast = null;
89
+ this._dataActual.quoteOpen = null;
90
+ this._dataActual.quoteHigh = null;
91
+ this._dataActual.quoteLow = null;
92
+ this._dataActual.quoteChange = null;
93
+ this._dataActual.quoteChangePercent = null;
94
+ this._dataActual.quoteTime = null;
95
+ this._dataActual.quoteVolume = null;
96
+
77
97
  this._dataFormat.quoteLast = null;
78
98
  this._dataFormat.quoteOpen = null;
79
99
  this._dataFormat.quoteHigh = null;
@@ -117,44 +137,63 @@ module.exports = (() => {
117
137
  this._dataFormat.summaryTotalPreviousNegative = false;
118
138
 
119
139
  this._items.forEach((item) => {
120
- item.registerQuoteChangeHandler((quote, sender) => {
140
+ this._disposeStack.push(item.registerQuoteChangeHandler((quote, sender) => {
121
141
  if (this._single) {
122
142
  const precision = sender.position.instrument.currency.precision;
123
143
 
124
144
  this._dataActual.currentPrice = quote.lastPrice;
125
145
  this._dataFormat.currentPrice = formatNumber(this._dataActual.currentPrice, precision);
126
146
 
127
- this._dataFormat.quoteLast = formatNumber(quote.previousPrice, precision);
128
- this._dataFormat.quoteOpen = formatNumber(quote.openPrice, precision);
129
- this._dataFormat.quoteHigh = formatNumber(quote.highPrice, precision);
130
- this._dataFormat.quoteLow = formatNumber(quote.lowPrice, precision);
131
- this._dataFormat.quoteChange = formatNumber(quote.priceChange, precision);
132
- this._dataFormat.quoteChangePercent = formatPercent(new Decimal(quote.percentChange || 0), 2);
133
- this._dataFormat.quoteTime = quote.timeDisplay;
134
- this._dataFormat.quoteVolume = formatNumber(quote.volume, 0);
147
+ this._dataActual.quoteLast = quote.previousPrice;
148
+ this._dataActual.quoteOpen = quote.openPrice;
149
+ this._dataActual.quoteHigh = quote.highPrice;
150
+ this._dataActual.quoteLow = quote.lowPrice;
151
+ this._dataActual.quoteChange = quote.priceChange;
152
+ this._dataActual.quoteChangePercent = quote.percentChange;
153
+ this._dataActual.quoteTime = quote.timeDisplay;
154
+ this._dataActual.quoteVolume = quote.volume;
155
+
156
+ this._dataFormat.quoteLast = formatNumber(this._dataActual.quoteLast , precision);
157
+ this._dataFormat.quoteOpen = formatNumber(this._dataActual.quoteOpen, precision);
158
+ this._dataFormat.quoteHigh = formatNumber(this._dataActual.quoteHigh, precision);
159
+ this._dataFormat.quoteLow = formatNumber(this._dataActual.quoteLow, precision);
160
+ this._dataFormat.quoteChange = formatNumber(this._dataActual.quoteChange, precision);
161
+ this._dataFormat.quoteChangePercent = formatPercent(new Decimal(this._dataActual.quoteChangePercent || 0), 2);
162
+ this._dataFormat.quoteTime = this._dataActual.quoteTime;
163
+ this._dataFormat.quoteVolume = formatNumber(this._dataActual.quoteVolume, 0);
135
164
  } else {
136
165
  this._dataActual.currentPrice = null;
137
166
  this._dataFormat.currentPrice = null;
138
167
  }
139
168
 
140
169
  calculatePriceData(this, this._container.getForexQuotes(), sender, false);
141
- });
170
+ }));
142
171
 
143
172
  if (this._single) {
144
- item.registerNewsExistsChangeHandler((exists, sender) => {
173
+ this._disposeStack.push(item.registerNewsExistsChangeHandler((exists, sender) => {
145
174
  this._dataActual.newsExists = exists;
146
175
  this._dataFormat.newsExists = exists;
147
- });
176
+ }));
148
177
 
149
- item.registerFundamentalDataChangeHandler((data, sender) => {
178
+ this._disposeStack.push(item.registerFundamentalDataChangeHandler((data, sender) => {
150
179
  this._dataFormat.fundamental = data;
151
- });
180
+ }));
152
181
  }
153
182
  });
154
183
 
155
184
  this.refresh();
156
185
  }
157
186
 
187
+ /**
188
+ * A unique (and otherwise meaningless) idenfitifer for the group.
189
+ *
190
+ * @public
191
+ * @returns {Number}
192
+ */
193
+ get id() {
194
+ return this._id;
195
+ }
196
+
158
197
  /**
159
198
  * The key of the group.
160
199
  *
@@ -240,6 +279,27 @@ module.exports = (() => {
240
279
  return this._excluded;
241
280
  }
242
281
 
282
+ /**
283
+ * Sets the list of items which are excluded from group aggregation calculations.
284
+ *
285
+ * @public
286
+ * @param {Array.<Object>} items
287
+ */
288
+ setExcludedItems(items) {
289
+ this._excludedItems = items;
290
+ this._consideredItems = array.difference(this._items, this._excludedItems);
291
+
292
+ this._excludedItemMap = this._excludedItems.reduce((map, item) => {
293
+ const key = item.position.position;
294
+
295
+ map[key] = item;
296
+
297
+ return map;
298
+ }, { });
299
+
300
+ this.refresh();
301
+ }
302
+
243
303
  /**
244
304
  * Causes aggregated data to be recalculated using a new exchange rate.
245
305
  *
@@ -256,7 +316,7 @@ module.exports = (() => {
256
316
  assert.argumentIsRequired(value, 'value', Boolean);
257
317
 
258
318
  if (this._excluded !== value) {
259
- this._excludedChangeEvent(this._excluded = value);
319
+ this._groupExcludedChangeEvent.fire(this._excluded = value);
260
320
  }
261
321
  }
262
322
 
@@ -300,8 +360,27 @@ module.exports = (() => {
300
360
  calculateMarketPercent(this, this._container.getForexQuotes(), true);
301
361
  }
302
362
 
363
+ /**
364
+ * Adds an observer for change in the market percentage of the group.
365
+ *
366
+ * @public
367
+ * @param {Function} handler
368
+ * @return {Disposable}
369
+ */
303
370
  registerMarketPercentChangeHandler(handler) {
304
- this._marketPercentChangeEvent.register(handler);
371
+ return this._marketPercentChangeEvent.register(handler);
372
+ }
373
+
374
+ /**
375
+ * Adds an observer for changes to the exclusion of the group
376
+ * from higher level aggregations.
377
+ *
378
+ * @public
379
+ * @param {Function} handler
380
+ * @return {Disposable}
381
+ */
382
+ registerGroupExcludedChangeHandler(handler) {
383
+ return this._groupExcludedChangeEvent.register(handler);
305
384
  }
306
385
 
307
386
  toString() {
@@ -347,7 +426,7 @@ module.exports = (() => {
347
426
 
348
427
  const currency = group.currency;
349
428
 
350
- const items = group._items;
429
+ const items = group._consideredItems;
351
430
 
352
431
  group._bypassCurrencyTranslation = items.every(item => item.currency === currency);
353
432
 
@@ -415,11 +494,16 @@ module.exports = (() => {
415
494
  }
416
495
 
417
496
  const parent = group._parent;
497
+ const currency = group.currency;
418
498
 
419
499
  const actual = group._dataActual;
420
500
  const format = group._dataFormat;
421
501
 
422
- const currency = group.currency;
502
+ const refresh = (is.boolean(forceRefresh) && forceRefresh) || (actual.market === null || actual.unrealizedToday === null || actual.total === null);
503
+
504
+ if (!refresh && group._excludedItemMap.hasOwnProperty(item.position.position)) {
505
+ return;
506
+ }
423
507
 
424
508
  const translate = (item, value) => {
425
509
  let translated;
@@ -433,12 +517,10 @@ module.exports = (() => {
433
517
  return translated;
434
518
  };
435
519
 
436
- const refresh = (is.boolean(forceRefresh) && forceRefresh) || (actual.market === null || actual.unrealizedToday === null || actual.total === null);
437
-
438
520
  let updates;
439
521
 
440
522
  if (refresh) {
441
- const items = group._items;
523
+ const items = group._consideredItems;
442
524
 
443
525
  updates = items.reduce((updates, item) => {
444
526
  updates.market = updates.market.add(translate(item, item.data.market));
@@ -453,7 +535,6 @@ module.exports = (() => {
453
535
  unrealized: Decimal.ZERO,
454
536
  unrealizedToday: Decimal.ZERO,
455
537
  summaryTotalCurrent: Decimal.ZERO
456
-
457
538
  });
458
539
  } else {
459
540
  updates = {
@@ -196,9 +196,10 @@ module.exports = (() => {
196
196
  *
197
197
  * @public
198
198
  * @param {Function} handler
199
+ * @returns {Disposable}
199
200
  */
200
201
  registerQuoteChangeHandler(handler) {
201
- this._quoteChangedEvent.register(handler);
202
+ return this._quoteChangedEvent.register(handler);
202
203
  }
203
204
 
204
205
  /**
@@ -206,9 +207,10 @@ module.exports = (() => {
206
207
  *
207
208
  * @public
208
209
  * @param {Function} handler
210
+ * @returns {Disposable}
209
211
  */
210
212
  registerFundamentalDataChangeHandler(handler) {
211
- this._fundamentalDataChangeEvent.register(handler);
213
+ return this._fundamentalDataChangeEvent.register(handler);
212
214
  }
213
215
 
214
216
  /**
@@ -216,9 +218,10 @@ module.exports = (() => {
216
218
  *
217
219
  * @public
218
220
  * @param {Function} handler
221
+ * @returns {Disposable}
219
222
  */
220
223
  registerNewsExistsChangeHandler(handler) {
221
- this._newsExistsChangedEvent.register(handler);
224
+ return this._newsExistsChangedEvent.register(handler);
222
225
  }
223
226
 
224
227
  toString() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.0.141",
3
+ "version": "1.0.145",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -116,7 +116,7 @@ module.exports = (() => {
116
116
  return InstrumentType;
117
117
  })();
118
118
 
119
- },{"@barchart/common-js/lang/Enum":16,"@barchart/common-js/lang/assert":19}],2:[function(require,module,exports){
119
+ },{"@barchart/common-js/lang/Enum":18,"@barchart/common-js/lang/assert":21}],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":13,"@barchart/common-js/lang/Decimal":14,"@barchart/common-js/lang/Enum":16,"@barchart/common-js/lang/array":18,"@barchart/common-js/lang/assert":19,"@barchart/common-js/lang/is":21}],3:[function(require,module,exports){
376
+ },{"@barchart/common-js/lang/Day":15,"@barchart/common-js/lang/Decimal":16,"@barchart/common-js/lang/Enum":18,"@barchart/common-js/lang/array":20,"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23}],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,13 +713,14 @@ module.exports = (() => {
713
713
  return TransactionType;
714
714
  })();
715
715
 
716
- },{"@barchart/common-js/lang/Enum":16,"@barchart/common-js/lang/assert":19}],4:[function(require,module,exports){
716
+ },{"@barchart/common-js/lang/Enum":18,"@barchart/common-js/lang/assert":21}],4:[function(require,module,exports){
717
717
  const array = require('@barchart/common-js/lang/array'),
718
718
  assert = require('@barchart/common-js/lang/assert'),
719
719
  ComparatorBuilder = require('@barchart/common-js/collections/sorting/ComparatorBuilder'),
720
720
  comparators = require('@barchart/common-js/collections/sorting/comparators'),
721
721
  Currency = require('@barchart/common-js/lang/Currency'),
722
722
  Decimal = require('@barchart/common-js/lang/Decimal'),
723
+ DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
723
724
  is = require('@barchart/common-js/lang/is'),
724
725
  Rate = require('@barchart/common-js/lang/Rate'),
725
726
  Tree = require('@barchart/common-js/collections/Tree');
@@ -763,6 +764,18 @@ module.exports = (() => {
763
764
  const currentSummaryFrame = PositionSummaryFrame.YTD;
764
765
  const currentSummaryRange = array.last(currentSummaryFrame.getRecentRanges(0));
765
766
 
767
+ this._groupBindings = { };
768
+
769
+ const addGroupBinding = (group, dispoable) => {
770
+ const id = group.id;
771
+
772
+ if (!this._groupBindings.hasOwnProperty(id)) {
773
+ this._groupBindings[id] = new DisposableStack();
774
+ }
775
+
776
+ this._groupBindings[id].push(dispoable);
777
+ };
778
+
766
779
  this._portfolios = portfolios.reduce((map, portfolio) => {
767
780
  map[portfolio.portfolio] = portfolio;
768
781
 
@@ -930,12 +943,30 @@ module.exports = (() => {
930
943
 
931
944
  compositeGroups.sort(builder.toComparator());
932
945
 
946
+ const initializeGroupObservers = (group, groupTree) => {
947
+ addGroupBinding(group, group.registerGroupExcludedChangeHandler((excluded, sender) => {
948
+ groupTree.climb((parentGroup, parentTree) => {
949
+ let excludedItems = [ ];
950
+
951
+ currentTree.walk((childGroup, childTree) => {
952
+ if (childGroup.excluded) {
953
+ excludedItems = excludedItems.concat(childGroup.items);
954
+ }
955
+ }, false, false);
956
+
957
+ parentGroup.setExcludedItems(array.unique(excludedItems));
958
+ }, false);
959
+ }));
960
+ };
961
+
933
962
  compositeGroups.forEach((group) => {
934
963
  const childTree = currentTree.addChild(group);
935
964
 
936
- group.registerMarketPercentChangeHandler(() => {
965
+ initializeGroupObservers(group, childTree);
966
+
967
+ addGroupBinding(group, group.registerMarketPercentChangeHandler(() => {
937
968
  currentTree.walk((childGroup) => childGroup.refreshMarketPercent());
938
- });
969
+ }));
939
970
 
940
971
  createGroups(childTree, group.items, array.dropLeft(levelDefinitions));
941
972
  });
@@ -1095,6 +1126,7 @@ module.exports = (() => {
1095
1126
  /**
1096
1127
  * Returns a single level of grouping from one of the internal trees.
1097
1128
  *
1129
+ * @public
1098
1130
  * @param {String} name
1099
1131
  * @param {Array.<String> keys
1100
1132
  * @returns {PositionGroup}
@@ -1110,6 +1142,7 @@ module.exports = (() => {
1110
1142
  * Returns all child groups from a level of grouping within one of
1111
1143
  * the internal trees.
1112
1144
  *
1145
+ * @public
1113
1146
  * @param {String} name
1114
1147
  * @param {Array.<String> keys
1115
1148
  * @returns {Array.<PositionGroup>}
@@ -1121,6 +1154,13 @@ module.exports = (() => {
1121
1154
  return findNode(this._trees[name], keys).getChildren().map(node => node.getValue());
1122
1155
  }
1123
1156
 
1157
+ /**
1158
+ * Returns all positions for the given portfolio.
1159
+ *
1160
+ * @public
1161
+ * @param {String} portfolio
1162
+ * @return {Array.<Object>}
1163
+ */
1124
1164
  getPositions(portfolio) {
1125
1165
  return this._items.reduce((positions, item) => {
1126
1166
  if (item.position.portfolio === portfolio) {
@@ -1175,10 +1215,12 @@ module.exports = (() => {
1175
1215
  return PositionContainer;
1176
1216
  })();
1177
1217
 
1178
- },{"./../data/PositionSummaryFrame":2,"./PositionGroup":5,"./PositionItem":6,"./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/Decimal":14,"@barchart/common-js/lang/Rate":17,"@barchart/common-js/lang/array":18,"@barchart/common-js/lang/assert":19,"@barchart/common-js/lang/is":21}],5:[function(require,module,exports){
1179
- const assert = require('@barchart/common-js/lang/assert'),
1218
+ },{"./../data/PositionSummaryFrame":2,"./PositionGroup":5,"./PositionItem":6,"./definitions/PositionTreeDefinition":8,"@barchart/common-js/collections/Tree":10,"@barchart/common-js/collections/sorting/ComparatorBuilder":11,"@barchart/common-js/collections/sorting/comparators":12,"@barchart/common-js/collections/specialized/DisposableStack":13,"@barchart/common-js/lang/Currency":14,"@barchart/common-js/lang/Decimal":16,"@barchart/common-js/lang/Rate":19,"@barchart/common-js/lang/array":20,"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23}],5:[function(require,module,exports){
1219
+ const array = require('@barchart/common-js/lang/array'),
1220
+ assert = require('@barchart/common-js/lang/assert'),
1180
1221
  Currency = require('@barchart/common-js/lang/Currency'),
1181
1222
  Decimal = require('@barchart/common-js/lang/Decimal'),
1223
+ DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
1182
1224
  Event = require('@barchart/common-js/messaging/Event'),
1183
1225
  formatter = require('@barchart/common-js/lang/formatter'),
1184
1226
  is = require('@barchart/common-js/lang/is'),
@@ -1187,6 +1229,8 @@ const assert = require('@barchart/common-js/lang/assert'),
1187
1229
  module.exports = (() => {
1188
1230
  'use strict';
1189
1231
 
1232
+ let counter = 0;
1233
+
1190
1234
  /**
1191
1235
  * A grouping of {@link PositionItem} instances. The group aggregates from across
1192
1236
  * all the positions and performs currency translation, as necessary.
@@ -1202,6 +1246,7 @@ module.exports = (() => {
1202
1246
  */
1203
1247
  class PositionGroup {
1204
1248
  constructor(container, parent, items, currency, key, description, single) {
1249
+ this._id = counter++;
1205
1250
  this._container = container;
1206
1251
  this._parent = parent || null;
1207
1252
 
@@ -1219,9 +1264,15 @@ module.exports = (() => {
1219
1264
  this._showClosedPositions = false;
1220
1265
 
1221
1266
  this._marketPercentChangeEvent = new Event(this);
1222
- this._excludedChangeEvent = new Event(this);
1267
+ this._groupExcludedChangeEvent = new Event(this);
1223
1268
  this._showClosedPositionsChangeEvent = new Event(this);
1224
1269
 
1270
+ this._disposeStack = new DisposableStack();
1271
+
1272
+ this._excludedItems = [ ];
1273
+ this._excludedItemMap = { };
1274
+ this._consideredItems = this._items;
1275
+
1225
1276
  this._dataFormat = { };
1226
1277
  this._dataActual = { };
1227
1278
 
@@ -1252,6 +1303,15 @@ module.exports = (() => {
1252
1303
  this._dataFormat.fundamental = { };
1253
1304
  }
1254
1305
 
1306
+ this._dataActual.quoteLast = null;
1307
+ this._dataActual.quoteOpen = null;
1308
+ this._dataActual.quoteHigh = null;
1309
+ this._dataActual.quoteLow = null;
1310
+ this._dataActual.quoteChange = null;
1311
+ this._dataActual.quoteChangePercent = null;
1312
+ this._dataActual.quoteTime = null;
1313
+ this._dataActual.quoteVolume = null;
1314
+
1255
1315
  this._dataFormat.quoteLast = null;
1256
1316
  this._dataFormat.quoteOpen = null;
1257
1317
  this._dataFormat.quoteHigh = null;
@@ -1295,44 +1355,63 @@ module.exports = (() => {
1295
1355
  this._dataFormat.summaryTotalPreviousNegative = false;
1296
1356
 
1297
1357
  this._items.forEach((item) => {
1298
- item.registerQuoteChangeHandler((quote, sender) => {
1358
+ this._disposeStack.push(item.registerQuoteChangeHandler((quote, sender) => {
1299
1359
  if (this._single) {
1300
1360
  const precision = sender.position.instrument.currency.precision;
1301
1361
 
1302
1362
  this._dataActual.currentPrice = quote.lastPrice;
1303
1363
  this._dataFormat.currentPrice = formatNumber(this._dataActual.currentPrice, precision);
1304
1364
 
1305
- this._dataFormat.quoteLast = formatNumber(quote.previousPrice, precision);
1306
- this._dataFormat.quoteOpen = formatNumber(quote.openPrice, precision);
1307
- this._dataFormat.quoteHigh = formatNumber(quote.highPrice, precision);
1308
- this._dataFormat.quoteLow = formatNumber(quote.lowPrice, precision);
1309
- this._dataFormat.quoteChange = formatNumber(quote.priceChange, precision);
1310
- this._dataFormat.quoteChangePercent = formatPercent(new Decimal(quote.percentChange || 0), 2);
1311
- this._dataFormat.quoteTime = quote.timeDisplay;
1312
- this._dataFormat.quoteVolume = formatNumber(quote.volume, 0);
1365
+ this._dataActual.quoteLast = quote.previousPrice;
1366
+ this._dataActual.quoteOpen = quote.openPrice;
1367
+ this._dataActual.quoteHigh = quote.highPrice;
1368
+ this._dataActual.quoteLow = quote.lowPrice;
1369
+ this._dataActual.quoteChange = quote.priceChange;
1370
+ this._dataActual.quoteChangePercent = quote.percentChange;
1371
+ this._dataActual.quoteTime = quote.timeDisplay;
1372
+ this._dataActual.quoteVolume = quote.volume;
1373
+
1374
+ this._dataFormat.quoteLast = formatNumber(this._dataActual.quoteLast , precision);
1375
+ this._dataFormat.quoteOpen = formatNumber(this._dataActual.quoteOpen, precision);
1376
+ this._dataFormat.quoteHigh = formatNumber(this._dataActual.quoteHigh, precision);
1377
+ this._dataFormat.quoteLow = formatNumber(this._dataActual.quoteLow, precision);
1378
+ this._dataFormat.quoteChange = formatNumber(this._dataActual.quoteChange, precision);
1379
+ this._dataFormat.quoteChangePercent = formatPercent(new Decimal(this._dataActual.quoteChangePercent || 0), 2);
1380
+ this._dataFormat.quoteTime = this._dataActual.quoteTime;
1381
+ this._dataFormat.quoteVolume = formatNumber(this._dataActual.quoteVolume, 0);
1313
1382
  } else {
1314
1383
  this._dataActual.currentPrice = null;
1315
1384
  this._dataFormat.currentPrice = null;
1316
1385
  }
1317
1386
 
1318
1387
  calculatePriceData(this, this._container.getForexQuotes(), sender, false);
1319
- });
1388
+ }));
1320
1389
 
1321
1390
  if (this._single) {
1322
- item.registerNewsExistsChangeHandler((exists, sender) => {
1391
+ this._disposeStack.push(item.registerNewsExistsChangeHandler((exists, sender) => {
1323
1392
  this._dataActual.newsExists = exists;
1324
1393
  this._dataFormat.newsExists = exists;
1325
- });
1394
+ }));
1326
1395
 
1327
- item.registerFundamentalDataChangeHandler((data, sender) => {
1396
+ this._disposeStack.push(item.registerFundamentalDataChangeHandler((data, sender) => {
1328
1397
  this._dataFormat.fundamental = data;
1329
- });
1398
+ }));
1330
1399
  }
1331
1400
  });
1332
1401
 
1333
1402
  this.refresh();
1334
1403
  }
1335
1404
 
1405
+ /**
1406
+ * A unique (and otherwise meaningless) idenfitifer for the group.
1407
+ *
1408
+ * @public
1409
+ * @returns {Number}
1410
+ */
1411
+ get id() {
1412
+ return this._id;
1413
+ }
1414
+
1336
1415
  /**
1337
1416
  * The key of the group.
1338
1417
  *
@@ -1418,6 +1497,27 @@ module.exports = (() => {
1418
1497
  return this._excluded;
1419
1498
  }
1420
1499
 
1500
+ /**
1501
+ * Sets the list of items which are excluded from group aggregation calculations.
1502
+ *
1503
+ * @public
1504
+ * @param {Array.<Object>} items
1505
+ */
1506
+ setExcludedItems(items) {
1507
+ this._excludedItems = items;
1508
+ this._consideredItems = array.difference(this._items, this._excludedItems);
1509
+
1510
+ this._excludedItemMap = this._excludedItems.reduce((map, item) => {
1511
+ const key = item.position.position;
1512
+
1513
+ map[key] = item;
1514
+
1515
+ return map;
1516
+ }, { });
1517
+
1518
+ this.refresh();
1519
+ }
1520
+
1421
1521
  /**
1422
1522
  * Causes aggregated data to be recalculated using a new exchange rate.
1423
1523
  *
@@ -1434,7 +1534,7 @@ module.exports = (() => {
1434
1534
  assert.argumentIsRequired(value, 'value', Boolean);
1435
1535
 
1436
1536
  if (this._excluded !== value) {
1437
- this._excludedChangeEvent(this._excluded = value);
1537
+ this._groupExcludedChangeEvent.fire(this._excluded = value);
1438
1538
  }
1439
1539
  }
1440
1540
 
@@ -1478,8 +1578,27 @@ module.exports = (() => {
1478
1578
  calculateMarketPercent(this, this._container.getForexQuotes(), true);
1479
1579
  }
1480
1580
 
1581
+ /**
1582
+ * Adds an observer for change in the market percentage of the group.
1583
+ *
1584
+ * @public
1585
+ * @param {Function} handler
1586
+ * @return {Disposable}
1587
+ */
1481
1588
  registerMarketPercentChangeHandler(handler) {
1482
- this._marketPercentChangeEvent.register(handler);
1589
+ return this._marketPercentChangeEvent.register(handler);
1590
+ }
1591
+
1592
+ /**
1593
+ * Adds an observer for changes to the exclusion of the group
1594
+ * from higher level aggregations.
1595
+ *
1596
+ * @public
1597
+ * @param {Function} handler
1598
+ * @return {Disposable}
1599
+ */
1600
+ registerGroupExcludedChangeHandler(handler) {
1601
+ return this._groupExcludedChangeEvent.register(handler);
1483
1602
  }
1484
1603
 
1485
1604
  toString() {
@@ -1525,7 +1644,7 @@ module.exports = (() => {
1525
1644
 
1526
1645
  const currency = group.currency;
1527
1646
 
1528
- const items = group._items;
1647
+ const items = group._consideredItems;
1529
1648
 
1530
1649
  group._bypassCurrencyTranslation = items.every(item => item.currency === currency);
1531
1650
 
@@ -1593,11 +1712,16 @@ module.exports = (() => {
1593
1712
  }
1594
1713
 
1595
1714
  const parent = group._parent;
1715
+ const currency = group.currency;
1596
1716
 
1597
1717
  const actual = group._dataActual;
1598
1718
  const format = group._dataFormat;
1599
1719
 
1600
- const currency = group.currency;
1720
+ const refresh = (is.boolean(forceRefresh) && forceRefresh) || (actual.market === null || actual.unrealizedToday === null || actual.total === null);
1721
+
1722
+ if (!refresh && group._excludedItemMap.hasOwnProperty(item.position.position)) {
1723
+ return;
1724
+ }
1601
1725
 
1602
1726
  const translate = (item, value) => {
1603
1727
  let translated;
@@ -1611,12 +1735,10 @@ module.exports = (() => {
1611
1735
  return translated;
1612
1736
  };
1613
1737
 
1614
- const refresh = (is.boolean(forceRefresh) && forceRefresh) || (actual.market === null || actual.unrealizedToday === null || actual.total === null);
1615
-
1616
1738
  let updates;
1617
1739
 
1618
1740
  if (refresh) {
1619
- const items = group._items;
1741
+ const items = group._consideredItems;
1620
1742
 
1621
1743
  updates = items.reduce((updates, item) => {
1622
1744
  updates.market = updates.market.add(translate(item, item.data.market));
@@ -1631,7 +1753,6 @@ module.exports = (() => {
1631
1753
  unrealized: Decimal.ZERO,
1632
1754
  unrealizedToday: Decimal.ZERO,
1633
1755
  summaryTotalCurrent: Decimal.ZERO
1634
-
1635
1756
  });
1636
1757
  } else {
1637
1758
  updates = {
@@ -1743,7 +1864,7 @@ module.exports = (() => {
1743
1864
  return PositionGroup;
1744
1865
  })();
1745
1866
 
1746
- },{"@barchart/common-js/lang/Currency":12,"@barchart/common-js/lang/Decimal":14,"@barchart/common-js/lang/Rate":17,"@barchart/common-js/lang/assert":19,"@barchart/common-js/lang/formatter":20,"@barchart/common-js/lang/is":21,"@barchart/common-js/messaging/Event":23}],6:[function(require,module,exports){
1867
+ },{"@barchart/common-js/collections/specialized/DisposableStack":13,"@barchart/common-js/lang/Currency":14,"@barchart/common-js/lang/Decimal":16,"@barchart/common-js/lang/Rate":19,"@barchart/common-js/lang/array":20,"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/formatter":22,"@barchart/common-js/lang/is":23,"@barchart/common-js/messaging/Event":25}],6:[function(require,module,exports){
1747
1868
  const array = require('@barchart/common-js/lang/array'),
1748
1869
  assert = require('@barchart/common-js/lang/assert'),
1749
1870
  Currency = require('@barchart/common-js/lang/Currency'),
@@ -1942,9 +2063,10 @@ module.exports = (() => {
1942
2063
  *
1943
2064
  * @public
1944
2065
  * @param {Function} handler
2066
+ * @returns {Disposable}
1945
2067
  */
1946
2068
  registerQuoteChangeHandler(handler) {
1947
- this._quoteChangedEvent.register(handler);
2069
+ return this._quoteChangedEvent.register(handler);
1948
2070
  }
1949
2071
 
1950
2072
  /**
@@ -1952,9 +2074,10 @@ module.exports = (() => {
1952
2074
  *
1953
2075
  * @public
1954
2076
  * @param {Function} handler
2077
+ * @returns {Disposable}
1955
2078
  */
1956
2079
  registerFundamentalDataChangeHandler(handler) {
1957
- this._fundamentalDataChangeEvent.register(handler);
2080
+ return this._fundamentalDataChangeEvent.register(handler);
1958
2081
  }
1959
2082
 
1960
2083
  /**
@@ -1962,9 +2085,10 @@ module.exports = (() => {
1962
2085
  *
1963
2086
  * @public
1964
2087
  * @param {Function} handler
2088
+ * @returns {Disposable}
1965
2089
  */
1966
2090
  registerNewsExistsChangeHandler(handler) {
1967
- this._newsExistsChangedEvent.register(handler);
2091
+ return this._newsExistsChangedEvent.register(handler);
1968
2092
  }
1969
2093
 
1970
2094
  toString() {
@@ -2109,7 +2233,7 @@ module.exports = (() => {
2109
2233
  return PositionItem;
2110
2234
  })();
2111
2235
 
2112
- },{"./../data/InstrumentType":1,"@barchart/common-js/lang/Currency":12,"@barchart/common-js/lang/Decimal":14,"@barchart/common-js/lang/array":18,"@barchart/common-js/lang/assert":19,"@barchart/common-js/lang/is":21,"@barchart/common-js/messaging/Event":23}],7:[function(require,module,exports){
2236
+ },{"./../data/InstrumentType":1,"@barchart/common-js/lang/Currency":14,"@barchart/common-js/lang/Decimal":16,"@barchart/common-js/lang/array":20,"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23,"@barchart/common-js/messaging/Event":25}],7:[function(require,module,exports){
2113
2237
  const assert = require('@barchart/common-js/lang/assert'),
2114
2238
  is = require('@barchart/common-js/lang/is');
2115
2239
 
@@ -2265,7 +2389,7 @@ module.exports = (() => {
2265
2389
  return PositionLevelDefinition;
2266
2390
  })();
2267
2391
 
2268
- },{"@barchart/common-js/lang/assert":19,"@barchart/common-js/lang/is":21}],8:[function(require,module,exports){
2392
+ },{"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23}],8:[function(require,module,exports){
2269
2393
  const assert = require('@barchart/common-js/lang/assert');
2270
2394
 
2271
2395
  const PositionLevelDefinition = require('./PositionLevelDefinition');
@@ -2319,7 +2443,139 @@ module.exports = (() => {
2319
2443
  return PositionTreeDefinitions;
2320
2444
  })();
2321
2445
 
2322
- },{"./PositionLevelDefinition":7,"@barchart/common-js/lang/assert":19}],9:[function(require,module,exports){
2446
+ },{"./PositionLevelDefinition":7,"@barchart/common-js/lang/assert":21}],9:[function(require,module,exports){
2447
+ 'use strict';
2448
+
2449
+ 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; }; }();
2450
+
2451
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2452
+
2453
+ var assert = require('./../lang/assert');
2454
+
2455
+ module.exports = function () {
2456
+ 'use strict';
2457
+
2458
+ /**
2459
+ * A stack collection (supports LIFO operations).
2460
+ *
2461
+ * @public
2462
+ */
2463
+
2464
+ var Stack = function () {
2465
+ function Stack() {
2466
+ _classCallCheck(this, Stack);
2467
+
2468
+ this._array = [];
2469
+ }
2470
+
2471
+ /**
2472
+ * Adds an item to the stack.
2473
+ *
2474
+ * @public
2475
+ * @param {object} item
2476
+ * @returns {object} - The item added to the stack.
2477
+ */
2478
+
2479
+
2480
+ _createClass(Stack, [{
2481
+ key: 'push',
2482
+ value: function push(item) {
2483
+ this._array.unshift(item);
2484
+
2485
+ return item;
2486
+ }
2487
+
2488
+ /**
2489
+ * Removes and returns an item from the stack. Throws if the stack is empty.
2490
+ *
2491
+ * @public
2492
+ * @returns {object} - The removed from the stack.
2493
+ */
2494
+
2495
+ }, {
2496
+ key: 'pop',
2497
+ value: function pop() {
2498
+ if (this.empty()) {
2499
+ throw new Error('Stack is empty');
2500
+ }
2501
+
2502
+ return this._array.shift();
2503
+ }
2504
+
2505
+ /**
2506
+ * Returns the next item in the stack (without removing it). Throws if the stack is empty.
2507
+ *
2508
+ * @public
2509
+ * @returns {object} - The item added to the queue.
2510
+ */
2511
+
2512
+ }, {
2513
+ key: 'peek',
2514
+ value: function peek() {
2515
+ if (this.empty()) {
2516
+ throw new Error('Stack is empty');
2517
+ }
2518
+
2519
+ return this._array[0];
2520
+ }
2521
+
2522
+ /**
2523
+ * Returns true if the queue is empty; otherwise false.
2524
+ *
2525
+ * @public
2526
+ * @returns {boolean}
2527
+ */
2528
+
2529
+ }, {
2530
+ key: 'empty',
2531
+ value: function empty() {
2532
+ return this._array.length === 0;
2533
+ }
2534
+
2535
+ /**
2536
+ * Runs an action on each item in the stack.
2537
+ *
2538
+ * @public
2539
+ * @param {Function} action - The action to run.
2540
+ */
2541
+
2542
+ }, {
2543
+ key: 'scan',
2544
+ value: function scan(action) {
2545
+ assert.argumentIsRequired(action, 'action', Function);
2546
+
2547
+ this._array.forEach(function (x) {
2548
+ return action(x);
2549
+ });
2550
+ }
2551
+
2552
+ /**
2553
+ * Outputs an array of the stacks's items; without affecting the
2554
+ * queue's internal state;
2555
+ *
2556
+ * @public
2557
+ * @returns {Array}
2558
+ */
2559
+
2560
+ }, {
2561
+ key: 'toArray',
2562
+ value: function toArray() {
2563
+ return this._array.slice(0);
2564
+ }
2565
+ }, {
2566
+ key: 'toString',
2567
+ value: function toString() {
2568
+ return '[Stack]';
2569
+ }
2570
+ }]);
2571
+
2572
+ return Stack;
2573
+ }();
2574
+
2575
+ return Stack;
2576
+ }();
2577
+
2578
+ },{"./../lang/assert":21}],10:[function(require,module,exports){
2323
2579
  'use strict';
2324
2580
 
2325
2581
  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; }; }();
@@ -2628,7 +2884,7 @@ module.exports = function () {
2628
2884
  return Tree;
2629
2885
  }();
2630
2886
 
2631
- },{"./../lang/is":21}],10:[function(require,module,exports){
2887
+ },{"./../lang/is":23}],11:[function(require,module,exports){
2632
2888
  'use strict';
2633
2889
 
2634
2890
  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; }; }();
@@ -2772,7 +3028,7 @@ module.exports = function () {
2772
3028
  return ComparatorBuilder;
2773
3029
  }();
2774
3030
 
2775
- },{"./../../lang/assert":19,"./comparators":11}],11:[function(require,module,exports){
3031
+ },{"./../../lang/assert":21,"./comparators":12}],12:[function(require,module,exports){
2776
3032
  'use strict';
2777
3033
 
2778
3034
  var assert = require('./../../lang/assert');
@@ -2847,7 +3103,115 @@ module.exports = function () {
2847
3103
  };
2848
3104
  }();
2849
3105
 
2850
- },{"./../../lang/assert":19}],12:[function(require,module,exports){
3106
+ },{"./../../lang/assert":21}],13:[function(require,module,exports){
3107
+ 'use strict';
3108
+
3109
+ 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; }; }();
3110
+
3111
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3112
+
3113
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
3114
+
3115
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
3116
+
3117
+ var Stack = require('./../Stack');
3118
+
3119
+ var assert = require('./../../lang/assert'),
3120
+ Disposable = require('./../../lang/Disposable'),
3121
+ is = require('./../../lang/is');
3122
+
3123
+ module.exports = function () {
3124
+ 'use strict';
3125
+
3126
+ /**
3127
+ * A stack of {@link Disposable} instances which itself inherits {@Disposable}.
3128
+ * When {@link DisposableStack#dispose} is called, then each item in the collection
3129
+ * is disposed in order.
3130
+ *
3131
+ * @public
3132
+ * @extends {Disposable}
3133
+ */
3134
+
3135
+ var DisposableStack = function (_Disposable) {
3136
+ _inherits(DisposableStack, _Disposable);
3137
+
3138
+ function DisposableStack() {
3139
+ _classCallCheck(this, DisposableStack);
3140
+
3141
+ var _this = _possibleConstructorReturn(this, (DisposableStack.__proto__ || Object.getPrototypeOf(DisposableStack)).call(this));
3142
+
3143
+ _this._stack = new Stack();
3144
+ return _this;
3145
+ }
3146
+
3147
+ /**
3148
+ * Adds a new {@link Disposable} instance to the stack.
3149
+ *
3150
+ * @public
3151
+ * @param {Disposable} disposable - The item to add.
3152
+ */
3153
+
3154
+
3155
+ _createClass(DisposableStack, [{
3156
+ key: 'push',
3157
+ value: function push(disposable) {
3158
+ assert.argumentIsRequired(disposable, 'disposable', Disposable, 'Disposable');
3159
+
3160
+ if (this.getIsDisposed()) {
3161
+ throw new Error('Unable to push item onto DisposableStack because it has been disposed.');
3162
+ }
3163
+
3164
+ this._stack.push(disposable);
3165
+ }
3166
+ }, {
3167
+ key: '_onDispose',
3168
+ value: function _onDispose() {
3169
+ while (!this._stack.empty()) {
3170
+ this._stack.pop().dispose();
3171
+ }
3172
+ }
3173
+ }], [{
3174
+ key: 'fromArray',
3175
+ value: function fromArray(bindings) {
3176
+ assert.argumentIsArray(bindings, 'bindings', Disposable, 'Disposable');
3177
+
3178
+ var returnRef = new DisposableStack();
3179
+
3180
+ for (var i = 0; i < bindings.length; i++) {
3181
+ returnRef.push(bindings[i]);
3182
+ }
3183
+
3184
+ return returnRef;
3185
+ }
3186
+ }, {
3187
+ key: 'pushPromise',
3188
+ value: function pushPromise(stack, promise) {
3189
+ assert.argumentIsRequired(stack, 'stack', DisposableStack, 'DisposableStack');
3190
+ assert.argumentIsRequired(promise, 'promise');
3191
+
3192
+ return promise.then(function (b) {
3193
+ var bindings = void 0;
3194
+
3195
+ if (is.array(b)) {
3196
+ bindings = b;
3197
+ } else {
3198
+ bindings = [b];
3199
+ }
3200
+
3201
+ bindings.forEach(function (binding) {
3202
+ return stack.push(binding);
3203
+ });
3204
+ });
3205
+ }
3206
+ }]);
3207
+
3208
+ return DisposableStack;
3209
+ }(Disposable);
3210
+
3211
+ return DisposableStack;
3212
+ }();
3213
+
3214
+ },{"./../../lang/Disposable":17,"./../../lang/assert":21,"./../../lang/is":23,"./../Stack":9}],14:[function(require,module,exports){
2851
3215
  'use strict';
2852
3216
 
2853
3217
  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; }; }();
@@ -2878,7 +3242,7 @@ module.exports = function () {
2878
3242
  var Currency = function (_Enum) {
2879
3243
  _inherits(Currency, _Enum);
2880
3244
 
2881
- function Currency(code, description, precision) {
3245
+ function Currency(code, description, precision, alternateDescription) {
2882
3246
  _classCallCheck(this, Currency);
2883
3247
 
2884
3248
  var _this = _possibleConstructorReturn(this, (Currency.__proto__ || Object.getPrototypeOf(Currency)).call(this, code, description));
@@ -2886,7 +3250,11 @@ module.exports = function () {
2886
3250
  assert.argumentIsRequired(precision, 'precision', Number);
2887
3251
  assert.argumentIsValid(precision, 'precision', is.integer, 'is an integer');
2888
3252
 
3253
+ assert.argumentIsOptional(alternateDescription, 'alternateDescription', String);
3254
+
2889
3255
  _this._precision = precision;
3256
+
3257
+ _this._alternateDescription = alternateDescription || description;
2890
3258
  return _this;
2891
3259
  }
2892
3260
 
@@ -2909,6 +3277,19 @@ module.exports = function () {
2909
3277
  return this._precision;
2910
3278
  }
2911
3279
 
3280
+ /**
3281
+ * An alternate human-readable description.
3282
+ *
3283
+ * @public
3284
+ * @returns {String}
3285
+ */
3286
+
3287
+ }, {
3288
+ key: 'alternateDescription',
3289
+ get: function get() {
3290
+ return this._alternateDescription;
3291
+ }
3292
+
2912
3293
  /**
2913
3294
  * Given a code, returns the enumeration item.
2914
3295
  *
@@ -2966,14 +3347,14 @@ module.exports = function () {
2966
3347
  return Currency;
2967
3348
  }(Enum);
2968
3349
 
2969
- var cad = new Currency('CAD', 'Canadian Dollar', 2);
2970
- var eur = new Currency('EUR', 'Euro', 2);
2971
- var usd = new Currency('USD', 'US Dollar', 2);
3350
+ var cad = new Currency('CAD', 'Canadian Dollar', 2, 'CAD$');
3351
+ var eur = new Currency('EUR', 'Euro', 2, 'EUR');
3352
+ var usd = new Currency('USD', 'US Dollar', 2, 'US$');
2972
3353
 
2973
3354
  return Currency;
2974
3355
  }();
2975
3356
 
2976
- },{"./Enum":16,"./assert":19,"./is":21}],13:[function(require,module,exports){
3357
+ },{"./Enum":18,"./assert":21,"./is":23}],15:[function(require,module,exports){
2977
3358
  'use strict';
2978
3359
 
2979
3360
  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; }; }();
@@ -3526,7 +3907,7 @@ module.exports = function () {
3526
3907
  return Day;
3527
3908
  }();
3528
3909
 
3529
- },{"./../collections/sorting/ComparatorBuilder":10,"./../collections/sorting/comparators":11,"./assert":19,"./is":21}],14:[function(require,module,exports){
3910
+ },{"./../collections/sorting/ComparatorBuilder":11,"./../collections/sorting/comparators":12,"./assert":21,"./is":23}],16:[function(require,module,exports){
3530
3911
  'use strict';
3531
3912
 
3532
3913
  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; }; }();
@@ -3942,9 +4323,9 @@ module.exports = function () {
3942
4323
  assert.argumentIsRequired(a, 'a', Decimal, 'Decimal');
3943
4324
  assert.argumentIsRequired(b, 'b', Decimal, 'Decimal');
3944
4325
 
3945
- if (a._big.gt(b)) {
4326
+ if (a._big.gt(b._big)) {
3946
4327
  return 1;
3947
- } else if (a._big.lt(b)) {
4328
+ } else if (a._big.lt(b._big)) {
3948
4329
  return -1;
3949
4330
  } else {
3950
4331
  return 0;
@@ -4106,7 +4487,7 @@ module.exports = function () {
4106
4487
  return Decimal;
4107
4488
  }();
4108
4489
 
4109
- },{"./Enum":16,"./assert":19,"./is":21,"big.js":24}],15:[function(require,module,exports){
4490
+ },{"./Enum":18,"./assert":21,"./is":23,"big.js":26}],17:[function(require,module,exports){
4110
4491
  'use strict';
4111
4492
 
4112
4493
  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; }; }();
@@ -4255,7 +4636,7 @@ module.exports = function () {
4255
4636
  return Disposable;
4256
4637
  }();
4257
4638
 
4258
- },{"./assert":19}],16:[function(require,module,exports){
4639
+ },{"./assert":21}],18:[function(require,module,exports){
4259
4640
  'use strict';
4260
4641
 
4261
4642
  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; }; }();
@@ -4397,7 +4778,7 @@ module.exports = function () {
4397
4778
  return Enum;
4398
4779
  }();
4399
4780
 
4400
- },{"./assert":19}],17:[function(require,module,exports){
4781
+ },{"./assert":21}],19:[function(require,module,exports){
4401
4782
  'use strict';
4402
4783
 
4403
4784
  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; }; }();
@@ -4405,12 +4786,10 @@ var _createClass = function () { function defineProperties(target, props) { for
4405
4786
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4406
4787
 
4407
4788
  var assert = require('./assert'),
4408
- is = require('./is'),
4409
4789
  memoize = require('./memoize');
4410
4790
 
4411
4791
  var Currency = require('./Currency'),
4412
- Decimal = require('./Decimal'),
4413
- Enum = require('./Enum');
4792
+ Decimal = require('./Decimal');
4414
4793
 
4415
4794
  module.exports = function () {
4416
4795
  'use strict';
@@ -4590,12 +4969,7 @@ module.exports = function () {
4590
4969
  assert.argumentIsRequired(amount, 'amount', Decimal, 'Decimal');
4591
4970
  assert.argumentIsRequired(currency, 'currency', Currency, 'Currency');
4592
4971
  assert.argumentIsRequired(desiredCurrency, 'desiredCurrency', Currency, 'Currency');
4593
-
4594
- for (var _len = arguments.length, rates = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
4595
- rates[_key - 3] = arguments[_key];
4596
- }
4597
-
4598
- assert.argumentIsArray(rates, 'rates', Rate, 'Rate');
4972
+ //assert.argumentIsArray(rates, 'rates', Rate, 'Rate');
4599
4973
 
4600
4974
  var converted = void 0;
4601
4975
 
@@ -4605,6 +4979,10 @@ module.exports = function () {
4605
4979
  var numerator = desiredCurrency;
4606
4980
  var denominator = currency;
4607
4981
 
4982
+ for (var _len = arguments.length, rates = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
4983
+ rates[_key - 3] = arguments[_key];
4984
+ }
4985
+
4608
4986
  var rate = rates.find(function (r) {
4609
4987
  return r.numerator === numerator && r.denominator === denominator || r.numerator === denominator && r.denominator === numerator;
4610
4988
  });
@@ -4655,7 +5033,7 @@ module.exports = function () {
4655
5033
  return Rate;
4656
5034
  }();
4657
5035
 
4658
- },{"./Currency":12,"./Decimal":14,"./Enum":16,"./assert":19,"./is":21,"./memoize":22}],18:[function(require,module,exports){
5036
+ },{"./Currency":14,"./Decimal":16,"./assert":21,"./memoize":24}],20:[function(require,module,exports){
4659
5037
  'use strict';
4660
5038
 
4661
5039
  var assert = require('./assert'),
@@ -5036,7 +5414,7 @@ module.exports = function () {
5036
5414
  };
5037
5415
  }();
5038
5416
 
5039
- },{"./assert":19,"./is":21}],19:[function(require,module,exports){
5417
+ },{"./assert":21,"./is":23}],21:[function(require,module,exports){
5040
5418
  'use strict';
5041
5419
 
5042
5420
  var is = require('./is');
@@ -5184,7 +5562,7 @@ module.exports = function () {
5184
5562
  };
5185
5563
  }();
5186
5564
 
5187
- },{"./is":21}],20:[function(require,module,exports){
5565
+ },{"./is":23}],22:[function(require,module,exports){
5188
5566
  'use strict';
5189
5567
 
5190
5568
  module.exports = function () {
@@ -5249,7 +5627,7 @@ module.exports = function () {
5249
5627
  };
5250
5628
  }();
5251
5629
 
5252
- },{}],21:[function(require,module,exports){
5630
+ },{}],23:[function(require,module,exports){
5253
5631
  'use strict';
5254
5632
 
5255
5633
  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; };
@@ -5472,7 +5850,7 @@ module.exports = function () {
5472
5850
  };
5473
5851
  }();
5474
5852
 
5475
- },{}],22:[function(require,module,exports){
5853
+ },{}],24:[function(require,module,exports){
5476
5854
  'use strict';
5477
5855
 
5478
5856
  var assert = require('./assert'),
@@ -5545,7 +5923,7 @@ module.exports = function () {
5545
5923
  };
5546
5924
  }();
5547
5925
 
5548
- },{"./assert":19,"./is":21}],23:[function(require,module,exports){
5926
+ },{"./assert":21,"./is":23}],25:[function(require,module,exports){
5549
5927
  'use strict';
5550
5928
 
5551
5929
  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; }; }();
@@ -5717,7 +6095,7 @@ module.exports = function () {
5717
6095
  return Event;
5718
6096
  }();
5719
6097
 
5720
- },{"./../lang/Disposable":15,"./../lang/assert":19}],24:[function(require,module,exports){
6098
+ },{"./../lang/Disposable":17,"./../lang/assert":21}],26:[function(require,module,exports){
5721
6099
  /*
5722
6100
  * big.js v5.0.3
5723
6101
  * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic.
@@ -6658,7 +7036,7 @@ module.exports = function () {
6658
7036
  }
6659
7037
  })(this);
6660
7038
 
6661
- },{}],25:[function(require,module,exports){
7039
+ },{}],27:[function(require,module,exports){
6662
7040
  const Day = require('@barchart/common-js/lang/Day'),
6663
7041
  Decimal = require('@barchart/common-js/lang/Decimal');
6664
7042
 
@@ -7015,7 +7393,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
7015
7393
  });
7016
7394
  });
7017
7395
 
7018
- },{"./../../../lib/data/PositionSummaryFrame":2,"./../../../lib/data/TransactionType":3,"@barchart/common-js/lang/Day":13,"@barchart/common-js/lang/Decimal":14}],26:[function(require,module,exports){
7396
+ },{"./../../../lib/data/PositionSummaryFrame":2,"./../../../lib/data/TransactionType":3,"@barchart/common-js/lang/Day":15,"@barchart/common-js/lang/Decimal":16}],28:[function(require,module,exports){
7019
7397
  const Currency = require('@barchart/common-js/lang/Currency'),
7020
7398
  Decimal = require('@barchart/common-js/lang/Decimal');
7021
7399
 
@@ -7124,4 +7502,4 @@ describe('When a position container data is gathered', () => {
7124
7502
  });
7125
7503
  });
7126
7504
 
7127
- },{"./../../../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}]},{},[25,26]);
7505
+ },{"./../../../lib/data/InstrumentType":1,"./../../../lib/processing/PositionContainer":4,"./../../../lib/processing/definitions/PositionLevelDefinition":7,"./../../../lib/processing/definitions/PositionTreeDefinition":8,"@barchart/common-js/lang/Currency":14,"@barchart/common-js/lang/Decimal":16}]},{},[27,28]);