@barchart/portfolio-api-common 1.0.254 → 1.0.258

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
  }
@@ -730,7 +781,7 @@ module.exports = (() => {
730
781
  actual.unrealized = updates.unrealized;
731
782
  actual.unrealizedToday = updates.unrealizedToday;
732
783
  actual.summaryTotalCurrent = updates.summaryTotalCurrent;
733
- actual.total = updates.unrealizedToday.add(actual.realized).add(actual.income);
784
+ actual.total = updates.unrealized.add(actual.realized).add(actual.income);
734
785
 
735
786
  format.market = formatCurrency(actual.market, currency);
736
787
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.0.254",
3
+ "version": "1.0.258",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -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
  }
@@ -2487,7 +2538,7 @@ module.exports = (() => {
2487
2538
  actual.unrealized = updates.unrealized;
2488
2539
  actual.unrealizedToday = updates.unrealizedToday;
2489
2540
  actual.summaryTotalCurrent = updates.summaryTotalCurrent;
2490
- actual.total = updates.unrealizedToday.add(actual.realized).add(actual.income);
2541
+ actual.total = updates.unrealized.add(actual.realized).add(actual.income);
2491
2542
 
2492
2543
  format.market = formatCurrency(actual.market, currency);
2493
2544