@barchart/portfolio-api-common 1.2.85 → 1.2.86
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
|
|
|
@@ -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
|
|
@@ -124,7 +124,7 @@ module.exports = (() => {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
|
-
* The
|
|
127
|
+
* The current summary of the encapsulated position.
|
|
128
128
|
*
|
|
129
129
|
* @public
|
|
130
130
|
* @returns {Object}
|
|
@@ -134,7 +134,7 @@ module.exports = (() => {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
|
-
* Previous
|
|
137
|
+
* Previous summaries for the encapsulated position.
|
|
138
138
|
*
|
|
139
139
|
* @public
|
|
140
140
|
* @returns {Object}
|
|
@@ -147,7 +147,7 @@ module.exports = (() => {
|
|
|
147
147
|
* Various data regarding the encapsulated position.
|
|
148
148
|
*
|
|
149
149
|
* @public
|
|
150
|
-
* @returns {
|
|
150
|
+
* @returns {Object}
|
|
151
151
|
*/
|
|
152
152
|
get data() {
|
|
153
153
|
return this._data;
|
|
@@ -157,7 +157,7 @@ module.exports = (() => {
|
|
|
157
157
|
* The current quote for the symbol of the encapsulated position.
|
|
158
158
|
*
|
|
159
159
|
* @public
|
|
160
|
-
* @returns {null|
|
|
160
|
+
* @returns {null|Object}
|
|
161
161
|
*/
|
|
162
162
|
get quote() {
|
|
163
163
|
return 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
|
|
|
@@ -3239,8 +3247,8 @@ module.exports = (() => {
|
|
|
3239
3247
|
'use strict';
|
|
3240
3248
|
|
|
3241
3249
|
/**
|
|
3242
|
-
* A container for a single position, which handles quote changes and
|
|
3243
|
-
*
|
|
3250
|
+
* A container for a single position, which handles quote changes and notifies
|
|
3251
|
+
* observers -- which are typically parent-level {@link PositionGroup}
|
|
3244
3252
|
* instances.
|
|
3245
3253
|
*
|
|
3246
3254
|
* @public
|
|
@@ -3352,7 +3360,7 @@ module.exports = (() => {
|
|
|
3352
3360
|
}
|
|
3353
3361
|
|
|
3354
3362
|
/**
|
|
3355
|
-
* The
|
|
3363
|
+
* The current summary of the encapsulated position.
|
|
3356
3364
|
*
|
|
3357
3365
|
* @public
|
|
3358
3366
|
* @returns {Object}
|
|
@@ -3362,7 +3370,7 @@ module.exports = (() => {
|
|
|
3362
3370
|
}
|
|
3363
3371
|
|
|
3364
3372
|
/**
|
|
3365
|
-
* Previous
|
|
3373
|
+
* Previous summaries for the encapsulated position.
|
|
3366
3374
|
*
|
|
3367
3375
|
* @public
|
|
3368
3376
|
* @returns {Object}
|
|
@@ -3375,7 +3383,7 @@ module.exports = (() => {
|
|
|
3375
3383
|
* Various data regarding the encapsulated position.
|
|
3376
3384
|
*
|
|
3377
3385
|
* @public
|
|
3378
|
-
* @returns {
|
|
3386
|
+
* @returns {Object}
|
|
3379
3387
|
*/
|
|
3380
3388
|
get data() {
|
|
3381
3389
|
return this._data;
|
|
@@ -3385,7 +3393,7 @@ module.exports = (() => {
|
|
|
3385
3393
|
* The current quote for the symbol of the encapsulated position.
|
|
3386
3394
|
*
|
|
3387
3395
|
* @public
|
|
3388
|
-
* @returns {null|
|
|
3396
|
+
* @returns {null|Object}
|
|
3389
3397
|
*/
|
|
3390
3398
|
get quote() {
|
|
3391
3399
|
return this._currentQuote;
|
|
@@ -17456,6 +17464,76 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17456
17464
|
});
|
|
17457
17465
|
});
|
|
17458
17466
|
});
|
|
17467
|
+
|
|
17468
|
+
describe('and recent ranges are calculated', () => {
|
|
17469
|
+
let todayYear;
|
|
17470
|
+
let todayMonth;
|
|
17471
|
+
let todayDay;
|
|
17472
|
+
|
|
17473
|
+
beforeEach(() => {
|
|
17474
|
+
const today = new Date();
|
|
17475
|
+
|
|
17476
|
+
todayYear = today.getFullYear();
|
|
17477
|
+
todayMonth = today.getMonth() + 1;
|
|
17478
|
+
todayDay = today.getDate();
|
|
17479
|
+
});
|
|
17480
|
+
|
|
17481
|
+
describe('the most recent YTD frame', () => {
|
|
17482
|
+
let ranges;
|
|
17483
|
+
|
|
17484
|
+
beforeEach(() => {
|
|
17485
|
+
ranges = PositionSummaryFrame.YTD.getRecentRanges(0);
|
|
17486
|
+
});
|
|
17487
|
+
|
|
17488
|
+
it('should contain one range', () => {
|
|
17489
|
+
expect(ranges.length).toEqual(1);
|
|
17490
|
+
});
|
|
17491
|
+
|
|
17492
|
+
it('the range should begin at the end of last year', () => {
|
|
17493
|
+
expect(ranges[0].start.format()).toEqual(`${todayYear - 1}-12-31`);
|
|
17494
|
+
});
|
|
17495
|
+
|
|
17496
|
+
it('the range should end at the end of this year', () => {
|
|
17497
|
+
expect(ranges[0].end.format()).toEqual(`${todayYear}-12-31`);
|
|
17498
|
+
});
|
|
17499
|
+
});
|
|
17500
|
+
|
|
17501
|
+
describe('the three most recent YEARLY frames', () => {
|
|
17502
|
+
let ranges;
|
|
17503
|
+
|
|
17504
|
+
beforeEach(() => {
|
|
17505
|
+
ranges = PositionSummaryFrame.YEARLY.getRecentRanges(2);
|
|
17506
|
+
});
|
|
17507
|
+
|
|
17508
|
+
it('should contain three range', () => {
|
|
17509
|
+
expect(ranges.length).toEqual(3);
|
|
17510
|
+
});
|
|
17511
|
+
|
|
17512
|
+
it('the first range should begin at the end of this year (minus three years)', () => {
|
|
17513
|
+
expect(ranges[0].start.format()).toEqual(`${todayYear - 4}-12-31`);
|
|
17514
|
+
});
|
|
17515
|
+
|
|
17516
|
+
it('the first range should end at the end of this year (minus two years)', () => {
|
|
17517
|
+
expect(ranges[0].end.format()).toEqual(`${todayYear - 3}-12-31`);
|
|
17518
|
+
});
|
|
17519
|
+
|
|
17520
|
+
it('the second range should begin at the end of this year (minus two years)', () => {
|
|
17521
|
+
expect(ranges[1].start.format()).toEqual(`${todayYear - 3}-12-31`);
|
|
17522
|
+
});
|
|
17523
|
+
|
|
17524
|
+
it('the second range should end at the end of this year (minus one years)', () => {
|
|
17525
|
+
expect(ranges[1].end.format()).toEqual(`${todayYear - 2}-12-31`);
|
|
17526
|
+
});
|
|
17527
|
+
|
|
17528
|
+
it('the third range should begin at the end of the year before last', () => {
|
|
17529
|
+
expect(ranges[2].start.format()).toEqual(`${todayYear - 2}-12-31`);
|
|
17530
|
+
});
|
|
17531
|
+
|
|
17532
|
+
it('the third range should end at the end of last year', () => {
|
|
17533
|
+
expect(ranges[2].end.format()).toEqual(`${todayYear - 1}-12-31`);
|
|
17534
|
+
});
|
|
17535
|
+
});
|
|
17536
|
+
});
|
|
17459
17537
|
});
|
|
17460
17538
|
|
|
17461
17539
|
},{"./../../../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 +17635,8 @@ describe('When requesting all the user-initiated transaction types', () => {
|
|
|
17557
17635
|
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
17558
17636
|
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
17559
17637
|
|
|
17560
|
-
const InstrumentType = require('./../../../lib/data/InstrumentType')
|
|
17638
|
+
const InstrumentType = require('./../../../lib/data/InstrumentType'),
|
|
17639
|
+
PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame');
|
|
17561
17640
|
|
|
17562
17641
|
const PositionContainer = require('./../../../lib/processing/PositionContainer'),
|
|
17563
17642
|
PositionLevelDefinition = require('./../../../lib/processing/definitions/PositionLevelDefinition'),
|
|
@@ -17590,6 +17669,37 @@ describe('When a position container data is gathered', () => {
|
|
|
17590
17669
|
};
|
|
17591
17670
|
}
|
|
17592
17671
|
|
|
17672
|
+
function getSummaries(position, frame, count) {
|
|
17673
|
+
const ranges = frame.getRecentRanges(count - 1);
|
|
17674
|
+
|
|
17675
|
+
return ranges.map((range) => {
|
|
17676
|
+
return {
|
|
17677
|
+
portfolio: position.portfolio,
|
|
17678
|
+
position: position.position,
|
|
17679
|
+
frame: frame,
|
|
17680
|
+
start: {
|
|
17681
|
+
date: range.start,
|
|
17682
|
+
open: position.snapshot.open,
|
|
17683
|
+
value: position.snapshot.value,
|
|
17684
|
+
basis: position.snapshot.basis
|
|
17685
|
+
},
|
|
17686
|
+
end: {
|
|
17687
|
+
date: range.end,
|
|
17688
|
+
open: position.snapshot.open,
|
|
17689
|
+
value: position.snapshot.value,
|
|
17690
|
+
basis: position.snapshot.basis
|
|
17691
|
+
},
|
|
17692
|
+
period: {
|
|
17693
|
+
buys: new Decimal(0),
|
|
17694
|
+
sells: new Decimal(0),
|
|
17695
|
+
income: new Decimal(0),
|
|
17696
|
+
realized: new Decimal(0),
|
|
17697
|
+
unrealized: new Decimal(0)
|
|
17698
|
+
}
|
|
17699
|
+
};
|
|
17700
|
+
});
|
|
17701
|
+
}
|
|
17702
|
+
|
|
17593
17703
|
describe('for two portfolios, each with the same position, and the second portfolio with an addition position', () => {
|
|
17594
17704
|
let portfolios;
|
|
17595
17705
|
let positions;
|
|
@@ -17612,7 +17722,12 @@ describe('When a position container data is gathered', () => {
|
|
|
17612
17722
|
getPosition('My Second Portfolio', 'TSLA')
|
|
17613
17723
|
];
|
|
17614
17724
|
|
|
17615
|
-
summaries =
|
|
17725
|
+
summaries = positions.reduce((accumulator, position) => {
|
|
17726
|
+
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YTD, 1));
|
|
17727
|
+
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YEARLY, 3));
|
|
17728
|
+
|
|
17729
|
+
return accumulator;
|
|
17730
|
+
}, [ ]);
|
|
17616
17731
|
});
|
|
17617
17732
|
|
|
17618
17733
|
describe('and a container is created grouping by total, portfolio, and instrument', () => {
|
|
@@ -17659,11 +17774,49 @@ describe('When a position container data is gathered', () => {
|
|
|
17659
17774
|
it('the "b" portfolio group should have two items', () => {
|
|
17660
17775
|
expect(container.getGroup(name, [ 'totals', 'My Second Portfolio' ]).items.length).toEqual(2);
|
|
17661
17776
|
});
|
|
17777
|
+
|
|
17778
|
+
describe('and an item is pulled for one of the positions', function() {
|
|
17779
|
+
let item;
|
|
17780
|
+
|
|
17781
|
+
let todayYear;
|
|
17782
|
+
let todayMonth;
|
|
17783
|
+
let todayDay;
|
|
17784
|
+
|
|
17785
|
+
beforeEach(() => {
|
|
17786
|
+
item = container.getGroup(name, [ 'totals', 'My First Portfolio' ]).items[0];
|
|
17787
|
+
|
|
17788
|
+
const today = new Date();
|
|
17789
|
+
|
|
17790
|
+
todayYear = today.getFullYear();
|
|
17791
|
+
todayMonth = today.getMonth() + 1;
|
|
17792
|
+
todayDay = today.getDate();
|
|
17793
|
+
});
|
|
17794
|
+
|
|
17795
|
+
it('the current summary should be a YTD summary for this year', () => {
|
|
17796
|
+
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`));
|
|
17797
|
+
});
|
|
17798
|
+
|
|
17799
|
+
it('should have two previous summaries', () => {
|
|
17800
|
+
expect(item.previousSummaries.length).toEqual(3);
|
|
17801
|
+
});
|
|
17802
|
+
|
|
17803
|
+
it('the previous (x1) summary should be a YEARLY summary for three years ago', () => {
|
|
17804
|
+
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`));
|
|
17805
|
+
});
|
|
17806
|
+
|
|
17807
|
+
it('the previous (x2) summary should be a YEARLY summary for the year before last', () => {
|
|
17808
|
+
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`));
|
|
17809
|
+
});
|
|
17810
|
+
|
|
17811
|
+
it('the previous (x3) summary should be a YEARLY summary for last year', () => {
|
|
17812
|
+
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`));
|
|
17813
|
+
});
|
|
17814
|
+
});
|
|
17662
17815
|
});
|
|
17663
17816
|
});
|
|
17664
17817
|
});
|
|
17665
17818
|
|
|
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){
|
|
17819
|
+
},{"./../../../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
17820
|
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
17668
17821
|
Day = require('@barchart/common-js/lang/Day'),
|
|
17669
17822
|
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
|
});
|