@barchart/portfolio-api-common 1.2.113 → 1.2.117

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.
@@ -241,7 +241,32 @@ module.exports = (() => {
241
241
  }
242
242
 
243
243
  function getMonthlyRanges(transactions) {
244
- return [ ];
244
+ const ranges = [ ];
245
+
246
+ if (!transactions.length) {
247
+ return ranges;
248
+ }
249
+
250
+ const first = array.first(transactions);
251
+ const last = array.last(transactions);
252
+
253
+ const firstDate = first.date;
254
+ let lastDate;
255
+
256
+ lastDate = last.snapshot.open.getIsZero()
257
+ ? new Day(last.date.year, last.date.month, last.date.day).addMonths(1)
258
+ : Day.getToday();
259
+ lastDate = lastDate.getEndOfMonth();
260
+
261
+ for (
262
+ let end = firstDate.getEndOfMonth();
263
+ end.format() <= lastDate.format();
264
+ end = end.addMonths(1).getEndOfMonth()
265
+ ) {
266
+ ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
267
+ }
268
+
269
+ return ranges;
245
270
  }
246
271
 
247
272
  function getYearToDateRanges(transactions) {
@@ -278,7 +303,11 @@ module.exports = (() => {
278
303
  }
279
304
 
280
305
  function getMonthlyStartDate(periods, date) {
281
- return null;
306
+ const today = date || Day.getToday();
307
+
308
+ return today
309
+ .subtractMonths(periods)
310
+ .subtractDays(today.day);
282
311
  }
283
312
 
284
313
  function getYearToDateStartDate(periods, date) {
@@ -352,6 +352,17 @@ module.exports = (() => {
352
352
  static get DEBIT() {
353
353
  return debit;
354
354
  }
355
+
356
+ /**
357
+ * A system-generated transaction, indicating the security has stopped active trading.
358
+ *
359
+ * @public
360
+ * @static
361
+ * @returns {TransactionType}
362
+ */
363
+ static get DELIST() {
364
+ return delist;
365
+ }
355
366
 
356
367
  /**
357
368
  * A system-generated deposit, arising from another transaction.
@@ -401,6 +412,7 @@ module.exports = (() => {
401
412
  const split = new TransactionType('SP', 'Split', 'Split', 1, false, false, false, true, false, false, true, false, false);
402
413
  const fee = new TransactionType('F', 'Fee', 'Fee', 0, false, false, false, false, false, true, false, false, false);
403
414
  const feeUnits = new TransactionType('FU', 'Fee Units', 'Fee', 0, false, false, false, false, true, false, false, false, false);
415
+ const delist = new TransactionType('DL', 'Delist', 'Delist', 0, false, false, false, false, false, false, false, false, false);
404
416
 
405
417
  const distributionCash = new TransactionType('DC', 'Distribution (Cash)', 'Cash Distribution', 1, false, false, true, false, false, false, true, false, false);
406
418
  const distributionReinvest = new TransactionType('DY', 'Distribution (Reinvested)', 'Distribution Reinvest', 1, false, false, false, true, false, false, true, false, false);
@@ -244,6 +244,7 @@ module.exports = (() => {
244
244
  associateTypes(InstrumentType.EQUITY, TransactionType.DIVIDEND_REINVEST, false);
245
245
  associateTypes(InstrumentType.EQUITY, TransactionType.DIVIDEND_STOCK, false);
246
246
  associateTypes(InstrumentType.EQUITY, TransactionType.SPLIT, false);
247
+ associateTypes(InstrumentType.EQUITY, TransactionType.DELIST, false);
247
248
 
248
249
  associateTypes(InstrumentType.FUND, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
249
250
  associateTypes(InstrumentType.FUND, TransactionType.SELL, true, [ PositionDirection.LONG ]);
@@ -252,6 +253,7 @@ module.exports = (() => {
252
253
  associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_CASH, false);
253
254
  associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_REINVEST, false);
254
255
  associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_FUND, false);
256
+ associateTypes(InstrumentType.FUND, TransactionType.DELIST, false);
255
257
 
256
258
  associateTypes(InstrumentType.OTHER, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
257
259
  associateTypes(InstrumentType.OTHER, TransactionType.SELL, true, [ PositionDirection.LONG ]);
@@ -216,7 +216,7 @@ module.exports = (() => {
216
216
  formatters.set(TransactionType.INCOME, (t) => {
217
217
  return {
218
218
  total: t.income.amount
219
- };
219
+ };
220
220
  });
221
221
 
222
222
  formatters.set(TransactionType.FEE, (t) => {
@@ -254,6 +254,10 @@ module.exports = (() => {
254
254
  price: rate
255
255
  };
256
256
  });
257
+
258
+ formatters.set(TransactionType.DELIST, () => {
259
+ return { };
260
+ });
257
261
 
258
262
  const cashFormatter = (t) => {
259
263
  return {
@@ -298,4 +302,4 @@ module.exports = (() => {
298
302
  .toComparator();
299
303
 
300
304
  return TransactionFormatter;
301
- })();
305
+ })();
@@ -786,9 +786,9 @@ module.exports = (() => {
786
786
  actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
787
787
  actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
788
788
 
789
- actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
790
- actual.periodPercentPrevious = calculatePeriodPercent(actual.periodRealizedPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedPrevious, actual.periodUnrealizedBasisPrevious);
791
- actual.periodPercentPrevious2 = calculatePeriodPercent(actual.periodRealizedPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedPrevious2, actual.periodUnrealizedBasisPrevious2);
789
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
790
+ actual.periodPercentPrevious = calculatePeriodPercent(actual.summaryTotalPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedBasisPrevious);
791
+ actual.periodPercentPrevious2 = calculatePeriodPercent(actual.summaryTotalPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedBasisPrevious2);
792
792
 
793
793
  format.periodPercent = formatPercent(actual.periodPercent, 2);
794
794
  format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
@@ -921,7 +921,7 @@ module.exports = (() => {
921
921
  if (group.single && item) {
922
922
  actual.periodUnrealized = item.data.periodUnrealized;
923
923
 
924
- actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
924
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
925
925
  format.periodPercent = formatPercent(actual.periodPercent, 2);
926
926
  }
927
927
  }
@@ -982,8 +982,8 @@ module.exports = (() => {
982
982
  }
983
983
  }
984
984
 
985
- function calculatePeriodPercent(realized, realizedBasis, unrealized, unrealizedBasis) {
986
- const numerator = realized.add(unrealized);
985
+ function calculatePeriodPercent(periodSummaryTotal, realizedBasis, unrealizedBasis) {
986
+ const numerator = periodSummaryTotal;
987
987
  const denominator = realizedBasis.add(unrealizedBasis);
988
988
 
989
989
  return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
@@ -648,8 +648,6 @@ module.exports = (() => {
648
648
  let returnRef;
649
649
 
650
650
  if (currentSummary) {
651
- const period = currentSummary.period;
652
-
653
651
  returnRef = currentSummary.end.basis.absolute();
654
652
  } else {
655
653
  returnRef = Decimal.ZERO;
@@ -113,6 +113,10 @@ module.exports = (() => {
113
113
  static get VALUATION() {
114
114
  return valuation;
115
115
  }
116
+
117
+ static get DELIST() {
118
+ return delist;
119
+ }
116
120
 
117
121
  static get INCOME() {
118
122
  return income;
@@ -322,8 +326,18 @@ module.exports = (() => {
322
326
  .withField('force', DataType.BOOLEAN, true)
323
327
  .schema
324
328
  );
325
-
326
- const income = new TransactionSchema(SchemaBuilder.withName(TransactionType.INCOME.code)
329
+
330
+ const delist = new TransactionSchema(SchemaBuilder.withName(TransactionType.DELIST.code)
331
+ .withField('portfolio', DataType.STRING)
332
+ .withField('position', DataType.STRING)
333
+ .withField('sequence', DataType.NUMBER, true)
334
+ .withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
335
+ .withField('date', DataType.DAY)
336
+ .withField('force', DataType.BOOLEAN, true)
337
+ .schema
338
+ );
339
+
340
+ const income = new TransactionSchema(SchemaBuilder.withName(TransactionType.INCOME.code)
327
341
  .withField('portfolio', DataType.STRING)
328
342
  .withField('position', DataType.STRING)
329
343
  .withField('sequence', DataType.NUMBER, true)
@@ -349,6 +363,7 @@ module.exports = (() => {
349
363
  addSchemaToMap(TransactionType.DEPOSIT, deposit);
350
364
  addSchemaToMap(TransactionType.WITHDRAWAL, withdrawal);
351
365
  addSchemaToMap(TransactionType.VALUATION, valuation);
366
+ addSchemaToMap(TransactionType.DELIST, delist);
352
367
  addSchemaToMap(TransactionType.INCOME, income);
353
368
 
354
369
  return TransactionSchema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.2.113",
3
+ "version": "1.2.117",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -632,7 +632,32 @@ module.exports = (() => {
632
632
  }
633
633
 
634
634
  function getMonthlyRanges(transactions) {
635
- return [ ];
635
+ const ranges = [ ];
636
+
637
+ if (!transactions.length) {
638
+ return ranges;
639
+ }
640
+
641
+ const first = array.first(transactions);
642
+ const last = array.last(transactions);
643
+
644
+ const firstDate = first.date;
645
+ let lastDate;
646
+
647
+ lastDate = last.snapshot.open.getIsZero()
648
+ ? new Day(last.date.year, last.date.month, last.date.day).addMonths(1)
649
+ : Day.getToday();
650
+ lastDate = lastDate.getEndOfMonth();
651
+
652
+ for (
653
+ let end = firstDate.getEndOfMonth();
654
+ end.format() <= lastDate.format();
655
+ end = end.addMonths(1).getEndOfMonth()
656
+ ) {
657
+ ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
658
+ }
659
+
660
+ return ranges;
636
661
  }
637
662
 
638
663
  function getYearToDateRanges(transactions) {
@@ -669,7 +694,11 @@ module.exports = (() => {
669
694
  }
670
695
 
671
696
  function getMonthlyStartDate(periods, date) {
672
- return null;
697
+ const today = date || Day.getToday();
698
+
699
+ return today
700
+ .subtractMonths(periods)
701
+ .subtractDays(today.day);
673
702
  }
674
703
 
675
704
  function getYearToDateStartDate(periods, date) {
@@ -1060,6 +1089,17 @@ module.exports = (() => {
1060
1089
  static get DEBIT() {
1061
1090
  return debit;
1062
1091
  }
1092
+
1093
+ /**
1094
+ * A system-generated transaction, indicating the security has stopped active trading.
1095
+ *
1096
+ * @public
1097
+ * @static
1098
+ * @returns {TransactionType}
1099
+ */
1100
+ static get DELIST() {
1101
+ return delist;
1102
+ }
1063
1103
 
1064
1104
  /**
1065
1105
  * A system-generated deposit, arising from another transaction.
@@ -1109,6 +1149,7 @@ module.exports = (() => {
1109
1149
  const split = new TransactionType('SP', 'Split', 'Split', 1, false, false, false, true, false, false, true, false, false);
1110
1150
  const fee = new TransactionType('F', 'Fee', 'Fee', 0, false, false, false, false, false, true, false, false, false);
1111
1151
  const feeUnits = new TransactionType('FU', 'Fee Units', 'Fee', 0, false, false, false, false, true, false, false, false, false);
1152
+ const delist = new TransactionType('DL', 'Delist', 'Delist', 0, false, false, false, false, false, false, false, false, false);
1112
1153
 
1113
1154
  const distributionCash = new TransactionType('DC', 'Distribution (Cash)', 'Cash Distribution', 1, false, false, true, false, false, false, true, false, false);
1114
1155
  const distributionReinvest = new TransactionType('DY', 'Distribution (Reinvested)', 'Distribution Reinvest', 1, false, false, false, true, false, false, true, false, false);
@@ -1372,6 +1413,7 @@ module.exports = (() => {
1372
1413
  associateTypes(InstrumentType.EQUITY, TransactionType.DIVIDEND_REINVEST, false);
1373
1414
  associateTypes(InstrumentType.EQUITY, TransactionType.DIVIDEND_STOCK, false);
1374
1415
  associateTypes(InstrumentType.EQUITY, TransactionType.SPLIT, false);
1416
+ associateTypes(InstrumentType.EQUITY, TransactionType.DELIST, false);
1375
1417
 
1376
1418
  associateTypes(InstrumentType.FUND, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
1377
1419
  associateTypes(InstrumentType.FUND, TransactionType.SELL, true, [ PositionDirection.LONG ]);
@@ -1380,6 +1422,7 @@ module.exports = (() => {
1380
1422
  associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_CASH, false);
1381
1423
  associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_REINVEST, false);
1382
1424
  associateTypes(InstrumentType.FUND, TransactionType.DISTRIBUTION_FUND, false);
1425
+ associateTypes(InstrumentType.FUND, TransactionType.DELIST, false);
1383
1426
 
1384
1427
  associateTypes(InstrumentType.OTHER, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
1385
1428
  associateTypes(InstrumentType.OTHER, TransactionType.SELL, true, [ PositionDirection.LONG ]);
@@ -3246,9 +3289,9 @@ module.exports = (() => {
3246
3289
  actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
3247
3290
  actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
3248
3291
 
3249
- actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
3250
- actual.periodPercentPrevious = calculatePeriodPercent(actual.periodRealizedPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedPrevious, actual.periodUnrealizedBasisPrevious);
3251
- actual.periodPercentPrevious2 = calculatePeriodPercent(actual.periodRealizedPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedPrevious2, actual.periodUnrealizedBasisPrevious2);
3292
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
3293
+ actual.periodPercentPrevious = calculatePeriodPercent(actual.summaryTotalPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedBasisPrevious);
3294
+ actual.periodPercentPrevious2 = calculatePeriodPercent(actual.summaryTotalPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedBasisPrevious2);
3252
3295
 
3253
3296
  format.periodPercent = formatPercent(actual.periodPercent, 2);
3254
3297
  format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
@@ -3381,7 +3424,7 @@ module.exports = (() => {
3381
3424
  if (group.single && item) {
3382
3425
  actual.periodUnrealized = item.data.periodUnrealized;
3383
3426
 
3384
- actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
3427
+ actual.periodPercent = calculatePeriodPercent(actual.summaryTotalCurrent, actual.periodRealizedBasis, actual.periodUnrealizedBasis);
3385
3428
  format.periodPercent = formatPercent(actual.periodPercent, 2);
3386
3429
  }
3387
3430
  }
@@ -3442,8 +3485,8 @@ module.exports = (() => {
3442
3485
  }
3443
3486
  }
3444
3487
 
3445
- function calculatePeriodPercent(realized, realizedBasis, unrealized, unrealizedBasis) {
3446
- const numerator = realized.add(unrealized);
3488
+ function calculatePeriodPercent(periodSummaryTotal, realizedBasis, unrealizedBasis) {
3489
+ const numerator = periodSummaryTotal;
3447
3490
  const denominator = realizedBasis.add(unrealizedBasis);
3448
3491
 
3449
3492
  return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
@@ -4105,8 +4148,6 @@ module.exports = (() => {
4105
4148
  let returnRef;
4106
4149
 
4107
4150
  if (currentSummary) {
4108
- const period = currentSummary.period;
4109
-
4110
4151
  returnRef = currentSummary.end.basis.absolute();
4111
4152
  } else {
4112
4153
  returnRef = Decimal.ZERO;
@@ -4672,6 +4713,10 @@ module.exports = (() => {
4672
4713
  static get VALUATION() {
4673
4714
  return valuation;
4674
4715
  }
4716
+
4717
+ static get DELIST() {
4718
+ return delist;
4719
+ }
4675
4720
 
4676
4721
  static get INCOME() {
4677
4722
  return income;
@@ -4881,8 +4926,18 @@ module.exports = (() => {
4881
4926
  .withField('force', DataType.BOOLEAN, true)
4882
4927
  .schema
4883
4928
  );
4884
-
4885
- const income = new TransactionSchema(SchemaBuilder.withName(TransactionType.INCOME.code)
4929
+
4930
+ const delist = new TransactionSchema(SchemaBuilder.withName(TransactionType.DELIST.code)
4931
+ .withField('portfolio', DataType.STRING)
4932
+ .withField('position', DataType.STRING)
4933
+ .withField('sequence', DataType.NUMBER, true)
4934
+ .withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
4935
+ .withField('date', DataType.DAY)
4936
+ .withField('force', DataType.BOOLEAN, true)
4937
+ .schema
4938
+ );
4939
+
4940
+ const income = new TransactionSchema(SchemaBuilder.withName(TransactionType.INCOME.code)
4886
4941
  .withField('portfolio', DataType.STRING)
4887
4942
  .withField('position', DataType.STRING)
4888
4943
  .withField('sequence', DataType.NUMBER, true)
@@ -4908,6 +4963,7 @@ module.exports = (() => {
4908
4963
  addSchemaToMap(TransactionType.DEPOSIT, deposit);
4909
4964
  addSchemaToMap(TransactionType.WITHDRAWAL, withdrawal);
4910
4965
  addSchemaToMap(TransactionType.VALUATION, valuation);
4966
+ addSchemaToMap(TransactionType.DELIST, delist);
4911
4967
  addSchemaToMap(TransactionType.INCOME, income);
4912
4968
 
4913
4969
  return TransactionSchema;
@@ -6311,6 +6367,19 @@ module.exports = function () {
6311
6367
  return this.addYears(years, true);
6312
6368
  }
6313
6369
 
6370
+ /**
6371
+ * Returns a new Day instance for the end of the month of the current instance.
6372
+ *
6373
+ * @public
6374
+ * @returns {Day}
6375
+ */
6376
+
6377
+ }, {
6378
+ key: 'getEndOfMonth',
6379
+ value: function getEndOfMonth() {
6380
+ return new Day(this.year, this.month, Day.getDaysInMonth(this.year, this.month));
6381
+ }
6382
+
6314
6383
  /**
6315
6384
  * Indicates if another {@link Day} occurs before the current instance.
6316
6385
  *
@@ -10103,7 +10172,7 @@ module.exports = function () {
10103
10172
  * the schema.
10104
10173
  *
10105
10174
  * @public
10106
- * @param {data} data
10175
+ * @param {Object} data
10107
10176
  * @returns {Object}
10108
10177
  */
10109
10178
 
@@ -10185,7 +10254,13 @@ module.exports = function () {
10185
10254
  };
10186
10255
 
10187
10256
  return function (key, value) {
10188
- return advance(key).reviver(value);
10257
+ var item = advance(key);
10258
+
10259
+ if (key === '') {
10260
+ return value;
10261
+ } else {
10262
+ return item.reviver(value);
10263
+ }
10189
10264
  };
10190
10265
  }
10191
10266
 
@@ -17827,6 +17902,50 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17827
17902
  });
17828
17903
  });
17829
17904
 
17905
+ describe('and month position summary ranges are processed for a transaction set that does not close', () => {
17906
+ let ranges;
17907
+
17908
+ beforeEach(() => {
17909
+ const transactions = [
17910
+ {
17911
+ date: new Day(2018, 10, 20),
17912
+ snapshot: {
17913
+ open: new Decimal(1)
17914
+ },
17915
+ type: TransactionType.BUY
17916
+ },
17917
+ {
17918
+ date: new Day(2018, 11, 21),
17919
+ snapshot: {
17920
+ open: new Decimal(1)
17921
+ },
17922
+ type: TransactionType.BUY
17923
+ }
17924
+ ];
17925
+
17926
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
17927
+ });
17928
+
17929
+ it('should have three ranges (assuming the current year is 2018 and the current month is December)', () => {
17930
+ expect(ranges.length).toEqual(3);
17931
+ });
17932
+
17933
+ it('the first range should be from 2018-09-30 to 2018-10-31', () => {
17934
+ expect(ranges[0].start.format()).toEqual('2018-09-30');
17935
+ expect(ranges[0].end.format()).toEqual('2018-10-31');
17936
+ });
17937
+
17938
+ it('the second range should be from 2018-10-31 to 2018-11-30', () => {
17939
+ expect(ranges[1].start.format()).toEqual('2018-10-31');
17940
+ expect(ranges[1].end.format()).toEqual('2018-11-30');
17941
+ });
17942
+
17943
+ it('the third range should be from 2018-10-31 to 2018-11-30', () => {
17944
+ expect(ranges[2].start.format()).toEqual('2018-11-30');
17945
+ expect(ranges[2].end.format()).toEqual('2018-12-31');
17946
+ });
17947
+ });
17948
+
17830
17949
  describe('and getting the start date for yearly frames', () => {
17831
17950
  describe('for one year ago', function() {
17832
17951
  let start;
@@ -17869,6 +17988,55 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17869
17988
  });
17870
17989
  });
17871
17990
 
17991
+
17992
+
17993
+
17994
+ ////
17995
+
17996
+ describe('and getting the start date for monthly frames', () => {
17997
+ describe('for one month ago', function () {
17998
+ let start;
17999
+
18000
+ beforeEach(() => {
18001
+ start = PositionSummaryFrame.MONTHLY.getStartDate(1);
18002
+ });
18003
+
18004
+ it('should be on the last day of month', () => {
18005
+ const today = Day.getToday();
18006
+
18007
+ expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 2));
18008
+ });
18009
+
18010
+ it('should be month ago', () => {
18011
+ expect(start.month).toEqual(Day.getToday().month - 2);
18012
+ });
18013
+ });
18014
+
18015
+ describe('for three months ago', function () {
18016
+ let start;
18017
+
18018
+ beforeEach(() => {
18019
+ start = PositionSummaryFrame.MONTHLY.getStartDate(3);
18020
+ });
18021
+
18022
+ it('should be on the last day of month', () => {
18023
+ const today = Day.getToday();
18024
+
18025
+ expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 4));
18026
+ });
18027
+
18028
+ it('should be 3 month ago', () => {
18029
+ expect(start.month).toEqual(Day.getToday().month - 4);
18030
+ });
18031
+ });
18032
+ });
18033
+
18034
+ ////
18035
+
18036
+
18037
+
18038
+
18039
+
17872
18040
  describe('and recent ranges are calculated', () => {
17873
18041
  let todayYear;
17874
18042
  let todayMonth;
@@ -311,6 +311,50 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
311
311
  });
