@barchart/portfolio-api-common 1.2.125 → 1.2.126

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.
@@ -243,27 +243,25 @@ module.exports = (() => {
243
243
  function getMonthlyRanges(transactions) {
244
244
  const ranges = [ ];
245
245
 
246
- if (!transactions.length) {
247
- return ranges;
248
- }
249
-
250
- const first = array.first(transactions);
251
- const last = array.last(transactions);
246
+ if (transactions.length !== 0) {
247
+ const first = array.first(transactions);
248
+ const last = array.last(transactions);
252
249
 
253
- const firstDate = first.date;
250
+ const firstDate = first.date;
254
251
 
255
- let lastDate;
252
+ let lastDate;
256
253
 
257
- if (last.snapshot.open.getIsZero()) {
258
- lastDate = new Day(last.date.year, last.date.month, last.date.day).addMonths(1);
259
- } else {
260
- lastDate = Day.getToday();
261
- }
254
+ if (last.snapshot.open.getIsZero()) {
255
+ lastDate = last.date;
256
+ } else {
257
+ lastDate = Day.getToday();
258
+ }
262
259
 
263
- lastDate = lastDate.getEndOfMonth();
260
+ lastDate = lastDate.getEndOfMonth();
264
261
 
265
- for (let end = firstDate.getEndOfMonth(); end.format() <= lastDate.format(); end = end.addMonths(1).getEndOfMonth()) {
266
- ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
262
+ for (let end = firstDate.getEndOfMonth(); !end.getIsAfter(lastDate); end = end.addMonths(1).getEndOfMonth()) {
263
+ ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
264
+ }
267
265
  }
268
266
 
269
267
  return ranges;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.2.125",
3
+ "version": "1.2.126",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -634,27 +634,25 @@ module.exports = (() => {
634
634
  function getMonthlyRanges(transactions) {
635
635
  const ranges = [ ];
636
636
 
637
- if (!transactions.length) {
638
- return ranges;
639
- }
640
-
641
- const first = array.first(transactions);
642
- const last = array.last(transactions);
637
+ if (transactions.length !== 0) {
638
+ const first = array.first(transactions);
639
+ const last = array.last(transactions);
643
640
 
644
- const firstDate = first.date;
641
+ const firstDate = first.date;
645
642
 
646
- let lastDate;
643
+ let lastDate;
647
644
 
648
- if (last.snapshot.open.getIsZero()) {
649
- lastDate = new Day(last.date.year, last.date.month, last.date.day).addMonths(1);
650
- } else {
651
- lastDate = Day.getToday();
652
- }
645
+ if (last.snapshot.open.getIsZero()) {
646
+ lastDate = last.date;
647
+ } else {
648
+ lastDate = Day.getToday();
649
+ }
653
650
 
654
- lastDate = lastDate.getEndOfMonth();
651
+ lastDate = lastDate.getEndOfMonth();
655
652
 
656
- for (let end = firstDate.getEndOfMonth(); end.format() <= lastDate.format(); end = end.addMonths(1).getEndOfMonth()) {
657
- ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
653
+ for (let end = firstDate.getEndOfMonth(); !end.getIsAfter(lastDate); end = end.addMonths(1).getEndOfMonth()) {
654
+ ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
655
+ }
658
656
  }
659
657
 
660
658
  return ranges;
@@ -17860,7 +17858,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17860
17858
  });
17861
17859
  });
17862
17860
 
17863
- describe('and yearly position summary ranges are processed for a transaction set that opens in 2019 and closes in 2016, but has after-the-fact superfluous valuations in 2017 and 2018', () => {
17861
+ describe('and yearly position summary ranges are processed for a transaction set that opens in 2015 and closes in 2016, but has after-the-fact superfluous valuations in 2017 and 2018', () => {
17864
17862
  let ranges;
17865
17863
 
17866
17864
  beforeEach(() => {
@@ -17913,6 +17911,120 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17913
17911
  });
17914
17912
  });
17915
17913
 
17914
+ describe('and monthly position summary ranges are processed for a transaction set that does not close', () => {
17915
+ let ranges;
17916
+
17917
+ beforeEach(() => {
17918
+ const transactions = [
17919
+ {
17920
+ date: new Day(2019, 1, 20),
17921
+ snapshot: {
17922
+ open: new Decimal(1)
17923
+ },
17924
+ type: TransactionType.BUY
17925
+ },
17926
+ {
17927
+ date: new Day(2019, 2, 21),
17928
+ snapshot: {
17929
+ open: new Decimal(1)
17930
+ },
17931
+ type: TransactionType.BUY
17932
+ }
17933
+ ];
17934
+
17935
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
17936
+ });
17937
+
17938
+ it('should have at least two ranges', () => {
17939
+ expect(ranges.length > 1).toEqual(true);
17940
+ });
17941
+
17942
+ it('the first range should be from 12-31-2018 to 01-31-2019', () => {
17943
+ expect(ranges[0].start.format()).toEqual('2018-12-31');
17944
+ expect(ranges[0].end.format()).toEqual('2019-01-31');
17945
+ });
17946
+
17947
+ it('the last range should be for the current month', () => {
17948
+ const today = Day.getToday();
17949
+
17950
+ expect(ranges[ranges.length - 1].start.format()).toEqual(today.getEndOfMonth().subtractMonths(1).getEndOfMonth().format());
17951
+ expect(ranges[ranges.length - 1].end.format()).toEqual(today.getEndOfMonth().format());
17952
+ });
17953
+ });
17954
+
17955
+ describe('and monthly position summary ranges are processed for a transaction set closes the same month', () => {
17956
+ let ranges;
17957
+
17958
+ beforeEach(() => {
17959
+ const transactions = [
17960
+ {
17961
+ date: new Day(2018, 12, 1),
17962
+ snapshot: {
17963
+ open: new Decimal(1)
17964
+ },
17965
+ type: TransactionType.BUY
17966
+ },
17967
+ {
17968
+ date: new Day(2018, 12, 31),
17969
+ snapshot: {
17970
+ open: new Decimal(0)
17971
+ },
17972
+ type: TransactionType.SELL
17973
+ }
17974
+ ];
17975
+
17976
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
17977
+ });
17978
+
17979
+ it('should have one range', () => {
17980
+ expect(ranges.length).toEqual(1);
17981
+ });
17982
+
17983
+ it('the first range should be from 11-30-2018 to 12-31-2018', () => {
17984
+ expect(ranges[0].start.format()).toEqual('2018-11-30');
17985
+ expect(ranges[0].end.format()).toEqual('2018-12-31');
17986
+ });
17987
+ });
17988
+
17989
+ describe('and monthly position summary ranges are processed for a transaction set closes the next month', () => {
17990
+ let ranges;
17991
+
17992
+ beforeEach(() => {
17993
+ const transactions = [
17994
+ {
17995
+ date: new Day(2015, 10, 20),
17996
+ snapshot: {
17997
+ open: new Decimal(1)
17998
+ },
17999
+ type: TransactionType.BUY
18000
+ },
18001
+ {
18002
+ date: new Day(2015, 11, 20),
18003
+ snapshot: {
18004
+ open: new Decimal(0)
18005
+ },
18006
+ type: TransactionType.SELL
18007
+ }
18008
+ ];
18009
+
18010
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
18011
+ });
18012
+
18013
+ it('should have two ranges', () => {
18014
+ expect(ranges.length).toEqual(2);
18015
+ });
18016
+
18017
+ it('the first range should be from 09-30-2015 to 10-31-2015', () => {
18018
+ expect(ranges[0].start.format()).toEqual('2015-09-30');
18019
+ expect(ranges[0].end.format()).toEqual('2015-10-31');
18020
+ });
18021
+
18022
+ it('the second range should be from 10-31-2015 to 11-30-2015', () => {
18023
+ expect(ranges[1].start.format()).toEqual('2015-10-31');
18024
+ expect(ranges[1].end.format()).toEqual('2015-11-30');
18025
+ });
18026
+ });
18027
+
17916
18028
  describe('and a year-to-date position summary ranges are processed for a transaction set that closed in 2017', () => {
17917
18029
  let ranges;
17918
18030
 
@@ -173,7 +173,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
173
173
  });
174
174
  });
175
175
 
176
- describe('and yearly position summary ranges are processed for a transaction set that opens in 2019 and closes in 2016, but has after-the-fact superfluous valuations in 2017 and 2018', () => {
176
+ describe('and yearly position summary ranges are processed for a transaction set that opens in 2015 and closes in 2016, but has after-the-fact superfluous valuations in 2017 and 2018', () => {
177
177
  let ranges;
178
178
 
179
179
  beforeEach(() => {
@@ -226,6 +226,120 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
226
226
  });
227
227
  });
228
228
 
229
+ describe('and monthly position summary ranges are processed for a transaction set that does not close', () => {
230
+ let ranges;
231
+
232
+ beforeEach(() => {
233
+ const transactions = [
234
+ {
235
+ date: new Day(2019, 1, 20),
236
+ snapshot: {
237
+ open: new Decimal(1)
238
+ },
239
+ type: TransactionType.BUY
240
+ },
241
+ {
242
+ date: new Day(2019, 2, 21),
243
+ snapshot: {
244
+ open: new Decimal(1)
245
+ },
246
+ type: TransactionType.BUY
247
+ }
248
+ ];
249
+
250
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
251
+ });
252
+
253
+ it('should have at least two ranges', () => {
254
+ expect(ranges.length > 1).toEqual(true);
255
+ });
256
+
257
+ it('the first range should be from 12-31-2018 to 01-31-2019', () => {
258
+ expect(ranges[0].start.format()).toEqual('2018-12-31');
259
+ expect(ranges[0].end.format()).toEqual('2019-01-31');
260
+ });
261
+
262
+ it('the last range should be for the current month', () => {
263
+ const today = Day.getToday();
264
+
265
+ expect(ranges[ranges.length - 1].start.format()).toEqual(today.getEndOfMonth().subtractMonths(1).getEndOfMonth().format());
266
+ expect(ranges[ranges.length - 1].end.format()).toEqual(today.getEndOfMonth().format());
267
+ });
268
+ });
269
+
270
+ describe('and monthly position summary ranges are processed for a transaction set closes the same month', () => {
271
+ let ranges;
272
+
273
+ beforeEach(() => {
274
+ const transactions = [
275
+ {
276
+ date: new Day(2018, 12, 1),
277
+ snapshot: {
278
+ open: new Decimal(1)
279
+ },
280
+ type: TransactionType.BUY
281
+ },
282
+ {
283
+ date: new Day(2018, 12, 31),
284
+ snapshot: {
285
+ open: new Decimal(0)
286
+ },
287
+ type: TransactionType.SELL
288
+ }
289
+ ];
290
+
291
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
292
+ });
293
+
294
+ it('should have one range', () => {
295
+ expect(ranges.length).toEqual(1);
296
+ });
297
+
298
+ it('the first range should be from 11-30-2018 to 12-31-2018', () => {
299
+ expect(ranges[0].start.format()).toEqual('2018-11-30');
300
+ expect(ranges[0].end.format()).toEqual('2018-12-31');
301
+ });
302
+ });
303
+
304
+ describe('and monthly position summary ranges are processed for a transaction set closes the next month', () => {
305
+ let ranges;
306
+
307
+ beforeEach(() => {
308
+ const transactions = [
309
+ {
310
+ date: new Day(2015, 10, 20),
311
+ snapshot: {
312
+ open: new Decimal(1)
313
+ },
314
+ type: TransactionType.BUY
315
+ },
316
+ {
317
+ date: new Day(2015, 11, 20),
318
+ snapshot: {
319
+ open: new Decimal(0)
320
+ },
321
+ type: TransactionType.SELL
322
+ }
323
+ ];
324
+
325
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
326
+ });
327
+
328
+ it('should have two ranges', () => {
329
+ expect(ranges.length).toEqual(2);
330
+ });
331
+
332
+ it('the first range should be from 09-30-2015 to 10-31-2015', () => {
333
+ expect(ranges[0].start.format()).toEqual('2015-09-30');
334
+ expect(ranges[0].end.format()).toEqual('2015-10-31');
335
+ });
336
+
337
+ it('the second range should be from 10-31-2015 to 11-30-2015', () => {
338
+ expect(ranges[1].start.format()).toEqual('2015-10-31');
339
+ expect(ranges[1].end.format()).toEqual('2015-11-30');
340
+ });
341
+ });
342
+
229
343
  describe('and a year-to-date position summary ranges are processed for a transaction set that closed in 2017', () => {
230
344
  let ranges;
231
345