@barchart/portfolio-api-common 1.2.92 → 1.2.96
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 +32 -10
- package/lib/processing/PositionContainer.js +8 -6
- package/lib/processing/PositionGroup.js +35 -29
- package/lib/processing/PositionItem.js +37 -7
- package/lib/processing/definitions/PositionTreeDefinition.js +1 -0
- package/package.json +1 -1
- package/test/SpecRunner.js +145 -52
- 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
|
/**
|
|
@@ -242,29 +264,29 @@ module.exports = (() => {
|
|
|
242
264
|
return ranges;
|
|
243
265
|
}
|
|
244
266
|
|
|
245
|
-
function getYearlyStartDate(periods) {
|
|
246
|
-
const today = Day.getToday();
|
|
267
|
+
function getYearlyStartDate(periods, date) {
|
|
268
|
+
const today = date || Day.getToday();
|
|
247
269
|
|
|
248
|
-
return
|
|
270
|
+
return today
|
|
249
271
|
.subtractMonths(today.month - 1)
|
|
250
272
|
.subtractDays(today.day)
|
|
251
273
|
.subtractYears(periods);
|
|
252
274
|
}
|
|
253
275
|
|
|
254
|
-
function getQuarterlyStartDate(periods) {
|
|
276
|
+
function getQuarterlyStartDate(periods, date) {
|
|
255
277
|
return null;
|
|
256
278
|
}
|
|
257
279
|
|
|
258
|
-
function getMonthlyStartDate(periods) {
|
|
280
|
+
function getMonthlyStartDate(periods, date) {
|
|
259
281
|
return null;
|
|
260
282
|
}
|
|
261
283
|
|
|
262
|
-
function getYearToDateStartDate(periods) {
|
|
284
|
+
function getYearToDateStartDate(periods, date) {
|
|
263
285
|
return null;
|
|
264
286
|
}
|
|
265
287
|
|
|
266
288
|
function getYearlyRangeDescription(start, end) {
|
|
267
|
-
return end.year.toString()
|
|
289
|
+
return `Year ended ${end.year.toString()}`;
|
|
268
290
|
}
|
|
269
291
|
|
|
270
292
|
function getQuarterlyRangeDescription(start, end) {
|
|
@@ -42,20 +42,22 @@ module.exports = (() => {
|
|
|
42
42
|
* @param {Array.<Object>} portfolios - The portfolios.
|
|
43
43
|
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
44
44
|
* @param {Array.<Object>} summaries - The positions summaries (for all of the positions).
|
|
45
|
-
* @param {PositionSummaryFrame=} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
45
|
+
* @param {PositionSummaryFrame=} reportFrame - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
46
46
|
*/
|
|
47
47
|
class PositionContainer {
|
|
48
|
-
constructor(definitions, portfolios, positions, summaries,
|
|
48
|
+
constructor(definitions, portfolios, positions, summaries, reportFrame) {
|
|
49
49
|
assert.argumentIsArray(definitions, 'definitions', PositionTreeDefinition, 'PositionTreeDefinition');
|
|
50
50
|
assert.argumentIsArray(portfolios, 'portfolios');
|
|
51
51
|
assert.argumentIsArray(positions, 'positions');
|
|
52
52
|
assert.argumentIsArray(summaries, 'summaries');
|
|
53
|
-
assert.argumentIsOptional(
|
|
53
|
+
assert.argumentIsOptional(reportFrame, 'reportFrame', PositionSummaryFrame, 'PositionSummaryFrame');
|
|
54
54
|
|
|
55
55
|
this._definitions = definitions;
|
|
56
56
|
|
|
57
57
|
this._groupBindings = { };
|
|
58
58
|
|
|
59
|
+
this._reporting = reportFrame instanceof PositionSummaryFrame;
|
|
60
|
+
|
|
59
61
|
this._positionSymbolAddedEvent = new Event(this);
|
|
60
62
|
this._positionSymbolRemovedEvent = new Event(this);
|
|
61
63
|
|
|
@@ -65,10 +67,10 @@ module.exports = (() => {
|
|
|
65
67
|
return map;
|
|
66
68
|
}, { });
|
|
67
69
|
|
|
68
|
-
this._currentSummaryFrame =
|
|
70
|
+
this._currentSummaryFrame = reportFrame || PositionSummaryFrame.YTD;
|
|
69
71
|
this._currentSummaryRange = array.last(this._currentSummaryFrame.getRecentRanges(0));
|
|
70
72
|
|
|
71
|
-
this._previousSummaryFrame =
|
|
73
|
+
this._previousSummaryFrame = reportFrame || PositionSummaryFrame.YEARLY;
|
|
72
74
|
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(3);
|
|
73
75
|
|
|
74
76
|
if (this._currentSummaryFrame === this._previousSummaryFrame) {
|
|
@@ -942,7 +944,7 @@ module.exports = (() => {
|
|
|
942
944
|
const currentSummary = this._summariesCurrent[ position.position ] || null;
|
|
943
945
|
const previousSummaries = this._summariesPrevious[ position.position ] || getSummaryArray(this._previousSummaryRanges);
|
|
944
946
|
|
|
945
|
-
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries);
|
|
947
|
+
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries, this._reporting);
|
|
946
948
|
} else {
|
|
947
949
|
returnRef = null;
|
|
948
950
|
}
|
|
@@ -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
|
}
|
|
@@ -20,9 +20,10 @@ module.exports = (() => {
|
|
|
20
20
|
* @param {Object} position
|
|
21
21
|
* @param {Object} currentSummary
|
|
22
22
|
* @param {Array.<Object>} previousSummaries
|
|
23
|
+
* @param {Boolean} reporting
|
|
23
24
|
*/
|
|
24
25
|
class PositionItem extends Disposable {
|
|
25
|
-
constructor(portfolio, position, currentSummary, previousSummaries) {
|
|
26
|
+
constructor(portfolio, position, currentSummary, previousSummaries, reporting) {
|
|
26
27
|
super();
|
|
27
28
|
|
|
28
29
|
this._portfolio = portfolio;
|
|
@@ -36,6 +37,8 @@ module.exports = (() => {
|
|
|
36
37
|
this._currentSummary = currentSummary || null;
|
|
37
38
|
this._previousSummaries = previousSummaries || [ ];
|
|
38
39
|
|
|
40
|
+
this._reporting = reporting;
|
|
41
|
+
|
|
39
42
|
this._data = { };
|
|
40
43
|
|
|
41
44
|
this._data.basis = null;
|
|
@@ -65,9 +68,12 @@ module.exports = (() => {
|
|
|
65
68
|
this._data.summaryTotalPrevious = null;
|
|
66
69
|
this._data.summaryTotalPrevious2 = null;
|
|
67
70
|
|
|
68
|
-
this._data.
|
|
69
|
-
this._data.
|
|
71
|
+
this._data.marketPrevious = null;
|
|
72
|
+
this._data.marketPrevious2 = null;
|
|
70
73
|
|
|
74
|
+
this._data.quantityPrevious = null;
|
|
75
|
+
this._data.quantityPrevious2 = null;
|
|
76
|
+
|
|
71
77
|
this._data.realized = null;
|
|
72
78
|
this._data.income = null;
|
|
73
79
|
this._data.basisPrice = null;
|
|
@@ -361,7 +367,7 @@ module.exports = (() => {
|
|
|
361
367
|
|
|
362
368
|
function calculateStaticData(item) {
|
|
363
369
|
const position = item.position;
|
|
364
|
-
const snapshot = item.
|
|
370
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
365
371
|
const previousSummaries = item.previousSummaries;
|
|
366
372
|
|
|
367
373
|
const data = item._data;
|
|
@@ -391,8 +397,10 @@ module.exports = (() => {
|
|
|
391
397
|
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
392
398
|
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
393
399
|
|
|
394
|
-
data.
|
|
395
|
-
data.
|
|
400
|
+
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
401
|
+
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
402
|
+
|
|
403
|
+
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
396
404
|
|
|
397
405
|
if (snapshot.open.getIsZero()) {
|
|
398
406
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -403,7 +411,7 @@ module.exports = (() => {
|
|
|
403
411
|
|
|
404
412
|
function calculatePriceData(item, price) {
|
|
405
413
|
const position = item.position;
|
|
406
|
-
const snapshot = item.
|
|
414
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
407
415
|
const previousSummaries = item.previousSummaries;
|
|
408
416
|
|
|
409
417
|
const data = item._data;
|
|
@@ -555,5 +563,27 @@ module.exports = (() => {
|
|
|
555
563
|
return is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
|
|
556
564
|
}
|
|
557
565
|
|
|
566
|
+
function getSnapshot(position, currentSummary, reporting) {
|
|
567
|
+
let snapshot;
|
|
568
|
+
|
|
569
|
+
if (reporting) {
|
|
570
|
+
snapshot = { };
|
|
571
|
+
|
|
572
|
+
snapshot.date = currentSummary.end.date;
|
|
573
|
+
snapshot.open = currentSummary.end.open;
|
|
574
|
+
snapshot.direction = currentSummary.end.direction;
|
|
575
|
+
snapshot.buys = currentSummary.period.buys;
|
|
576
|
+
snapshot.sells = currentSummary.period.sells;
|
|
577
|
+
snapshot.gain = currentSummary.period.realized;
|
|
578
|
+
snapshot.basis = currentSummary.end.basis;
|
|
579
|
+
snapshot.income = currentSummary.period.income;
|
|
580
|
+
snapshot.value = currentSummary.end.value;
|
|
581
|
+
} else {
|
|
582
|
+
snapshot = position.snapshot;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return snapshot;
|
|
586
|
+
}
|
|
587
|
+
|
|
558
588
|
return PositionItem;
|
|
559
589
|
})();
|
|
@@ -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) {
|
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
|
/**
|
|
@@ -633,29 +655,29 @@ module.exports = (() => {
|
|
|
633
655
|
return ranges;
|
|
634
656
|
}
|
|
635
657
|
|
|
636
|
-
function getYearlyStartDate(periods) {
|
|
637
|
-
const today = Day.getToday();
|
|
658
|
+
function getYearlyStartDate(periods, date) {
|
|
659
|
+
const today = date || Day.getToday();
|
|
638
660
|
|
|
639
|
-
return
|
|
661
|
+
return today
|
|
640
662
|
.subtractMonths(today.month - 1)
|
|
641
663
|
.subtractDays(today.day)
|
|
642
664
|
.subtractYears(periods);
|
|
643
665
|
}
|
|
644
666
|
|
|
645
|
-
function getQuarterlyStartDate(periods) {
|
|
667
|
+
function getQuarterlyStartDate(periods, date) {
|
|
646
668
|
return null;
|
|
647
669
|
}
|
|
648
670
|
|
|
649
|
-
function getMonthlyStartDate(periods) {
|
|
671
|
+
function getMonthlyStartDate(periods, date) {
|
|
650
672
|
return null;
|
|
651
673
|
}
|
|
652
674
|
|
|
653
|
-
function getYearToDateStartDate(periods) {
|
|
675
|
+
function getYearToDateStartDate(periods, date) {
|
|
654
676
|
return null;
|
|
655
677
|
}
|
|
656
678
|
|
|
657
679
|
function getYearlyRangeDescription(start, end) {
|
|
658
|
-
return end.year.toString()
|
|
680
|
+
return `Year ended ${end.year.toString()}`;
|
|
659
681
|
}
|
|
660
682
|
|
|
661
683
|
function getQuarterlyRangeDescription(start, end) {
|
|
@@ -1444,20 +1466,22 @@ module.exports = (() => {
|
|
|
1444
1466
|
* @param {Array.<Object>} portfolios - The portfolios.
|
|
1445
1467
|
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
1446
1468
|
* @param {Array.<Object>} summaries - The positions summaries (for all of the positions).
|
|
1447
|
-
* @param {PositionSummaryFrame=} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
1469
|
+
* @param {PositionSummaryFrame=} reportFrame - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
1448
1470
|
*/
|
|
1449
1471
|
class PositionContainer {
|
|
1450
|
-
constructor(definitions, portfolios, positions, summaries,
|
|
1472
|
+
constructor(definitions, portfolios, positions, summaries, reportFrame) {
|
|
1451
1473
|
assert.argumentIsArray(definitions, 'definitions', PositionTreeDefinition, 'PositionTreeDefinition');
|
|
1452
1474
|
assert.argumentIsArray(portfolios, 'portfolios');
|
|
1453
1475
|
assert.argumentIsArray(positions, 'positions');
|
|
1454
1476
|
assert.argumentIsArray(summaries, 'summaries');
|
|
1455
|
-
assert.argumentIsOptional(
|
|
1477
|
+
assert.argumentIsOptional(reportFrame, 'reportFrame', PositionSummaryFrame, 'PositionSummaryFrame');
|
|
1456
1478
|
|
|
1457
1479
|
this._definitions = definitions;
|
|
1458
1480
|
|
|
1459
1481
|
this._groupBindings = { };
|
|
1460
1482
|
|
|
1483
|
+
this._reporting = reportFrame instanceof PositionSummaryFrame;
|
|
1484
|
+
|
|
1461
1485
|
this._positionSymbolAddedEvent = new Event(this);
|
|
1462
1486
|
this._positionSymbolRemovedEvent = new Event(this);
|
|
1463
1487
|
|
|
@@ -1467,10 +1491,10 @@ module.exports = (() => {
|
|
|
1467
1491
|
return map;
|
|
1468
1492
|
}, { });
|
|
1469
1493
|
|
|
1470
|
-
this._currentSummaryFrame =
|
|
1494
|
+
this._currentSummaryFrame = reportFrame || PositionSummaryFrame.YTD;
|
|
1471
1495
|
this._currentSummaryRange = array.last(this._currentSummaryFrame.getRecentRanges(0));
|
|
1472
1496
|
|
|
1473
|
-
this._previousSummaryFrame =
|
|
1497
|
+
this._previousSummaryFrame = reportFrame || PositionSummaryFrame.YEARLY;
|
|
1474
1498
|
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(3);
|
|
1475
1499
|
|
|
1476
1500
|
if (this._currentSummaryFrame === this._previousSummaryFrame) {
|
|
@@ -2344,7 +2368,7 @@ module.exports = (() => {
|
|
|
2344
2368
|
const currentSummary = this._summariesCurrent[ position.position ] || null;
|
|
2345
2369
|
const previousSummaries = this._summariesPrevious[ position.position ] || getSummaryArray(this._previousSummaryRanges);
|
|
2346
2370
|
|
|
2347
|
-
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries);
|
|
2371
|
+
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries, this._reporting);
|
|
2348
2372
|
} else {
|
|
2349
2373
|
returnRef = null;
|
|
2350
2374
|
}
|
|
@@ -2483,12 +2507,14 @@ module.exports = (() => {
|
|
|
2483
2507
|
this._dataFormat.locked = false;
|
|
2484
2508
|
this._dataFormat.newsExists = false;
|
|
2485
2509
|
this._dataFormat.quantity = null;
|
|
2510
|
+
this._dataFormat.quantityPrevious = null;
|
|
2486
2511
|
this._dataFormat.basisPrice = null;
|
|
2487
2512
|
|
|
2488
2513
|
this._dataActual.key = this._key;
|
|
2489
2514
|
this._dataActual.description = this._description;
|
|
2490
2515
|
this._dataActual.newsExists = false;
|
|
2491
2516
|
this._dataActual.quantity = null;
|
|
2517
|
+
this._dataActual.quantityPrevious = null;
|
|
2492
2518
|
this._dataActual.basisPrice = null;
|
|
2493
2519
|
|
|
2494
2520
|
if (this._single && items.length === 1) {
|
|
@@ -2538,10 +2564,10 @@ module.exports = (() => {
|
|
|
2538
2564
|
this._dataActual.summaryTotalCurrent = null;
|
|
2539
2565
|
this._dataActual.summaryTotalPrevious = null;
|
|
2540
2566
|
this._dataActual.summaryTotalPrevious2 = null;
|
|
2541
|
-
this._dataActual.
|
|
2542
|
-
this._dataActual.
|
|
2543
|
-
this._dataActual.
|
|
2544
|
-
this._dataActual.
|
|
2567
|
+
this._dataActual.marketPrevious = null;
|
|
2568
|
+
this._dataActual.marketPrevious2 = null;
|
|
2569
|
+
this._dataActual.marketChange = null;
|
|
2570
|
+
this._dataActual.marketChangePercent = null;
|
|
2545
2571
|
this._dataActual.cashTotal = null;
|
|
2546
2572
|
|
|
2547
2573
|
this._dataFormat.currentPrice = null;
|
|
@@ -2565,10 +2591,10 @@ module.exports = (() => {
|
|
|
2565
2591
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
2566
2592
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
2567
2593
|
this._dataFormat.summaryTotalPrevious2Negative = false;
|
|
2568
|
-
this._dataFormat.
|
|
2569
|
-
this._dataFormat.
|
|
2570
|
-
this._dataFormat.
|
|
2571
|
-
this._dataFormat.
|
|
2594
|
+
this._dataFormat.marketPrevious = null;
|
|
2595
|
+
this._dataFormat.marketPrevious2 = null;
|
|
2596
|
+
this._dataFormat.marketChange = null;
|
|
2597
|
+
this._dataFormat.marketChangePercent = null;
|
|
2572
2598
|
this._dataFormat.cashTotal = null;
|
|
2573
2599
|
this._dataFormat.portfolioType = null;
|
|
2574
2600
|
|
|
@@ -3065,8 +3091,8 @@ module.exports = (() => {
|
|
|
3065
3091
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
|
|
3066
3092
|
updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
|
|
3067
3093
|
updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
|
|
3068
|
-
updates.
|
|
3069
|
-
updates.
|
|
3094
|
+
updates.marketPrevious = updates.marketPrevious.add(translate(item, item.data.marketPrevious));
|
|
3095
|
+
updates.marketPrevious2 = updates.marketPrevious2.add(translate(item, item.data.marketPrevious2));
|
|
3070
3096
|
|
|
3071
3097
|
if (item.position.instrument.type === InstrumentType.CASH) {
|
|
3072
3098
|
updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
|
|
@@ -3081,8 +3107,8 @@ module.exports = (() => {
|
|
|
3081
3107
|
summaryTotalCurrent: Decimal.ZERO,
|
|
3082
3108
|
summaryTotalPrevious: Decimal.ZERO,
|
|
3083
3109
|
summaryTotalPrevious2: Decimal.ZERO,
|
|
3084
|
-
|
|
3085
|
-
|
|
3110
|
+
marketPrevious: Decimal.ZERO,
|
|
3111
|
+
marketPrevious2: Decimal.ZERO,
|
|
3086
3112
|
cashTotal: Decimal.ZERO
|
|
3087
3113
|
});
|
|
3088
3114
|
|
|
@@ -3093,8 +3119,8 @@ module.exports = (() => {
|
|
|
3093
3119
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3094
3120
|
actual.summaryTotalPrevious = updates.summaryTotalPrevious;
|
|
3095
3121
|
actual.summaryTotalPrevious2 = updates.summaryTotalPrevious2;
|
|
3096
|
-
actual.
|
|
3097
|
-
actual.
|
|
3122
|
+
actual.marketPrevious = updates.marketPrevious;
|
|
3123
|
+
actual.marketPrevious2 = updates.marketPrevious2;
|
|
3098
3124
|
actual.cashTotal = updates.cashTotal;
|
|
3099
3125
|
|
|
3100
3126
|
format.basis = formatCurrency(actual.basis, currency);
|
|
@@ -3106,8 +3132,8 @@ module.exports = (() => {
|
|
|
3106
3132
|
format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
|
|
3107
3133
|
format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
|
|
3108
3134
|
format.summaryTotalPrevious2Negative = updates.summaryTotalPrevious2.getIsNegative();
|
|
3109
|
-
format.
|
|
3110
|
-
format.
|
|
3135
|
+
format.marketPrevious = formatCurrency(updates.marketPrevious, currency);
|
|
3136
|
+
format.marketPrevious2 = formatCurrency(updates.marketPrevious2, currency);
|
|
3111
3137
|
format.cashTotal = formatCurrency(updates.cashTotal, currency);
|
|
3112
3138
|
|
|
3113
3139
|
calculateUnrealizedPercent(group);
|
|
@@ -3116,9 +3142,13 @@ module.exports = (() => {
|
|
|
3116
3142
|
const item = group._items[0];
|
|
3117
3143
|
|
|
3118
3144
|
actual.quantity = item.position.snapshot.open;
|
|
3145
|
+
actual.quantityPrevious = item.data.quantityPrevious;
|
|
3146
|
+
|
|
3119
3147
|
actual.basisPrice = item.data.basisPrice;
|
|
3120
3148
|
|
|
3121
3149
|
format.quantity = formatDecimal(actual.quantity, 2);
|
|
3150
|
+
format.quantityPrevious = formatDecimal(actual.quantityPrevious, 2);
|
|
3151
|
+
|
|
3122
3152
|
format.basisPrice = formatCurrency(actual.basisPrice, currency);
|
|
3123
3153
|
|
|
3124
3154
|
format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
|
|
@@ -3205,23 +3235,23 @@ module.exports = (() => {
|
|
|
3205
3235
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3206
3236
|
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
3207
3237
|
|
|
3208
|
-
let
|
|
3209
|
-
let
|
|
3238
|
+
let marketChange = updates.market.subtract(actual.marketPrevious);
|
|
3239
|
+
let marketChangePercent;
|
|
3210
3240
|
|
|
3211
|
-
if (actual.
|
|
3212
|
-
if (
|
|
3213
|
-
|
|
3214
|
-
} else if (
|
|
3215
|
-
|
|
3241
|
+
if (actual.marketPrevious.getIsZero()) {
|
|
3242
|
+
if (marketChange.getIsPositive()) {
|
|
3243
|
+
marketChangePercent = Decimal.ONE;
|
|
3244
|
+
} else if (marketChange.getIsNegative()) {
|
|
3245
|
+
marketChangePercent = Decimal.NEGATIVE_ONE;
|
|
3216
3246
|
} else {
|
|
3217
|
-
|
|
3247
|
+
marketChangePercent = Decimal.ZERO;
|
|
3218
3248
|
}
|
|
3219
3249
|
} else {
|
|
3220
|
-
|
|
3250
|
+
marketChangePercent = marketChange.divide(actual.marketPrevious);
|
|
3221
3251
|
}
|
|
3222
3252
|
|
|
3223
|
-
actual.
|
|
3224
|
-
actual.
|
|
3253
|
+
actual.marketChange = marketChange;
|
|
3254
|
+
actual.marketChangePercent = marketChangePercent;
|
|
3225
3255
|
|
|
3226
3256
|
format.market = formatCurrency(actual.market, currency);
|
|
3227
3257
|
|
|
@@ -3242,8 +3272,8 @@ module.exports = (() => {
|
|
|
3242
3272
|
format.total = formatCurrency(actual.total, currency);
|
|
3243
3273
|
format.totalNegative = actual.total.getIsNegative();
|
|
3244
3274
|
|
|
3245
|
-
format.
|
|
3246
|
-
format.
|
|
3275
|
+
format.marketChange = formatCurrency(actual.marketChange, currency);
|
|
3276
|
+
format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
|
|
3247
3277
|
|
|
3248
3278
|
calculateUnrealizedPercent(group);
|
|
3249
3279
|
}
|
|
@@ -3332,9 +3362,10 @@ module.exports = (() => {
|
|
|
3332
3362
|
* @param {Object} position
|
|
3333
3363
|
* @param {Object} currentSummary
|
|
3334
3364
|
* @param {Array.<Object>} previousSummaries
|
|
3365
|
+
* @param {Boolean} reporting
|
|
3335
3366
|
*/
|
|
3336
3367
|
class PositionItem extends Disposable {
|
|
3337
|
-
constructor(portfolio, position, currentSummary, previousSummaries) {
|
|
3368
|
+
constructor(portfolio, position, currentSummary, previousSummaries, reporting) {
|
|
3338
3369
|
super();
|
|
3339
3370
|
|
|
3340
3371
|
this._portfolio = portfolio;
|
|
@@ -3348,6 +3379,8 @@ module.exports = (() => {
|
|
|
3348
3379
|
this._currentSummary = currentSummary || null;
|
|
3349
3380
|
this._previousSummaries = previousSummaries || [ ];
|
|
3350
3381
|
|
|
3382
|
+
this._reporting = reporting;
|
|
3383
|
+
|
|
3351
3384
|
this._data = { };
|
|
3352
3385
|
|
|
3353
3386
|
this._data.basis = null;
|
|
@@ -3377,9 +3410,12 @@ module.exports = (() => {
|
|
|
3377
3410
|
this._data.summaryTotalPrevious = null;
|
|
3378
3411
|
this._data.summaryTotalPrevious2 = null;
|
|
3379
3412
|
|
|
3380
|
-
this._data.
|
|
3381
|
-
this._data.
|
|
3413
|
+
this._data.marketPrevious = null;
|
|
3414
|
+
this._data.marketPrevious2 = null;
|
|
3382
3415
|
|
|
3416
|
+
this._data.quantityPrevious = null;
|
|
3417
|
+
this._data.quantityPrevious2 = null;
|
|
3418
|
+
|
|
3383
3419
|
this._data.realized = null;
|
|
3384
3420
|
this._data.income = null;
|
|
3385
3421
|
this._data.basisPrice = null;
|
|
@@ -3673,7 +3709,7 @@ module.exports = (() => {
|
|
|
3673
3709
|
|
|
3674
3710
|
function calculateStaticData(item) {
|
|
3675
3711
|
const position = item.position;
|
|
3676
|
-
const snapshot = item.
|
|
3712
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
3677
3713
|
const previousSummaries = item.previousSummaries;
|
|
3678
3714
|
|
|
3679
3715
|
const data = item._data;
|
|
@@ -3703,8 +3739,10 @@ module.exports = (() => {
|
|
|
3703
3739
|
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
3704
3740
|
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
3705
3741
|
|
|
3706
|
-
data.
|
|
3707
|
-
data.
|
|
3742
|
+
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
3743
|
+
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
3744
|
+
|
|
3745
|
+
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
3708
3746
|
|
|
3709
3747
|
if (snapshot.open.getIsZero()) {
|
|
3710
3748
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -3715,7 +3753,7 @@ module.exports = (() => {
|
|
|
3715
3753
|
|
|
3716
3754
|
function calculatePriceData(item, price) {
|
|
3717
3755
|
const position = item.position;
|
|
3718
|
-
const snapshot = item.
|
|
3756
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
3719
3757
|
const previousSummaries = item.previousSummaries;
|
|
3720
3758
|
|
|
3721
3759
|
const data = item._data;
|
|
@@ -3867,6 +3905,28 @@ module.exports = (() => {
|
|
|
3867
3905
|
return is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
|
|
3868
3906
|
}
|
|
3869
3907
|
|
|
3908
|
+
function getSnapshot(position, currentSummary, reporting) {
|
|
3909
|
+
let snapshot;
|
|
3910
|
+
|
|
3911
|
+
if (reporting) {
|
|
3912
|
+
snapshot = { };
|
|
3913
|
+
|
|
3914
|
+
snapshot.date = currentSummary.end.date;
|
|
3915
|
+
snapshot.open = currentSummary.end.open;
|
|
3916
|
+
snapshot.direction = currentSummary.end.direction;
|
|
3917
|
+
snapshot.buys = currentSummary.period.buys;
|
|
3918
|
+
snapshot.sells = currentSummary.period.sells;
|
|
3919
|
+
snapshot.gain = currentSummary.period.realized;
|
|
3920
|
+
snapshot.basis = currentSummary.end.basis;
|
|
3921
|
+
snapshot.income = currentSummary.period.income;
|
|
3922
|
+
snapshot.value = currentSummary.end.value;
|
|
3923
|
+
} else {
|
|
3924
|
+
snapshot = position.snapshot;
|
|
3925
|
+
}
|
|
3926
|
+
|
|
3927
|
+
return snapshot;
|
|
3928
|
+
}
|
|
3929
|
+
|
|
3870
3930
|
return PositionItem;
|
|
3871
3931
|
})();
|
|
3872
3932
|
|
|
@@ -4194,6 +4254,7 @@ module.exports = (() => {
|
|
|
4194
4254
|
* @public
|
|
4195
4255
|
* @param {String} name
|
|
4196
4256
|
* @param {Array.<PositionLevelDefinition>} definitions
|
|
4257
|
+
* @oaram {Array.<String>=} exclusionDependencies
|
|
4197
4258
|
*/
|
|
4198
4259
|
class PositionTreeDefinitions {
|
|
4199
4260
|
constructor(name, definitions, exclusionDependencies) {
|
|
@@ -17632,6 +17693,38 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17632
17693
|
});
|
|
17633
17694
|
});
|
|
17634
17695
|
});
|
|
17696
|
+
|
|
17697
|
+
describe('and prior ranges are calculated', () => {
|
|
17698
|
+
describe('for YEARLY ranges', () => {
|
|
17699
|
+
describe('from 2017-10-10, including one previous ranges', () => {
|
|
17700
|
+
let ranges;
|
|
17701
|
+
|
|
17702
|
+
beforeEach(() => {
|
|
17703
|
+
ranges = PositionSummaryFrame.YEARLY.getPriorRanges(new Day(2015, 4, 20), 1);
|
|
17704
|
+
});
|
|
17705
|
+
|
|
17706
|
+
it('should return two ranges', () => {
|
|
17707
|
+
expect(ranges.length).toEqual(2);
|
|
17708
|
+
});
|
|
17709
|
+
|
|
17710
|
+
it('the first range should begin on 2013-12-31', () => {
|
|
17711
|
+
expect(ranges[0].start.getIsEqual(new Day(2013, 12, 31))).toEqual(true);
|
|
17712
|
+
});
|
|
17713
|
+
|
|
17714
|
+
it('the first range should end on 2014-12-31', () => {
|
|
17715
|
+
expect(ranges[0].end.getIsEqual(new Day(2014, 12, 31))).toEqual(true);
|
|
17716
|
+
});
|
|
17717
|
+
|
|
17718
|
+
it('the second range should begin on 2014-12-31', () => {
|
|
17719
|
+
expect(ranges[1].start.getIsEqual(new Day(2014, 12, 31))).toEqual(true);
|
|
17720
|
+
});
|
|
17721
|
+
|
|
17722
|
+
it('the second range should end on 2015-12-31', () => {
|
|
17723
|
+
expect(ranges[1].end.getIsEqual(new Day(2015, 12, 31))).toEqual(true);
|
|
17724
|
+
});
|
|
17725
|
+
});
|
|
17726
|
+
});
|
|
17727
|
+
});
|
|
17635
17728
|
});
|
|
17636
17729
|
|
|
17637
17730
|
},{"./../../../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
|
});
|