312
312
  });
313
313
 
314
+ describe('and month position summary ranges are processed for a transaction set that does not close', () => {
315
+ let ranges;
316
+
317
+ beforeEach(() => {
318
+ const transactions = [
319
+ {
320
+ date: new Day(2018, 10, 20),
321
+ snapshot: {
322
+ open: new Decimal(1)
323
+ },
324
+ type: TransactionType.BUY
325
+ },
326
+ {
327
+ date: new Day(2018, 11, 21),
328
+ snapshot: {
329
+ open: new Decimal(1)
330
+ },
331
+ type: TransactionType.BUY
332
+ }
333
+ ];
334
+
335
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
336
+ });
337
+
338
+ it('should have three ranges (assuming the current year is 2018 and the current month is December)', () => {
339
+ expect(ranges.length).toEqual(3);
340
+ });
341
+
342
+ it('the first range should be from 2018-09-30 to 2018-10-31', () => {
343
+ expect(ranges[0].start.format()).toEqual('2018-09-30');
344
+ expect(ranges[0].end.format()).toEqual('2018-10-31');
345
+ });
346
+
347
+ it('the second range should be from 2018-10-31 to 2018-11-30', () => {
348
+ expect(ranges[1].start.format()).toEqual('2018-10-31');
349
+ expect(ranges[1].end.format()).toEqual('2018-11-30');
350
+ });
351
+
352
+ it('the third range should be from 2018-10-31 to 2018-11-30', () => {
353
+ expect(ranges[2].start.format()).toEqual('2018-11-30');
354
+ expect(ranges[2].end.format()).toEqual('2018-12-31');
355
+ });
356
+ });
357
+
314
358
  describe('and getting the start date for yearly frames', () => {
315
359
  describe('for one year ago', function() {
316
360
  let start;
@@ -353,6 +397,55 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
353
397
  });
354
398
  });
