@barchart/portfolio-api-common 1.2.83 → 1.2.87
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.
|
@@ -39,16 +39,18 @@ module.exports = (() => {
|
|
|
39
39
|
*
|
|
40
40
|
* @public
|
|
41
41
|
* @param {Array.<PositionTreeDefinition>} definitions
|
|
42
|
-
* @param {Array.<Object>} portfolios
|
|
43
|
-
* @param {Array.<Object>} positions
|
|
44
|
-
* @param {Array.<Object>} summaries
|
|
42
|
+
* @param {Array.<Object>} portfolios - The portfolios.
|
|
43
|
+
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
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
46
|
*/
|
|
46
47
|
class PositionContainer {
|
|
47
|
-
constructor(definitions, portfolios, positions, summaries) {
|
|
48
|
+
constructor(definitions, portfolios, positions, summaries, frame) {
|
|
48
49
|
assert.argumentIsArray(definitions, 'definitions', PositionTreeDefinition, 'PositionTreeDefinition');
|
|
49
50
|
assert.argumentIsArray(portfolios, 'portfolios');
|
|
50
51
|
assert.argumentIsArray(positions, 'positions');
|
|
51
52
|
assert.argumentIsArray(summaries, 'summaries');
|
|
53
|
+
assert.argumentIsOptional(frame, 'frame', PositionSummaryFrame, 'PositionSummaryFrame');
|
|
52
54
|
|
|
53
55
|
this._definitions = definitions;
|
|
54
56
|
|
|
@@ -63,18 +65,24 @@ module.exports = (() => {
|
|
|
63
65
|
return map;
|
|
64
66
|
}, { });
|
|
65
67
|
|
|
66
|
-
this._currentSummaryFrame = PositionSummaryFrame.YTD;
|
|
68
|
+
this._currentSummaryFrame = frame || PositionSummaryFrame.YTD;
|
|
67
69
|
this._currentSummaryRange = array.last(this._currentSummaryFrame.getRecentRanges(0));
|
|
68
70
|
|
|
71
|
+
this._previousSummaryFrame = frame || PositionSummaryFrame.YEARLY;
|
|
72
|
+
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(3);
|
|
73
|
+
|
|
74
|
+
if (this._currentSummaryFrame === this._previousSummaryFrame) {
|
|
75
|
+
this._previousSummaryRanges.pop();
|
|
76
|
+
} else {
|
|
77
|
+
this._previousSummaryRanges.shift();
|
|
78
|
+
}
|
|
79
|
+
|
|
69
80
|
this._summariesCurrent = summaries.reduce((map, summary) => {
|
|
70
81
|
addSummaryCurrent(map, summary, this._currentSummaryFrame, this._currentSummaryRange);
|
|
71
82
|
|
|
72
83
|
return map;
|
|
73
84
|
}, { });
|
|
74
85
|
|
|
75
|
-
this._previousSummaryFrame = PositionSummaryFrame.YEARLY;
|
|
76
|
-
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(1);
|
|
77
|
-
|
|
78
86
|
this._summariesPrevious = summaries.reduce((map, summary) => {
|
|
79
87
|
addSummaryPrevious(map, summary, this._previousSummaryFrame, this._previousSummaryRanges);
|
|
80
88
|
|
|
@@ -275,8 +283,17 @@ module.exports = (() => {
|
|
|
275
283
|
}
|
|
276
284
|
|
|
277
285
|
const existingBarchartSymbols = this.getPositionSymbols(false);
|
|
286
|
+
const existingPositionItem = this._items.find(item => item.position.position === position.position);
|
|
278
287
|
|
|
279
|
-
|
|
288
|
+
let currentQuote = null;
|
|
289
|
+
let previousQuote = null;
|
|
290
|
+
|
|
291
|
+
if (existingPositionItem) {
|
|
292
|
+
currentQuote = existingPositionItem.quote || null;
|
|
293
|
+
previousQuote = existingPositionItem.previousQuote || null;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
removePositionItem.call(this, existingPositionItem);
|
|
280
297
|
|
|
281
298
|
summaries.forEach((summary) => {
|
|
282
299
|
addSummaryCurrent(this._summariesCurrent, summary, this._currentSummaryFrame, this._currentSummaryRange);
|
|
@@ -288,6 +305,14 @@ module.exports = (() => {
|
|
|
288
305
|
addBarchartSymbol(this._symbols, item);
|
|
289
306
|
addDisplaySymbol(this._symbolsDisplay, item);
|
|
290
307
|
|
|
308
|
+
if (previousQuote !== null) {
|
|
309
|
+
item.setQuote(previousQuote);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (currentQuote !== null) {
|
|
313
|
+
item.setQuote(currentQuote);
|
|
314
|
+
}
|
|
315
|
+
|
|
291
316
|
this._items.push(item);
|
|
292
317
|
|
|
293
318
|
const createGroupOrInjectItem = (parentTree, treeDefinition, levelDefinitions) => {
|
|
@@ -397,13 +422,13 @@ module.exports = (() => {
|
|
|
397
422
|
* @param {Object} position
|
|
398
423
|
* @return {Boolean}
|
|
399
424
|
*/
|
|
400
|
-
getPositionLock(
|
|
425
|
+
getPositionLock(position) {
|
|
401
426
|
assert.argumentIsRequired(position, 'position', Object);
|
|
402
427
|
assert.argumentIsRequired(position.position, 'position.position', String);
|
|
403
428
|
|
|
404
429
|
const item = this._items.find(i => i.position.position === position.position);
|
|
405
430
|
|
|
406
|
-
return is.object(item) && item.locked;
|
|
431
|
+
return is.object(item) && item.data.locked;
|
|
407
432
|
}
|
|
408
433
|
|
|
409
434
|
/**
|
|
@@ -907,7 +932,7 @@ module.exports = (() => {
|
|
|
907
932
|
}
|
|
908
933
|
}
|
|
909
934
|
|
|
910
|
-
function createPositionItem(position) {
|
|
935
|
+
function createPositionItem(position, currentQuote, previousQuote) {
|
|
911
936
|
const portfolio = this._portfolios[position.portfolio];
|
|
912
937
|
|
|
913
938
|
let returnRef;
|
|
@@ -11,8 +11,8 @@ module.exports = (() => {
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* A container for a single position, which handles quote changes and
|
|
15
|
-
*
|
|
14
|
+
* A container for a single position, which handles quote changes and notifies
|
|
15
|
+
* observers -- which are typically parent-level {@link PositionGroup}
|
|
16
16
|
* instances.
|
|
17
17
|
*
|
|
18
18
|
* @public
|
|
@@ -41,6 +41,7 @@ module.exports = (() => {
|
|
|
41
41
|
this._data.basis = null;
|
|
42
42
|
|
|
43
43
|
this._currentQuote = null;
|
|
44
|
+
this._previousQuote = null;
|
|
44
45
|
this._currentPrice = null;
|
|
45
46
|
|
|
46
47
|
this._data.currentPrice = null;
|
|
@@ -124,7 +125,7 @@ module.exports = (() => {
|
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
/**
|
|
127
|
-
* The
|
|
128
|
+
* The current summary of the encapsulated position.
|
|
128
129
|
*
|
|
129
130
|
* @public
|
|
130
131
|
* @returns {Object}
|
|
@@ -134,7 +135,7 @@ module.exports = (() => {
|
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
/**
|
|
137
|
-
* Previous
|
|
138
|
+
* Previous summaries for the encapsulated position.
|
|
138
139
|
*
|
|
139
140
|
* @public
|
|
140
141
|
* @returns {Object}
|
|
@@ -147,22 +148,32 @@ module.exports = (() => {
|
|
|
147
148
|
* Various data regarding the encapsulated position.
|
|
148
149
|
*
|
|
149
150
|
* @public
|
|
150
|
-
* @returns {
|
|
151
|
+
* @returns {Object}
|
|
151
152
|
*/
|
|
152
153
|
get data() {
|
|
153
154
|
return this._data;
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
/**
|
|
157
|
-
* The
|
|
158
|
+
* The most recent quote for the symbol of the encapsulated position.
|
|
158
159
|
*
|
|
159
160
|
* @public
|
|
160
|
-
* @returns {null|
|
|
161
|
+
* @returns {null|Object}
|
|
161
162
|
*/
|
|
162
163
|
get quote() {
|
|
163
164
|
return this._currentQuote;
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
/**
|
|
168
|
+
* The second most recent quote for the symbol of the encapsulated position.
|
|
169
|
+
*
|
|
170
|
+
* @public
|
|
171
|
+
* @returns {null|Object}
|
|
172
|
+
*/
|
|
173
|
+
get previousQuote() {
|
|
174
|
+
return this._previousQuote;
|
|
175
|
+
}
|
|
176
|
+
|
|
166
177
|
updatePortfolio(portfolio) {
|
|
167
178
|
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
168
179
|
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
@@ -200,6 +211,7 @@ module.exports = (() => {
|
|
|
200
211
|
this._currentPricePrevious = this._currentPrice;
|
|
201
212
|
this._currentPrice = quote.lastPrice;
|
|
202
213
|
|
|
214
|
+
this._previousQuote = this._currentQuote;
|
|
203
215
|
this._currentQuote = quote;
|
|
204
216
|
|
|
205
217
|
this._quoteChangedEvent.fire(this._currentQuote);
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -1418,16 +1418,18 @@ module.exports = (() => {
|
|
|
1418
1418
|
*
|
|
1419
1419
|
* @public
|
|
1420
1420
|
* @param {Array.<PositionTreeDefinition>} definitions
|
|
1421
|
-
* @param {Array.<Object>} portfolios
|
|
1422
|
-
* @param {Array.<Object>} positions
|
|
1423
|
-
* @param {Array.<Object>} summaries
|
|
1421
|
+
* @param {Array.<Object>} portfolios - The portfolios.
|
|
1422
|
+
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
1423
|
+
* @param {Array.<Object>} summaries - The positions summaries (for all of the positions).
|
|
1424
|
+
* @param {PositionSummaryFrame} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
1424
1425
|
*/
|
|
1425
1426
|
class PositionContainer {
|
|
1426
|
-
constructor(definitions, portfolios, positions, summaries) {
|
|
1427
|
+
constructor(definitions, portfolios, positions, summaries, frame) {
|
|
1427
1428
|
assert.argumentIsArray(definitions, 'definitions', PositionTreeDefinition, 'PositionTreeDefinition');
|
|
1428
1429
|
assert.argumentIsArray(portfolios, 'portfolios');
|
|
1429
1430
|
assert.argumentIsArray(positions, 'positions');
|
|
1430
1431
|
assert.argumentIsArray(summaries, 'summaries');
|
|
1432
|
+
assert.argumentIsOptional(frame, 'frame', PositionSummaryFrame, 'PositionSummaryFrame');
|
|
1431
1433
|
|
|
1432
1434
|
this._definitions = definitions;
|
|
1433
1435
|
|
|
@@ -1442,18 +1444,24 @@ module.exports = (() => {
|
|
|
1442
1444
|
return map;
|
|
1443
1445
|
}, { });
|
|
1444
1446
|
|
|
1445
|
-
this._currentSummaryFrame = PositionSummaryFrame.YTD;
|
|
1447
|
+
this._currentSummaryFrame = frame || PositionSummaryFrame.YTD;
|
|
1446
1448
|
this._currentSummaryRange = array.last(this._currentSummaryFrame.getRecentRanges(0));
|
|
1447
1449
|
|
|
1450
|
+
this._previousSummaryFrame = frame || PositionSummaryFrame.YEARLY;
|
|
1451
|
+
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(3);
|
|
1452
|
+
|
|
1453
|
+
if (this._currentSummaryFrame === this._previousSummaryFrame) {
|
|
1454
|
+
this._previousSummaryRanges.pop();
|
|
1455
|
+
} else {
|
|
1456
|
+
this._previousSummaryRanges.shift();
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1448
1459
|
this._summariesCurrent = summaries.reduce((map, summary) => {
|
|
1449
1460
|
addSummaryCurrent(map, summary, this._currentSummaryFrame, this._currentSummaryRange);
|
|
1450
1461
|
|
|
1451
1462
|
return map;
|
|
1452
1463
|
}, { });
|
|
1453
1464
|
|
|
1454
|
-
this._previousSummaryFrame = PositionSummaryFrame.YEARLY;
|
|
1455
|
-
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(1);
|
|
1456
|
-
|
|
1457
1465
|
this._summariesPrevious = summaries.reduce((map, summary) => {
|
|
1458
1466
|
addSummaryPrevious(map, summary, this._previousSummaryFrame, this._previousSummaryRanges);
|
|
1459
1467
|
|
|
@@ -1654,8 +1662,17 @@ module.exports = (() => {
|
|
|
1654
1662
|
}
|
|
1655
1663
|
|
|
1656
1664
|
const existingBarchartSymbols = this.getPositionSymbols(false);
|
|
1665
|
+
const existingPositionItem = this._items.find(item => item.position.position === position.position);
|
|
1657
1666
|
|
|
1658
|
-
|
|
1667
|
+
let currentQuote = null;
|
|
1668
|
+
let previousQuote = null;
|
|
1669
|
+
|
|
1670
|
+
if (existingPositionItem) {
|
|
1671
|
+
currentQuote = existingPositionItem.quote || null;
|
|
1672
|
+
previousQuote = existingPositionItem.previousQuote || null;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
removePositionItem.call(this, existingPositionItem);
|
|
1659
1676
|
|
|
1660
1677
|
summaries.forEach((summary) => {
|
|
1661
1678
|
addSummaryCurrent(this._summariesCurrent, summary, this._currentSummaryFrame, this._currentSummaryRange);
|
|
@@ -1667,6 +1684,14 @@ module.exports = (() => {
|
|
|
1667
1684
|
addBarchartSymbol(this._symbols, item);
|
|
1668
1685
|
addDisplaySymbol(this._symbolsDisplay, item);
|
|
1669
1686
|
|
|
1687
|
+
if (previousQuote !== null) {
|
|
1688
|
+
item.setQuote(previousQuote);
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
if (currentQuote !== null) {
|
|
1692
|
+
item.setQuote(currentQuote);
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1670
1695
|
this._items.push(item);
|
|
1671
1696
|
|
|
1672
1697
|
const createGroupOrInjectItem = (parentTree, treeDefinition, levelDefinitions) => {
|
|
@@ -1776,13 +1801,13 @@ module.exports = (() => {
|
|
|
1776
1801
|
* @param {Object} position
|
|
1777
1802
|
* @return {Boolean}
|
|
1778
1803
|
*/
|
|
1779
|
-
getPositionLock(
|
|
1804
|
+
getPositionLock(position) {
|
|
1780
1805
|
assert.argumentIsRequired(position, 'position', Object);
|
|
1781
1806
|
assert.argumentIsRequired(position.position, 'position.position', String);
|
|
1782
1807
|
|
|
1783
1808
|
const item = this._items.find(i => i.position.position === position.position);
|
|
1784
1809
|
|
|
1785
|
-
return is.object(item) && item.locked;
|
|
1810
|
+
return is.object(item) && item.data.locked;
|
|
1786
1811
|
}
|
|
1787
1812
|
|
|
1788
1813
|
/**
|
|
@@ -2286,7 +2311,7 @@ module.exports = (() => {
|
|
|
2286
2311
|
}
|
|
2287
2312
|
}
|
|
2288
2313
|
|
|
2289
|
-
function createPositionItem(position) {
|
|
2314
|
+
function createPositionItem(position, currentQuote, previousQuote) {
|
|
2290
2315
|
const portfolio = this._portfolios[position.portfolio];
|
|
2291
2316
|
|
|
2292
2317
|
let returnRef;
|
|
@@ -3239,8 +3264,8 @@ module.exports = (() => {
|
|
|
3239
3264
|
'use strict';
|
|
3240
3265
|
|
|
3241
3266
|
/**
|
|
3242
|
-
* A container for a single position, which handles quote changes and
|
|
3243
|
-
*
|
|
3267
|
+
* A container for a single position, which handles quote changes and notifies
|
|
3268
|
+
* observers -- which are typically parent-level {@link PositionGroup}
|
|
3244
3269
|
* instances.
|
|
3245
3270
|
*
|
|
3246
3271
|
* @public
|
|
@@ -3269,6 +3294,7 @@ module.exports = (() => {
|
|
|
3269
3294
|
this._data.basis = null;
|
|
3270
3295
|
|
|
3271
3296
|
this._currentQuote = null;
|
|
3297
|
+
this._previousQuote = null;
|
|
3272
3298
|
this._currentPrice = null;
|
|
3273
3299
|
|
|
3274
3300
|
this._data.currentPrice = null;
|
|
@@ -3352,7 +3378,7 @@ module.exports = (() => {
|
|
|
3352
3378
|
}
|
|
3353
3379
|
|
|
3354
3380
|
/**
|
|
3355
|
-
* The
|
|
3381
|
+
* The current summary of the encapsulated position.
|
|
3356
3382
|
*
|
|
3357
3383
|
* @public
|
|
3358
3384
|
* @returns {Object}
|
|
@@ -3362,7 +3388,7 @@ module.exports = (() => {
|
|
|
3362
3388
|
}
|
|
3363
3389
|
|
|
3364
3390
|
/**
|
|
3365
|
-
* Previous
|
|
3391
|
+
* Previous summaries for the encapsulated position.
|
|
3366
3392
|
*
|
|
3367
3393
|
* @public
|
|
3368
3394
|
* @returns {Object}
|
|
@@ -3375,22 +3401,32 @@ module.exports = (() => {
|
|
|
3375
3401
|
* Various data regarding the encapsulated position.
|
|
3376
3402
|
*
|
|
3377
3403
|
* @public
|
|
3378
|
-
* @returns {
|
|
3404
|
+
* @returns {Object}
|
|
3379
3405
|
*/
|
|
3380
3406
|
get data() {
|
|
3381
3407
|
return this._data;
|
|
3382
3408
|
}
|
|
3383
3409
|
|
|
3384
3410
|
/**
|
|
3385
|
-
* The
|
|
3411
|
+
* The most recent quote for the symbol of the encapsulated position.
|
|
3386
3412
|
*
|
|
3387
3413
|
* @public
|
|
3388
|
-
* @returns {null|
|
|
3414
|
+
* @returns {null|Object}
|
|
3389
3415
|
*/
|
|
3390
3416
|
get quote() {
|
|
3391
3417
|
return this._currentQuote;
|
|
3392
3418
|
}
|
|
3393
3419
|
|
|
3420
|
+
/**
|
|
3421
|
+
* The second most recent quote for the symbol of the encapsulated position.
|
|
3422
|
+
*
|
|
3423
|
+
* @public
|
|
3424
|
+
* @returns {null|Object}
|
|
3425
|
+
*/
|
|
3426
|
+
get previousQuote() {
|
|
3427
|
+
return this._previousQuote;
|
|
3428
|
+
}
|
|
3429
|
+
|
|
3394
3430
|
updatePortfolio(portfolio) {
|
|
3395
3431
|
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
3396
3432
|
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
@@ -3428,6 +3464,7 @@ module.exports = (() => {
|
|
|
3428
3464
|
this._currentPricePrevious = this._currentPrice;
|
|
3429
3465
|
this._currentPrice = quote.lastPrice;
|
|
3430
3466
|
|
|
3467
|
+
this._previousQuote = this._currentQuote;
|
|
3431
3468
|
this._currentQuote = quote;
|
|
3432
3469
|
|
|
3433
3470
|
this._quoteChangedEvent.fire(this._currentQuote);
|
|
@@ -17456,6 +17493,76 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17456
17493
|
});
|
|
17457
17494
|
});
|
|
17458
17495
|
});
|
|
17496
|
+
|
|
17497
|
+
describe('and recent ranges are calculated', () => {
|
|
17498
|
+
let todayYear;
|
|
17499
|
+
let todayMonth;
|
|
17500
|
+
let todayDay;
|
|
17501
|
+
|
|
17502
|
+
beforeEach(() => {
|
|
17503
|
+
const today = new Date();
|
|
17504
|
+
|
|
17505
|
+
todayYear = today.getFullYear();
|
|
17506
|
+
todayMonth = today.getMonth() + 1;
|
|
17507
|
+
todayDay = today.getDate();
|
|
17508
|
+
});
|
|
17509
|
+
|
|
17510
|
+
describe('the most recent YTD frame', () => {
|
|
17511
|
+
let ranges;
|
|
17512
|
+
|
|
17513
|
+
beforeEach(() => {
|
|
17514
|
+
ranges = PositionSummaryFrame.YTD.getRecentRanges(0);
|
|
17515
|
+
});
|
|
17516
|
+
|
|
17517
|
+
it('should contain one range', () => {
|
|
17518
|
+
expect(ranges.length).toEqual(1);
|
|
17519
|
+
});
|
|
17520
|
+
|
|
17521
|
+
it('the range should begin at the end of last year', () => {
|
|
17522
|
+
expect(ranges[0].start.format()).toEqual(`${todayYear - 1}-12-31`);
|
|
17523
|
+
});
|
|
17524
|
+
|
|
17525
|
+
it('the range should end at the end of this year', () => {
|
|
17526
|
+
expect(ranges[0].end.format()).toEqual(`${todayYear}-12-31`);
|
|
17527
|
+
});
|
|
17528
|
+
});
|
|
17529
|
+
|
|
17530
|
+
describe('the three most recent YEARLY frames', () => {
|
|
17531
|
+
let ranges;
|
|
17532
|
+
|
|
17533
|
+
beforeEach(() => {
|
|
17534
|
+
ranges = PositionSummaryFrame.YEARLY.getRecentRanges(2);
|
|
17535
|
+
});
|
|
17536
|
+
|
|
17537
|
+
it('should contain three range', () => {
|
|
17538
|
+
expect(ranges.length).toEqual(3);
|
|
17539
|
+
});
|
|
17540
|
+
|
|
17541
|
+
it('the first range should begin at the end of this year (minus three years)', () => {
|
|
17542
|
+
expect(ranges[0].start.format()).toEqual(`${todayYear - 4}-12-31`);
|
|
17543
|
+
});
|
|
17544
|
+
|
|
17545
|
+
it('the first range should end at the end of this year (minus two years)', () => {
|
|
17546
|
+
expect(ranges[0].end.format()).toEqual(`${todayYear - 3}-12-31`);
|
|
17547
|
+
});
|
|
17548
|
+
|
|
17549
|
+
it('the second range should begin at the end of this year (minus two years)', () => {
|
|
17550
|
+
expect(ranges[1].start.format()).toEqual(`${todayYear - 3}-12-31`);
|
|
17551
|
+
});
|
|
17552
|
+
|
|
17553
|
+
it('the second range should end at the end of this year (minus one years)', () => {
|
|
17554
|
+
expect(ranges[1].end.format()).toEqual(`${todayYear - 2}-12-31`);
|
|
17555
|
+
});
|
|
17556
|
+
|
|
17557
|
+
it('the third range should begin at the end of the year before last', () => {
|
|
17558
|
+
expect(ranges[2].start.format()).toEqual(`${todayYear - 2}-12-31`);
|
|
17559
|
+
});
|
|
17560
|
+
|
|
17561
|
+
it('the third range should end at the end of last year', () => {
|
|
17562
|
+
expect(ranges[2].end.format()).toEqual(`${todayYear - 1}-12-31`);
|
|
17563
|
+
});
|
|
17564
|
+
});
|
|
17565
|
+
});
|
|
17459
17566
|
});
|
|
17460
17567
|
|
|
17461
17568
|
},{"./../../../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){
|
|
@@ -17557,7 +17664,8 @@ describe('When requesting all the user-initiated transaction types', () => {
|
|
|
17557
17664
|
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
17558
17665
|
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
17559
17666
|
|
|
17560
|
-
const InstrumentType = require('./../../../lib/data/InstrumentType')
|
|
17667
|
+
const InstrumentType = require('./../../../lib/data/InstrumentType'),
|
|
17668
|
+
PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame');
|
|
17561
17669
|
|
|
17562
17670
|
const PositionContainer = require('./../../../lib/processing/PositionContainer'),
|
|
17563
17671
|
PositionLevelDefinition = require('./../../../lib/processing/definitions/PositionLevelDefinition'),
|
|
@@ -17590,6 +17698,37 @@ describe('When a position container data is gathered', () => {
|
|
|
17590
17698
|
};
|
|
17591
17699
|
}
|
|
17592
17700
|
|
|
17701
|
+
function getSummaries(position, frame, count) {
|
|
17702
|
+
const ranges = frame.getRecentRanges(count - 1);
|
|
17703
|
+
|
|
17704
|
+
return ranges.map((range) => {
|
|
17705
|
+
return {
|
|
17706
|
+
portfolio: position.portfolio,
|
|
17707
|
+
position: position.position,
|
|
17708
|
+
frame: frame,
|
|
17709
|
+
start: {
|
|
17710
|
+
date: range.start,
|
|
17711
|
+
open: position.snapshot.open,
|
|
17712
|
+
value: position.snapshot.value,
|
|
17713
|
+
basis: position.snapshot.basis
|
|
17714
|
+
},
|
|
17715
|
+
end: {
|
|
17716
|
+
date: range.end,
|
|
17717
|
+
open: position.snapshot.open,
|
|
17718
|
+
value: position.snapshot.value,
|
|
17719
|
+
basis: position.snapshot.basis
|
|
17720
|
+
},
|
|
17721
|
+
period: {
|
|
17722
|
+
buys: new Decimal(0),
|
|
17723
|
+
sells: new Decimal(0),
|
|
17724
|
+
income: new Decimal(0),
|
|
17725
|
+
realized: new Decimal(0),
|
|
17726
|
+
unrealized: new Decimal(0)
|
|
17727
|
+
}
|
|
17728
|
+
};
|
|
17729
|
+
});
|
|
17730
|
+
}
|
|
17731
|
+
|
|
17593
17732
|
describe('for two portfolios, each with the same position, and the second portfolio with an addition position', () => {
|
|
17594
17733
|
let portfolios;
|
|
17595
17734
|
let positions;
|
|
@@ -17612,7 +17751,12 @@ describe('When a position container data is gathered', () => {
|
|
|
17612
17751
|
getPosition('My Second Portfolio', 'TSLA')
|
|
17613
17752
|
];
|
|
17614
17753
|
|
|
17615
|
-
summaries =
|
|
17754
|
+
summaries = positions.reduce((accumulator, position) => {
|
|
17755
|
+
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YTD, 1));
|
|
17756
|
+
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YEARLY, 3));
|
|
17757
|
+
|
|
17758
|
+
return accumulator;
|
|
17759
|
+
}, [ ]);
|
|
17616
17760
|
});
|
|
17617
17761
|
|
|
17618
17762
|
describe('and a container is created grouping by total, portfolio, and instrument', () => {
|
|
@@ -17659,11 +17803,49 @@ describe('When a position container data is gathered', () => {
|
|
|
17659
17803
|
it('the "b" portfolio group should have two items', () => {
|
|
17660
17804
|
expect(container.getGroup(name, [ 'totals', 'My Second Portfolio' ]).items.length).toEqual(2);
|
|
17661
17805
|
});
|
|
17806
|
+
|
|
17807
|
+
describe('and an item is pulled for one of the positions', function() {
|
|
17808
|
+
let item;
|
|
17809
|
+
|
|
17810
|
+
let todayYear;
|
|
17811
|
+
let todayMonth;
|
|
17812
|
+
let todayDay;
|
|
17813
|
+
|
|
17814
|
+
beforeEach(() => {
|
|
17815
|
+
item = container.getGroup(name, [ 'totals', 'My First Portfolio' ]).items[0];
|
|
17816
|
+
|
|
17817
|
+
const today = new Date();
|
|
17818
|
+
|
|
17819
|
+
todayYear = today.getFullYear();
|
|
17820
|
+
todayMonth = today.getMonth() + 1;
|
|
17821
|
+
todayDay = today.getDate();
|
|
17822
|
+
});
|
|
17823
|
+
|
|
17824
|
+
it('the current summary should be a YTD summary for this year', () => {
|
|
17825
|
+
expect(item.currentSummary).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YTD && s.start.date.format() === `${(todayYear - 1)}-12-31` && s.end.date.format() === `${(todayYear - 0)}-12-31`));
|
|
17826
|
+
});
|
|
17827
|
+
|
|
17828
|
+
it('should have two previous summaries', () => {
|
|
17829
|
+
expect(item.previousSummaries.length).toEqual(3);
|
|
17830
|
+
});
|
|
17831
|
+
|
|
17832
|
+
it('the previous (x1) summary should be a YEARLY summary for three years ago', () => {
|
|
17833
|
+
expect(item.previousSummaries[0]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 4)}-12-31` && s.end.date.format() === `${(todayYear - 3)}-12-31`));
|
|
17834
|
+
});
|
|
17835
|
+
|
|
17836
|
+
it('the previous (x2) summary should be a YEARLY summary for the year before last', () => {
|
|
17837
|
+
expect(item.previousSummaries[1]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 3)}-12-31` && s.end.date.format() === `${(todayYear - 2)}-12-31`));
|
|
17838
|
+
});
|
|
17839
|
+
|
|
17840
|
+
it('the previous (x3) summary should be a YEARLY summary for last year', () => {
|
|
17841
|
+
expect(item.previousSummaries[2]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 2)}-12-31` && s.end.date.format() === `${(todayYear - 1)}-12-31`));
|
|
17842
|
+
});
|
|
17843
|
+
});
|
|
17662
17844
|
});
|
|
17663
17845
|
});
|
|
17664
17846
|
});
|
|
17665
17847
|
|
|
17666
|
-
},{"./../../../lib/data/InstrumentType":1,"./../../../lib/processing/PositionContainer":6,"./../../../lib/processing/definitions/PositionLevelDefinition":9,"./../../../lib/processing/definitions/PositionLevelType":10,"./../../../lib/processing/definitions/PositionTreeDefinition":11,"@barchart/common-js/lang/Currency":20,"@barchart/common-js/lang/Decimal":22}],55:[function(require,module,exports){
|
|
17848
|
+
},{"./../../../lib/data/InstrumentType":1,"./../../../lib/data/PositionSummaryFrame":3,"./../../../lib/processing/PositionContainer":6,"./../../../lib/processing/definitions/PositionLevelDefinition":9,"./../../../lib/processing/definitions/PositionLevelType":10,"./../../../lib/processing/definitions/PositionTreeDefinition":11,"@barchart/common-js/lang/Currency":20,"@barchart/common-js/lang/Decimal":22}],55:[function(require,module,exports){
|
|
17667
17849
|
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
17668
17850
|
Day = require('@barchart/common-js/lang/Day'),
|
|
17669
17851
|
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
@@ -352,4 +352,74 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
352
352
|
});
|
|
353
353
|
});
|
|
354
354
|
});
|
|
355
|
+
|
|
356
|
+
describe('and recent ranges are calculated', () => {
|
|
357
|
+
let todayYear;
|
|
358
|
+
let todayMonth;
|
|
359
|
+
let todayDay;
|
|
360
|
+
|
|
361
|
+
beforeEach(() => {
|
|
362
|
+
const today = new Date();
|
|
363
|
+
|
|
364
|
+
todayYear = today.getFullYear();
|
|
365
|
+
todayMonth = today.getMonth() + 1;
|
|
366
|
+
todayDay = today.getDate();
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
describe('the most recent YTD frame', () => {
|
|
370
|
+
let ranges;
|
|
371
|
+
|
|
372
|
+
beforeEach(() => {
|
|
373
|
+
ranges = PositionSummaryFrame.YTD.getRecentRanges(0);
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
it('should contain one range', () => {
|
|
377
|
+
expect(ranges.length).toEqual(1);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it('the range should begin at the end of last year', () => {
|
|
381
|
+
expect(ranges[0].start.format()).toEqual(`${todayYear - 1}-12-31`);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it('the range should end at the end of this year', () => {
|
|
385
|
+
expect(ranges[0].end.format()).toEqual(`${todayYear}-12-31`);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
describe('the three most recent YEARLY frames', () => {
|
|
390
|
+
let ranges;
|
|
391
|
+
|
|
392
|
+
beforeEach(() => {
|
|
393
|
+
ranges = PositionSummaryFrame.YEARLY.getRecentRanges(2);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('should contain three range', () => {
|
|
397
|
+
expect(ranges.length).toEqual(3);
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
it('the first range should begin at the end of this year (minus three years)', () => {
|
|
401
|
+
expect(ranges[0].start.format()).toEqual(`${todayYear - 4}-12-31`);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it('the first range should end at the end of this year (minus two years)', () => {
|
|
405
|
+
expect(ranges[0].end.format()).toEqual(`${todayYear - 3}-12-31`);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('the second range should begin at the end of this year (minus two years)', () => {
|
|
409
|
+
expect(ranges[1].start.format()).toEqual(`${todayYear - 3}-12-31`);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it('the second range should end at the end of this year (minus one years)', () => {
|
|
413
|
+
expect(ranges[1].end.format()).toEqual(`${todayYear - 2}-12-31`);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it('the third range should begin at the end of the year before last', () => {
|
|
417
|
+
expect(ranges[2].start.format()).toEqual(`${todayYear - 2}-12-31`);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
it('the third range should end at the end of last year', () => {
|
|
421
|
+
expect(ranges[2].end.format()).toEqual(`${todayYear - 1}-12-31`);
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
});
|
|
355
425
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
2
2
|
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
3
3
|
|
|
4
|
-
const InstrumentType = require('./../../../lib/data/InstrumentType')
|
|
4
|
+
const InstrumentType = require('./../../../lib/data/InstrumentType'),
|
|
5
|
+
PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame');
|
|
5
6
|
|
|
6
7
|
const PositionContainer = require('./../../../lib/processing/PositionContainer'),
|
|
7
8
|
PositionLevelDefinition = require('./../../../lib/processing/definitions/PositionLevelDefinition'),
|
|
@@ -34,6 +35,37 @@ describe('When a position container data is gathered', () => {
|
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
function getSummaries(position, frame, count) {
|
|
39
|
+
const ranges = frame.getRecentRanges(count - 1);
|
|
40
|
+
|
|
41
|
+
return ranges.map((range) => {
|
|
42
|
+
return {
|
|
43
|
+
portfolio: position.portfolio,
|
|
44
|
+
position: position.position,
|
|
45
|
+
frame: frame,
|
|
46
|
+
start: {
|
|
47
|
+
date: range.start,
|
|
48
|
+
open: position.snapshot.open,
|
|
49
|
+
value: position.snapshot.value,
|
|
50
|
+
basis: position.snapshot.basis
|
|
51
|
+
},
|
|
52
|
+
end: {
|
|
53
|
+
date: range.end,
|
|
54
|
+
open: position.snapshot.open,
|
|
55
|
+
value: position.snapshot.value,
|
|
56
|
+
basis: position.snapshot.basis
|
|
57
|
+
},
|
|
58
|
+
period: {
|
|
59
|
+
buys: new Decimal(0),
|
|
60
|
+
sells: new Decimal(0),
|
|
61
|
+
income: new Decimal(0),
|
|
62
|
+
realized: new Decimal(0),
|
|
63
|
+
unrealized: new Decimal(0)
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
37
69
|
describe('for two portfolios, each with the same position, and the second portfolio with an addition position', () => {
|
|
38
70
|
let portfolios;
|
|
39
71
|
let positions;
|
|
@@ -56,7 +88,12 @@ describe('When a position container data is gathered', () => {
|
|
|
56
88
|
getPosition('My Second Portfolio', 'TSLA')
|
|
57
89
|
];
|
|
58
90
|
|
|
59
|
-
summaries =
|
|
91
|
+
summaries = positions.reduce((accumulator, position) => {
|
|
92
|
+
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YTD, 1));
|
|
93
|
+
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YEARLY, 3));
|
|
94
|
+
|
|
95
|
+
return accumulator;
|
|
96
|
+
}, [ ]);
|
|
60
97
|
});
|
|
61
98
|
|
|
62
99
|
describe('and a container is created grouping by total, portfolio, and instrument', () => {
|
|
@@ -103,6 +140,44 @@ describe('When a position container data is gathered', () => {
|
|
|
103
140
|
it('the "b" portfolio group should have two items', () => {
|
|
104
141
|
expect(container.getGroup(name, [ 'totals', 'My Second Portfolio' ]).items.length).toEqual(2);
|
|
105
142
|
});
|
|
143
|
+
|
|
144
|
+
describe('and an item is pulled for one of the positions', function() {
|
|
145
|
+
let item;
|
|
146
|
+
|
|
147
|
+
let todayYear;
|
|
148
|
+
let todayMonth;
|
|
149
|
+
let todayDay;
|
|
150
|
+
|
|
151
|
+
beforeEach(() => {
|
|
152
|
+
item = container.getGroup(name, [ 'totals', 'My First Portfolio' ]).items[0];
|
|
153
|
+
|
|
154
|
+
const today = new Date();
|
|
155
|
+
|
|
156
|
+
todayYear = today.getFullYear();
|
|
157
|
+
todayMonth = today.getMonth() + 1;
|
|
158
|
+
todayDay = today.getDate();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('the current summary should be a YTD summary for this year', () => {
|
|
162
|
+
expect(item.currentSummary).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YTD && s.start.date.format() === `${(todayYear - 1)}-12-31` && s.end.date.format() === `${(todayYear - 0)}-12-31`));
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should have two previous summaries', () => {
|
|
166
|
+
expect(item.previousSummaries.length).toEqual(3);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('the previous (x1) summary should be a YEARLY summary for three years ago', () => {
|
|
170
|
+
expect(item.previousSummaries[0]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 4)}-12-31` && s.end.date.format() === `${(todayYear - 3)}-12-31`));
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('the previous (x2) summary should be a YEARLY summary for the year before last', () => {
|
|
174
|
+
expect(item.previousSummaries[1]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 3)}-12-31` && s.end.date.format() === `${(todayYear - 2)}-12-31`));
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('the previous (x3) summary should be a YEARLY summary for last year', () => {
|
|
178
|
+
expect(item.previousSummaries[2]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 2)}-12-31` && s.end.date.format() === `${(todayYear - 1)}-12-31`));
|
|
179
|
+
});
|
|
180
|
+
});
|
|
106
181
|
});
|
|
107
182
|
});
|
|
108
183
|
});
|