@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
|
-
|
|
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.
|
|
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
package/test/SpecRunner.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
2541
|
+
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
2491
2542
|
|
|
2492
2543
|
format.market = formatCurrency(actual.market, currency);
|
|
2493
2544
|
|