@barchart/portfolio-api-common 1.2.91 → 1.2.95
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/data/PositionSummaryFrame.js +42 -10
- package/lib/processing/PositionGroup.js +35 -29
- package/lib/processing/PositionItem.js +9 -4
- package/lib/processing/definitions/PositionTreeDefinition.js +1 -0
- package/lib/serialization/PositionSummaryDefinitionSchema.js +58 -0
- package/lib/serialization/PositionSummarySchema.js +1 -2
- package/package.json +1 -1
- package/test/SpecRunner.js +119 -43
- package/test/specs/data/PositionSummaryFrameSpec.js +32 -0
|
@@ -8,7 +8,7 @@ module.exports = (() => {
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* An enumeration used to define
|
|
11
|
+
* An enumeration used to define time frames for position summaries.
|
|
12
12
|
*
|
|
13
13
|
* @public
|
|
14
14
|
* @extends {Enum}
|
|
@@ -94,22 +94,44 @@ module.exports = (() => {
|
|
|
94
94
|
* @return {Array.<PositionSummaryRange>}
|
|
95
95
|
*/
|
|
96
96
|
getRangesFromDate(date) {
|
|
97
|
+
assert.argumentIsRequired(date, 'date', Day, 'Day');
|
|
98
|
+
|
|
97
99
|
const transaction = { date: date, snapshot: { open: Decimal.ONE } };
|
|
98
100
|
|
|
99
101
|
return this.getRanges([ transaction ]);
|
|
100
102
|
}
|
|
101
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Returns the range immediately prior to the range containing the
|
|
106
|
+
* date supplied.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
* @param {Day} date
|
|
110
|
+
* @param {Number} periods
|
|
111
|
+
*/
|
|
112
|
+
getPriorRanges(date, periods) {
|
|
113
|
+
assert.argumentIsRequired(date, 'date', Day, 'Day');
|
|
114
|
+
assert.argumentIsRequired(periods, 'periods', Number, 'Number');
|
|
115
|
+
|
|
116
|
+
const transactionOne = { date: this.getStartDate((periods - 1), date), snapshot: { open: Decimal.ONE } };
|
|
117
|
+
const transactionTwo = { date: date, snapshot: { open: Decimal.ZERO } };
|
|
118
|
+
|
|
119
|
+
return this._rangeCalculator([ transactionOne, transactionTwo ]);
|
|
120
|
+
}
|
|
121
|
+
|
|
102
122
|
/**
|
|
103
123
|
* Returns the start date for a frame, a given number of periods ago.
|
|
104
124
|
*
|
|
105
125
|
* @public
|
|
106
126
|
* @param {Number} periods
|
|
127
|
+
* @param {Day=} start
|
|
107
128
|
* @returns {Day}
|
|
108
129
|
*/
|
|
109
|
-
getStartDate(periods) {
|
|
130
|
+
getStartDate(periods, start) {
|
|
110
131
|
assert.argumentIsRequired(periods, 'periods', Number);
|
|
132
|
+
assert.argumentIsOptional(start, 'start', Day, 'Day');
|
|
111
133
|
|
|
112
|
-
return this._startDateCalculator(periods);
|
|
134
|
+
return this._startDateCalculator(periods, start);
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
/**
|
|
@@ -171,6 +193,16 @@ module.exports = (() => {
|
|
|
171
193
|
* @property {Day} end
|
|
172
194
|
*/
|
|
173
195
|
|
|
196
|
+
/**
|
|
197
|
+
* The start and and date for a {@link PositionSummaryFrame} along with the frame type.
|
|
198
|
+
*
|
|
199
|
+
* @typedef PositionSummaryDefinition
|
|
200
|
+
* @type {Object}
|
|
201
|
+
* @property {Day} start
|
|
202
|
+
* @property {Day} end
|
|
203
|
+
* @property {PositionSummaryFrame} frame
|
|
204
|
+
*/
|
|
205
|
+
|
|
174
206
|
function getRange(start, end) {
|
|
175
207
|
return {
|
|
176
208
|
start: start,
|
|
@@ -232,29 +264,29 @@ module.exports = (() => {
|
|
|
232
264
|
return ranges;
|
|
233
265
|
}
|
|
234
266
|
|
|
235
|
-
function getYearlyStartDate(periods) {
|
|
236
|
-
const today = Day.getToday();
|
|
267
|
+
function getYearlyStartDate(periods, date) {
|
|
268
|
+
const today = date || Day.getToday();
|
|
237
269
|
|
|
238
|
-
return
|
|
270
|
+
return today
|
|
239
271
|
.subtractMonths(today.month - 1)
|
|
240
272
|
.subtractDays(today.day)
|
|
241
273
|
.subtractYears(periods);
|
|
242
274
|
}
|
|
243
275
|
|
|
244
|
-
function getQuarterlyStartDate(periods) {
|
|
276
|
+
function getQuarterlyStartDate(periods, date) {
|
|
245
277
|
return null;
|
|
246
278
|
}
|
|
247
279
|
|
|
248
|
-
function getMonthlyStartDate(periods) {
|
|
280
|
+
function getMonthlyStartDate(periods, date) {
|
|
249
281
|
return null;
|
|
250
282
|
}
|
|
251
283
|
|
|
252
|
-
function getYearToDateStartDate(periods) {
|
|
284
|
+
function getYearToDateStartDate(periods, date) {
|
|
253
285
|
return null;
|
|
254
286
|
}
|
|
255
287
|
|
|
256
288
|
function getYearlyRangeDescription(start, end) {
|
|
257
|
-
return end.year.toString()
|
|
289
|
+
return `Year ended ${end.year.toString()}`;
|
|
258
290
|
}
|
|
259
291
|
|
|
260
292
|
function getQuarterlyRangeDescription(start, end) {
|
|
@@ -75,12 +75,14 @@ module.exports = (() => {
|
|
|
75
75
|
this._dataFormat.locked = false;
|
|
76
76
|
this._dataFormat.newsExists = false;
|
|
77
77
|
this._dataFormat.quantity = null;
|
|
78
|
+
this._dataFormat.quantityPrevious = null;
|
|
78
79
|
this._dataFormat.basisPrice = null;
|
|
79
80
|
|
|
80
81
|
this._dataActual.key = this._key;
|
|
81
82
|
this._dataActual.description = this._description;
|
|
82
83
|
this._dataActual.newsExists = false;
|
|
83
84
|
this._dataActual.quantity = null;
|
|
85
|
+
this._dataActual.quantityPrevious = null;
|
|
84
86
|
this._dataActual.basisPrice = null;
|
|
85
87
|
|
|
86
88
|
if (this._single && items.length === 1) {
|
|
@@ -130,10 +132,10 @@ module.exports = (() => {
|
|
|
130
132
|
this._dataActual.summaryTotalCurrent = null;
|
|
131
133
|
this._dataActual.summaryTotalPrevious = null;
|
|
132
134
|
this._dataActual.summaryTotalPrevious2 = null;
|
|
133
|
-
this._dataActual.
|
|
134
|
-
this._dataActual.
|
|
135
|
-
this._dataActual.
|
|
136
|
-
this._dataActual.
|
|
135
|
+
this._dataActual.marketPrevious = null;
|
|
136
|
+
this._dataActual.marketPrevious2 = null;
|
|
137
|
+
this._dataActual.marketChange = null;
|
|
138
|
+
this._dataActual.marketChangePercent = null;
|
|
137
139
|
this._dataActual.cashTotal = null;
|
|
138
140
|
|
|
139
141
|
this._dataFormat.currentPrice = null;
|
|
@@ -157,10 +159,10 @@ module.exports = (() => {
|
|
|
157
159
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
158
160
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
159
161
|
this._dataFormat.summaryTotalPrevious2Negative = false;
|
|
160
|
-
this._dataFormat.
|
|
161
|
-
this._dataFormat.
|
|
162
|
-
this._dataFormat.
|
|
163
|
-
this._dataFormat.
|
|
162
|
+
this._dataFormat.marketPrevious = null;
|
|
163
|
+
this._dataFormat.marketPrevious2 = null;
|
|
164
|
+
this._dataFormat.marketChange = null;
|
|
165
|
+
this._dataFormat.marketChangePercent = null;
|
|
164
166
|
this._dataFormat.cashTotal = null;
|
|
165
167
|
this._dataFormat.portfolioType = null;
|
|
166
168
|
|
|
@@ -657,8 +659,8 @@ module.exports = (() => {
|
|
|
657
659
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
|
|
658
660
|
updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
|
|
659
661
|
updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
|
|
660
|
-
updates.
|
|
661
|
-
updates.
|
|
662
|
+
updates.marketPrevious = updates.marketPrevious.add(translate(item, item.data.marketPrevious));
|
|
663
|
+
updates.marketPrevious2 = updates.marketPrevious2.add(translate(item, item.data.marketPrevious2));
|
|
662
664
|
|
|
663
665
|
if (item.position.instrument.type === InstrumentType.CASH) {
|
|
664
666
|
updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
|
|
@@ -673,8 +675,8 @@ module.exports = (() => {
|
|
|
673
675
|
summaryTotalCurrent: Decimal.ZERO,
|
|
674
676
|
summaryTotalPrevious: Decimal.ZERO,
|
|
675
677
|
summaryTotalPrevious2: Decimal.ZERO,
|
|
676
|
-
|
|
677
|
-
|
|
678
|
+
marketPrevious: Decimal.ZERO,
|
|
679
|
+
marketPrevious2: Decimal.ZERO,
|
|
678
680
|
cashTotal: Decimal.ZERO
|
|
679
681
|
});
|
|
680
682
|
|
|
@@ -685,8 +687,8 @@ module.exports = (() => {
|
|
|
685
687
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
686
688
|
actual.summaryTotalPrevious = updates.summaryTotalPrevious;
|
|
687
689
|
actual.summaryTotalPrevious2 = updates.summaryTotalPrevious2;
|
|
688
|
-
actual.
|
|
689
|
-
actual.
|
|
690
|
+
actual.marketPrevious = updates.marketPrevious;
|
|
691
|
+
actual.marketPrevious2 = updates.marketPrevious2;
|
|
690
692
|
actual.cashTotal = updates.cashTotal;
|
|
691
693
|
|
|
692
694
|
format.basis = formatCurrency(actual.basis, currency);
|
|
@@ -698,8 +700,8 @@ module.exports = (() => {
|
|
|
698
700
|
format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
|
|
699
701
|
format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
|
|
700
702
|
format.summaryTotalPrevious2Negative = updates.summaryTotalPrevious2.getIsNegative();
|
|
701
|
-
format.
|
|
702
|
-
format.
|
|
703
|
+
format.marketPrevious = formatCurrency(updates.marketPrevious, currency);
|
|
704
|
+
format.marketPrevious2 = formatCurrency(updates.marketPrevious2, currency);
|
|
703
705
|
format.cashTotal = formatCurrency(updates.cashTotal, currency);
|
|
704
706
|
|
|
705
707
|
calculateUnrealizedPercent(group);
|
|
@@ -708,9 +710,13 @@ module.exports = (() => {
|
|
|
708
710
|
const item = group._items[0];
|
|
709
711
|
|
|
710
712
|
actual.quantity = item.position.snapshot.open;
|
|
713
|
+
actual.quantityPrevious = item.data.quantityPrevious;
|
|
714
|
+
|
|
711
715
|
actual.basisPrice = item.data.basisPrice;
|
|
712
716
|
|
|
713
717
|
format.quantity = formatDecimal(actual.quantity, 2);
|
|
718
|
+
format.quantityPrevious = formatDecimal(actual.quantityPrevious, 2);
|
|
719
|
+
|
|
714
720
|
format.basisPrice = formatCurrency(actual.basisPrice, currency);
|
|
715
721
|
|
|
716
722
|
format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
|
|
@@ -797,23 +803,23 @@ module.exports = (() => {
|
|
|
797
803
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
798
804
|
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
799
805
|
|
|
800
|
-
let
|
|
801
|
-
let
|
|
806
|
+
let marketChange = updates.market.subtract(actual.marketPrevious);
|
|
807
|
+
let marketChangePercent;
|
|
802
808
|
|
|
803
|
-
if (actual.
|
|
804
|
-
if (
|
|
805
|
-
|
|
806
|
-
} else if (
|
|
807
|
-
|
|
809
|
+
if (actual.marketPrevious.getIsZero()) {
|
|
810
|
+
if (marketChange.getIsPositive()) {
|
|
811
|
+
marketChangePercent = Decimal.ONE;
|
|
812
|
+
} else if (marketChange.getIsNegative()) {
|
|
813
|
+
marketChangePercent = Decimal.NEGATIVE_ONE;
|
|
808
814
|
} else {
|
|
809
|
-
|
|
815
|
+
marketChangePercent = Decimal.ZERO;
|
|
810
816
|
}
|
|
811
817
|
} else {
|
|
812
|
-
|
|
818
|
+
marketChangePercent = marketChange.divide(actual.marketPrevious);
|
|
813
819
|
}
|
|
814
820
|
|
|
815
|
-
actual.
|
|
816
|
-
actual.
|
|
821
|
+
actual.marketChange = marketChange;
|
|
822
|
+
actual.marketChangePercent = marketChangePercent;
|
|
817
823
|
|
|
818
824
|
format.market = formatCurrency(actual.market, currency);
|
|
819
825
|
|
|
@@ -834,8 +840,8 @@ module.exports = (() => {
|
|
|
834
840
|
format.total = formatCurrency(actual.total, currency);
|
|
835
841
|
format.totalNegative = actual.total.getIsNegative();
|
|
836
842
|
|
|
837
|
-
format.
|
|
838
|
-
format.
|
|
843
|
+
format.marketChange = formatCurrency(actual.marketChange, currency);
|
|
844
|
+
format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
|
|
839
845
|
|
|
840
846
|
calculateUnrealizedPercent(group);
|
|
841
847
|
}
|
|
@@ -65,9 +65,12 @@ module.exports = (() => {
|
|
|
65
65
|
this._data.summaryTotalPrevious = null;
|
|
66
66
|
this._data.summaryTotalPrevious2 = null;
|
|
67
67
|
|
|
68
|
-
this._data.
|
|
69
|
-
this._data.
|
|
68
|
+
this._data.marketPrevious = null;
|
|
69
|
+
this._data.marketPrevious2 = null;
|
|
70
70
|
|
|
71
|
+
this._data.quantityPrevious = null;
|
|
72
|
+
this._data.quantityPrevious2 = null;
|
|
73
|
+
|
|
71
74
|
this._data.realized = null;
|
|
72
75
|
this._data.income = null;
|
|
73
76
|
this._data.basisPrice = null;
|
|
@@ -391,8 +394,10 @@ module.exports = (() => {
|
|
|
391
394
|
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
392
395
|
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
393
396
|
|
|
394
|
-
data.
|
|
395
|
-
data.
|
|
397
|
+
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
398
|
+
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
399
|
+
|
|
400
|
+
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
396
401
|
|
|
397
402
|
if (snapshot.open.getIsZero()) {
|
|
398
403
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -11,6 +11,7 @@ module.exports = (() => {
|
|
|
11
11
|
* @public
|
|
12
12
|
* @param {String} name
|
|
13
13
|
* @param {Array.<PositionLevelDefinition>} definitions
|
|
14
|
+
* @oaram {Array.<String>=} exclusionDependencies
|
|
14
15
|
*/
|
|
15
16
|
class PositionTreeDefinitions {
|
|
16
17
|
constructor(name, definitions, exclusionDependencies) {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const DataType = require('@barchart/common-js/serialization/json/DataType'),
|
|
2
|
+
Enum = require('@barchart/common-js/lang/Enum'),
|
|
3
|
+
Schema = require('@barchart/common-js/serialization/json/Schema'),
|
|
4
|
+
SchemaBuilder = require('@barchart/common-js/serialization/json/builders/SchemaBuilder');
|
|
5
|
+
|
|
6
|
+
const PositionSummaryFrame = require('./../data/PositionSummaryFrame');
|
|
7
|
+
|
|
8
|
+
module.exports = (() => {
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The schemas which can be used to represent position summary objects.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
* @extends {Enum}
|
|
16
|
+
*/
|
|
17
|
+
class PositionSummaryDefinitionSchema extends Enum {
|
|
18
|
+
constructor(schema) {
|
|
19
|
+
super(schema.name, schema.name);
|
|
20
|
+
|
|
21
|
+
this._schema = schema;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The actual {@link Schema}.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
* @returns {Schema}
|
|
29
|
+
*/
|
|
30
|
+
get schema() {
|
|
31
|
+
return this._schema;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The complete position summary definition schema.
|
|
36
|
+
*
|
|
37
|
+
* @static
|
|
38
|
+
* @public
|
|
39
|
+
* @returns {PositionSummaryDefinitionSchema}
|
|
40
|
+
*/
|
|
41
|
+
static get COMPLETE() {
|
|
42
|
+
return complete;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toString() {
|
|
46
|
+
return '[PositionSummaryDefinitionSchema]';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const complete = new PositionSummaryDefinitionSchema(SchemaBuilder.withName('complete')
|
|
51
|
+
.withField('start', DataType.DAY)
|
|
52
|
+
.withField('end', DataType.DAY)
|
|
53
|
+
.withField('frame', DataType.forEnum(PositionSummaryFrame, 'PositionSummaryFrame'))
|
|
54
|
+
.schema
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return PositionSummaryDefinitionSchema;
|
|
58
|
+
})();
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
DataType = require('@barchart/common-js/serialization/json/DataType'),
|
|
1
|
+
const DataType = require('@barchart/common-js/serialization/json/DataType'),
|
|
3
2
|
Enum = require('@barchart/common-js/lang/Enum'),
|
|
4
3
|
Schema = require('@barchart/common-js/serialization/json/Schema'),
|
|
5
4
|
SchemaBuilder = require('@barchart/common-js/serialization/json/builders/SchemaBuilder');
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -399,7 +399,7 @@ module.exports = (() => {
|
|
|
399
399
|
'use strict';
|
|
400
400
|
|
|
401
401
|
/**
|
|
402
|
-
* An enumeration used to define
|
|
402
|
+
* An enumeration used to define time frames for position summaries.
|
|
403
403
|
*
|
|
404
404
|
* @public
|
|
405
405
|
* @extends {Enum}
|
|
@@ -485,22 +485,44 @@ module.exports = (() => {
|
|
|
485
485
|
* @return {Array.<PositionSummaryRange>}
|
|
486
486
|
*/
|
|
487
487
|
getRangesFromDate(date) {
|
|
488
|
+
assert.argumentIsRequired(date, 'date', Day, 'Day');
|
|
489
|
+
|
|
488
490
|
const transaction = { date: date, snapshot: { open: Decimal.ONE } };
|
|
489
491
|
|
|
490
492
|
return this.getRanges([ transaction ]);
|
|
491
493
|
}
|
|
492
494
|
|
|
495
|
+
/**
|
|
496
|
+
* Returns the range immediately prior to the range containing the
|
|
497
|
+
* date supplied.
|
|
498
|
+
*
|
|
499
|
+
* @public
|
|
500
|
+
* @param {Day} date
|
|
501
|
+
* @param {Number} periods
|
|
502
|
+
*/
|
|
503
|
+
getPriorRanges(date, periods) {
|
|
504
|
+
assert.argumentIsRequired(date, 'date', Day, 'Day');
|
|
505
|
+
assert.argumentIsRequired(periods, 'periods', Number, 'Number');
|
|
506
|
+
|
|
507
|
+
const transactionOne = { date: this.getStartDate((periods - 1), date), snapshot: { open: Decimal.ONE } };
|
|
508
|
+
const transactionTwo = { date: date, snapshot: { open: Decimal.ZERO } };
|
|
509
|
+
|
|
510
|
+
return this._rangeCalculator([ transactionOne, transactionTwo ]);
|
|
511
|
+
}
|
|
512
|
+
|
|
493
513
|
/**
|
|
494
514
|
* Returns the start date for a frame, a given number of periods ago.
|
|
495
515
|
*
|
|
496
516
|
* @public
|
|
497
517
|
* @param {Number} periods
|
|
518
|
+
* @param {Day=} start
|
|
498
519
|
* @returns {Day}
|
|
499
520
|
*/
|
|
500
|
-
getStartDate(periods) {
|
|
521
|
+
getStartDate(periods, start) {
|
|
501
522
|
assert.argumentIsRequired(periods, 'periods', Number);
|
|
523
|
+
assert.argumentIsOptional(start, 'start', Day, 'Day');
|
|
502
524
|
|
|
503
|
-
return this._startDateCalculator(periods);
|
|
525
|
+
return this._startDateCalculator(periods, start);
|
|
504
526
|
}
|
|
505
527
|
|
|
506
528
|
/**
|
|
@@ -562,6 +584,16 @@ module.exports = (() => {
|
|
|
562
584
|
* @property {Day} end
|
|
563
585
|
*/
|
|
564
586
|
|
|
587
|
+
/**
|
|
588
|
+
* The start and and date for a {@link PositionSummaryFrame} along with the frame type.
|
|
589
|
+
*
|
|
590
|
+
* @typedef PositionSummaryDefinition
|
|
591
|
+
* @type {Object}
|
|
592
|
+
* @property {Day} start
|
|
593
|
+
* @property {Day} end
|
|
594
|
+
* @property {PositionSummaryFrame} frame
|
|
595
|
+
*/
|
|
596
|
+
|
|
565
597
|
function getRange(start, end) {
|
|
566
598
|
return {
|
|
567
599
|
start: start,
|
|
@@ -623,29 +655,29 @@ module.exports = (() => {
|
|
|
623
655
|
return ranges;
|
|
624
656
|
}
|
|
625
657
|
|
|
626
|
-
function getYearlyStartDate(periods) {
|
|
627
|
-
const today = Day.getToday();
|
|
658
|
+
function getYearlyStartDate(periods, date) {
|
|
659
|
+
const today = date || Day.getToday();
|
|
628
660
|
|
|
629
|
-
return
|
|
661
|
+
return today
|
|
630
662
|
.subtractMonths(today.month - 1)
|
|
631
663
|
.subtractDays(today.day)
|
|
632
664
|
.subtractYears(periods);
|
|
633
665
|
}
|
|
634
666
|
|
|
635
|
-
function getQuarterlyStartDate(periods) {
|
|
667
|
+
function getQuarterlyStartDate(periods, date) {
|
|
636
668
|
return null;
|
|
637
669
|
}
|
|
638
670
|
|
|
639
|
-
function getMonthlyStartDate(periods) {
|
|
671
|
+
function getMonthlyStartDate(periods, date) {
|
|
640
672
|
return null;
|
|
641
673
|
}
|
|
642
674
|
|
|
643
|
-
function getYearToDateStartDate(periods) {
|
|
675
|
+
function getYearToDateStartDate(periods, date) {
|
|
644
676
|
return null;
|
|
645
677
|
}
|
|
646
678
|
|
|
647
679
|
function getYearlyRangeDescription(start, end) {
|
|
648
|
-
return end.year.toString()
|
|
680
|
+
return `Year ended ${end.year.toString()}`;
|
|
649
681
|
}
|
|
650
682
|
|
|
651
683
|
function getQuarterlyRangeDescription(start, end) {
|
|
@@ -2473,12 +2505,14 @@ module.exports = (() => {
|
|
|
2473
2505
|
this._dataFormat.locked = false;
|
|
2474
2506
|
this._dataFormat.newsExists = false;
|
|
2475
2507
|
this._dataFormat.quantity = null;
|
|
2508
|
+
this._dataFormat.quantityPrevious = null;
|
|
2476
2509
|
this._dataFormat.basisPrice = null;
|
|
2477
2510
|
|
|
2478
2511
|
this._dataActual.key = this._key;
|
|
2479
2512
|
this._dataActual.description = this._description;
|
|
2480
2513
|
this._dataActual.newsExists = false;
|
|
2481
2514
|
this._dataActual.quantity = null;
|
|
2515
|
+
this._dataActual.quantityPrevious = null;
|
|
2482
2516
|
this._dataActual.basisPrice = null;
|
|
2483
2517
|
|
|
2484
2518
|
if (this._single && items.length === 1) {
|
|
@@ -2528,10 +2562,10 @@ module.exports = (() => {
|
|
|
2528
2562
|
this._dataActual.summaryTotalCurrent = null;
|
|
2529
2563
|
this._dataActual.summaryTotalPrevious = null;
|
|
2530
2564
|
this._dataActual.summaryTotalPrevious2 = null;
|
|
2531
|
-
this._dataActual.
|
|
2532
|
-
this._dataActual.
|
|
2533
|
-
this._dataActual.
|
|
2534
|
-
this._dataActual.
|
|
2565
|
+
this._dataActual.marketPrevious = null;
|
|
2566
|
+
this._dataActual.marketPrevious2 = null;
|
|
2567
|
+
this._dataActual.marketChange = null;
|
|
2568
|
+
this._dataActual.marketChangePercent = null;
|
|
2535
2569
|
this._dataActual.cashTotal = null;
|
|
2536
2570
|
|
|
2537
2571
|
this._dataFormat.currentPrice = null;
|
|
@@ -2555,10 +2589,10 @@ module.exports = (() => {
|
|
|
2555
2589
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
2556
2590
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
2557
2591
|
this._dataFormat.summaryTotalPrevious2Negative = false;
|
|
2558
|
-
this._dataFormat.
|
|
2559
|
-
this._dataFormat.
|
|
2560
|
-
this._dataFormat.
|
|
2561
|
-
this._dataFormat.
|
|
2592
|
+
this._dataFormat.marketPrevious = null;
|
|
2593
|
+
this._dataFormat.marketPrevious2 = null;
|
|
2594
|
+
this._dataFormat.marketChange = null;
|
|
2595
|
+
this._dataFormat.marketChangePercent = null;
|
|
2562
2596
|
this._dataFormat.cashTotal = null;
|
|
2563
2597
|
this._dataFormat.portfolioType = null;
|
|
2564
2598
|
|
|
@@ -3055,8 +3089,8 @@ module.exports = (() => {
|
|
|
3055
3089
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
|
|
3056
3090
|
updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
|
|
3057
3091
|
updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
|
|
3058
|
-
updates.
|
|
3059
|
-
updates.
|
|
3092
|
+
updates.marketPrevious = updates.marketPrevious.add(translate(item, item.data.marketPrevious));
|
|
3093
|
+
updates.marketPrevious2 = updates.marketPrevious2.add(translate(item, item.data.marketPrevious2));
|
|
3060
3094
|
|
|
3061
3095
|
if (item.position.instrument.type === InstrumentType.CASH) {
|
|
3062
3096
|
updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
|
|
@@ -3071,8 +3105,8 @@ module.exports = (() => {
|
|
|
3071
3105
|
summaryTotalCurrent: Decimal.ZERO,
|
|
3072
3106
|
summaryTotalPrevious: Decimal.ZERO,
|
|
3073
3107
|
summaryTotalPrevious2: Decimal.ZERO,
|
|
3074
|
-
|
|
3075
|
-
|
|
3108
|
+
marketPrevious: Decimal.ZERO,
|
|
3109
|
+
marketPrevious2: Decimal.ZERO,
|
|
3076
3110
|
cashTotal: Decimal.ZERO
|
|
3077
3111
|
});
|
|
3078
3112
|
|
|
@@ -3083,8 +3117,8 @@ module.exports = (() => {
|
|
|
3083
3117
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3084
3118
|
actual.summaryTotalPrevious = updates.summaryTotalPrevious;
|
|
3085
3119
|
actual.summaryTotalPrevious2 = updates.summaryTotalPrevious2;
|
|
3086
|
-
actual.
|
|
3087
|
-
actual.
|
|
3120
|
+
actual.marketPrevious = updates.marketPrevious;
|
|
3121
|
+
actual.marketPrevious2 = updates.marketPrevious2;
|
|
3088
3122
|
actual.cashTotal = updates.cashTotal;
|
|
3089
3123
|
|
|
3090
3124
|
format.basis = formatCurrency(actual.basis, currency);
|
|
@@ -3096,8 +3130,8 @@ module.exports = (() => {
|
|
|
3096
3130
|
format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
|
|
3097
3131
|
format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
|
|
3098
3132
|
format.summaryTotalPrevious2Negative = updates.summaryTotalPrevious2.getIsNegative();
|
|
3099
|
-
format.
|
|
3100
|
-
format.
|
|
3133
|
+
format.marketPrevious = formatCurrency(updates.marketPrevious, currency);
|
|
3134
|
+
format.marketPrevious2 = formatCurrency(updates.marketPrevious2, currency);
|
|
3101
3135
|
format.cashTotal = formatCurrency(updates.cashTotal, currency);
|
|
3102
3136
|
|
|
3103
3137
|
calculateUnrealizedPercent(group);
|
|
@@ -3106,9 +3140,13 @@ module.exports = (() => {
|
|
|
3106
3140
|
const item = group._items[0];
|
|
3107
3141
|
|
|
3108
3142
|
actual.quantity = item.position.snapshot.open;
|
|
3143
|
+
actual.quantityPrevious = item.data.quantityPrevious;
|
|
3144
|
+
|
|
3109
3145
|
actual.basisPrice = item.data.basisPrice;
|
|
3110
3146
|
|
|
3111
3147
|
format.quantity = formatDecimal(actual.quantity, 2);
|
|
3148
|
+
format.quantityPrevious = formatDecimal(actual.quantityPrevious, 2);
|
|
3149
|
+
|
|
3112
3150
|
format.basisPrice = formatCurrency(actual.basisPrice, currency);
|
|
3113
3151
|
|
|
3114
3152
|
format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
|
|
@@ -3195,23 +3233,23 @@ module.exports = (() => {
|
|
|
3195
3233
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3196
3234
|
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
3197
3235
|
|
|
3198
|
-
let
|
|
3199
|
-
let
|
|
3236
|
+
let marketChange = updates.market.subtract(actual.marketPrevious);
|
|
3237
|
+
let marketChangePercent;
|
|
3200
3238
|
|
|
3201
|
-
if (actual.
|
|
3202
|
-
if (
|
|
3203
|
-
|
|
3204
|
-
} else if (
|
|
3205
|
-
|
|
3239
|
+
if (actual.marketPrevious.getIsZero()) {
|
|
3240
|
+
if (marketChange.getIsPositive()) {
|
|
3241
|
+
marketChangePercent = Decimal.ONE;
|
|
3242
|
+
} else if (marketChange.getIsNegative()) {
|
|
3243
|
+
marketChangePercent = Decimal.NEGATIVE_ONE;
|
|
3206
3244
|
} else {
|
|
3207
|
-
|
|
3245
|
+
marketChangePercent = Decimal.ZERO;
|
|
3208
3246
|
}
|
|
3209
3247
|
} else {
|
|
3210
|
-
|
|
3248
|
+
marketChangePercent = marketChange.divide(actual.marketPrevious);
|
|
3211
3249
|
}
|
|
3212
3250
|
|
|
3213
|
-
actual.
|
|
3214
|
-
actual.
|
|
3251
|
+
actual.marketChange = marketChange;
|
|
3252
|
+
actual.marketChangePercent = marketChangePercent;
|
|
3215
3253
|
|
|
3216
3254
|
format.market = formatCurrency(actual.market, currency);
|
|
3217
3255
|
|
|
@@ -3232,8 +3270,8 @@ module.exports = (() => {
|
|
|
3232
3270
|
format.total = formatCurrency(actual.total, currency);
|
|
3233
3271
|
format.totalNegative = actual.total.getIsNegative();
|
|
3234
3272
|
|
|
3235
|
-
format.
|
|
3236
|
-
format.
|
|
3273
|
+
format.marketChange = formatCurrency(actual.marketChange, currency);
|
|
3274
|
+
format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
|
|
3237
3275
|
|
|
3238
3276
|
calculateUnrealizedPercent(group);
|
|
3239
3277
|
}
|
|
@@ -3367,9 +3405,12 @@ module.exports = (() => {
|
|
|
3367
3405
|
this._data.summaryTotalPrevious = null;
|
|
3368
3406
|
this._data.summaryTotalPrevious2 = null;
|
|
3369
3407
|
|
|
3370
|
-
this._data.
|
|
3371
|
-
this._data.
|
|
3408
|
+
this._data.marketPrevious = null;
|
|
3409
|
+
this._data.marketPrevious2 = null;
|
|
3372
3410
|
|
|
3411
|
+
this._data.quantityPrevious = null;
|
|
3412
|
+
this._data.quantityPrevious2 = null;
|
|
3413
|
+
|
|
3373
3414
|
this._data.realized = null;
|
|
3374
3415
|
this._data.income = null;
|
|
3375
3416
|
this._data.basisPrice = null;
|
|
@@ -3693,8 +3734,10 @@ module.exports = (() => {
|
|
|
3693
3734
|
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
3694
3735
|
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
3695
3736
|
|
|
3696
|
-
data.
|
|
3697
|
-
data.
|
|
3737
|
+
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
3738
|
+
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
3739
|
+
|
|
3740
|
+
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
3698
3741
|
|
|
3699
3742
|
if (snapshot.open.getIsZero()) {
|
|
3700
3743
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -4184,6 +4227,7 @@ module.exports = (() => {
|
|
|
4184
4227
|
* @public
|
|
4185
4228
|
* @param {String} name
|
|
4186
4229
|
* @param {Array.<PositionLevelDefinition>} definitions
|
|
4230
|
+
* @oaram {Array.<String>=} exclusionDependencies
|
|
4187
4231
|
*/
|
|
4188
4232
|
class PositionTreeDefinitions {
|
|
4189
4233
|
constructor(name, definitions, exclusionDependencies) {
|
|
@@ -17622,6 +17666,38 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17622
17666
|
});
|
|
17623
17667
|
});
|
|
17624
17668
|
});
|
|
17669
|
+
|
|
17670
|
+
describe('and prior ranges are calculated', () => {
|
|
17671
|
+
describe('for YEARLY ranges', () => {
|
|
17672
|
+
describe('from 2017-10-10, including one previous ranges', () => {
|
|
17673
|
+
let ranges;
|
|
17674
|
+
|
|
17675
|
+
beforeEach(() => {
|
|
17676
|
+
ranges = PositionSummaryFrame.YEARLY.getPriorRanges(new Day(2015, 4, 20), 1);
|
|
17677
|
+
});
|
|
17678
|
+
|
|
17679
|
+
it('should return two ranges', () => {
|
|
17680
|
+
expect(ranges.length).toEqual(2);
|
|
17681
|
+
});
|
|
17682
|
+
|
|
17683
|
+
it('the first range should begin on 2013-12-31', () => {
|
|
17684
|
+
expect(ranges[0].start.getIsEqual(new Day(2013, 12, 31))).toEqual(true);
|
|
17685
|
+
});
|
|
17686
|
+
|
|
17687
|
+
it('the first range should end on 2014-12-31', () => {
|
|
17688
|
+
expect(ranges[0].end.getIsEqual(new Day(2014, 12, 31))).toEqual(true);
|
|
17689
|
+
});
|
|
17690
|
+
|
|
17691
|
+
it('the second range should begin on 2014-12-31', () => {
|
|
17692
|
+
expect(ranges[1].start.getIsEqual(new Day(2014, 12, 31))).toEqual(true);
|
|
17693
|
+
});
|
|
17694
|
+
|
|
17695
|
+
it('the second range should end on 2015-12-31', () => {
|
|
17696
|
+
expect(ranges[1].end.getIsEqual(new Day(2015, 12, 31))).toEqual(true);
|
|
17697
|
+
});
|
|
17698
|
+
});
|
|
17699
|
+
});
|
|
17700
|
+
});
|
|
17625
17701
|
});
|
|
17626
17702
|
|
|
17627
17703
|
},{"./../../../lib/data/PositionSummaryFrame":3,"./../../../lib/data/TransactionType":4,"@barchart/common-js/lang/Day":21,"@barchart/common-js/lang/Decimal":22}],53:[function(require,module,exports){
|
|
@@ -422,4 +422,36 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
422
422
|
});
|
|
423
423
|
});
|
|
424
424
|
});
|
|
425
|
+
|
|
426
|
+
describe('and prior ranges are calculated', () => {
|
|
427
|
+
describe('for YEARLY ranges', () => {
|
|
428
|
+
describe('from 2017-10-10, including one previous ranges', () => {
|
|
429
|
+
let ranges;
|
|
430
|
+
|
|
431
|
+
beforeEach(() => {
|
|
432
|
+
ranges = PositionSummaryFrame.YEARLY.getPriorRanges(new Day(2015, 4, 20), 1);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('should return two ranges', () => {
|
|
436
|
+
expect(ranges.length).toEqual(2);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
it('the first range should begin on 2013-12-31', () => {
|
|
440
|
+
expect(ranges[0].start.getIsEqual(new Day(2013, 12, 31))).toEqual(true);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('the first range should end on 2014-12-31', () => {
|
|
444
|
+
expect(ranges[0].end.getIsEqual(new Day(2014, 12, 31))).toEqual(true);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it('the second range should begin on 2014-12-31', () => {
|
|
448
|
+
expect(ranges[1].start.getIsEqual(new Day(2014, 12, 31))).toEqual(true);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
it('the second range should end on 2015-12-31', () => {
|
|
452
|
+
expect(ranges[1].end.getIsEqual(new Day(2015, 12, 31))).toEqual(true);
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
});
|
|
425
457
|
});
|