@barchart/portfolio-api-common 1.0.255 → 1.0.259

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.
@@ -120,6 +120,17 @@ module.exports = (() => {
120
120
  return transactionDeleteFailedNoTransaction;
121
121
  }
122
122
 
123
+ /**
124
+ * Unable to delete, the position's direction would switch.
125
+ *
126
+ * @public
127
+ * @static
128
+ * @returns {FailureType}
129
+ */
130
+ static get TRANSACTION_DELETE_FAILED_DIRECTION_SWITCH_ON_REWRITE() {
131
+ return transactionDeleteFailedDirectionSwitchOnRewrite;
132
+ }
133
+
123
134
  toString() {
124
135
  return '[PortfolioFailureType]';
125
136
  }
@@ -138,6 +149,7 @@ module.exports = (() => {
138
149
 
139
150
  const transactionDeleteFailedOutOfSequence = new FailureType('TRANSACTION_DELETE_FAILED_OUT_OF_SEQUENCE', 'Deleting any transaction, except for the most recent, will cause transaction history to be re-written. Please confirm your intent to re-write transaction history (which could take some time and alter the historical results for this position).');
140
151
  const transactionDeleteFailedNoTransaction = new FailureType('TRANSACTION_DELETE_FAILED_NO_TRANSACTION', 'Unable to delete transaction. The referenced transaction does not exist.');
152
+ const transactionDeleteFailedDirectionSwitchOnRewrite = new FailureType('TRANSACTION_DELETE_FAILED_DIRECTION_SWITCH_ON_REWRITE', 'Deleting this transaction would cause your history to be re-written and the position to switch from long to short (i.e. positive to negative) or vice versa.');
141
153
 
142
154
  return PortfolioFailureType;
143
155
  })();
@@ -495,18 +495,61 @@ module.exports = (() => {
495
495
  calculatePriceData(this, this._container.getForexQuotes(), sender, false);
496
496
  });
497
497
 
498
+ let fundamentalBinding = item.registerFundamentalDataChangeHandler((data, sender) => {
499
+ if (this._single) {
500
+ this._dataFormat.fundamental = data;
501
+ } else {
502
+ const fundamentalFields = [ 'percentChange1m', 'percentChange1y', 'percentChange3m', 'percentChangeYtd' ];
503
+
504
+ const fundamentalData = this.items.reduce((sums, item, i) => {
505
+ if (item.data && item.data.fundamental && item.data.fundamental.raw) {
506
+ const fundamental = item.data.fundamental.raw;
507
+
508
+ fundamentalFields.forEach((fieldName) => {
509
+ const summary = sums[fieldName];
510
+ const value = fundamental[fieldName];
511
+
512
+ if (is.number(value)) {
513
+ summary.total = sums[fieldName].total + value;
514
+ summary.count = sums[fieldName].count + 1;
515
+ }
516
+
517
+ if ((i + 1) == this.items.length) {
518
+ let averageFormat;
519
+
520
+ if (summary.count > 0) {
521
+ averageFormat = formatPercent(new Decimal(summary.total / summary.count), 2, true);
522
+ } else {
523
+ averageFormat = '--';
524
+ }
525
+
526
+ summary.averageFormat = averageFormat;
527
+ }
528
+ });
529
+ }
530
+
531
+ return sums;
532
+ }, fundamentalFields.reduce((sums, fieldName) => {
533
+ sums[fieldName] = { total: 0, count: 0, averageFormat: '--' };
534
+
535
+ return sums;
536
+ }, { }));
537
+
538
+ this._dataFormat.fundamental = fundamentalFields.reduce((sums, fieldName) => {
539
+ sums[fieldName] = fundamentalData[fieldName].averageFormat;
540
+
541
+ return sums;
542
+ }, { });
543
+ }
544
+ });
545
+
498
546
  let newsBinding = Disposable.getEmpty();
499
- let fundamentalBinding = Disposable.getEmpty();
500
547
 
501
548
  if (this._single) {
502
549
  newsBinding = item.registerNewsExistsChangeHandler((exists, sender) => {
503
550
  this._dataActual.newsExists = exists;
504
551
  this._dataFormat.newsExists = exists;
505
552
  });
506
-
507
- fundamentalBinding = item.registerFundamentalDataChangeHandler((data, sender) => {
508
- this._dataFormat.fundamental = data;
509
- });
510
553
  }
511
554
 
512
555
  this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio, sender) => {
@@ -553,9 +596,17 @@ module.exports = (() => {
553
596
  }
554
597
  }
555
598
 
556
- function formatPercent(decimal, precision) {
599
+ function formatPercent(decimal, precision, plus) {
557
600
  if (decimal !== null) {
558
- return formatDecimal(decimal.multiply(100), precision) + '%';
601
+ let prefix;
602
+
603
+ if (is.boolean(plus) && plus && !Decimal.getIsNegative(decimal)) {
604
+ prefix = '+';
605
+ } else {
606
+ prefix = '';
607
+ }
608
+
609
+ return `${prefix}${formatDecimal(decimal.multiply(100), precision)}%`;
559
610
  } else {
560
611
  return '—';
561
612
  }
@@ -626,7 +677,7 @@ module.exports = (() => {
626
677
  actual.cashTotal = updates.cashTotal;
627
678
 
628
679
  format.basis = formatCurrency(actual.basis, currency);
629
- format.realized = formatCurrency(actual.basis, currency);
680
+ format.realized = formatCurrency(actual.realized, currency);
630
681
  format.unrealized = formatCurrency(actual.unrealized, currency);
631
682
  format.income = formatCurrency(actual.income, currency);
632
683
  format.summaryTotalCurrent = formatCurrency(updates.summaryTotalCurrent, currency);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.0.255",
3
+ "version": "1.0.259",
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 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){
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){
2
2
  const uuid = require('uuid');
3
3
 
4
4
  const assert = require('@barchart/common-js/lang/assert'),
@@ -2252,18 +2252,61 @@ module.exports = (() => {
2252
2252
  calculatePriceData(this, this._container.getForexQuotes(), sender, false);
2253
2253
  });
2254
2254
 
2255
+ let fundamentalBinding = item.registerFundamentalDataChangeHandler((data, sender) => {
2256
+ if (this._single) {
2257
+ this._dataFormat.fundamental = data;
2258
+ } else {
2259
+ const fundamentalFields = [ 'percentChange1m', 'percentChange1y', 'percentChange3m', 'percentChangeYtd' ];
2260
+
2261
+ const fundamentalData = this.items.reduce((sums, item, i) => {
2262
+ if (item.data && item.data.fundamental && item.data.fundamental.raw) {
2263
+ const fundamental = item.data.fundamental.raw;
2264
+
2265
+ fundamentalFields.forEach((fieldName) => {
2266
+ const summary = sums[fieldName];
2267
+ const value = fundamental[fieldName];
2268
+
2269
+ if (is.number(value)) {
2270
+ summary.total = sums[fieldName].total + value;
2271
+ summary.count = sums[fieldName].count + 1;
2272
+ }
2273
+
2274
+ if ((i + 1) == this.items.length) {
2275
+ let averageFormat;
2276
+
2277
+ if (summary.count > 0) {
2278
+ averageFormat = formatPercent(new Decimal(summary.total / summary.count), 2, true);
2279
+ } else {
2280
+ averageFormat = '--';
2281
+ }
2282
+
2283
+ summary.averageFormat = averageFormat;
2284
+ }
2285
+ });
2286
+ }
2287
+
2288
+ return sums;
2289
+ }, fundamentalFields.reduce((sums, fieldName) => {
2290
+ sums[fieldName] = { total: 0, count: 0, averageFormat: '--' };
2291
+
2292
+ return sums;
2293
+ }, { }));
2294
+
2295
+ this._dataFormat.fundamental = fundamentalFields.reduce((sums, fieldName) => {
2296
+ sums[fieldName] = fundamentalData[fieldName].averageFormat;
2297
+
2298
+ return sums;
2299
+ }, { });
2300
+ }
2301
+ });
2302
+
2255
2303
  let newsBinding = Disposable.getEmpty();
2256
- let fundamentalBinding = Disposable.getEmpty();
2257
2304
 
2258
2305
  if (this._single) {
2259
2306
  newsBinding = item.registerNewsExistsChangeHandler((exists, sender) => {
2260
2307
  this._dataActual.newsExists = exists;
2261
2308
  this._dataFormat.newsExists = exists;
2262
2309
  });
2263
-
2264
- fundamentalBinding = item.registerFundamentalDataChangeHandler((data, sender) => {
2265
- this._dataFormat.fundamental = data;
2266
- });
2267
2310
  }
2268
2311
 
2269
2312
  this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio, sender) => {
@@ -2310,9 +2353,17 @@ module.exports = (() => {
2310
2353
  }
2311
2354
  }
2312
2355
 
2313
- function formatPercent(decimal, precision) {
2356
+ function formatPercent(decimal, precision, plus) {
2314
2357
  if (decimal !== null) {
2315
- return formatDecimal(decimal.multiply(100), precision) + '%';
2358
+ let prefix;
2359
+
2360
+ if (is.boolean(plus) && plus && !Decimal.getIsNegative(decimal)) {
2361
+ prefix = '+';
2362
+ } else {
2363
+ prefix = '';
2364
+ }
2365
+
2366
+ return `${prefix}${formatDecimal(decimal.multiply(100), precision)}%`;
2316
2367
  } else {
2317
2368
  return '—';
2318
2369
  }
@@ -2383,7 +2434,7 @@ module.exports = (() => {
2383
2434
  actual.cashTotal = updates.cashTotal;
2384
2435
 
2385
2436
  format.basis = formatCurrency(actual.basis, currency);
2386
- format.realized = formatCurrency(actual.basis, currency);
2437
+ format.realized = formatCurrency(actual.realized, currency);
2387
2438
  format.unrealized = formatCurrency(actual.unrealized, currency);
2388
2439
  format.income = formatCurrency(actual.income, currency);
2389
2440
  format.summaryTotalCurrent = formatCurrency(updates.summaryTotalCurrent, currency);
@@ -3584,31 +3635,14 @@ module.exports = function () {
3584
3635
  }
3585
3636
 
3586
3637
  /**
3587
- * Gets the root node.
3638
+ * Returns the parent node. If this is the root node, a null value is returned.
3588
3639
  *
3589
3640
  * @public
3590
- * @returns {Tree}
3641
+ * @returns {Tree|null}
3591
3642
  */
3592
3643
 
3593
3644
 
3594
3645
  _createClass(Tree, [{
3595
- key: 'getRoot',
3596
- value: function getRoot() {
3597
- if (this.getIsRoot()) {
3598
- return this;
3599
- } else {
3600
- return this._parent.getRoot();
3601
- }
3602
- }
3603
-
3604
- /**
3605
- * Returns the parent node. If this is the root node, a null value is returned.
3606
- *
3607
- * @public
3608
- * @returns {Tree|null}
3609
- */
3610
-
3611
- }, {
3612
3646
  key: 'getParent',
3613
3647
  value: function getParent() {
3614
3648
  return this._parent;
@@ -3709,23 +3743,6 @@ module.exports = function () {
3709
3743
  }
3710
3744
  }
3711
3745
 
3712
- /**
3713
- * Removes the current node from the parent tree. Use on a root node
3714
- * has no effect.
3715
- *
3716
- * @public
3717
- */
3718
-
3719
- }, {
3720
- key: 'sever',
3721
- value: function sever() {
3722
- if (this.getIsRoot()) {
3723
- return;
3724
- }
3725
-
3726
- this.getParent().removeChild(this);
3727
- }
3728
-
3729
3746
  /**
3730
3747
  * Searches the children nodes for the first child node that matches the
3731
3748
  * predicate.
@@ -3830,33 +3847,6 @@ module.exports = function () {
3830
3847
  }
3831
3848
  }
3832
3849
 
3833
- /**
3834
- * Climbs the tree, evaluating each parent until a predicate is matched. Once matched,
3835
- * the {@link Tree} node is returned. Otherwise, if the predicate cannot be matched,
3836
- * a null value is returned.
3837
- *
3838
- * @public
3839
- * @param {Tree~nodePredicate} predicate - A predicate that tests each child node. The predicate takes two arguments -- the node's value, and the node itself.
3840
- * @param {boolean=} includeCurrentNode - If true, the predicate will be applied to the current node.
3841
- * @returns {Tree|null}
3842
- */
3843
-
3844
- }, {
3845
- key: 'findParent',
3846
- value: function findParent(predicate, includeCurrentNode) {
3847
- var returnRef = void 0;
3848
-
3849
- if (is.boolean(includeCurrentNode) && includeCurrentNode && predicate(this.getValue(), this)) {
3850
- returnRef = this;
3851
- } else if (this._parent !== null) {
3852
- returnRef = this._parent.findParent(predicate, true);
3853
- } else {
3854
- returnRef = null;
3855
- }
3856
-
3857
- return returnRef;
3858
- }
3859
-
3860
3850
  /**
3861
3851
  * Creates a representation of the tree using JavaScript objects and arrays.
3862
3852
  *
@@ -5147,20 +5137,6 @@ module.exports = function () {
5147
5137
  return this._big.gt(getBig(other));
5148
5138
  }
5149
5139
 
5150
- /**
5151
- * Returns true if the current instance is greater than or equal to the value.
5152
- *
5153
- * @public
5154
- * @param {Decimal|Number|String} other - The value to compare.
5155
- * @returns {Boolean}
5156
- */
5157
-
5158
- }, {
5159
- key: 'getIsGreaterThanOrEqual',
5160
- value: function getIsGreaterThanOrEqual(other) {
5161
- return this._big.gte(getBig(other));
5162
- }
5163
-
5164
5140
  /**
5165
5141
  * Returns true if the current instance is less than the value.
5166
5142
  *
@@ -5175,20 +5151,6 @@ module.exports = function () {
5175
5151
  return this._big.lt(getBig(other));
5176
5152
  }
5177
5153
 
5178
- /**
5179
- * Returns true if the current instance is less than or equal to the value.
5180
- *
5181
- * @public
5182
- * @param {Decimal|Number|String} other - The value to compare.
5183
- * @returns {Boolean}
5184
- */
5185
-
5186
- }, {
5187
- key: 'getIsLessThanOrEqual',
5188
- value: function getIsLessThanOrEqual(other) {
5189
- return this._big.lte(getBig(other));
5190
- }
5191
-
5192
5154
  /**
5193
5155
  * Returns true if the current instance is equal to the value.
5194
5156
  *
@@ -5388,9 +5350,9 @@ module.exports = function () {
5388
5350
  assert.argumentIsRequired(a, 'a', Decimal, 'Decimal');
5389
5351
  assert.argumentIsRequired(b, 'b', Decimal, 'Decimal');
5390
5352
 
5391
- if (a._big.gt(b._big)) {
5353
+ if (a._big.gt(b)) {
5392
5354
  return 1;
5393
- } else if (a._big.lt(b._big)) {
5355
+ } else if (a._big.lt(b)) {
5394
5356
  return -1;
5395
5357
  } else {
5396
5358
  return 0;
@@ -5851,10 +5813,12 @@ var _createClass = function () { function defineProperties(target, props) { for
5851
5813
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5852
5814
 
5853
5815
  var assert = require('./assert'),
5816
+ is = require('./is'),
5854
5817
  memoize = require('./memoize');
5855
5818
 
5856
5819
  var Currency = require('./Currency'),
5857
- Decimal = require('./Decimal');
5820
+ Decimal = require('./Decimal'),
5821
+ Enum = require('./Enum');
5858
5822
 
5859
5823
  module.exports = function () {
5860
5824
  'use strict';
@@ -6034,7 +5998,12 @@ module.exports = function () {
6034
5998
  assert.argumentIsRequired(amount, 'amount', Decimal, 'Decimal');
6035
5999
  assert.argumentIsRequired(currency, 'currency', Currency, 'Currency');
6036
6000
  assert.argumentIsRequired(desiredCurrency, 'desiredCurrency', Currency, 'Currency');
6037
- //assert.argumentIsArray(rates, 'rates', Rate, 'Rate');
6001
+
6002
+ for (var _len = arguments.length, rates = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
6003
+ rates[_key - 3] = arguments[_key];
6004
+ }
6005
+
6006
+ assert.argumentIsArray(rates, 'rates', Rate, 'Rate');
6038
6007
 
6039
6008
  var converted = void 0;
6040
6009
 
@@ -6044,10 +6013,6 @@ module.exports = function () {
6044
6013
  var numerator = desiredCurrency;
6045
6014
  var denominator = currency;
6046
6015
 
6047
- for (var _len = arguments.length, rates = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
6048
- rates[_key - 3] = arguments[_key];
6049
- }
6050
-
6051
6016
  var rate = rates.find(function (r) {
6052
6017
  return r.numerator === numerator && r.denominator === denominator || r.numerator === denominator && r.denominator === numerator;
6053
6018
  });
@@ -6098,7 +6063,7 @@ module.exports = function () {
6098
6063
  return Rate;
6099
6064
  }();
6100
6065
 
6101
- },{"./Currency":15,"./Decimal":17,"./assert":22,"./memoize":25}],21:[function(require,module,exports){
6066
+ },{"./Currency":15,"./Decimal":17,"./Enum":19,"./assert":22,"./is":24,"./memoize":25}],21:[function(require,module,exports){
6102
6067
  'use strict';
6103
6068
 
6104
6069
  var assert = require('./assert'),
@@ -6475,26 +6440,6 @@ module.exports = function () {
6475
6440
  });
6476
6441
 
6477
6442
  return returnRef;
6478
- },
6479
-
6480
-
6481
- /**
6482
- * Removes the first item from an array which matches a predicate.
6483
- *
6484
- * @static
6485
- * @public
6486
- * @param {Array} a
6487
- * @param {Function} predicate
6488
- */
6489
- remove: function remove(a, predicate) {
6490
- assert.argumentIsArray(a, 'a');
6491
- assert.argumentIsRequired(predicate, 'predicate', Function);
6492
-
6493
- var index = a.findIndex(predicate);
6494
-
6495
- if (!(index < 0)) {
6496
- a.splice(index, 1);
6497
- }
6498
6443
  }
6499
6444
  };
6500
6445
  }();