@barchart/portfolio-api-common 1.2.111 → 1.2.115

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
+ })();
@@ -169,7 +169,17 @@ module.exports = (() => {
169
169
  this._dataActual.periodPrice = null;
170
170
  this._dataActual.periodPricePrevious = null;
171
171
  this._dataActual.periodRealized = null;
172
+ this._dataActual.periodRealizedPrevious = null;
173
+ this._dataActual.periodRealizedPrevious2 = null;
174
+ this._dataActual.periodRealizedBasis = null;
175
+ this._dataActual.periodRealizedBasisPrevious = null;
176
+ this._dataActual.periodRealizedBasisPrevious2 = null;
172
177
  this._dataActual.periodUnrealized = null;
178
+ this._dataActual.periodUnrealizedPrevious = null;
179
+ this._dataActual.periodUnrealizedPrevious2 = null;
180
+ this._dataActual.periodUnrealizedBasis = null;
181
+ this._dataActual.periodUnrealizedBasisPrevious = null;
182
+ this._dataActual.periodUnrealizedBasisPrevious2 = null;
173
183
  this._dataActual.periodIncome = null;
174
184
 
175
185
  this._dataFormat.periodPrice = null;
@@ -178,6 +188,14 @@ module.exports = (() => {
178
188
  this._dataFormat.periodUnrealized = null;
179
189
  this._dataFormat.periodIncome = null;
180
190
 
191
+ this._dataActual.periodPercent = null;
192
+ this._dataActual.periodPreviousPercent = null;
193
+ this._dataActual.periodPrevious2Percent = null;
194
+
195
+ this._dataFormat.periodPercent = null;
196
+ this._dataFormat.periodPreviousPercent = null;
197
+ this._dataFormat.periodPrevious2Percent = null;
198
+
181
199
  this._items.forEach((item) => {
182
200
  bindItem.call(this, item);
183
201
  });
@@ -731,7 +749,9 @@ module.exports = (() => {
731
749
 
732
750
  calculateUnrealizedPercent(group);
733
751
 
734
- if (group.single && group._items.length === 1) {
752
+ const groupItems = group._items;
753
+
754
+ if (group.single && groupItems.length === 1) {
735
755
  const item = group._items[0];
736
756
 
737
757
  actual.quantity = item.data.quantity;
@@ -750,12 +770,34 @@ module.exports = (() => {
750
770
  format.periodPrice = formatCurrency(actual.periodPrice, currency);
751
771
  format.periodPricePrevious = formatCurrency(actual.periodPricePrevious, currency);
752
772
 
773
+ actual.periodRealized = item.data.periodRealized;
774
+ actual.periodRealizedPrevious = item.data.periodRealizedPrevious;
775
+ actual.periodRealizedPrevious2 = item.data.periodRealizedPrevious2;
776
+
777
+ actual.periodRealizedBasis = item.data.periodRealizedBasis;
778
+ actual.periodRealizedBasisPrevious = item.data.periodRealizedBasisPrevious;
779
+ actual.periodRealizedBasisPrevious2 = item.data.periodRealizedBasisPrevious2;
780
+
781
+ actual.periodUnrealized = item.data.periodUnrealized;
782
+ actual.periodUnrealizedPrevious = item.data.periodUnrealizedPrevious;
783
+ actual.periodUnrealizedPrevious2 = item.data.periodUnrealizedPrevious2;
784
+
785
+ actual.periodUnrealizedBasis = item.data.periodUnrealizedBasis;
786
+ actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
787
+ actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
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);
792
+
793
+ format.periodPercent = formatPercent(actual.periodPercent, 2);
794
+ format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
795
+ format.periodPercentPrevious2 = formatPercent(actual.periodPercentPrevious2, 2);
796
+
753
797
  format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
754
798
  format.locked = definition.type === PositionLevelType.POSITION && item.data.locked;
755
799
  }
756
800
 
757
- const groupItems = group._items;
758
-
759
801
  let portfolioType = null;
760
802
 
761
803
  if (groupItems.length > 0) {
@@ -875,6 +917,13 @@ module.exports = (() => {
875
917
  format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
876
918
 
877
919
  calculateUnrealizedPercent(group);
920
+
921
+ if (group.single && item) {
922
+ actual.periodUnrealized = item.data.periodUnrealized;
923
+
924
+ actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
925
+ format.periodPercent = formatPercent(actual.periodPercent, 2);
926
+ }
878
927
  }
879
928
 
880
929
  function calculateMarketPercent(group, rates, parentGroup, portfolioGroup) {
@@ -933,6 +982,13 @@ module.exports = (() => {
933
982
  }
934
983
  }
935
984
 
985
+ function calculatePeriodPercent(realized, realizedBasis, unrealized, unrealizedBasis) {
986
+ const numerator = realized.add(unrealized);
987
+ const denominator = realizedBasis.add(unrealizedBasis);
988
+
989
+ return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
990
+ }
991
+
936
992
  const unchanged = { up: false, down: false };
937
993
 
938
994
  return PositionGroup;
@@ -79,7 +79,21 @@ module.exports = (() => {
79
79
  this._data.basisPrice = null;
80
80
 
81
81
  this._data.periodRealized = null;
82
+ this._data.periodRealizedPrevious = null;
83
+ this._data.periodRealizedPrevious2 = null;
84
+
85
+ this._data.periodRealizedBasis = null;
86
+ this._data.periodRealizedBasisPrevious = null;
87
+ this._data.periodRealizedBasisPrevious2 = null;
88
+
82
89
  this._data.periodUnrealized = null;
90
+ this._data.periodUnrealizedPrevious = null;
91
+ this._data.periodUnrealizedPrevious2 = null;
92
+
93
+ this._data.periodUnrealizedBasis = null;
94
+ this._data.periodUnrealizedBasisPrevious = null;
95
+ this._data.periodUnrealizedBasisPrevious2 = null;
96
+
83
97
  this._data.periodIncome = null;
84
98
 
85
99
  this._data.periodPrice = null;
@@ -89,15 +103,15 @@ module.exports = (() => {
89
103
  this._data.fundamental = { };
90
104
  this._data.locked = getIsLocked(position);
91
105
 
92
- calculateStaticData(this);
93
- calculatePriceData(this, null);
94
-
95
106
  this._quoteChangedEvent = new Event(this);
96
107
  this._newsExistsChangedEvent = new Event(this);
97
108
  this._fundamentalDataChangedEvent = new Event(this);
98
109
  this._lockChangedEvent = new Event(this);
99
110
  this._portfolioChangedEvent = new Event(this);
100
111
  this._positionItemDisposeEvent = new Event(this);
112
+
113
+ calculateStaticData(this);
114
+ calculatePriceData(this, null);
101
115
  }
102
116
 
103
117
  /**
@@ -411,9 +425,23 @@ module.exports = (() => {
411
425
  data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
412
426
  data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
413
427
 
414
- data.periodRealized = calculateRealizedPeriod(item.currentSummary, previousSummary1);
415
- data.periodUnrealized = calculateUnrealizedPeriod(item.currentSummary, previousSummary1);
416
- data.periodIncome = calculateIncomePeriod(item.currentSummary, previousSummary1);
428
+ data.periodRealized = calculatePeriodRealized(item.currentSummary, previousSummary1);
429
+ data.periodRealizedPrevious = calculatePeriodRealized(previousSummary1, previousSummary2);
430
+ data.periodRealizedPrevious2 = calculatePeriodRealized(previousSummary2, previousSummary3);
431
+
432
+ data.periodRealizedBasis = calculatePeriodRealizedBasis(item.currentSummary, previousSummary1);
433
+ data.periodRealizedBasisPrevious = calculatePeriodRealizedBasis(previousSummary1, previousSummary2);
434
+ data.periodRealizedBasisPrevious2 = calculatePeriodRealizedBasis(previousSummary2, previousSummary3);
435
+
436
+ data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary1);
437
+ data.periodUnrealizedPrevious = calculatePeriodUnrealized(previousSummary1, previousSummary2);
438
+ data.periodUnrealizedPrevious2 = calculatePeriodUnrealized(previousSummary2, previousSummary3);
439
+
440
+ data.periodUnrealizedBasis = calculatePeriodUnrealizedBasis(item.currentSummary, previousSummary1);
441
+ data.periodUnrealizedBasisPrevious = calculatePeriodUnrealizedBasis(previousSummary1, previousSummary2);
442
+ data.periodUnrealizedBasisPrevious2 = calculatePeriodUnrealizedBasis(previousSummary2, previousSummary3);
443
+
444
+ data.periodIncome = calculatePeriodIncome(item.currentSummary, previousSummary1);
417
445
 
418
446
  if (snapshot.open.getIsZero()) {
419
447
  data.basisPrice = Decimal.ZERO;
@@ -540,11 +568,16 @@ module.exports = (() => {
540
568
 
541
569
  data.unrealized = unrealized;
542
570
  data.unrealizedChange = unrealizedChange;
571
+
572
+ data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary, data.unrealized);
573
+ data.periodUnrealizedChange = unrealizedChange;
543
574
  } else {
544
575
  data.summaryTotalCurrentChange = Decimal.ZERO;
545
576
 
546
577
  data.unrealized = Decimal.ZERO;
547
578
  data.unrealizedChange = Decimal.ZERO;
579
+
580
+ data.periodUnrealizedChange = Decimal.ZERO;
548
581
  }
549
582
  } else {
550
583
  data.summaryTotalCurrentChange = Decimal.ZERO;
@@ -568,7 +601,7 @@ module.exports = (() => {
568
601
  return returnRef;
569
602
  }
570
603
 
571
- function calculateRealizedPeriod(currentSummary, previousSummary) {
604
+ function calculatePeriodRealized(currentSummary, previousSummary) {
572
605
  let returnRef;
573
606
 
574
607
  if (currentSummary) {
@@ -582,13 +615,42 @@ module.exports = (() => {
582
615
  return returnRef;
583
616
  }
584
617
 
585
- function calculateUnrealizedPeriod(currentSummary, previousSummary) {
618
+ function calculatePeriodRealizedBasis(currentSummary, previousSummary) {
619
+ let returnRef;
620
+
621
+ if (currentSummary) {
622
+ const period = currentSummary.period;
623
+
624
+ returnRef = period.sells.subtract(calculatePeriodRealized(currentSummary, previousSummary));
625
+ } else {
626
+ returnRef = Decimal.ZERO;
627
+ }
628
+
629
+ return returnRef;
630
+ }
631
+
632
+ function calculatePeriodUnrealized(currentSummary, previousSummary, override) {
633
+ let returnRef;
634
+
635
+ if (currentSummary) {
636
+ const period = currentSummary.period;
637
+ const unrealized = override || period.unrealized;
638
+
639
+ returnRef = unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
640
+ } else {
641
+ returnRef = Decimal.ZERO;
642
+ }
643
+
644
+ return returnRef;
645
+ }
646
+
647
+ function calculatePeriodUnrealizedBasis(currentSummary, previousSummary) {
586
648
  let returnRef;
587
649
 
588
650
  if (currentSummary) {
589
651
  const period = currentSummary.period;
590
652
 
591
- returnRef = period.unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
653
+ returnRef = currentSummary.end.basis.absolute();
592
654
  } else {
593
655
  returnRef = Decimal.ZERO;
594
656
  }
@@ -596,7 +658,7 @@ module.exports = (() => {
596
658
  return returnRef;
597
659
  }
598
660
 
599
- function calculateIncomePeriod(currentSummary, previousSummary) {
661
+ function calculatePeriodIncome(currentSummary, previousSummary) {
600
662
  let returnRef;
601
663
 
602
664
  if (currentSummary) {
@@ -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.111",
3
+ "version": "1.2.115",
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 ]);
@@ -2629,7 +2672,17 @@ module.exports = (() => {
2629
2672
  this._dataActual.periodPrice = null;
2630
2673
  this._dataActual.periodPricePrevious = null;
2631
2674
  this._dataActual.periodRealized = null;
2675
+ this._dataActual.periodRealizedPrevious = null;
2676
+ this._dataActual.periodRealizedPrevious2 = null;
2677
+ this._dataActual.periodRealizedBasis = null;
2678
+ this._dataActual.periodRealizedBasisPrevious = null;
2679
+ this._dataActual.periodRealizedBasisPrevious2 = null;
2632
2680
  this._dataActual.periodUnrealized = null;
2681
+ this._dataActual.periodUnrealizedPrevious = null;
2682
+ this._dataActual.periodUnrealizedPrevious2 = null;
2683
+ this._dataActual.periodUnrealizedBasis = null;
2684
+ this._dataActual.periodUnrealizedBasisPrevious = null;
2685
+ this._dataActual.periodUnrealizedBasisPrevious2 = null;
2633
2686
  this._dataActual.periodIncome = null;
2634
2687
 
2635
2688
  this._dataFormat.periodPrice = null;
@@ -2638,6 +2691,14 @@ module.exports = (() => {
2638
2691
  this._dataFormat.periodUnrealized = null;
2639
2692
  this._dataFormat.periodIncome = null;
2640
2693
 
2694
+ this._dataActual.periodPercent = null;
2695
+ this._dataActual.periodPreviousPercent = null;
2696
+ this._dataActual.periodPrevious2Percent = null;
2697
+
2698
+ this._dataFormat.periodPercent = null;
2699
+ this._dataFormat.periodPreviousPercent = null;
2700
+ this._dataFormat.periodPrevious2Percent = null;
2701
+
2641
2702
  this._items.forEach((item) => {
2642
2703
  bindItem.call(this, item);
2643
2704
  });
@@ -3191,7 +3252,9 @@ module.exports = (() => {
3191
3252
 
3192
3253
  calculateUnrealizedPercent(group);
3193
3254
 
3194
- if (group.single && group._items.length === 1) {
3255
+ const groupItems = group._items;
3256
+
3257
+ if (group.single && groupItems.length === 1) {
3195
3258
  const item = group._items[0];
3196
3259
 
3197
3260
  actual.quantity = item.data.quantity;
@@ -3210,12 +3273,34 @@ module.exports = (() => {
3210
3273
  format.periodPrice = formatCurrency(actual.periodPrice, currency);
3211
3274
  format.periodPricePrevious = formatCurrency(actual.periodPricePrevious, currency);
3212
3275
 
3276
+ actual.periodRealized = item.data.periodRealized;
3277
+ actual.periodRealizedPrevious = item.data.periodRealizedPrevious;
3278
+ actual.periodRealizedPrevious2 = item.data.periodRealizedPrevious2;
3279
+
3280
+ actual.periodRealizedBasis = item.data.periodRealizedBasis;
3281
+ actual.periodRealizedBasisPrevious = item.data.periodRealizedBasisPrevious;
3282
+ actual.periodRealizedBasisPrevious2 = item.data.periodRealizedBasisPrevious2;
3283
+
3284
+ actual.periodUnrealized = item.data.periodUnrealized;
3285
+ actual.periodUnrealizedPrevious = item.data.periodUnrealizedPrevious;
3286
+ actual.periodUnrealizedPrevious2 = item.data.periodUnrealizedPrevious2;
3287
+
3288
+ actual.periodUnrealizedBasis = item.data.periodUnrealizedBasis;
3289
+ actual.periodUnrealizedBasisPrevious = item.data.periodUnrealizedBasisPrevious;
3290
+ actual.periodUnrealizedBasisPrevious2 = item.data.periodUnrealizedBasisPrevious2;
3291
+
3292
+ actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
3293
+ actual.periodPercentPrevious = calculatePeriodPercent(actual.periodRealizedPrevious, actual.periodRealizedBasisPrevious, actual.periodUnrealizedPrevious, actual.periodUnrealizedBasisPrevious);
3294
+ actual.periodPercentPrevious2 = calculatePeriodPercent(actual.periodRealizedPrevious2, actual.periodRealizedBasisPrevious2, actual.periodUnrealizedPrevious2, actual.periodUnrealizedBasisPrevious2);
3295
+
3296
+ format.periodPercent = formatPercent(actual.periodPercent, 2);
3297
+ format.periodPercentPrevious = formatPercent(actual.periodPercentPrevious, 2);
3298
+ format.periodPercentPrevious2 = formatPercent(actual.periodPercentPrevious2, 2);
3299
+
3213
3300
  format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
3214
3301
  format.locked = definition.type === PositionLevelType.POSITION && item.data.locked;
3215
3302
  }
3216
3303
 
3217
- const groupItems = group._items;
3218
-
3219
3304
  let portfolioType = null;
3220
3305
 
3221
3306
  if (groupItems.length > 0) {
@@ -3335,6 +3420,13 @@ module.exports = (() => {
3335
3420
  format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
3336
3421
 
3337
3422
  calculateUnrealizedPercent(group);
3423
+
3424
+ if (group.single && item) {
3425
+ actual.periodUnrealized = item.data.periodUnrealized;
3426
+
3427
+ actual.periodPercent = calculatePeriodPercent(actual.periodRealized, actual.periodRealizedBasis, actual.periodUnrealized, actual.periodUnrealizedBasis);
3428
+ format.periodPercent = formatPercent(actual.periodPercent, 2);
3429
+ }
3338
3430
  }
3339
3431
 
3340
3432
  function calculateMarketPercent(group, rates, parentGroup, portfolioGroup) {
@@ -3393,6 +3485,13 @@ module.exports = (() => {
3393
3485
  }
3394
3486
  }
3395
3487
 
3488
+ function calculatePeriodPercent(realized, realizedBasis, unrealized, unrealizedBasis) {
3489
+ const numerator = realized.add(unrealized);
3490
+ const denominator = realizedBasis.add(unrealizedBasis);
3491
+
3492
+ return denominator.getIsZero() ? Decimal.ZERO : numerator.divide(denominator);
3493
+ }
3494
+
3396
3495
  const unchanged = { up: false, down: false };
3397
3496
 
3398
3497
  return PositionGroup;
@@ -3480,7 +3579,21 @@ module.exports = (() => {
3480
3579
  this._data.basisPrice = null;
3481
3580
 
3482
3581
  this._data.periodRealized = null;
3582
+ this._data.periodRealizedPrevious = null;
3583
+ this._data.periodRealizedPrevious2 = null;
3584
+
3585
+ this._data.periodRealizedBasis = null;
3586
+ this._data.periodRealizedBasisPrevious = null;
3587
+ this._data.periodRealizedBasisPrevious2 = null;
3588
+
3483
3589
  this._data.periodUnrealized = null;
3590
+ this._data.periodUnrealizedPrevious = null;
3591
+ this._data.periodUnrealizedPrevious2 = null;
3592
+
3593
+ this._data.periodUnrealizedBasis = null;
3594
+ this._data.periodUnrealizedBasisPrevious = null;
3595
+ this._data.periodUnrealizedBasisPrevious2 = null;
3596
+
3484
3597
  this._data.periodIncome = null;
3485
3598
 
3486
3599
  this._data.periodPrice = null;
@@ -3490,15 +3603,15 @@ module.exports = (() => {
3490
3603
  this._data.fundamental = { };
3491
3604
  this._data.locked = getIsLocked(position);
3492
3605
 
3493
- calculateStaticData(this);
3494
- calculatePriceData(this, null);
3495
-
3496
3606
  this._quoteChangedEvent = new Event(this);
3497
3607
  this._newsExistsChangedEvent = new Event(this);
3498
3608
  this._fundamentalDataChangedEvent = new Event(this);
3499
3609
  this._lockChangedEvent = new Event(this);
3500
3610
  this._portfolioChangedEvent = new Event(this);
3501
3611
  this._positionItemDisposeEvent = new Event(this);
3612
+
3613
+ calculateStaticData(this);
3614
+ calculatePriceData(this, null);
3502
3615
  }
3503
3616
 
3504
3617
  /**
@@ -3812,9 +3925,23 @@ module.exports = (() => {
3812
3925
  data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
3813
3926
  data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
3814
3927
 
3815
- data.periodRealized = calculateRealizedPeriod(item.currentSummary, previousSummary1);
3816
- data.periodUnrealized = calculateUnrealizedPeriod(item.currentSummary, previousSummary1);
3817
- data.periodIncome = calculateIncomePeriod(item.currentSummary, previousSummary1);
3928
+ data.periodRealized = calculatePeriodRealized(item.currentSummary, previousSummary1);
3929
+ data.periodRealizedPrevious = calculatePeriodRealized(previousSummary1, previousSummary2);
3930
+ data.periodRealizedPrevious2 = calculatePeriodRealized(previousSummary2, previousSummary3);
3931
+
3932
+ data.periodRealizedBasis = calculatePeriodRealizedBasis(item.currentSummary, previousSummary1);
3933
+ data.periodRealizedBasisPrevious = calculatePeriodRealizedBasis(previousSummary1, previousSummary2);
3934
+ data.periodRealizedBasisPrevious2 = calculatePeriodRealizedBasis(previousSummary2, previousSummary3);
3935
+
3936
+ data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary1);
3937
+ data.periodUnrealizedPrevious = calculatePeriodUnrealized(previousSummary1, previousSummary2);
3938
+ data.periodUnrealizedPrevious2 = calculatePeriodUnrealized(previousSummary2, previousSummary3);
3939
+
3940
+ data.periodUnrealizedBasis = calculatePeriodUnrealizedBasis(item.currentSummary, previousSummary1);
3941
+ data.periodUnrealizedBasisPrevious = calculatePeriodUnrealizedBasis(previousSummary1, previousSummary2);
3942
+ data.periodUnrealizedBasisPrevious2 = calculatePeriodUnrealizedBasis(previousSummary2, previousSummary3);
3943
+
3944
+ data.periodIncome = calculatePeriodIncome(item.currentSummary, previousSummary1);
3818
3945
 
3819
3946
  if (snapshot.open.getIsZero()) {
3820
3947
  data.basisPrice = Decimal.ZERO;
@@ -3941,11 +4068,16 @@ module.exports = (() => {
3941
4068
 
3942
4069
  data.unrealized = unrealized;
3943
4070
  data.unrealizedChange = unrealizedChange;
4071
+
4072
+ data.periodUnrealized = calculatePeriodUnrealized(item.currentSummary, previousSummary, data.unrealized);
4073
+ data.periodUnrealizedChange = unrealizedChange;
3944
4074
  } else {
3945
4075
  data.summaryTotalCurrentChange = Decimal.ZERO;
3946
4076
 
3947
4077
  data.unrealized = Decimal.ZERO;
3948
4078
  data.unrealizedChange = Decimal.ZERO;
4079
+
4080
+ data.periodUnrealizedChange = Decimal.ZERO;
3949
4081
  }
3950
4082
  } else {
3951
4083
  data.summaryTotalCurrentChange = Decimal.ZERO;
@@ -3969,7 +4101,7 @@ module.exports = (() => {
3969
4101
  return returnRef;
3970
4102
  }
3971
4103
 
3972
- function calculateRealizedPeriod(currentSummary, previousSummary) {
4104
+ function calculatePeriodRealized(currentSummary, previousSummary) {
3973
4105
  let returnRef;
3974
4106
 
3975
4107
  if (currentSummary) {
@@ -3983,21 +4115,50 @@ module.exports = (() => {
3983
4115
  return returnRef;
3984
4116
  }
3985
4117
 
3986
- function calculateUnrealizedPeriod(currentSummary, previousSummary) {
4118
+ function calculatePeriodRealizedBasis(currentSummary, previousSummary) {
3987
4119
  let returnRef;
3988
4120
 
3989
4121
  if (currentSummary) {
3990
4122
  const period = currentSummary.period;
3991
4123
 
3992
- returnRef = period.unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
4124
+ returnRef = period.sells.subtract(calculatePeriodRealized(currentSummary, previousSummary));
3993
4125
  } else {
3994
4126
  returnRef = Decimal.ZERO;
3995
4127
  }
3996
4128
 
3997
4129
  return returnRef;
3998
4130
  }
4131
+
4132
+ function calculatePeriodUnrealized(currentSummary, previousSummary, override) {
4133
+ let returnRef;
3999
4134
 
4000
- function calculateIncomePeriod(currentSummary, previousSummary) {
4135
+ if (currentSummary) {
4136
+ const period = currentSummary.period;
4137
+ const unrealized = override || period.unrealized;
4138
+
4139
+ returnRef = unrealized.subtract(previousSummary !== null ? previousSummary.period.unrealized : Decimal.ZERO);
4140
+ } else {
4141
+ returnRef = Decimal.ZERO;
4142
+ }
4143
+
4144
+ return returnRef;
4145
+ }
4146
+
4147
+ function calculatePeriodUnrealizedBasis(currentSummary, previousSummary) {
4148
+ let returnRef;
4149
+
4150
+ if (currentSummary) {
4151
+ const period = currentSummary.period;
4152
+
4153
+ returnRef = currentSummary.end.basis.absolute();
4154
+ } else {
4155
+ returnRef = Decimal.ZERO;
4156
+ }
4157
+
4158
+ return returnRef;
4159
+ }
4160
+
4161
+ function calculatePeriodIncome(currentSummary, previousSummary) {
4001
4162
  let returnRef;
4002
4163
 
4003
4164
  if (currentSummary) {
@@ -4554,6 +4715,10 @@ module.exports = (() => {
4554
4715
  static get VALUATION() {
4555
4716
  return valuation;
4556
4717
  }
4718
+
4719
+ static get DELIST() {
4720
+ return delist;
4721
+ }
4557
4722
 
4558
4723
  static get INCOME() {
4559
4724
  return income;
@@ -4763,8 +4928,18 @@ module.exports = (() => {
4763
4928
  .withField('force', DataType.BOOLEAN, true)
4764
4929
  .schema
4765
4930
  );
4766
-
4767
- const income = new TransactionSchema(SchemaBuilder.withName(TransactionType.INCOME.code)
4931
+
4932
+ const delist = new TransactionSchema(SchemaBuilder.withName(TransactionType.DELIST.code)
4933
+ .withField('portfolio', DataType.STRING)
4934
+ .withField('position', DataType.STRING)
4935
+ .withField('sequence', DataType.NUMBER, true)
4936
+ .withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
4937
+ .withField('date', DataType.DAY)
4938
+ .withField('force', DataType.BOOLEAN, true)
4939
+ .schema
4940
+ );
4941
+
4942
+ const income = new TransactionSchema(SchemaBuilder.withName(TransactionType.INCOME.code)
4768
4943
  .withField('portfolio', DataType.STRING)
4769
4944
  .withField('position', DataType.STRING)
4770
4945
  .withField('sequence', DataType.NUMBER, true)
@@ -4790,6 +4965,7 @@ module.exports = (() => {
4790
4965
  addSchemaToMap(TransactionType.DEPOSIT, deposit);
4791
4966
  addSchemaToMap(TransactionType.WITHDRAWAL, withdrawal);
4792
4967
  addSchemaToMap(TransactionType.VALUATION, valuation);
4968
+ addSchemaToMap(TransactionType.DELIST, delist);
4793
4969
  addSchemaToMap(TransactionType.INCOME, income);
4794
4970
 
4795
4971
  return TransactionSchema;
@@ -6193,6 +6369,19 @@ module.exports = function () {
6193
6369
  return this.addYears(years, true);
6194
6370
  }
6195
6371
 
6372
+ /**
6373
+ * Returns a new Day instance for the end of the month of the current instance.
6374
+ *
6375
+ * @public
6376
+ * @returns {Day}
6377
+ */
6378
+
6379
+ }, {
6380
+ key: 'getEndOfMonth',
6381
+ value: function getEndOfMonth() {
6382
+ return new Day(this.year, this.month, Day.getDaysInMonth(this.year, this.month));
6383
+ }
6384
+
6196
6385
  /**
6197
6386
  * Indicates if another {@link Day} occurs before the current instance.
6198
6387
  *
@@ -9985,7 +10174,7 @@ module.exports = function () {
9985
10174
  * the schema.
9986
10175
  *
9987
10176
  * @public
9988
- * @param {data} data
10177
+ * @param {Object} data
9989
10178
  * @returns {Object}
9990
10179
  */
9991
10180
 
@@ -10067,7 +10256,13 @@ module.exports = function () {
10067
10256
  };
10068
10257
 
10069
10258
  return function (key, value) {
10070
- return advance(key).reviver(value);
10259
+ var item = advance(key);
10260
+
10261
+ if (key === '') {
10262
+ return value;
10263
+ } else {
10264
+ return item.reviver(value);
10265
+ }
10071
10266
  };
10072
10267
  }
10073
10268
 
@@ -17709,6 +17904,50 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17709
17904
  });
17710
17905
  });
17711
17906
 
17907
+ describe('and month position summary ranges are processed for a transaction set that does not close', () => {
17908
+ let ranges;
17909
+
17910
+ beforeEach(() => {
17911
+ const transactions = [
17912
+ {
17913
+ date: new Day(2018, 10, 20),
17914
+ snapshot: {
17915
+ open: new Decimal(1)
17916
+ },
17917
+ type: TransactionType.BUY
17918
+ },
17919
+ {
17920
+ date: new Day(2018, 11, 21),
17921
+ snapshot: {
17922
+ open: new Decimal(1)
17923
+ },
17924
+ type: TransactionType.BUY
17925
+ }
17926
+ ];
17927
+
17928
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
17929
+ });
17930
+
17931
+ it('should have three ranges (assuming the current year is 2018 and the current month is December)', () => {
17932
+ expect(ranges.length).toEqual(3);
17933
+ });
17934
+
17935
+ it('the first range should be from 2018-09-30 to 2018-10-31', () => {
17936
+ expect(ranges[0].start.format()).toEqual('2018-09-30');
17937
+ expect(ranges[0].end.format()).toEqual('2018-10-31');
17938
+ });
17939
+
17940
+ it('the second range should be from 2018-10-31 to 2018-11-30', () => {
17941
+ expect(ranges[1].start.format()).toEqual('2018-10-31');
17942
+ expect(ranges[1].end.format()).toEqual('2018-11-30');
17943
+ });
17944
+
17945
+ it('the third range should be from 2018-10-31 to 2018-11-30', () => {
17946
+ expect(ranges[2].start.format()).toEqual('2018-11-30');
17947
+ expect(ranges[2].end.format()).toEqual('2018-12-31');
17948
+ });
17949
+ });
17950
+
17712
17951
  describe('and getting the start date for yearly frames', () => {
17713
17952
  describe('for one year ago', function() {
17714
17953
  let start;
@@ -17751,6 +17990,55 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17751
17990
  });
17752
17991
  });
17753
17992
 
17993
+
17994
+
17995
+
17996
+ ////
17997
+
17998
+ describe('and getting the start date for monthly frames', () => {
17999
+ describe('for one month ago', function () {
18000
+ let start;
18001
+
18002
+ beforeEach(() => {
18003
+ start = PositionSummaryFrame.MONTHLY.getStartDate(1);
18004
+ });
18005
+
18006
+ it('should be on the last day of month', () => {
18007
+ const today = Day.getToday();
18008
+
18009
+ expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 2));
18010
+ });
18011
+
18012
+ it('should be month ago', () => {
18013
+ expect(start.month).toEqual(Day.getToday().month - 2);
18014
+ });
18015
+ });
18016
+
18017
+ describe('for three months ago', function () {
18018
+ let start;
18019
+
18020
+ beforeEach(() => {
18021
+ start = PositionSummaryFrame.MONTHLY.getStartDate(3);
18022
+ });
18023
+
18024
+ it('should be on the last day of month', () => {
18025
+ const today = Day.getToday();
18026
+
18027
+ expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 4));
18028
+ });
18029
+
18030
+ it('should be 3 month ago', () => {
18031
+ expect(start.month).toEqual(Day.getToday().month - 4);
18032
+ });
18033
+ });
18034
+ });
18035
+
18036
+ ////
18037
+
18038
+
18039
+
18040
+
18041
+
17754
18042
  describe('and recent ranges are calculated', () => {
17755
18043
  let todayYear;
17756
18044
  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;