@barchart/portfolio-api-common 1.0.166 → 1.0.170

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.
@@ -11,7 +11,9 @@ const array = require('@barchart/common-js/lang/array'),
11
11
 
12
12
  const PositionSummaryFrame = require('./../data/PositionSummaryFrame');
13
13
 
14
- const PositionTreeDefinition = require('./definitions/PositionTreeDefinition');
14
+ const PositionLevelDefinition = require('./definitions/PositionLevelDefinition'),
15
+ PositionLevelType = require('./definitions/PositionLevelType'),
16
+ PositionTreeDefinition = require('./definitions/PositionTreeDefinition');
15
17
 
16
18
  const PositionGroup = require('./PositionGroup'),
17
19
  PositionItem = require('./PositionItem');
@@ -128,10 +130,9 @@ module.exports = (() => {
128
130
  }, { });
129
131
 
130
132
  this._currencies = this._items.reduce((map, item) => {
131
- const position = item.position;
133
+ const currency = extractCurrency(item.position);
132
134
 
133
- if (position.instrument && position.instrument.currency) {
134
- const currency = position.instrument.currency;
135
+ if (currency) {
135
136
  const code = currency.code;
136
137
 
137
138
  if (!map.hasOwnProperty(code)) {
@@ -167,6 +168,13 @@ module.exports = (() => {
167
168
  }, { });
168
169
  }
169
170
 
171
+ /**
172
+ * Adds a new portfolio to the container, injecting it into aggregation
173
+ * trees, as necessary.
174
+ *
175
+ * @public
176
+ * @param {Object} portfolio
177
+ */
170
178
  addPortfolio(portfolio) {
171
179
  assert.argumentIsRequired(portfolio, 'portfolio', Object);
172
180
  assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
@@ -222,8 +230,31 @@ module.exports = (() => {
222
230
  }
223
231
  }
224
232
 
233
+ /**
234
+ * Removes an existing portfolio, and all of it's positions, from the container. This
235
+ * also triggers removal of the portfolio and it's positions from any applicable
236
+ * aggregation trees.
237
+ *
238
+ * @public
239
+ * @param {Object} portfolio
240
+ */
225
241
  removePortfolio(portfolio) {
242
+ assert.argumentIsRequired(portfolio, 'portfolio', Object);
243
+ assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
244
+
245
+ this.startTransaction(() => {
246
+ getPositionItemsForPortfolio(this._items, portfolio.portfolio).forEach(item => removePositionItem.call(this, item));
226
247
 
248
+ delete this._portfolios[portfolio.portfolio];
249
+
250
+ Object.keys(this._trees).forEach((key) => {
251
+ this._trees[key].walk((group, groupNode) => {
252
+ if (group.definition.type === PositionLevelType.PORTFOLIO && group.key === PositionLevelDefinition.getKeyForPortfolioGroup(portfolio)) {
253
+ groupNode.sever();
254
+ }
255
+ }, true, false);
256
+ });
257
+ });
227
258
  }
228
259
 
229
260
  mutatePosition(position, summary) {
@@ -231,7 +262,7 @@ module.exports = (() => {
231
262
  }
232
263
 
233
264
  removePosition(position) {
234
-
265
+ removePositionItem.call(this, this._items.find((item) => item.position.position === position));
235
266
  }
236
267
 
237
268
  /**
@@ -314,7 +345,6 @@ module.exports = (() => {
314
345
  assert.argumentIsRequired(quote, 'quote', Object);
315
346
 
316
347
  const rate = Rate.fromPair(quote.lastPrice, symbol);
317
-
318
348
  const index = this._forexQuotes.findIndex(existing => existing.formatPair() === rate.formatPair());
319
349
 
320
350
  if (index < 0) {
@@ -409,13 +439,13 @@ module.exports = (() => {
409
439
  }
410
440
 
411
441
  /**
412
- * Returns all portfolios in the container
442
+ * Returns all portfolios in the container.
413
443
  *
414
444
  * @public
415
445
  * @return {Array.<Object>}
416
446
  */
417
447
  getPortfolios() {
418
- return this._portfolios;
448
+ return Object.keys(this._portfolios).map(id => this._portfolios[id]);
419
449
  }
420
450
 
421
451
  /**
@@ -426,24 +456,42 @@ module.exports = (() => {
426
456
  * @return {Array.<Object>}
427
457
  */
428
458
  getPositions(portfolio) {
429
- return this._items.reduce((positions, item) => {
430
- if (item.position.portfolio === portfolio) {
431
- positions.push(item);
432
- }
459
+ assert.argumentIsRequired(portfolio, 'portfolio', String);
433
460
 
434
- return positions;
435
- }, []);
461
+ return getPositionItemsForPortfolio(this._items, portfolio).map(item => item.position);
436
462
  }
437
463
 
438
- startTransaction(name, executor) {
439
- assert.argumentIsRequired(name, 'name', String);
464
+ /**
465
+ * Pauses aggregation calculations during the processing of an action.
466
+ *
467
+ * @public
468
+ * @param {Function} executor
469
+ * @param {String=|Array.<String>=} names
470
+ */
471
+ startTransaction(executor, names) {
472
+ let namesToUse;
473
+
474
+ if (is.array(names)) {
475
+ assert.argumentIsArray(names, 'names', String);
476
+
477
+ namesToUse = names;
478
+ } else {
479
+ assert.argumentIsOptional(names, 'names', String);
480
+
481
+ if (names) {
482
+ namesToUse = [ names ];
483
+ } else {
484
+ namesToUse = Object.keys(this._trees);
485
+ }
486
+ }
487
+
440
488
  assert.argumentIsRequired(executor, 'executor', Function);
441
489
 
442
- this._trees[name].walk(group => group.setSuspended(true), false, false);
490
+ namesToUse.forEach((name) => this._trees[name].walk(group => group.setSuspended(true), false, false));
443
491
 
444
492
  executor(this);
445
493
 
446
- this._trees[name].walk(group => group.setSuspended(false), false, false);
494
+ namesToUse.forEach((name) => this._trees[name].walk(group => group.setSuspended(false), false, false));
447
495
  }
448
496
 
449
497
  toString() {
@@ -475,6 +523,14 @@ module.exports = (() => {
475
523
  }
476
524
  }
477
525
 
526
+ function extractCurrency(position) {
527
+ if (position.instrument && position.instrument.currency) {
528
+ return position.instrument.currency;
529
+ } else {
530
+ return null;
531
+ }
532
+ }
533
+
478
534
  function addGroupBinding(group, dispoable) {
479
535
  const id = group.id;
480
536
 
@@ -604,5 +660,46 @@ module.exports = (() => {
604
660
  });
605
661
  }
606
662
 
663
+ function getPositionItemsForPortfolio(items, portfolio) {
664
+ return items.reduce((positionItems, item) => {
665
+ if (item.position.portfolio === portfolio) {
666
+ positionItems.push(item.position);
667
+ }
668
+
669
+ return positionItems;
670
+ }, [ ]);
671
+ }
672
+
673
+ function removePositionItem(positionItem) {
674
+ if (!positionItem) {
675
+ return;
676
+ }
677
+
678
+ delete this._summariesCurrent[positionItem.position.position];
679
+ delete this._summariesPrevious[positionItem.position.position];
680
+
681
+ array.remove(this._items, i => i === positionItem);
682
+
683
+ const barchartSymbol = extractSymbolForBarchart(positionItem.position);
684
+
685
+ if (this._symbols.hasOwnProperty(barchartSymbol)) {
686
+ array.remove(this._symbols[barchartSymbol], i => i === positionItem);
687
+ }
688
+
689
+ const displaySymbol = extractSymbolForDisplay(positionItem.position);
690
+
691
+ if (this._symbolsDisplay.hasOwnProperty(displaySymbol)) {
692
+ array.remove(this._symbols[displaySymbol], i => i === positionItem);
693
+ }
694
+
695
+ const currency = extractCurrency(positionItem.position);
696
+
697
+ if (currency && this._currencies.hasOwnProperty(currency.code)) {
698
+ array.remove(this._currencies[currency.code], i => i === positionItem);
699
+ }
700
+
701
+ positionItem.dispose();
702
+ }
703
+
607
704
  return PositionContainer;
608
705
  })();
@@ -2,6 +2,7 @@ const array = require('@barchart/common-js/lang/array'),
2
2
  assert = require('@barchart/common-js/lang/assert'),
3
3
  Currency = require('@barchart/common-js/lang/Currency'),
4
4
  Decimal = require('@barchart/common-js/lang/Decimal'),
5
+ Disposable = require('@barchart/common-js/lang/Disposable'),
5
6
  DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
6
7
  Event = require('@barchart/common-js/messaging/Event'),
7
8
  formatter = require('@barchart/common-js/lang/formatter'),
@@ -149,7 +150,7 @@ module.exports = (() => {
149
150
  this._dataFormat.portfolioType = null;
150
151
 
151
152
  this._items.forEach((item) => {
152
- this._disposeStack.push(item.registerQuoteChangeHandler((quote, sender) => {
153
+ const quoteBinding = item.registerQuoteChangeHandler((quote, sender) => {
153
154
  if (this._single) {
154
155
  const precision = sender.position.instrument.currency.precision;
155
156
 
@@ -185,18 +186,39 @@ module.exports = (() => {
185
186
  }
186
187
 
187
188
  calculatePriceData(this, this._container.getForexQuotes(), sender, false);
188
- }));
189
+ });
190
+
191
+ let newsBinding = Disposable.getEmpty();
192
+ let fundamentalBinding = Disposable.getEmpty();
189
193
 
190
194
  if (this._single) {
191
- this._disposeStack.push(item.registerNewsExistsChangeHandler((exists, sender) => {
195
+ newsBinding = item.registerNewsExistsChangeHandler((exists, sender) => {
192
196
  this._dataActual.newsExists = exists;
193
197
  this._dataFormat.newsExists = exists;
194
- }));
198
+ });
195
199
 
196
- this._disposeStack.push(item.registerFundamentalDataChangeHandler((data, sender) => {
200
+ fundamentalBinding = item.registerFundamentalDataChangeHandler((data, sender) => {
197
201
  this._dataFormat.fundamental = data;
198
- }));
202
+ });
199
203
  }
204
+
205
+ this._disposeStack.push(quoteBinding);
206
+ this._disposeStack.push(newsBinding);
207
+ this._disposeStack.push(fundamentalBinding);
208
+
209
+ this._disposeStack.push(item.registerPositionItemDisposeHandler(() => {
210
+ quoteBinding.dispose();
211
+ newsBinding.dispose();
212
+ fundamentalBinding.dispose();
213
+
214
+ array.remove(this._items, i => i === item);
215
+ array.remove(this._excludedItems, i => i === item);
216
+ array.remove(this._consideredItems, i => i === item);
217
+
218
+ delete this._excludedItemMap[item.position.position];
219
+
220
+ this.refresh();
221
+ }));
200
222
  });
201
223
 
202
224
  this.refresh();
@@ -373,22 +395,35 @@ module.exports = (() => {
373
395
  }
374
396
  }
375
397
 
398
+ /**
399
+ * Stops (or starts) group-level aggregation calculations.
400
+ *
401
+ * @public
402
+ * @param {Boolean} value
403
+ */
376
404
  setSuspended(value) {
377
405
  assert.argumentIsRequired(value, 'value', Boolean);
378
406
 
379
407
  if (this._suspended !== value) {
380
- if (this._suspended = value) {
408
+ this._suspended = value;
409
+
410
+ if (!this._suspended) {
381
411
  this.refresh();
382
412
  }
383
413
  }
384
414
  }
385
415
 
386
416
  /**
387
- * Causes all aggregated data to be recalculated.
417
+ * Causes all aggregated data to be recalculated (assuming the group has not
418
+ * been suspended).
388
419
  *
389
420
  * @public
390
421
  */
391
422
  refresh() {
423
+ if (this._suspended) {
424
+ return;
425
+ }
426
+
392
427
  const rates = this._container.getForexQuotes();
393
428
 
394
429
  calculateStaticData(this, rates);
@@ -2,6 +2,7 @@ const array = require('@barchart/common-js/lang/array'),
2
2
  assert = require('@barchart/common-js/lang/assert'),
3
3
  Currency = require('@barchart/common-js/lang/Currency'),
4
4
  Decimal = require('@barchart/common-js/lang/Decimal'),
5
+ Disposable = require('@barchart/common-js/lang/Disposable'),
5
6
  Event = require('@barchart/common-js/messaging/Event'),
6
7
  is = require('@barchart/common-js/lang/is');
7
8
 
@@ -21,8 +22,10 @@ module.exports = (() => {
21
22
  * @param {Object} currentSummary
22
23
  * @param {Array.<Object>} previousSummaries
23
24
  */
24
- class PositionItem {
25
+ class PositionItem extends Disposable {
25
26
  constructor(portfolio, position, currentSummary, previousSummaries) {
27
+ super();
28
+
26
29
  this._portfolio = portfolio;
27
30
  this._position = position;
28
31
  this._currency = position.instrument.currency || Currency.CAD;
@@ -67,6 +70,7 @@ module.exports = (() => {
67
70
  this._quoteChangedEvent = new Event(this);
68
71
  this._newsExistsChangedEvent = new Event(this);
69
72
  this._fundamentalDataChangeEvent = new Event(this);
73
+ this._positionItemDisposeEvent = new Event(this);
70
74
  }
71
75
 
72
76
  /**
@@ -149,6 +153,10 @@ module.exports = (() => {
149
153
  setQuote(quote) {
150
154
  assert.argumentIsRequired(quote, 'quote', Object);
151
155
 
156
+ if (this.getIsDisposed()) {
157
+ return;
158
+ }
159
+
152
160
  if (this._currentPricePrevious !== quote.lastPrice) {
153
161
  calculatePriceData(this, quote.lastPrice);
154
162
 
@@ -170,6 +178,10 @@ module.exports = (() => {
170
178
  setPositionFundamentalData(data) {
171
179
  assert.argumentIsRequired(data, 'data', Object);
172
180
 
181
+ if (this.getIsDisposed()) {
182
+ return;
183
+ }
184
+
173
185
  this._fundamentalDataChangeEvent.fire(this._data.fundamental = data);
174
186
  }
175
187
 
@@ -183,6 +195,10 @@ module.exports = (() => {
183
195
  setNewsArticleExists(value) {
184
196
  assert.argumentIsRequired(value, 'value', Boolean);
185
197
 
198
+ if (this.getIsDisposed()) {
199
+ return;
200
+ }
201
+
186
202
  if (this._data.newsExists !== value) {
187
203
  this._newsExistsChangedEvent.fire(this._data.newsExists = value);
188
204
  }
@@ -222,6 +238,26 @@ module.exports = (() => {
222
238
  return this._newsExistsChangedEvent.register(handler);
223
239
  }
224
240
 
241
+ /**
242
+ * Registers an observer for object disposal.
243
+ *
244
+ * @public
245
+ * @param {Function} handler
246
+ * @returns {Disposable}
247
+ */
248
+ registerPositionItemDisposeHandler(handler) {
249
+ return this._positionItemDisposeEvent.register(handler);
250
+ }
251
+
252
+ _onDispose() {
253
+ this._positionItemDisposeEvent.fire(this);
254
+
255
+ this._quoteChangedEvent.clear();
256
+ this._newsExistsChangedEvent.clear();
257
+ this._fundamentalDataChangeEvent.clear();
258
+ this._positionItemDisposeEvent.clear();
259
+ }
260
+
225
261
  toString() {
226
262
  return '[PositionItem]';
227
263
  }
@@ -4,6 +4,8 @@ const assert = require('@barchart/common-js/lang/assert'),
4
4
 
5
5
  const InstrumentType = require('./../../data/InstrumentType');
6
6
 
7
+ const PositionLevelType = require('./PositionLevelType');
8
+
7
9
  module.exports = (() => {
8
10
  'use strict';
9
11
 
@@ -23,8 +25,9 @@ module.exports = (() => {
23
25
  * @param {Function=} requiredGroupGenerator
24
26
  */
25
27
  class PositionLevelDefinition {
26
- constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash, requiredGroupGenerator) {
28
+ constructor(name, type, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash, requiredGroupGenerator) {
27
29
  assert.argumentIsRequired(name, 'name', String);
30
+ assert.argumentIsRequired(type, 'type', PositionLevelType, 'PositionLevelType');
28
31
  assert.argumentIsRequired(keySelector, 'keySelector', Function);
29
32
  assert.argumentIsRequired(descriptionSelector, 'descriptionSelector', Function);
30
33
  assert.argumentIsRequired(currencySelector, 'currencySelector', Function);
@@ -38,6 +41,7 @@ module.exports = (() => {
38
41
  assert.argumentIsOptional(requiredGroupGenerator, 'requiredGroupGenerator', Function);
39
42
 
40
43
  this._name = name;
44
+ this._type = type;
41
45
 
42
46
  this._keySelector = keySelector;
43
47
  this._descriptionSelector = descriptionSelector;
@@ -61,6 +65,16 @@ module.exports = (() => {
61
65
  return this._name;
62
66
  }
63
67
 
68
+ /**
69
+ * A general description of the type of items grouped together.
70
+ *
71
+ * @public
72
+ * @return {PositionLevelType}
73
+ */
74
+ get type() {
75
+ return this._type;
76
+ }
77
+
64
78
  /**
65
79
  * A function, when given a {@link PositionItem} returns a string that is used
66
80
  * to group {@link PositionItem} instances into different groups.
@@ -0,0 +1,29 @@
1
+ const Enum = require('@barchart/common-js/lang/Enum');
2
+
3
+ module.exports = (() => {
4
+ 'use strict';
5
+
6
+ class PositionLevelType extends Enum {
7
+ constructor(code) {
8
+ super(code, code);
9
+ }
10
+
11
+ static get PORTFOLIO() {
12
+ return portfolio;
13
+ }
14
+
15
+ static get POSITION() {
16
+ return position;
17
+ }
18
+
19
+ static get OTHER() {
20
+ return other;
21
+ }
22
+ }
23
+
24
+ const portfolio = new PositionLevelType('PORTFOLIO');
25
+ const position = new PositionLevelType('POSITION');
26
+ const other = new PositionLevelType('OTHER');
27
+
28
+ return PositionLevelType;
29
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.0.166",
3
+ "version": "1.0.170",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -1,4 +1,4 @@
1
- (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
1
+ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
2
  const assert = require('@barchart/common-js/lang/assert'),
3
3
  Enum = require('@barchart/common-js/lang/Enum');
4
4
 
@@ -116,7 +116,7 @@ module.exports = (() => {
116
116
  return InstrumentType;
117
117
  })();
118
118
 
119
- },{"@barchart/common-js/lang/Enum":18,"@barchart/common-js/lang/assert":21}],2:[function(require,module,exports){
119
+ },{"@barchart/common-js/lang/Enum":19,"@barchart/common-js/lang/assert":22}],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":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){
376
+ },{"@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){
377
377
  const assert = require('@barchart/common-js/lang/assert'),
378
378
  Enum = require('@barchart/common-js/lang/Enum');
379
379
 
@@ -713,7 +713,7 @@ module.exports = (() => {
713
713
  return TransactionType;
714
714
  })();
715
715
 
716
- },{"@barchart/common-js/lang/Enum":18,"@barchart/common-js/lang/assert":21}],4:[function(require,module,exports){
716
+ },{"@barchart/common-js/lang/Enum":19,"@barchart/common-js/lang/assert":22}],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'),
@@ -727,7 +727,9 @@ const array = require('@barchart/common-js/lang/array'),
727
727
 
728
728
  const PositionSummaryFrame = require('./../data/PositionSummaryFrame');
729
729
 
730
- const PositionTreeDefinition = require('./definitions/PositionTreeDefinition');
730
+ const PositionLevelDefinition = require('./definitions/PositionLevelDefinition'),
731
+ PositionLevelType = require('./definitions/PositionLevelType'),
732
+ PositionTreeDefinition = require('./definitions/PositionTreeDefinition');
731
733
 
732
734
  const PositionGroup = require('./PositionGroup'),
733
735
  PositionItem = require('./PositionItem');
@@ -844,10 +846,9 @@ module.exports = (() => {
844
846
  }, { });
845
847
 
846
848
  this._currencies = this._items.reduce((map, item) => {
847
- const position = item.position;
849
+ const currency = extractCurrency(item.position);
848
850
 
849
- if (position.instrument && position.instrument.currency) {
850
- const currency = position.instrument.currency;
851
+ if (currency) {
851
852
  const code = currency.code;
852
853
 
853
854
  if (!map.hasOwnProperty(code)) {
@@ -883,6 +884,13 @@ module.exports = (() => {
883
884
  }, { });
884
885
  }
885
886
 
887
+ /**
888
+ * Adds a new portfolio to the container, injecting it into aggregation
889
+ * trees, as necessary.
890
+ *
891
+ * @public
892
+ * @param {Object} portfolio
893
+ */
886
894
  addPortfolio(portfolio) {
887
895
  assert.argumentIsRequired(portfolio, 'portfolio', Object);
888
896
  assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
@@ -938,8 +946,31 @@ module.exports = (() => {
938
946
  }
939
947
  }
940
948
 
949
+ /**
950
+ * Removes an existing portfolio, and all of it's positions, from the container. This
951
+ * also triggers removal of the portfolio and it's positions from any applicable
952
+ * aggregation trees.
953
+ *
954
+ * @public
955
+ * @param {Object} portfolio
956
+ */
941
957
  removePortfolio(portfolio) {
958
+ assert.argumentIsRequired(portfolio, 'portfolio', Object);
959
+ assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
960
+
961
+ this.startTransaction(() => {
962
+ getPositionItemsForPortfolio(this._items, portfolio.portfolio).forEach(item => removePositionItem.call(this, item));
942
963
 
964
+ delete this._portfolios[portfolio.portfolio];
965
+
966
+ Object.keys(this._trees).forEach((key) => {
967
+ this._trees[key].walk((group, groupNode) => {
968
+ if (group.definition.type === PositionLevelType.PORTFOLIO && group.key === PositionLevelDefinition.getKeyForPortfolioGroup(portfolio)) {
969
+ groupNode.sever();
970
+ }
971
+ }, true, false);
972
+ });
973
+ });
943
974
  }
944
975
 
945
976
  mutatePosition(position, summary) {
@@ -947,7 +978,7 @@ module.exports = (() => {
947
978
  }
948
979
 
949
980
  removePosition(position) {
950
-
981
+ removePositionItem.call(this, this._items.find((item) => item.position.position === position));
951
982
  }
952
983
 
953
984
  /**
@@ -1030,7 +1061,6 @@ module.exports = (() => {
1030
1061
  assert.argumentIsRequired(quote, 'quote', Object);
1031
1062
 
1032
1063
  const rate = Rate.fromPair(quote.lastPrice, symbol);
1033
-
1034
1064
  const index = this._forexQuotes.findIndex(existing => existing.formatPair() === rate.formatPair());
1035
1065
 
1036
1066
  if (index < 0) {
@@ -1125,13 +1155,13 @@ module.exports = (() => {
1125
1155
  }
1126
1156
 
1127
1157
  /**
1128
- * Returns all portfolios in the container
1158
+ * Returns all portfolios in the container.
1129
1159
  *
1130
1160
  * @public
1131
1161
  * @return {Array.<Object>}
1132
1162
  */
1133
1163
  getPortfolios() {
1134
- return this._portfolios;
1164
+ return Object.keys(this._portfolios).map(id => this._portfolios[id]);
1135
1165
  }
1136
1166
 
1137
1167
  /**
@@ -1142,24 +1172,42 @@ module.exports = (() => {
1142
1172
  * @return {Array.<Object>}
1143
1173
  */
1144
1174
  getPositions(portfolio) {
1145
- return this._items.reduce((positions, item) => {
1146
- if (item.position.portfolio === portfolio) {
1147
- positions.push(item);
1148
- }
1175
+ assert.argumentIsRequired(portfolio, 'portfolio', String);
1149
1176
 
1150
- return positions;
1151
- }, []);
1177
+ return getPositionItemsForPortfolio(this._items, portfolio).map(item => item.position);
1152
1178
  }
1153
1179
 
1154
- startTransaction(name, executor) {
1155
- assert.argumentIsRequired(name, 'name', String);
1180
+ /**
1181
+ * Pauses aggregation calculations during the processing of an action.
1182
+ *
1183
+ * @public
1184
+ * @param {Function} executor
1185
+ * @param {String=|Array.<String>=} names
1186
+ */
1187
+ startTransaction(executor, names) {
1188
+ let namesToUse;
1189
+
1190
+ if (is.array(names)) {
1191
+ assert.argumentIsArray(names, 'names', String);
1192
+
1193
+ namesToUse = names;
1194
+ } else {
1195
+ assert.argumentIsOptional(names, 'names', String);
1196
+
1197
+ if (names) {
1198
+ namesToUse = [ names ];
1199
+ } else {
1200
+ namesToUse = Object.keys(this._trees);
1201
+ }
1202
+ }
1203
+
1156
1204
  assert.argumentIsRequired(executor, 'executor', Function);
1157
1205
 
1158
- this._trees[name].walk(group => group.setSuspended(true), false, false);
1206
+ namesToUse.forEach((name) => this._trees[name].walk(group => group.setSuspended(true), false, false));
1159
1207
 
1160
1208
  executor(this);
1161
1209
 
1162
- this._trees[name].walk(group => group.setSuspended(false), false, false);
1210
+ namesToUse.forEach((name) => this._trees[name].walk(group => group.setSuspended(false), false, false));
1163
1211
  }
1164
1212
 
1165
1213
  toString() {
@@ -1191,6 +1239,14 @@ module.exports = (() => {
1191
1239
  }
1192
1240
  }
1193
1241
 
1242
+ function extractCurrency(position) {
1243
+ if (position.instrument && position.instrument.currency) {
1244
+ return position.instrument.currency;
1245
+ } else {
1246
+ return null;
1247
+ }
1248
+ }
1249
+
1194
1250
  function addGroupBinding(group, dispoable) {
1195
1251
  const id = group.id;
1196
1252
 
@@ -1320,14 +1376,56 @@ module.exports = (() => {
1320
1376
  });
1321
1377
  }
1322
1378
 
1379
+ function getPositionItemsForPortfolio(items, portfolio) {
1380
+ return items.reduce((positionItems, item) => {
1381
+ if (item.position.portfolio === portfolio) {
1382
+ positionItems.push(item.position);
1383
+ }
1384
+
1385
+ return positionItems;
1386
+ }, [ ]);
1387
+ }
1388
+
1389
+ function removePositionItem(positionItem) {
1390
+ if (!positionItem) {
1391
+ return;
1392
+ }
1393
+
1394
+ delete this._summariesCurrent[positionItem.position.position];
1395
+ delete this._summariesPrevious[positionItem.position.position];
1396
+
1397
+ array.remove(this._items, i => i === positionItem);
1398
+
1399
+ const barchartSymbol = extractSymbolForBarchart(positionItem.position);
1400
+
1401
+ if (this._symbols.hasOwnProperty(barchartSymbol)) {
1402
+ array.remove(this._symbols[barchartSymbol], i => i === positionItem);
1403
+ }
1404
+
1405
+ const displaySymbol = extractSymbolForDisplay(positionItem.position);
1406
+
1407
+ if (this._symbolsDisplay.hasOwnProperty(displaySymbol)) {
1408
+ array.remove(this._symbols[displaySymbol], i => i === positionItem);
1409
+ }
1410
+
1411
+ const currency = extractCurrency(positionItem.position);
1412
+
1413
+ if (currency && this._currencies.hasOwnProperty(currency.code)) {
1414
+ array.remove(this._currencies[currency.code], i => i === positionItem);
1415
+ }
1416
+
1417
+ positionItem.dispose();
1418
+ }
1419
+
1323
1420
  return PositionContainer;
1324
1421
  })();
1325
1422
 
1326
- },{"./../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){
1423
+ },{"./../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}],5:[function(require,module,exports){
1327
1424
  const array = require('@barchart/common-js/lang/array'),
1328
1425
  assert = require('@barchart/common-js/lang/assert'),
1329
1426
  Currency = require('@barchart/common-js/lang/Currency'),
1330
1427
  Decimal = require('@barchart/common-js/lang/Decimal'),
1428
+ Disposable = require('@barchart/common-js/lang/Disposable'),
1331
1429
  DisposableStack = require('@barchart/common-js/collections/specialized/DisposableStack'),
1332
1430
  Event = require('@barchart/common-js/messaging/Event'),
1333
1431
  formatter = require('@barchart/common-js/lang/formatter'),
@@ -1475,7 +1573,7 @@ module.exports = (() => {
1475
1573
  this._dataFormat.portfolioType = null;
1476
1574
 
1477
1575
  this._items.forEach((item) => {
1478
- this._disposeStack.push(item.registerQuoteChangeHandler((quote, sender) => {
1576
+ const quoteBinding = item.registerQuoteChangeHandler((quote, sender) => {
1479
1577
  if (this._single) {
1480
1578
  const precision = sender.position.instrument.currency.precision;
1481
1579
 
@@ -1511,18 +1609,39 @@ module.exports = (() => {
1511
1609
  }
1512
1610
 
1513
1611
  calculatePriceData(this, this._container.getForexQuotes(), sender, false);
1514
- }));
1612
+ });
1613
+
1614
+ let newsBinding = Disposable.getEmpty();
1615
+ let fundamentalBinding = Disposable.getEmpty();
1515
1616
 
1516
1617
  if (this._single) {
1517
- this._disposeStack.push(item.registerNewsExistsChangeHandler((exists, sender) => {
1618
+ newsBinding = item.registerNewsExistsChangeHandler((exists, sender) => {
1518
1619
  this._dataActual.newsExists = exists;
1519
1620
  this._dataFormat.newsExists = exists;
1520
- }));
1621
+ });
1521
1622
 
1522
- this._disposeStack.push(item.registerFundamentalDataChangeHandler((data, sender) => {
1623
+ fundamentalBinding = item.registerFundamentalDataChangeHandler((data, sender) => {
1523
1624
  this._dataFormat.fundamental = data;
1524
- }));
1625
+ });
1525
1626
  }
1627
+
1628
+ this._disposeStack.push(quoteBinding);
1629
+ this._disposeStack.push(newsBinding);
1630
+ this._disposeStack.push(fundamentalBinding);
1631
+
1632
+ this._disposeStack.push(item.registerPositionItemDisposeHandler(() => {
1633
+ quoteBinding.dispose();
1634
+ newsBinding.dispose();
1635
+ fundamentalBinding.dispose();
1636
+
1637
+ array.remove(this._items, i => i === item);
1638
+ array.remove(this._excludedItems, i => i === item);
1639
+ array.remove(this._consideredItems, i => i === item);
1640
+
1641
+ delete this._excludedItemMap[item.position.position];
1642
+
1643
+ this.refresh();
1644
+ }));
1526
1645
  });
1527
1646
 
1528
1647
  this.refresh();
@@ -1699,22 +1818,35 @@ module.exports = (() => {
1699
1818
  }
1700
1819
  }
1701
1820
 
1821
+ /**
1822
+ * Stops (or starts) group-level aggregation calculations.
1823
+ *
1824
+ * @public
1825
+ * @param {Boolean} value
1826
+ */
1702
1827
  setSuspended(value) {
1703
1828
  assert.argumentIsRequired(value, 'value', Boolean);
1704
1829
 
1705
1830
  if (this._suspended !== value) {
1706
- if (this._suspended = value) {
1831
+ this._suspended = value;
1832
+
1833
+ if (!this._suspended) {
1707
1834
  this.refresh();
1708
1835
  }
1709
1836
  }
1710
1837
  }
1711
1838
 
1712
1839
  /**
1713
- * Causes all aggregated data to be recalculated.
1840
+ * Causes all aggregated data to be recalculated (assuming the group has not
1841
+ * been suspended).
1714
1842
  *
1715
1843
  * @public
1716
1844
  */
1717
1845
  refresh() {
1846
+ if (this._suspended) {
1847
+ return;
1848
+ }
1849
+
1718
1850
  const rates = this._container.getForexQuotes();
1719
1851
 
1720
1852
  calculateStaticData(this, rates);
@@ -2029,11 +2161,12 @@ module.exports = (() => {
2029
2161
  return PositionGroup;
2030
2162
  })();
2031
2163
 
2032
- },{"./../data/InstrumentType":1,"@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){
2164
+ },{"./../data/InstrumentType":1,"@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){
2033
2165
  const array = require('@barchart/common-js/lang/array'),
2034
2166
  assert = require('@barchart/common-js/lang/assert'),
2035
2167
  Currency = require('@barchart/common-js/lang/Currency'),
2036
2168
  Decimal = require('@barchart/common-js/lang/Decimal'),
2169
+ Disposable = require('@barchart/common-js/lang/Disposable'),
2037
2170
  Event = require('@barchart/common-js/messaging/Event'),
2038
2171
  is = require('@barchart/common-js/lang/is');
2039
2172
 
@@ -2053,8 +2186,10 @@ module.exports = (() => {
2053
2186
  * @param {Object} currentSummary
2054
2187
  * @param {Array.<Object>} previousSummaries
2055
2188
  */
2056
- class PositionItem {
2189
+ class PositionItem extends Disposable {
2057
2190
  constructor(portfolio, position, currentSummary, previousSummaries) {
2191
+ super();
2192
+
2058
2193
  this._portfolio = portfolio;
2059
2194
  this._position = position;
2060
2195
  this._currency = position.instrument.currency || Currency.CAD;
@@ -2099,6 +2234,7 @@ module.exports = (() => {
2099
2234
  this._quoteChangedEvent = new Event(this);
2100
2235
  this._newsExistsChangedEvent = new Event(this);
2101
2236
  this._fundamentalDataChangeEvent = new Event(this);
2237
+ this._positionItemDisposeEvent = new Event(this);
2102
2238
  }
2103
2239
 
2104
2240
  /**
@@ -2181,6 +2317,10 @@ module.exports = (() => {
2181
2317
  setQuote(quote) {
2182
2318
  assert.argumentIsRequired(quote, 'quote', Object);
2183
2319
 
2320
+ if (this.getIsDisposed()) {
2321
+ return;
2322
+ }
2323
+
2184
2324
  if (this._currentPricePrevious !== quote.lastPrice) {
2185
2325
  calculatePriceData(this, quote.lastPrice);
2186
2326
 
@@ -2202,6 +2342,10 @@ module.exports = (() => {
2202
2342
  setPositionFundamentalData(data) {
2203
2343
  assert.argumentIsRequired(data, 'data', Object);
2204
2344
 
2345
+ if (this.getIsDisposed()) {
2346
+ return;
2347
+ }
2348
+
2205
2349
  this._fundamentalDataChangeEvent.fire(this._data.fundamental = data);
2206
2350
  }
2207
2351
 
@@ -2215,6 +2359,10 @@ module.exports = (() => {
2215
2359
  setNewsArticleExists(value) {
2216
2360
  assert.argumentIsRequired(value, 'value', Boolean);
2217
2361
 
2362
+ if (this.getIsDisposed()) {
2363
+ return;
2364
+ }
2365
+
2218
2366
  if (this._data.newsExists !== value) {
2219
2367
  this._newsExistsChangedEvent.fire(this._data.newsExists = value);
2220
2368
  }
@@ -2254,6 +2402,26 @@ module.exports = (() => {
2254
2402
  return this._newsExistsChangedEvent.register(handler);
2255
2403
  }
2256
2404
 
2405
+ /**
2406
+ * Registers an observer for object disposal.
2407
+ *
2408
+ * @public
2409
+ * @param {Function} handler
2410
+ * @returns {Disposable}
2411
+ */
2412
+ registerPositionItemDisposeHandler(handler) {
2413
+ return this._positionItemDisposeEvent.register(handler);
2414
+ }
2415
+
2416
+ _onDispose() {
2417
+ this._positionItemDisposeEvent.fire(this);
2418
+
2419
+ this._quoteChangedEvent.clear();
2420
+ this._newsExistsChangedEvent.clear();
2421
+ this._fundamentalDataChangeEvent.clear();
2422
+ this._positionItemDisposeEvent.clear();
2423
+ }
2424
+
2257
2425
  toString() {
2258
2426
  return '[PositionItem]';
2259
2427
  }
@@ -2397,13 +2565,15 @@ module.exports = (() => {
2397
2565
  return PositionItem;
2398
2566
  })();
2399
2567
 
2400
- },{"./../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){
2568
+ },{"./../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/array":21,"@barchart/common-js/lang/assert":22,"@barchart/common-js/lang/is":24,"@barchart/common-js/messaging/Event":26}],7:[function(require,module,exports){
2401
2569
  const assert = require('@barchart/common-js/lang/assert'),
2402
2570
  Currency = require('@barchart/common-js/lang/Currency'),
2403
2571
  is = require('@barchart/common-js/lang/is');
2404
2572
 
2405
2573
  const InstrumentType = require('./../../data/InstrumentType');
2406
2574
 
2575
+ const PositionLevelType = require('./PositionLevelType');
2576
+
2407
2577
  module.exports = (() => {
2408
2578
  'use strict';
2409
2579
 
@@ -2423,8 +2593,9 @@ module.exports = (() => {
2423
2593
  * @param {Function=} requiredGroupGenerator
2424
2594
  */
2425
2595
  class PositionLevelDefinition {
2426
- constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash, requiredGroupGenerator) {
2596
+ constructor(name, type, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash, requiredGroupGenerator) {
2427
2597
  assert.argumentIsRequired(name, 'name', String);
2598
+ assert.argumentIsRequired(type, 'type', PositionLevelType, 'PositionLevelType');
2428
2599
  assert.argumentIsRequired(keySelector, 'keySelector', Function);
2429
2600
  assert.argumentIsRequired(descriptionSelector, 'descriptionSelector', Function);
2430
2601
  assert.argumentIsRequired(currencySelector, 'currencySelector', Function);
@@ -2438,6 +2609,7 @@ module.exports = (() => {
2438
2609
  assert.argumentIsOptional(requiredGroupGenerator, 'requiredGroupGenerator', Function);
2439
2610
 
2440
2611
  this._name = name;
2612
+ this._type = type;
2441
2613
 
2442
2614
  this._keySelector = keySelector;
2443
2615
  this._descriptionSelector = descriptionSelector;
@@ -2461,6 +2633,16 @@ module.exports = (() => {
2461
2633
  return this._name;
2462
2634
  }
2463
2635
 
2636
+ /**
2637
+ * A general description of the type of items grouped together.
2638
+ *
2639
+ * @public
2640
+ * @return {PositionLevelType}
2641
+ */
2642
+ get type() {
2643
+ return this._type;
2644
+ }
2645
+
2464
2646
  /**
2465
2647
  * A function, when given a {@link PositionItem} returns a string that is used
2466
2648
  * to group {@link PositionItem} instances into different groups.
@@ -2664,7 +2846,38 @@ module.exports = (() => {
2664
2846
  return PositionLevelDefinition;
2665
2847
  })();
2666
2848
 
2667
- },{"./../../data/InstrumentType":1,"@barchart/common-js/lang/Currency":14,"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23}],8:[function(require,module,exports){
2849
+ },{"./../../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){
2850
+ const Enum = require('@barchart/common-js/lang/Enum');
2851
+
2852
+ module.exports = (() => {
2853
+ 'use strict';
2854
+
2855
+ class PositionLevelType extends Enum {
2856
+ constructor(code) {
2857
+ super(code, code);
2858
+ }
2859
+
2860
+ static get PORTFOLIO() {
2861
+ return portfolio;
2862
+ }
2863
+
2864
+ static get POSITION() {
2865
+ return position;
2866
+ }
2867
+
2868
+ static get OTHER() {
2869
+ return other;
2870
+ }
2871
+ }
2872
+
2873
+ const portfolio = new PositionLevelType('PORTFOLIO');
2874
+ const position = new PositionLevelType('POSITION');
2875
+ const other = new PositionLevelType('OTHER');
2876
+
2877
+ return PositionLevelType;
2878
+ })();
2879
+
2880
+ },{"@barchart/common-js/lang/Enum":19}],9:[function(require,module,exports){
2668
2881
  const assert = require('@barchart/common-js/lang/assert');
2669
2882
 
2670
2883
  const PositionLevelDefinition = require('./PositionLevelDefinition');
@@ -2735,7 +2948,7 @@ module.exports = (() => {
2735
2948
  return PositionTreeDefinitions;
2736
2949
  })();
2737
2950
 
2738
- },{"./PositionLevelDefinition":7,"@barchart/common-js/lang/assert":21}],9:[function(require,module,exports){
2951
+ },{"./PositionLevelDefinition":7,"@barchart/common-js/lang/assert":22}],10:[function(require,module,exports){
2739
2952
  'use strict';
2740
2953
 
2741
2954
  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; }; }();
@@ -2867,7 +3080,7 @@ module.exports = function () {
2867
3080
  return Stack;
2868
3081
  }();
2869
3082
 
2870
- },{"./../lang/assert":21}],10:[function(require,module,exports){
3083
+ },{"./../lang/assert":22}],11:[function(require,module,exports){
2871
3084
  'use strict';
2872
3085
 
2873
3086
  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; }; }();
@@ -3008,6 +3221,23 @@ module.exports = function () {
3008
3221
  }
3009
3222
  }
3010
3223
 
3224
+ /**
3225
+ * Removes the current node from the parent tree. Use on a root node
3226
+ * has no effect.
3227
+ *
3228
+ * @public
3229
+ */
3230
+
3231
+ }, {
3232
+ key: 'sever',
3233
+ value: function sever() {
3234
+ if (this.getIsRoot()) {
3235
+ return;
3236
+ }
3237
+
3238
+ this.getParent().removeChild(this);
3239
+ }
3240
+
3011
3241
  /**
3012
3242
  * Searches the children nodes for the first child node that matches the
3013
3243
  * predicate.
@@ -3176,7 +3406,7 @@ module.exports = function () {
3176
3406
  return Tree;
3177
3407
  }();
3178
3408
 
3179
- },{"./../lang/is":23}],11:[function(require,module,exports){
3409
+ },{"./../lang/is":24}],12:[function(require,module,exports){
3180
3410
  'use strict';
3181
3411
 
3182
3412
  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; }; }();
@@ -3320,7 +3550,7 @@ module.exports = function () {
3320
3550
  return ComparatorBuilder;
3321
3551
  }();
3322
3552
 
3323
- },{"./../../lang/assert":21,"./comparators":12}],12:[function(require,module,exports){
3553
+ },{"./../../lang/assert":22,"./comparators":13}],13:[function(require,module,exports){
3324
3554
  'use strict';
3325
3555
 
3326
3556
  var assert = require('./../../lang/assert');
@@ -3395,7 +3625,7 @@ module.exports = function () {
3395
3625
  };
3396
3626
  }();
3397
3627
 
3398
- },{"./../../lang/assert":21}],13:[function(require,module,exports){
3628
+ },{"./../../lang/assert":22}],14:[function(require,module,exports){
3399
3629
  'use strict';
3400
3630
 
3401
3631
  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; }; }();
@@ -3503,7 +3733,7 @@ module.exports = function () {
3503
3733
  return DisposableStack;
3504
3734
  }();
3505
3735
 
3506
- },{"./../../lang/Disposable":17,"./../../lang/assert":21,"./../../lang/is":23,"./../Stack":9}],14:[function(require,module,exports){
3736
+ },{"./../../lang/Disposable":18,"./../../lang/assert":22,"./../../lang/is":24,"./../Stack":10}],15:[function(require,module,exports){
3507
3737
  'use strict';
3508
3738
 
3509
3739
  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; }; }();
@@ -3646,7 +3876,7 @@ module.exports = function () {
3646
3876
  return Currency;
3647
3877
  }();
3648
3878
 
3649
- },{"./Enum":18,"./assert":21,"./is":23}],15:[function(require,module,exports){
3879
+ },{"./Enum":19,"./assert":22,"./is":24}],16:[function(require,module,exports){
3650
3880
  'use strict';
3651
3881
 
3652
3882
  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; }; }();
@@ -4199,7 +4429,7 @@ module.exports = function () {
4199
4429
  return Day;
4200
4430
  }();
4201
4431
 
4202
- },{"./../collections/sorting/ComparatorBuilder":11,"./../collections/sorting/comparators":12,"./assert":21,"./is":23}],16:[function(require,module,exports){
4432
+ },{"./../collections/sorting/ComparatorBuilder":12,"./../collections/sorting/comparators":13,"./assert":22,"./is":24}],17:[function(require,module,exports){
4203
4433
  'use strict';
4204
4434
 
4205
4435
  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; }; }();
@@ -4402,6 +4632,20 @@ module.exports = function () {
4402
4632
  return this._big.gt(getBig(other));
4403
4633
  }
4404
4634
 
4635
+ /**
4636
+ * Returns true if the current instance is greater than or equal to the value.
4637
+ *
4638
+ * @public
4639
+ * @param {Decimal|Number|String} other - The value to compare.
4640
+ * @returns {Boolean}
4641
+ */
4642
+
4643
+ }, {
4644
+ key: 'getIsGreaterThanOrEqual',
4645
+ value: function getIsGreaterThanOrEqual(other) {
4646
+ return this._big.gte(getBig(other));
4647
+ }
4648
+
4405
4649
  /**
4406
4650
  * Returns true if the current instance is less than the value.
4407
4651
  *
@@ -4416,6 +4660,20 @@ module.exports = function () {
4416
4660
  return this._big.lt(getBig(other));
4417
4661
  }
4418
4662
 
4663
+ /**
4664
+ * Returns true if the current instance is less than or equal to the value.
4665
+ *
4666
+ * @public
4667
+ * @param {Decimal|Number|String} other - The value to compare.
4668
+ * @returns {Boolean}
4669
+ */
4670
+
4671
+ }, {
4672
+ key: 'getIsLessThanOrEqual',
4673
+ value: function getIsLessThanOrEqual(other) {
4674
+ return this._big.lte(getBig(other));
4675
+ }
4676
+
4419
4677
  /**
4420
4678
  * Returns true if the current instance is equal to the value.
4421
4679
  *
@@ -4779,7 +5037,7 @@ module.exports = function () {
4779
5037
  return Decimal;
4780
5038
  }();
4781
5039
 
4782
- },{"./Enum":18,"./assert":21,"./is":23,"big.js":26}],17:[function(require,module,exports){
5040
+ },{"./Enum":19,"./assert":22,"./is":24,"big.js":27}],18:[function(require,module,exports){
4783
5041
  'use strict';
4784
5042
 
4785
5043
  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; }; }();
@@ -4928,7 +5186,7 @@ module.exports = function () {
4928
5186
  return Disposable;
4929
5187
  }();
4930
5188
 
4931
- },{"./assert":21}],18:[function(require,module,exports){
5189
+ },{"./assert":22}],19:[function(require,module,exports){
4932
5190
  'use strict';
4933
5191
 
4934
5192
  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; }; }();
@@ -5070,7 +5328,7 @@ module.exports = function () {
5070
5328
  return Enum;
5071
5329
  }();
5072
5330
 
5073
- },{"./assert":21}],19:[function(require,module,exports){
5331
+ },{"./assert":22}],20:[function(require,module,exports){
5074
5332
  'use strict';
5075
5333
 
5076
5334
  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; }; }();
@@ -5325,7 +5583,7 @@ module.exports = function () {
5325
5583
  return Rate;
5326
5584
  }();
5327
5585
 
5328
- },{"./Currency":14,"./Decimal":16,"./assert":21,"./memoize":24}],20:[function(require,module,exports){
5586
+ },{"./Currency":15,"./Decimal":17,"./assert":22,"./memoize":25}],21:[function(require,module,exports){
5329
5587
  'use strict';
5330
5588
 
5331
5589
  var assert = require('./assert'),
@@ -5702,11 +5960,31 @@ module.exports = function () {
5702
5960
  });
5703
5961
 
5704
5962
  return returnRef;
5963
+ },
5964
+
5965
+
5966
+ /**
5967
+ * Removes the first item from an array which matches a predicate.
5968
+ *
5969
+ * @static
5970
+ * @public
5971
+ * @param {Array} a
5972
+ * @param {Function} predicate
5973
+ */
5974
+ remove: function remove(a, predicate) {
5975
+ assert.argumentIsArray(a, 'a');
5976
+ assert.argumentIsRequired(predicate, 'predicate', Function);
5977
+
5978
+ var index = a.findIndex(predicate);
5979
+
5980
+ if (!(index < 0)) {
5981
+ a.splice(index, 1);
5982
+ }
5705
5983
  }
5706
5984
  };
5707
5985
  }();
5708
5986
 
5709
- },{"./assert":21,"./is":23}],21:[function(require,module,exports){
5987
+ },{"./assert":22,"./is":24}],22:[function(require,module,exports){
5710
5988
  'use strict';
5711
5989
 
5712
5990
  var is = require('./is');
@@ -5854,7 +6132,7 @@ module.exports = function () {
5854
6132
  };
5855
6133
  }();
5856
6134
 
5857
- },{"./is":23}],22:[function(require,module,exports){
6135
+ },{"./is":24}],23:[function(require,module,exports){
5858
6136
  'use strict';
5859
6137
 
5860
6138
  module.exports = function () {
@@ -5919,7 +6197,7 @@ module.exports = function () {
5919
6197
  };
5920
6198
  }();
5921
6199
 
5922
- },{}],23:[function(require,module,exports){
6200
+ },{}],24:[function(require,module,exports){
5923
6201
  'use strict';
5924
6202
 
5925
6203
  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; };
@@ -6142,7 +6420,7 @@ module.exports = function () {
6142
6420
  };
6143
6421
  }();
6144
6422
 
6145
- },{}],24:[function(require,module,exports){
6423
+ },{}],25:[function(require,module,exports){
6146
6424
  'use strict';
6147
6425
 
6148
6426
  var assert = require('./assert'),
@@ -6215,7 +6493,7 @@ module.exports = function () {
6215
6493
  };
6216
6494
  }();
6217
6495
 
6218
- },{"./assert":21,"./is":23}],25:[function(require,module,exports){
6496
+ },{"./assert":22,"./is":24}],26:[function(require,module,exports){
6219
6497
  'use strict';
6220
6498
 
6221
6499
  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; }; }();
@@ -6387,7 +6665,7 @@ module.exports = function () {
6387
6665
  return Event;
6388
6666
  }();
6389
6667
 
6390
- },{"./../lang/Disposable":17,"./../lang/assert":21}],26:[function(require,module,exports){
6668
+ },{"./../lang/Disposable":18,"./../lang/assert":22}],27:[function(require,module,exports){
6391
6669
  /*
6392
6670
  * big.js v5.0.3
6393
6671
  * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic.
@@ -7328,7 +7606,7 @@ module.exports = function () {
7328
7606
  }
7329
7607
  })(this);
7330
7608
 
7331
- },{}],27:[function(require,module,exports){
7609
+ },{}],28:[function(require,module,exports){
7332
7610
  const Day = require('@barchart/common-js/lang/Day'),
7333
7611
  Decimal = require('@barchart/common-js/lang/Decimal');
7334
7612
 
@@ -7685,7 +7963,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
7685
7963
  });
7686
7964
  });
7687
7965
 
7688
- },{"./../../../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){
7966
+ },{"./../../../lib/data/PositionSummaryFrame":2,"./../../../lib/data/TransactionType":3,"@barchart/common-js/lang/Day":16,"@barchart/common-js/lang/Decimal":17}],29:[function(require,module,exports){
7689
7967
  const Currency = require('@barchart/common-js/lang/Currency'),
7690
7968
  Decimal = require('@barchart/common-js/lang/Decimal');
7691
7969
 
@@ -7693,6 +7971,7 @@ const InstrumentType = require('./../../../lib/data/InstrumentType');
7693
7971
 
7694
7972
  const PositionContainer = require('./../../../lib/processing/PositionContainer'),
7695
7973
  PositionLevelDefinition = require('./../../../lib/processing/definitions/PositionLevelDefinition'),
7974
+ PositionLevelType = require('./../../../lib/processing/definitions/PositionLevelType'),
7696
7975
  PositionTreeDefinition = require('./../../../lib/processing/definitions/PositionTreeDefinition');
7697
7976
 
7698
7977
  describe('When a position container data is gathered', () => {
@@ -7754,9 +8033,9 @@ describe('When a position container data is gathered', () => {
7754
8033
  beforeEach(() => {
7755
8034
  definitions = [
7756
8035
  new PositionTreeDefinition(name = 'the only tree', [
7757
- new PositionLevelDefinition('Total', x => 'totals', x => 'Total', x => Currency.CAD),
7758
- new PositionLevelDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
7759
- new PositionLevelDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
8036
+ new PositionLevelDefinition('Total', PositionLevelType.OTHER, x => 'totals', x => 'Total', x => Currency.CAD),
8037
+ new PositionLevelDefinition('Portfolio', PositionLevelType.PORTFOLIO, x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
8038
+ new PositionLevelDefinition('Position', PositionLevelType.POSITION, x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
7760
8039
  ])
7761
8040
  ];
7762
8041
 
@@ -7794,4 +8073,4 @@ describe('When a position container data is gathered', () => {
7794
8073
  });
7795
8074
  });
7796
8075
 
7797
- },{"./../../../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]);
8076
+ },{"./../../../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}]},{},[28,29]);
@@ -5,6 +5,7 @@ const InstrumentType = require('./../../../lib/data/InstrumentType');
5
5
 
6
6
  const PositionContainer = require('./../../../lib/processing/PositionContainer'),
7
7
  PositionLevelDefinition = require('./../../../lib/processing/definitions/PositionLevelDefinition'),
8
+ PositionLevelType = require('./../../../lib/processing/definitions/PositionLevelType'),
8
9
  PositionTreeDefinition = require('./../../../lib/processing/definitions/PositionTreeDefinition');
9
10
 
10
11
  describe('When a position container data is gathered', () => {
@@ -66,9 +67,9 @@ describe('When a position container data is gathered', () => {
66
67
  beforeEach(() => {
67
68
  definitions = [
68
69
  new PositionTreeDefinition(name = 'the only tree', [
69
- new PositionLevelDefinition('Total', x => 'totals', x => 'Total', x => Currency.CAD),
70
- new PositionLevelDefinition('Portfolio', x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
71
- new PositionLevelDefinition('Position', x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
70
+ new PositionLevelDefinition('Total', PositionLevelType.OTHER, x => 'totals', x => 'Total', x => Currency.CAD),
71
+ new PositionLevelDefinition('Portfolio', PositionLevelType.PORTFOLIO, x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
72
+ new PositionLevelDefinition('Position', PositionLevelType.POSITION, x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
72
73
  ])
73
74
  ];
74
75