355
399
 
400
+
401
+
402
+
403
+ ////
404
+
405
+ describe('and getting the start date for monthly frames', () => {
406
+ describe('for one month ago', function () {
407
+ let start;
408
+
409
+ beforeEach(() => {
410
+ start = PositionSummaryFrame.MONTHLY.getStartDate(1);
411
+ });
412
+
413
+ it('should be on the last day of month', () => {
414
+ const today = Day.getToday();
415
+
416
+ expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 2));
417
+ });
418
+
419
+ it('should be month ago', () => {
420
+ expect(start.month).toEqual(Day.getToday().month - 2);
421
+ });
422
+ });
423
+
424
+ describe('for three months ago', function () {
425
+ let start;
426
+
427
+ beforeEach(() => {
428
+ start = PositionSummaryFrame.MONTHLY.getStartDate(3);
429
+ });
430
+
431
+ it('should be on the last day of month', () => {
432
+ const today = Day.getToday();
433
+
434
+ expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 4));
435
+ });
436
+
437
+ it('should be 3 month ago', () => {
438
+ expect(start.month).toEqual(Day.getToday().month - 4);
439
+ });
440
+ });
441
+ });
442
+
443
+ ////
444
+
445
+
446
+
447
+
448
+
356
449
  describe('and recent ranges are calculated', () => {
357
450
  let todayYear;
358
451
  let todayMonth;