@barchart/portfolio-api-common 1.2.108 → 1.2.112
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.
- package/lib/api/failures/PortfolioFailureType.js +27 -3
- package/lib/formatters/TransactionFormatter.js +1 -0
- package/lib/processing/PositionGroup.js +59 -3
- package/lib/processing/PositionItem.js +72 -10
- package/lib/serialization/TransactionSchema.js +2 -1
- package/package.json +1 -1
- package/test/SpecRunner.js +133 -14
|
@@ -56,6 +56,17 @@ module.exports = (() => {
|
|
|
56
56
|
return positionUpdateFailedNoPosition;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Unable to delete, a related position is locked.
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
* @static
|
|
64
|
+
* @returns {FailureType}
|
|
65
|
+
*/
|
|
66
|
+
static get POSITION_DELETE_FAILED_POSITION_LOCKED() {
|
|
67
|
+
return positionDeleteFailedPositionLocked;
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
/**
|
|
60
71
|
* The position does not exist.
|
|
61
72
|
*
|
|
@@ -97,8 +108,8 @@ module.exports = (() => {
|
|
|
97
108
|
}
|
|
98
109
|
|
|
99
110
|
/**
|
|
100
|
-
* The transaction would cause the position to change
|
|
101
|
-
* short, or vice versa
|
|
111
|
+
* The transaction would cause the position direction to change
|
|
112
|
+
* from long to short, or vice versa.
|
|
102
113
|
*
|
|
103
114
|
* @public
|
|
104
115
|
* @static
|
|
@@ -144,7 +155,7 @@ module.exports = (() => {
|
|
|
144
155
|
}
|
|
145
156
|
|
|
146
157
|
/**
|
|
147
|
-
* The transaction failed because
|
|
158
|
+
* The transaction failed because a related position is locked.
|
|
148
159
|
*
|
|
149
160
|
* @public
|
|
150
161
|
* @static
|
|
@@ -188,6 +199,17 @@ module.exports = (() => {
|
|
|
188
199
|
return transactionDeleteFailedDirectionSwitchOnRewrite;
|
|
189
200
|
}
|
|
190
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Unable to delete, a related position is locked.
|
|
204
|
+
*
|
|
205
|
+
* @public
|
|
206
|
+
* @static
|
|
207
|
+
* @returns {FailureType}
|
|
208
|
+
*/
|
|
209
|
+
static get TRANSACTION_DELETE_FAILED_POSITION_LOCKED() {
|
|
210
|
+
return transactionDeleteFailedPositionLocked;
|
|
211
|
+
}
|
|
212
|
+
|
|
191
213
|
/**
|
|
192
214
|
* Unable to edit, the transaction doesn't exist.
|
|
193
215
|
*
|
|
@@ -221,6 +243,7 @@ module.exports = (() => {
|
|
|
221
243
|
|
|
222
244
|
const positionCreateFailedNoPortfolio = new FailureType('POSITION_CREATE_FAILED_NO_PORTFOLIO', 'Unable to create transaction. The portfolio does not exist, has it been deleted?');
|
|
223
245
|
const positionUpdateFailedNoPosition = new FailureType('POSITION_UPDATE_FAILED_NO_POSITION', 'Unable to update preferences for position. The position does not exist, has it been deleted?');
|
|
246
|
+
const positionDeleteFailedPositionLocked = new FailureType('POSITION_DELETE_FAILED_POSITION_LOCKED', 'Unable to delete position, your {L|description} history is being recalculated. Please wait a minute or two and retry.');
|
|
224
247
|
|
|
225
248
|
const transactionCreateFailedNoPosition = new FailureType('TRANSACTION_CREATE_FAILED_NO_POSITION', 'Unable to create transaction. The referenced position does not exist. Has it been deleted?');
|
|
226
249
|
const transactionCreateFailedOutOfSequence = new FailureType('TRANSACTION_CREATE_FAILED_OUT_OF_SEQUENCE', 'Unable to process transaction, because the transaction date is out-of-sequence. In other words, it would occur before an existing transaction. Please confirm your intent to re-write transaction history (which could take some time and alter the historical results for this position).');
|
|
@@ -235,6 +258,7 @@ module.exports = (() => {
|
|
|
235
258
|
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).');
|
|
236
259
|
const transactionDeleteFailedNoTransaction = new FailureType('TRANSACTION_DELETE_FAILED_NO_TRANSACTION', 'Unable to delete transaction. The referenced transaction does not exist.');
|
|
237
260
|
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.');
|
|
261
|
+
const transactionDeleteFailedPositionLocked = new FailureType('TRANSACTION_DELETE_FAILED_POSITION_LOCKED', 'Unable to delete transaction, your {L|description} history is being recalculated. Please wait a minute or two and retry.');
|
|
238
262
|
|
|
239
263
|
const transactionEditFailedNoTransaction = new FailureType('TRANSACTION_EDIT_FAILED_NO_TRANSACTION', 'Unable to edit transaction. The referenced transaction does not exist.');
|
|
240
264
|
const transactionEditFailedTypeReserved = new FailureType('TRANSACTION_EDIT_FAILED_TYPE_RESERVED', 'Unable to edit {U|type.description} transaction, this type of transaction is managed by the system.');
|
|
@@ -169,7 +169,17 @@ module.exports = (() => {
|
|
|
169
169
|
this._dataActual.periodPrice = null;
|
|
170
170
|
this._dataActual.periodPricePrevious = null;
|
|
171
171
|
this._dataActual.periodRealized = null;
|
|
172
|
+
this._dataActual.periodRealizedPrevious = null;
|
|
173
|
+
this._dataActual.periodRealizedPrevious2 = null;
|
|
174
|
+
this._dataActual.periodRealizedBasis = null;
|
|
175
|
+
this._dataActual.periodRealizedBasisPrevious = null;
|
|
176
|
+
this._dataActual.periodRealizedBasisPrevious2 = null;
|
|
172
177
|
this._dataActual.periodUnrealized = null;
|
|
178
|
+
this._dataActual.periodUnrealizedPrevious = null;
|
|
179
|
+
this._dataActual.periodUnrealizedPrevious2 = null;
|
|
180
|
+
this._dataActual.periodUnrealizedBasis = null;
|
|
181
|
+
this._dataActual.periodUnrealizedBasisPrevious = null;
|
|
182
|
+
this._dataActual.periodUnrealizedBasisPrevious2 = null;
|
|
173
183
|
this._dataActual.periodIncome = null;
|
|
174
184
|
|
|
175
185
|
this._dataFormat.periodPrice = null;
|
|
@@ -178,6 +188,14 @@ module.exports = (() => {
|
|
|
178
188
|
this._dataFormat.periodUnrealized = null;
|
|
179
189
|
this._dataFormat.periodIncome = null;
|
|
180
190
|
|
|
191
|
+
this._dataActual.periodPercent = null;
|
|
192
|
+
this._dataActual.periodPreviousPercent = null;
|
|
193
|
+
this._dataActual.periodPrevious2Percent = null;
|
|
194
|
+
|
|
195
|
+
this._dataFormat.periodPercent = null;
|
|
196
|
+
this._dataFormat.periodPreviousPercent = null;
|
|
197
|
+
this._dataFormat.periodPrevious2Percent = null;
|
|
198
|
+
|
|
181
199
|
this._items.forEach((item) => {
|
|
182
200
|
bindItem.call(this, item);
|
|
183
201
|
});
|
|
@@ -731,7 +749,9 @@ module.exports = (() => {
|
|
|
731
749
|
|
|
732
750
|
calculateUnrealizedPercent(group);
|
|
733
751
|
|
|
734
|
-
|
|
752
|
+
const groupItems = group._items;
|
|
753
|
+
|
|
754
|
+
if (group.single && groupItems.length === 1) {
|
|
735
755
|
const item = group._items[0];
|
|
736
756
|
|
|
737
757
|
actual.quantity = item.data.quantity;
|
|
@@ -750,12 +770,34 @@ module.exports = (() => {
|
|
|
750
770
|
format.periodPrice = formatCurrency(actual.periodPrice, currency);
|
|
751
771
|
format.periodPricePrevious = formatCurrency(actual.periodPricePrevious, currency);
|
|
752
772
|
|
|
773
|
+
actual.periodRealized = item.data.periodRealized;
|
|
774
|
+
actual.periodRealizedPrevious = item.data.periodRealizedPrevious;
|
|
775
|
+
actual.periodRealizedPrevious2 = item.data.periodRealizedPrevious2;
|
|
776
|
+
|
|
777
|
+
actual.periodRealizedBasis = item.data.periodRealizedBasis;
|
|
778
|
+
actual.periodRealizedBasisPrevious = item.data.periodRealizedBasisPrevious;
|
|
779
|
+
actual.periodRealizedBasisPrevious2 = item.data.periodRealizedBasisPrevious2;
|
|
780
|
+
|
|
781
|
+
actual.periodUnrealized = item.data.periodUnrealized;
|
|
782
|
+
actual.periodUnrealizedPrevious = item.data.periodUnrealizedPrevious;
|
|
783
|
+
actual.periodUnrealizedPrevious2 = item.data.periodUnrealizedPrevious2;
|
|
784
|
+
|
|
785
|
+
actual.periodUnrealizedBasis = item.data.periodUnrealizedBasis;
|
|
786
|
+
actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
|
|
787
|
+
actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
|
|
788
|
+
|
|
789
|
+
actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
|
|
790
|
+
actual.periodPercentPrevious = calculatePeriodPercent(actual.periodRealizedPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedPrevious, actual.periodUnrealizedBasisPrevious);
|
|
791
|
+
actual.periodPercentPrevious2 = calculatePeriodPercent(actual.periodRealizedPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedPrevious2, actual.periodUnrealizedBasisPrevious2);
|
|
792
|
+
|
|
793
|
+
format.periodPercent = formatPercent(actual.periodPercent, 2);
|
|
794
|
+
format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
|
|
795
|
+
format.periodPercentPrevious2 = formatPercent(actual.periodPercentPrevious2, 2);
|
|
796
|
+
|
|
753
797
|
format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
|
|
754
798
|
format.locked = definition.type === PositionLevelType.POSITION && item.data.locked;
|
|
755
799
|
}
|
|
756
800
|
|
|
757
|
-
const groupItems = group._items;
|
|
758
|
-
|
|
759
801
|
let portfolioType = null;
|
|
760
802
|
|
|
761
803
|
if (groupItems.length > 0) {
|
|
@@ -875,6 +917,13 @@ module.exports = (() => {
|
|
|
875
917
|
format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
|
|
876
918
|
|
|
877
919
|
calculateUnrealizedPercent(group);
|
|
920
|
+
|
|
921
|
+
if (group.single && item) {
|
|
922
|
+
actual.periodUnrealized = item.data.periodUnrealized;
|
|
923
|
+
|
|
924
|
+
actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
|
|
925
|
+
format.periodPercent = formatPercent(actual.periodPercent, 2);
|
|
926
|
+
}
|
|
878
927
|
}
|
|
879
928
|
|
|
880
929
|
function calculateMarketPercent(group, rates, parentGroup, portfolioGroup) {
|
|
@@ -933,6 +982,13 @@ module.exports = (() => {
|
|
|
933
982
|
}
|
|
934
983
|
}
|
|
935
984
|
|
|
985
|
+
function calculatePeriodPercent(realized, realizedBasis, unrealized, unrealizedBasis) {
|
|
986
|
+
const numerator = realizedBasis.add(unrealized);
|
|
987
|
+
const denominator = realizedBasis.add(unrealizedBasis);
|
|
988
|
+
|
|
989
|
+
return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
|
|
990
|
+
}
|
|
991
|
+
|
|
936
992
|
const unchanged = { up: false, down: false };
|
|
937
993
|
|
|
938
994
|
return PositionGroup;
|
|
@@ -79,7 +79,21 @@ module.exports = (() => {
|
|
|
79
79
|
this._data.basisPrice = null;
|
|
80
80
|
|
|
81
81
|
this._data.periodRealized = null;
|
|
82
|
+
this._data.periodRealizedPrevious = null;
|
|
83
|
+
this._data.periodRealizedPrevious2 = null;
|
|
84
|
+
|
|
85
|
+
this._data.periodRealizedBasis = null;
|
|
86
|
+
this._data.periodRealizedBasisPrevious = null;
|
|
87
|
+
this._data.periodRealizedBasisPrevious2 = null;
|
|
88
|
+
|
|
82
89
|
this._data.periodUnrealized = null;
|
|
90
|
+
this._data.periodUnrealizedPrevious = null;
|
|
91
|
+
this._data.periodUnrealizedPrevious2 = null;
|
|
92
|
+
|
|
93
|
+
this._data.periodUnrealizedBasis = null;
|
|
94
|
+
this._data.periodUnrealizedBasisPrevious = null;
|
|
95
|
+
this._data.periodUnrealizedBasisPrevious2 = null;
|
|
96
|
+
|
|
83
97
|
this._data.periodIncome = null;
|
|
84
98
|
|
|
85
99
|
this._data.periodPrice = null;
|
|
@@ -89,15 +103,15 @@ module.exports = (() => {
|
|
|
89
103
|
this._data.fundamental = { };
|
|
90
104
|
this._data.locked = getIsLocked(position);
|
|
91
105
|
|
|
92
|
-
calculateStaticData(this);
|
|
93
|
-
calculatePriceData(this, null);
|
|
94
|
-
|
|
95
106
|
this._quoteChangedEvent = new Event(this);
|
|
96
107
|
this._newsExistsChangedEvent = new Event(this);
|
|
97
108
|
this._fundamentalDataChangedEvent = new Event(this);
|
|
98
109
|
this._lockChangedEvent = new Event(this);
|
|
99
110
|
this._portfolioChangedEvent = new Event(this);
|
|
100
111
|
this._positionItemDisposeEvent = new Event(this);
|
|
112
|
+
|
|
113
|
+
calculateStaticData(this);
|
|
114
|
+
calculatePriceData(this, null);
|
|
101
115
|
}
|
|
102
116
|
|
|
103
117
|
/**
|
|
@@ -411,9 +425,23 @@ module.exports = (() => {
|
|
|
411
425
|
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
412
426
|
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
413
427
|
|
|
414
|
-
data.periodRealized =
|
|
415
|
-
data.
|
|
416
|
-
data.
|
|
428
|
+
data.periodRealized = calculatePeriodRealized(item.currentSummary, previousSummary1);
|
|
429
|
+
data.periodRealizedPrevious = calculatePeriodRealized(previousSummary1, previousSummary2);
|
|
430
|
+
data.periodRealizedPrevious2 = calculatePeriodRealized(previousSummary2, previousSummary3);
|
|
431
|
+
|
|
432
|
+
data.periodRealizedBasis = calculatePeriodRealizedBasis(item.currentSummary, previousSummary1);
|
|
433
|
+
data.periodRealizedBasisPrevious = calculatePeriodRealizedBasis(previousSummary1, previousSummary2);
|
|
434
|
+
data.periodRealizedBasisPrevious2 = calculatePeriodRealizedBasis(previousSummary2, previousSummary3);
|
|
435
|
+
|
|
436
|
+
data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary1);
|
|
437
|
+
data.periodUnrealizedPrevious = calculatePeriodUnrealized(previousSummary1, previousSummary2);
|
|
438
|
+
data.periodUnrealizedPrevious2 = calculatePeriodUnrealized(previousSummary2, previousSummary3);
|
|
439
|
+
|
|
440
|
+
data.periodUnrealizedBasis = calculatePeriodUnrealizedBasis(item.currentSummary, previousSummary1);
|
|
441
|
+
data.periodUnrealizedBasisPrevious = calculatePeriodUnrealizedBasis(previousSummary1, previousSummary2);
|
|
442
|
+
data.periodUnrealizedBasisPrevious2 = calculatePeriodUnrealizedBasis(previousSummary2, previousSummary3);
|
|
443
|
+
|
|
444
|
+
data.periodIncome = calculatePeriodIncome(item.currentSummary, previousSummary1);
|
|
417
445
|
|
|
418
446
|
if (snapshot.open.getIsZero()) {
|
|
419
447
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -540,11 +568,16 @@ module.exports = (() => {
|
|
|
540
568
|
|
|
541
569
|
data.unrealized = unrealized;
|
|
542
570
|
data.unrealizedChange = unrealizedChange;
|
|
571
|
+
|
|
572
|
+
data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary, data.unrealized);
|
|
573
|
+
data.periodUnrealizedChange = unrealizedChange;
|
|
543
574
|
} else {
|
|
544
575
|
data.summaryTotalCurrentChange = Decimal.ZERO;
|
|
545
576
|
|
|
546
577
|
data.unrealized = Decimal.ZERO;
|
|
547
578
|
data.unrealizedChange = Decimal.ZERO;
|
|
579
|
+
|
|
580
|
+
data.periodUnrealizedChange = Decimal.ZERO;
|
|
548
581
|
}
|
|
549
582
|
} else {
|
|
550
583
|
data.summaryTotalCurrentChange = Decimal.ZERO;
|
|
@@ -568,7 +601,7 @@ module.exports = (() => {
|
|
|
568
601
|
return returnRef;
|
|
569
602
|
}
|
|
570
603
|
|
|
571
|
-
function
|
|
604
|
+
function calculatePeriodRealized(currentSummary, previousSummary) {
|
|
572
605
|
let returnRef;
|
|
573
606
|
|
|
574
607
|
if (currentSummary) {
|
|
@@ -582,13 +615,42 @@ module.exports = (() => {
|
|
|
582
615
|
return returnRef;
|
|
583
616
|
}
|
|
584
617
|
|
|
585
|
-
function
|
|
618
|
+
function calculatePeriodRealizedBasis(currentSummary, previousSummary) {
|
|
619
|
+
let returnRef;
|
|
620
|
+
|
|
621
|
+
if (currentSummary) {
|
|
622
|
+
const period = currentSummary.period;
|
|
623
|
+
|
|
624
|
+
returnRef = period.sells.subtract(calculatePeriodRealized(currentSummary, previousSummary));
|
|
625
|
+
} else {
|
|
626
|
+
returnRef = Decimal.ZERO;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
return returnRef;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
function calculatePeriodUnrealized(currentSummary, previousSummary, override) {
|
|
633
|
+
let returnRef;
|
|
634
|
+
|
|
635
|
+
if (currentSummary) {
|
|
636
|
+
const period = currentSummary.period;
|
|
637
|
+
const unrealized = override || period.unrealized;
|
|
638
|
+
|
|
639
|
+
returnRef = unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
|
|
640
|
+
} else {
|
|
641
|
+
returnRef = Decimal.ZERO;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
return returnRef;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function calculatePeriodUnrealizedBasis(currentSummary, previousSummary) {
|
|
586
648
|
let returnRef;
|
|
587
649
|
|
|
588
650
|
if (currentSummary) {
|
|
589
651
|
const period = currentSummary.period;
|
|
590
652
|
|
|
591
|
-
returnRef =
|
|
653
|
+
returnRef = currentSummary.end.basis;
|
|
592
654
|
} else {
|
|
593
655
|
returnRef = Decimal.ZERO;
|
|
594
656
|
}
|
|
@@ -596,7 +658,7 @@ module.exports = (() => {
|
|
|
596
658
|
return returnRef;
|
|
597
659
|
}
|
|
598
660
|
|
|
599
|
-
function
|
|
661
|
+
function calculatePeriodIncome(currentSummary, previousSummary) {
|
|
600
662
|
let returnRef;
|
|
601
663
|
|
|
602
664
|
if (currentSummary) {
|
|
@@ -317,7 +317,8 @@ module.exports = (() => {
|
|
|
317
317
|
.withField('sequence', DataType.NUMBER, true)
|
|
318
318
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
319
319
|
.withField('date', DataType.DAY)
|
|
320
|
-
.withField('
|
|
320
|
+
.withField('rate', DataType.DECIMAL, true)
|
|
321
|
+
.withField('value', DataType.DECIMAL, true)
|
|
321
322
|
.withField('force', DataType.BOOLEAN, true)
|
|
322
323
|
.schema
|
|
323
324
|
);
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -2629,7 +2629,17 @@ module.exports = (() => {
|
|
|
2629
2629
|
this._dataActual.periodPrice = null;
|
|
2630
2630
|
this._dataActual.periodPricePrevious = null;
|
|
2631
2631
|
this._dataActual.periodRealized = null;
|
|
2632
|
+
this._dataActual.periodRealizedPrevious = null;
|
|
2633
|
+
this._dataActual.periodRealizedPrevious2 = null;
|
|
2634
|
+
this._dataActual.periodRealizedBasis = null;
|
|
2635
|
+
this._dataActual.periodRealizedBasisPrevious = null;
|
|
2636
|
+
this._dataActual.periodRealizedBasisPrevious2 = null;
|
|
2632
2637
|
this._dataActual.periodUnrealized = null;
|
|
2638
|
+
this._dataActual.periodUnrealizedPrevious = null;
|
|
2639
|
+
this._dataActual.periodUnrealizedPrevious2 = null;
|
|
2640
|
+
this._dataActual.periodUnrealizedBasis = null;
|
|
2641
|
+
this._dataActual.periodUnrealizedBasisPrevious = null;
|
|
2642
|
+
this._dataActual.periodUnrealizedBasisPrevious2 = null;
|
|
2633
2643
|
this._dataActual.periodIncome = null;
|
|
2634
2644
|
|
|
2635
2645
|
this._dataFormat.periodPrice = null;
|
|
@@ -2638,6 +2648,14 @@ module.exports = (() => {
|
|
|
2638
2648
|
this._dataFormat.periodUnrealized = null;
|
|
2639
2649
|
this._dataFormat.periodIncome = null;
|
|
2640
2650
|
|
|
2651
|
+
this._dataActual.periodPercent = null;
|
|
2652
|
+
this._dataActual.periodPreviousPercent = null;
|
|
2653
|
+
this._dataActual.periodPrevious2Percent = null;
|
|
2654
|
+
|
|
2655
|
+
this._dataFormat.periodPercent = null;
|
|
2656
|
+
this._dataFormat.periodPreviousPercent = null;
|
|
2657
|
+
this._dataFormat.periodPrevious2Percent = null;
|
|
2658
|
+
|
|
2641
2659
|
this._items.forEach((item) => {
|
|
2642
2660
|
bindItem.call(this, item);
|
|
2643
2661
|
});
|
|
@@ -3191,7 +3209,9 @@ module.exports = (() => {
|
|
|
3191
3209
|
|
|
3192
3210
|
calculateUnrealizedPercent(group);
|
|
3193
3211
|
|
|
3194
|
-
|
|
3212
|
+
const groupItems = group._items;
|
|
3213
|
+
|
|
3214
|
+
if (group.single && groupItems.length === 1) {
|
|
3195
3215
|
const item = group._items[0];
|
|
3196
3216
|
|
|
3197
3217
|
actual.quantity = item.data.quantity;
|
|
@@ -3210,12 +3230,34 @@ module.exports = (() => {
|
|
|
3210
3230
|
format.periodPrice = formatCurrency(actual.periodPrice, currency);
|
|
3211
3231
|
format.periodPricePrevious = formatCurrency(actual.periodPricePrevious, currency);
|
|
3212
3232
|
|
|
3233
|
+
actual.periodRealized = item.data.periodRealized;
|
|
3234
|
+
actual.periodRealizedPrevious = item.data.periodRealizedPrevious;
|
|
3235
|
+
actual.periodRealizedPrevious2 = item.data.periodRealizedPrevious2;
|
|
3236
|
+
|
|
3237
|
+
actual.periodRealizedBasis = item.data.periodRealizedBasis;
|
|
3238
|
+
actual.periodRealizedBasisPrevious = item.data.periodRealizedBasisPrevious;
|
|
3239
|
+
actual.periodRealizedBasisPrevious2 = item.data.periodRealizedBasisPrevious2;
|
|
3240
|
+
|
|
3241
|
+
actual.periodUnrealized = item.data.periodUnrealized;
|
|
3242
|
+
actual.periodUnrealizedPrevious = item.data.periodUnrealizedPrevious;
|
|
3243
|
+
actual.periodUnrealizedPrevious2 = item.data.periodUnrealizedPrevious2;
|
|
3244
|
+
|
|
3245
|
+
actual.periodUnrealizedBasis = item.data.periodUnrealizedBasis;
|
|
3246
|
+
actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
|
|
3247
|
+
actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
|
|
3248
|
+
|
|
3249
|
+
actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
|
|
3250
|
+
actual.periodPercentPrevious = calculatePeriodPercent(actual.periodRealizedPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedPrevious, actual.periodUnrealizedBasisPrevious);
|
|
3251
|
+
actual.periodPercentPrevious2 = calculatePeriodPercent(actual.periodRealizedPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedPrevious2, actual.periodUnrealizedBasisPrevious2);
|
|
3252
|
+
|
|
3253
|
+
format.periodPercent = formatPercent(actual.periodPercent, 2);
|
|
3254
|
+
format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
|
|
3255
|
+
format.periodPercentPrevious2 = formatPercent(actual.periodPercentPrevious2, 2);
|
|
3256
|
+
|
|
3213
3257
|
format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
|
|
3214
3258
|
format.locked = definition.type === PositionLevelType.POSITION && item.data.locked;
|
|
3215
3259
|
}
|
|
3216
3260
|
|
|
3217
|
-
const groupItems = group._items;
|
|
3218
|
-
|
|
3219
3261
|
let portfolioType = null;
|
|
3220
3262
|
|
|
3221
3263
|
if (groupItems.length > 0) {
|
|
@@ -3335,6 +3377,13 @@ module.exports = (() => {
|
|
|
3335
3377
|
format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
|
|
3336
3378
|
|
|
3337
3379
|
calculateUnrealizedPercent(group);
|
|
3380
|
+
|
|
3381
|
+
if (group.single && item) {
|
|
3382
|
+
actual.periodUnrealized = item.data.periodUnrealized;
|
|
3383
|
+
|
|
3384
|
+
actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
|
|
3385
|
+
format.periodPercent = formatPercent(actual.periodPercent, 2);
|
|
3386
|
+
}
|
|
3338
3387
|
}
|
|
3339
3388
|
|
|
3340
3389
|
function calculateMarketPercent(group, rates, parentGroup, portfolioGroup) {
|
|
@@ -3393,6 +3442,13 @@ module.exports = (() => {
|
|
|
3393
3442
|
}
|
|
3394
3443
|
}
|
|
3395
3444
|
|
|
3445
|
+
function calculatePeriodPercent(realized, realizedBasis, unrealized, unrealizedBasis) {
|
|
3446
|
+
const numerator = realizedBasis.add(unrealized);
|
|
3447
|
+
const denominator = realizedBasis.add(unrealizedBasis);
|
|
3448
|
+
|
|
3449
|
+
return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
|
|
3450
|
+
}
|
|
3451
|
+
|
|
3396
3452
|
const unchanged = { up: false, down: false };
|
|
3397
3453
|
|
|
3398
3454
|
return PositionGroup;
|
|
@@ -3480,7 +3536,21 @@ module.exports = (() => {
|
|
|
3480
3536
|
this._data.basisPrice = null;
|
|
3481
3537
|
|
|
3482
3538
|
this._data.periodRealized = null;
|
|
3539
|
+
this._data.periodRealizedPrevious = null;
|
|
3540
|
+
this._data.periodRealizedPrevious2 = null;
|
|
3541
|
+
|
|
3542
|
+
this._data.periodRealizedBasis = null;
|
|
3543
|
+
this._data.periodRealizedBasisPrevious = null;
|
|
3544
|
+
this._data.periodRealizedBasisPrevious2 = null;
|
|
3545
|
+
|
|
3483
3546
|
this._data.periodUnrealized = null;
|
|
3547
|
+
this._data.periodUnrealizedPrevious = null;
|
|
3548
|
+
this._data.periodUnrealizedPrevious2 = null;
|
|
3549
|
+
|
|
3550
|
+
this._data.periodUnrealizedBasis = null;
|
|
3551
|
+
this._data.periodUnrealizedBasisPrevious = null;
|
|
3552
|
+
this._data.periodUnrealizedBasisPrevious2 = null;
|
|
3553
|
+
|
|
3484
3554
|
this._data.periodIncome = null;
|
|
3485
3555
|
|
|
3486
3556
|
this._data.periodPrice = null;
|
|
@@ -3490,15 +3560,15 @@ module.exports = (() => {
|
|
|
3490
3560
|
this._data.fundamental = { };
|
|
3491
3561
|
this._data.locked = getIsLocked(position);
|
|
3492
3562
|
|
|
3493
|
-
calculateStaticData(this);
|
|
3494
|
-
calculatePriceData(this, null);
|
|
3495
|
-
|
|
3496
3563
|
this._quoteChangedEvent = new Event(this);
|
|
3497
3564
|
this._newsExistsChangedEvent = new Event(this);
|
|
3498
3565
|
this._fundamentalDataChangedEvent = new Event(this);
|
|
3499
3566
|
this._lockChangedEvent = new Event(this);
|
|
3500
3567
|
this._portfolioChangedEvent = new Event(this);
|
|
3501
3568
|
this._positionItemDisposeEvent = new Event(this);
|
|
3569
|
+
|
|
3570
|
+
calculateStaticData(this);
|
|
3571
|
+
calculatePriceData(this, null);
|
|
3502
3572
|
}
|
|
3503
3573
|
|
|
3504
3574
|
/**
|
|
@@ -3812,9 +3882,23 @@ module.exports = (() => {
|
|
|
3812
3882
|
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
3813
3883
|
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
3814
3884
|
|
|
3815
|
-
data.periodRealized =
|
|
3816
|
-
data.
|
|
3817
|
-
data.
|
|
3885
|
+
data.periodRealized = calculatePeriodRealized(item.currentSummary, previousSummary1);
|
|
3886
|
+
data.periodRealizedPrevious = calculatePeriodRealized(previousSummary1, previousSummary2);
|
|
3887
|
+
data.periodRealizedPrevious2 = calculatePeriodRealized(previousSummary2, previousSummary3);
|
|
3888
|
+
|
|
3889
|
+
data.periodRealizedBasis = calculatePeriodRealizedBasis(item.currentSummary, previousSummary1);
|
|
3890
|
+
data.periodRealizedBasisPrevious = calculatePeriodRealizedBasis(previousSummary1, previousSummary2);
|
|
3891
|
+
data.periodRealizedBasisPrevious2 = calculatePeriodRealizedBasis(previousSummary2, previousSummary3);
|
|
3892
|
+
|
|
3893
|
+
data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary1);
|
|
3894
|
+
data.periodUnrealizedPrevious = calculatePeriodUnrealized(previousSummary1, previousSummary2);
|
|
3895
|
+
data.periodUnrealizedPrevious2 = calculatePeriodUnrealized(previousSummary2, previousSummary3);
|
|
3896
|
+
|
|
3897
|
+
data.periodUnrealizedBasis = calculatePeriodUnrealizedBasis(item.currentSummary, previousSummary1);
|
|
3898
|
+
data.periodUnrealizedBasisPrevious = calculatePeriodUnrealizedBasis(previousSummary1, previousSummary2);
|
|
3899
|
+
data.periodUnrealizedBasisPrevious2 = calculatePeriodUnrealizedBasis(previousSummary2, previousSummary3);
|
|
3900
|
+
|
|
3901
|
+
data.periodIncome = calculatePeriodIncome(item.currentSummary, previousSummary1);
|
|
3818
3902
|
|
|
3819
3903
|
if (snapshot.open.getIsZero()) {
|
|
3820
3904
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -3941,11 +4025,16 @@ module.exports = (() => {
|
|
|
3941
4025
|
|
|
3942
4026
|
data.unrealized = unrealized;
|
|
3943
4027
|
data.unrealizedChange = unrealizedChange;
|
|
4028
|
+
|
|
4029
|
+
data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary, data.unrealized);
|
|
4030
|
+
data.periodUnrealizedChange = unrealizedChange;
|
|
3944
4031
|
} else {
|
|
3945
4032
|
data.summaryTotalCurrentChange = Decimal.ZERO;
|
|
3946
4033
|
|
|
3947
4034
|
data.unrealized = Decimal.ZERO;
|
|
3948
4035
|
data.unrealizedChange = Decimal.ZERO;
|
|
4036
|
+
|
|
4037
|
+
data.periodUnrealizedChange = Decimal.ZERO;
|
|
3949
4038
|
}
|
|
3950
4039
|
} else {
|
|
3951
4040
|
data.summaryTotalCurrentChange = Decimal.ZERO;
|
|
@@ -3969,7 +4058,7 @@ module.exports = (() => {
|
|
|
3969
4058
|
return returnRef;
|
|
3970
4059
|
}
|
|
3971
4060
|
|
|
3972
|
-
function
|
|
4061
|
+
function calculatePeriodRealized(currentSummary, previousSummary) {
|
|
3973
4062
|
let returnRef;
|
|
3974
4063
|
|
|
3975
4064
|
if (currentSummary) {
|
|
@@ -3983,13 +4072,42 @@ module.exports = (() => {
|
|
|
3983
4072
|
return returnRef;
|
|
3984
4073
|
}
|
|
3985
4074
|
|
|
3986
|
-
function
|
|
4075
|
+
function calculatePeriodRealizedBasis(currentSummary, previousSummary) {
|
|
4076
|
+
let returnRef;
|
|
4077
|
+
|
|
4078
|
+
if (currentSummary) {
|
|
4079
|
+
const period = currentSummary.period;
|
|
4080
|
+
|
|
4081
|
+
returnRef = period.sells.subtract(calculatePeriodRealized(currentSummary, previousSummary));
|
|
4082
|
+
} else {
|
|
4083
|
+
returnRef = Decimal.ZERO;
|
|
4084
|
+
}
|
|
4085
|
+
|
|
4086
|
+
return returnRef;
|
|
4087
|
+
}
|
|
4088
|
+
|
|
4089
|
+
function calculatePeriodUnrealized(currentSummary, previousSummary, override) {
|
|
4090
|
+
let returnRef;
|
|
4091
|
+
|
|
4092
|
+
if (currentSummary) {
|
|
4093
|
+
const period = currentSummary.period;
|
|
4094
|
+
const unrealized = override || period.unrealized;
|
|
4095
|
+
|
|
4096
|
+
returnRef = unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
|
|
4097
|
+
} else {
|
|
4098
|
+
returnRef = Decimal.ZERO;
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4101
|
+
return returnRef;
|
|
4102
|
+
}
|
|
4103
|
+
|
|
4104
|
+
function calculatePeriodUnrealizedBasis(currentSummary, previousSummary) {
|
|
3987
4105
|
let returnRef;
|
|
3988
4106
|
|
|
3989
4107
|
if (currentSummary) {
|
|
3990
4108
|
const period = currentSummary.period;
|
|
3991
4109
|
|
|
3992
|
-
returnRef =
|
|
4110
|
+
returnRef = currentSummary.end.basis;
|
|
3993
4111
|
} else {
|
|
3994
4112
|
returnRef = Decimal.ZERO;
|
|
3995
4113
|
}
|
|
@@ -3997,7 +4115,7 @@ module.exports = (() => {
|
|
|
3997
4115
|
return returnRef;
|
|
3998
4116
|
}
|
|
3999
4117
|
|
|
4000
|
-
function
|
|
4118
|
+
function calculatePeriodIncome(currentSummary, previousSummary) {
|
|
4001
4119
|
let returnRef;
|
|
4002
4120
|
|
|
4003
4121
|
if (currentSummary) {
|
|
@@ -4758,7 +4876,8 @@ module.exports = (() => {
|
|
|
4758
4876
|
.withField('sequence', DataType.NUMBER, true)
|
|
4759
4877
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
4760
4878
|
.withField('date', DataType.DAY)
|
|
4761
|
-
.withField('
|
|
4879
|
+
.withField('rate', DataType.DECIMAL, true)
|
|
4880
|
+
.withField('value', DataType.DECIMAL, true)
|
|
4762
4881
|
.withField('force', DataType.BOOLEAN, true)
|
|
4763
4882
|
.schema
|
|
4764
4883
|
);
|