@barchart/portfolio-api-common 1.2.124 → 1.2.128

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,31 @@ module.exports = (() => {
243
243
  function getMonthlyRanges(transactions) {
244
244
  const ranges = [ ];
245
245
 
246
- if (!transactions.length) {
247
- return ranges;
248
- }
246
+ if (transactions.length !== 0) {
247
+ const today = Day.getToday();
249
248
 
250
- const first = array.first(transactions);
251
- const last = array.last(transactions);
249
+ const first = array.first(transactions);
250
+ const last = array.last(transactions);
252
251
 
253
- const firstDate = first.date;
252
+ const firstDate = first.date;
254
253
 
255
- let lastDate;
254
+ let lastDate;
256
255
 
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
- }
256
+ if (last.snapshot.open.getIsZero()) {
257
+ lastDate = last.date;
258
+ } else {
259
+ lastDate = today;
260
+ }
262
261
 
263
- lastDate = lastDate.getEndOfMonth();
262
+ if (today.month === lastDate.month && today.year === lastDate.year) {
263
+ lastDate = lastDate.subtractMonths(1);
264
+ }
265
+
266
+ lastDate = lastDate.getEndOfMonth();
264
267
 
265
- for (let end = firstDate.getEndOfMonth(); end.format() <= lastDate.format(); end = end.addMonths(1).getEndOfMonth()) {
266
- ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
268
+ for (let end = firstDate.getEndOfMonth(); !end.getIsAfter(lastDate); end = end.addMonths(1).getEndOfMonth()) {
269
+ ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
270
+ }
267
271
  }
268
272
 
269
273
  return ranges;
@@ -22,9 +22,10 @@ module.exports = (() => {
22
22
  * @param {Boolean} corporateAction
23
23
  * @param {Boolean} initial
24
24
  * @param {Boolean} significant
25
+ * @param {Boolean} system
25
26
  */
26
27
  class TransactionType extends Enum {
27
- constructor(code, description, display, sequence, purchase, sale, income, opening, closing, fee, corporateAction, initial, significant) {
28
+ constructor(code, description, display, sequence, purchase, sale, income, opening, closing, fee, corporateAction, initial, significant, system) {
28
29
  super(code, description);
29
30
 
30
31
  assert.argumentIsRequired(display, 'display', String);
@@ -38,6 +39,7 @@ module.exports = (() => {
38
39
  assert.argumentIsRequired(corporateAction, 'corporateAction', Boolean);
39
40
  assert.argumentIsRequired(initial, 'initial', Boolean);
40
41
  assert.argumentIsRequired(significant, 'significant', Boolean);
42
+ assert.argumentIsRequired(system, 'system', Boolean);
41
43
 
42
44
  this._display = display;
43
45
  this._sequence = sequence;
@@ -50,6 +52,7 @@ module.exports = (() => {
50
52
  this._corporateAction = corporateAction;
51
53
  this._initial = initial;
52
54
  this._significant = significant;
55
+ this._system = system;
53
56
  }
54
57
 
55
58
  /**
@@ -176,6 +179,16 @@ module.exports = (() => {
176
179
  return this._significant;
177
180
  }
178
181
 
182
+ /**
183
+ * System transactions are generated automatically.
184
+ *
185
+ * @public
186
+ * @returns {Boolean}
187
+ */
188
+ get system() {
189
+ return this._system;
190
+ }
191
+
179
192
  /**
180
193
  * A purchase.
181
194
  *
@@ -401,29 +414,29 @@ module.exports = (() => {
401
414
  }
402
415
  }
403
416
 
404
- const buy = new TransactionType('B', 'Buy', 'Buy', 0, true, false, false, true, false, false, false, true, true);
405
- const sell = new TransactionType('S', 'Sell', 'Sell', 0, false, true, false, false, true, false, false, false, true);
406
- const buyShort = new TransactionType('BS', 'Buy To Cover', 'Buy To Cover', 0, true, false, false, false, true, false, false, false, true);
407
- const sellShort = new TransactionType('SS', 'Sell Short', 'Sell Short', 0, false, true, false, true, false, false, false, true, true);
408
- const dividend = new TransactionType('DV', 'Dividend', 'Dividend', 1, false, false, true, false, false, false, true, false, false);
409
- const dividendReinvest = new TransactionType('DX', 'Dividend (Reinvested)', 'Dividend Reinvest', 1, false, false, false, true, false, false, true, false, false);
410
- const dividendStock = new TransactionType('DS', 'Dividend (Stock)', 'Dividend Stock', 1, false, false, false, true, false, false, true, false, false);
411
- const split = new TransactionType('SP', 'Split', 'Split', 1, false, false, false, true, false, false, true, false, false);
412
- const fee = new TransactionType('F', 'Fee', 'Fee', 0, false, false, false, false, false, true, false, false, false);
413
- const feeUnits = new TransactionType('FU', 'Fee Units', 'Fee', 0, false, false, false, false, true, false, false, false, false);
414
- const delist = new TransactionType('DL', 'Delist', 'Delist', 1, false, false, false, false, false, false, true, false, false);
415
-
416
- const distributionCash = new TransactionType('DC', 'Distribution (Cash)', 'Cash Distribution', 1, false, false, true, false, false, false, true, false, false);
417
- const distributionReinvest = new TransactionType('DY', 'Distribution (Reinvested)', 'Distribution Reinvest', 1, false, false, false, true, false, false, true, false, false);
418
- const distributionFund = new TransactionType('DF', 'Distribution (Units)', 'Unit Distribution', 1, false, false, false, true, false, false, true, false, false);
419
-
420
- const deposit = new TransactionType('D', 'Deposit', 'Deposit', 0, false, false, false, false, false, false, false, true, true);
421
- const withdrawal = new TransactionType('W', 'Withdrawal', 'Withdrawal', 0, false, false, false, false, false, false, false, true, true);
422
- const debit = new TransactionType('DR', 'Debit', 'Debit', 0, false, false, false, false, false, false, false, true, true);
423
- const credit = new TransactionType('CR', 'Credit', 'Credit', 0, false, false, false, false, false, false, false, true, true);
424
-
425
- const valuation = new TransactionType('V', 'Valuation', 'Valuation', 0, false, false, false, false, false, false, false, false, false);
426
- const income = new TransactionType('I', 'Income', 'Income', 0, false, false, true, false, false, false, false, false, false);
417
+ const buy = new TransactionType('B', 'Buy', 'Buy', 0, true, false, false, true, false, false, false, true, true, false);
418
+ const sell = new TransactionType('S', 'Sell', 'Sell', 0, false, true, false, false, true, false, false, false, true, false);
419
+ const buyShort = new TransactionType('BS', 'Buy To Cover', 'Buy To Cover', 0, true, false, false, false, true, false, false, false, true, false);
420
+ const sellShort = new TransactionType('SS', 'Sell Short', 'Sell Short', 0, false, true, false, true, false, false, false, true, true, false);
421
+ const dividend = new TransactionType('DV', 'Dividend', 'Dividend', 1, false, false, true, false, false, false, true, false, false, true);
422
+ const dividendReinvest = new TransactionType('DX', 'Dividend (Reinvested)', 'Dividend Reinvest', 1, false, false, false, true, false, false, true, false, false, true);
423
+ const dividendStock = new TransactionType('DS', 'Dividend (Stock)', 'Dividend Stock', 1, false, false, false, true, false, false, true, false, false, true);
424
+ const split = new TransactionType('SP', 'Split', 'Split', 1, false, false, false, true, false, false, true, false, false, true);
425
+ const fee = new TransactionType('F', 'Fee', 'Fee', 0, false, false, false, false, false, true, false, false, false, false);
426
+ const feeUnits = new TransactionType('FU', 'Fee Units', 'Fee', 0, false, false, false, false, true, false, false, false, false, false);
427
+ const delist = new TransactionType('DL', 'Delist', 'Delist', 1, false, false, false, false, false, false, true, false, false, true);
428
+
429
+ const distributionCash = new TransactionType('DC', 'Distribution (Cash)', 'Cash Distribution', 1, false, false, true, false, false, false, true, false, false, true);
430
+ const distributionReinvest = new TransactionType('DY', 'Distribution (Reinvested)', 'Distribution Reinvest', 1, false, false, false, true, false, false, true, false, false, true);
431
+ const distributionFund = new TransactionType('DF', 'Distribution (Units)', 'Unit Distribution', 1, false, false, false, true, false, false, true, false, false, true);
432
+
433
+ const deposit = new TransactionType('D', 'Deposit', 'Deposit', 0, false, false, false, false, false, false, false, true, true, false);
434
+ const withdrawal = new TransactionType('W', 'Withdrawal', 'Withdrawal', 0, false, false, false, false, false, false, false, true, true, false);
435
+ const debit = new TransactionType('DR', 'Debit', 'Debit', 0, false, false, false, false, false, false, false, true, true, true);
436
+ const credit = new TransactionType('CR', 'Credit', 'Credit', 0, false, false, false, false, false, false, false, true, true, true);
437
+
438
+ const valuation = new TransactionType('V', 'Valuation', 'Valuation', 0, false, false, false, false, false, false, false, false, false, false);
439
+ const income = new TransactionType('I', 'Income', 'Income', 0, false, false, true, false, false, false, false, false, false, false);
427
440
 
428
441
  return TransactionType;
429
442
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.2.124",
3
+ "version": "1.2.128",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -23,9 +23,10 @@
23
23
  "gulp-bump": "~1.0.0",
24
24
  "gulp-git": "~1.6.0",
25
25
  "gulp-jasmine": "^2.2.1",
26
- "gulp-jshint": "~1.11.2",
26
+ "gulp-jshint": "~2.1.0",
27
27
  "gulp-util": "^3.0.7",
28
28
  "jsdoc": "^3.5.5",
29
+ "jshint": "2.9.5",
29
30
  "run-sequence": "~1.1.4",
30
31
  "vinyl-buffer": "^1.0.0",
31
32
  "vinyl-source-stream": "^1.1.0"
@@ -634,27 +634,31 @@ module.exports = (() => {
634
634
  function getMonthlyRanges(transactions) {
635
635
  const ranges = [ ];
636
636
 
637
- if (!transactions.length) {
638
- return ranges;
639
- }
637
+ if (transactions.length !== 0) {
638
+ const today = Day.getToday();
640
639
 
641
- const first = array.first(transactions);
642
- const last = array.last(transactions);
640
+ const first = array.first(transactions);
641
+ const last = array.last(transactions);
643
642
 
644
- const firstDate = first.date;
643
+ const firstDate = first.date;
645
644
 
646
- let lastDate;
645
+ let lastDate;
647
646
 
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
- }
647
+ if (last.snapshot.open.getIsZero()) {
648
+ lastDate = last.date;
649
+ } else {
650
+ lastDate = today;
651
+ }
653
652
 
654
- lastDate = lastDate.getEndOfMonth();
653
+ if (today.month === lastDate.month && today.year === lastDate.year) {
654
+ lastDate = lastDate.subtractMonths(1);
655
+ }
656
+
657
+ lastDate = lastDate.getEndOfMonth();
655
658
 
656
- for (let end = firstDate.getEndOfMonth(); end.format() <= lastDate.format(); end = end.addMonths(1).getEndOfMonth()) {
657
- ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
659
+ for (let end = firstDate.getEndOfMonth(); !end.getIsAfter(lastDate); end = end.addMonths(1).getEndOfMonth()) {
660
+ ranges.push(getRange(end.subtractMonths(1).getEndOfMonth(), end));
661
+ }
658
662
  }
659
663
 
660
664
  return ranges;
@@ -759,9 +763,10 @@ module.exports = (() => {
759
763
  * @param {Boolean} corporateAction
760
764
  * @param {Boolean} initial
761
765
  * @param {Boolean} significant
766
+ * @param {Boolean} system
762
767
  */
763
768
  class TransactionType extends Enum {
764
- constructor(code, description, display, sequence, purchase, sale, income, opening, closing, fee, corporateAction, initial, significant) {
769
+ constructor(code, description, display, sequence, purchase, sale, income, opening, closing, fee, corporateAction, initial, significant, system) {
765
770
  super(code, description);
766
771
 
767
772
  assert.argumentIsRequired(display, 'display', String);
@@ -775,6 +780,7 @@ module.exports = (() => {
775
780
  assert.argumentIsRequired(corporateAction, 'corporateAction', Boolean);
776
781
  assert.argumentIsRequired(initial, 'initial', Boolean);
777
782
  assert.argumentIsRequired(significant, 'significant', Boolean);
783
+ assert.argumentIsRequired(system, 'system', Boolean);
778
784
 
779
785
  this._display = display;
780
786
  this._sequence = sequence;
@@ -787,6 +793,7 @@ module.exports = (() => {
787
793
  this._corporateAction = corporateAction;
788
794
  this._initial = initial;
789
795
  this._significant = significant;
796
+ this._system = system;
790
797
  }
791
798
 
792
799
  /**
@@ -913,6 +920,16 @@ module.exports = (() => {
913
920
  return this._significant;
914
921
  }
915
922
 
923
+ /**
924
+ * System transactions are generated automatically.
925
+ *
926
+ * @public
927
+ * @returns {Boolean}
928
+ */
929
+ get system() {
930
+ return this._system;
931
+ }
932
+
916
933
  /**
917
934
  * A purchase.
918
935
  *
@@ -1138,29 +1155,29 @@ module.exports = (() => {
1138
1155
  }
1139
1156
  }
1140
1157
 
1141
- const buy = new TransactionType('B', 'Buy', 'Buy', 0, true, false, false, true, false, false, false, true, true);
1142
- const sell = new TransactionType('S', 'Sell', 'Sell', 0, false, true, false, false, true, false, false, false, true);
1143
- const buyShort = new TransactionType('BS', 'Buy To Cover', 'Buy To Cover', 0, true, false, false, false, true, false, false, false, true);
1144
- const sellShort = new TransactionType('SS', 'Sell Short', 'Sell Short', 0, false, true, false, true, false, false, false, true, true);
1145
- const dividend = new TransactionType('DV', 'Dividend', 'Dividend', 1, false, false, true, false, false, false, true, false, false);
1146
- const dividendReinvest = new TransactionType('DX', 'Dividend (Reinvested)', 'Dividend Reinvest', 1, false, false, false, true, false, false, true, false, false);
1147
- const dividendStock = new TransactionType('DS', 'Dividend (Stock)', 'Dividend Stock', 1, false, false, false, true, false, false, true, false, false);
1148
- const split = new TransactionType('SP', 'Split', 'Split', 1, false, false, false, true, false, false, true, false, false);
1149
- const fee = new TransactionType('F', 'Fee', 'Fee', 0, false, false, false, false, false, true, false, false, false);
1150
- const feeUnits = new TransactionType('FU', 'Fee Units', 'Fee', 0, false, false, false, false, true, false, false, false, false);
1151
- const delist = new TransactionType('DL', 'Delist', 'Delist', 1, false, false, false, false, false, false, true, false, false);
1152
-
1153
- const distributionCash = new TransactionType('DC', 'Distribution (Cash)', 'Cash Distribution', 1, false, false, true, false, false, false, true, false, false);
1154
- const distributionReinvest = new TransactionType('DY', 'Distribution (Reinvested)', 'Distribution Reinvest', 1, false, false, false, true, false, false, true, false, false);
1155
- const distributionFund = new TransactionType('DF', 'Distribution (Units)', 'Unit Distribution', 1, false, false, false, true, false, false, true, false, false);
1156
-
1157
- const deposit = new TransactionType('D', 'Deposit', 'Deposit', 0, false, false, false, false, false, false, false, true, true);
1158
- const withdrawal = new TransactionType('W', 'Withdrawal', 'Withdrawal', 0, false, false, false, false, false, false, false, true, true);
1159
- const debit = new TransactionType('DR', 'Debit', 'Debit', 0, false, false, false, false, false, false, false, true, true);
1160
- const credit = new TransactionType('CR', 'Credit', 'Credit', 0, false, false, false, false, false, false, false, true, true);
1161
-
1162
- const valuation = new TransactionType('V', 'Valuation', 'Valuation', 0, false, false, false, false, false, false, false, false, false);
1163
- const income = new TransactionType('I', 'Income', 'Income', 0, false, false, true, false, false, false, false, false, false);
1158
+ const buy = new TransactionType('B', 'Buy', 'Buy', 0, true, false, false, true, false, false, false, true, true, false);
1159
+ const sell = new TransactionType('S', 'Sell', 'Sell', 0, false, true, false, false, true, false, false, false, true, false);
1160
+ const buyShort = new TransactionType('BS', 'Buy To Cover', 'Buy To Cover', 0, true, false, false, false, true, false, false, false, true, false);
1161
+ const sellShort = new TransactionType('SS', 'Sell Short', 'Sell Short', 0, false, true, false, true, false, false, false, true, true, false);
1162
+ const dividend = new TransactionType('DV', 'Dividend', 'Dividend', 1, false, false, true, false, false, false, true, false, false, true);
1163
+ const dividendReinvest = new TransactionType('DX', 'Dividend (Reinvested)', 'Dividend Reinvest', 1, false, false, false, true, false, false, true, false, false, true);
1164
+ const dividendStock = new TransactionType('DS', 'Dividend (Stock)', 'Dividend Stock', 1, false, false, false, true, false, false, true, false, false, true);
1165
+ const split = new TransactionType('SP', 'Split', 'Split', 1, false, false, false, true, false, false, true, false, false, true);
1166
+ const fee = new TransactionType('F', 'Fee', 'Fee', 0, false, false, false, false, false, true, false, false, false, false);
1167
+ const feeUnits = new TransactionType('FU', 'Fee Units', 'Fee', 0, false, false, false, false, true, false, false, false, false, false);
1168
+ const delist = new TransactionType('DL', 'Delist', 'Delist', 1, false, false, false, false, false, false, true, false, false, true);
1169
+
1170
+ const distributionCash = new TransactionType('DC', 'Distribution (Cash)', 'Cash Distribution', 1, false, false, true, false, false, false, true, false, false, true);
1171
+ const distributionReinvest = new TransactionType('DY', 'Distribution (Reinvested)', 'Distribution Reinvest', 1, false, false, false, true, false, false, true, false, false, true);
1172
+ const distributionFund = new TransactionType('DF', 'Distribution (Units)', 'Unit Distribution', 1, false, false, false, true, false, false, true, false, false, true);
1173
+
1174
+ const deposit = new TransactionType('D', 'Deposit', 'Deposit', 0, false, false, false, false, false, false, false, true, true, false);
1175
+ const withdrawal = new TransactionType('W', 'Withdrawal', 'Withdrawal', 0, false, false, false, false, false, false, false, true, true, false);
1176
+ const debit = new TransactionType('DR', 'Debit', 'Debit', 0, false, false, false, false, false, false, false, true, true, true);
1177
+ const credit = new TransactionType('CR', 'Credit', 'Credit', 0, false, false, false, false, false, false, false, true, true, true);
1178
+
1179
+ const valuation = new TransactionType('V', 'Valuation', 'Valuation', 0, false, false, false, false, false, false, false, false, false, false);
1180
+ const income = new TransactionType('I', 'Income', 'Income', 0, false, false, true, false, false, false, false, false, false, false);
1164
1181
 
1165
1182
  return TransactionType;
1166
1183
  })();
@@ -14020,22 +14037,36 @@ moment.tz.load(require('./data/packed/latest.json'));
14020
14037
  function createDate (y, m, d, h, M, s, ms) {
14021
14038
  // can't just apply() to create a date:
14022
14039
  // https://stackoverflow.com/q/181348
14023
- var date = new Date(y, m, d, h, M, s, ms);
14024
-
14040
+ var date;
14025
14041
  // the date constructor remaps years 0-99 to 1900-1999
14026
- if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
14027
- date.setFullYear(y);
14042
+ if (y < 100 && y >= 0) {
14043
+ // preserve leap years using a full 400 year cycle, then reset
14044
+ date = new Date(y + 400, m, d, h, M, s, ms);
14045
+ if (isFinite(date.getFullYear())) {
14046
+ date.setFullYear(y);
14047
+ }
14048
+ } else {
14049
+ date = new Date(y, m, d, h, M, s, ms);
14028
14050
  }
14051
+
14029
14052
  return date;
14030
14053
  }
14031
14054
 
14032
14055
  function createUTCDate (y) {
14033
- var date = new Date(Date.UTC.apply(null, arguments));
14034
-
14056
+ var date;
14035
14057
  // the Date.UTC function remaps years 0-99 to 1900-1999
14036
- if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
14037
- date.setUTCFullYear(y);
14058
+ if (y < 100 && y >= 0) {
14059
+ var args = Array.prototype.slice.call(arguments);
14060
+ // preserve leap years using a full 400 year cycle, then reset
14061
+ args[0] = y + 400;
14062
+ date = new Date(Date.UTC.apply(null, args));
14063
+ if (isFinite(date.getUTCFullYear())) {
14064
+ date.setUTCFullYear(y);
14065
+ }
14066
+ } else {
14067
+ date = new Date(Date.UTC.apply(null, arguments));
14038
14068
  }
14069
+
14039
14070
  return date;
14040
14071
  }
14041
14072
 
@@ -14137,7 +14168,7 @@ moment.tz.load(require('./data/packed/latest.json'));
14137
14168
 
14138
14169
  var defaultLocaleWeek = {
14139
14170
  dow : 0, // Sunday is the first day of the week.
14140
- doy : 6 // The week that contains Jan 1st is the first week of the year.
14171
+ doy : 6 // The week that contains Jan 6th is the first week of the year.
14141
14172
  };
14142
14173
 
14143
14174
  function localeFirstDayOfWeek () {
@@ -14246,25 +14277,28 @@ moment.tz.load(require('./data/packed/latest.json'));
14246
14277
  }
14247
14278
 
14248
14279
  // LOCALES
14280
+ function shiftWeekdays (ws, n) {
14281
+ return ws.slice(n, 7).concat(ws.slice(0, n));
14282
+ }
14249
14283
 
14250
14284
  var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
14251
14285
  function localeWeekdays (m, format) {
14252
- if (!m) {
14253
- return isArray(this._weekdays) ? this._weekdays :
14254
- this._weekdays['standalone'];
14255
- }
14256
- return isArray(this._weekdays) ? this._weekdays[m.day()] :
14257
- this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
14286
+ var weekdays = isArray(this._weekdays) ? this._weekdays :
14287
+ this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];
14288
+ return (m === true) ? shiftWeekdays(weekdays, this._week.dow)
14289
+ : (m) ? weekdays[m.day()] : weekdays;
14258
14290
  }
14259
14291
 
14260
14292
  var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
14261
14293
  function localeWeekdaysShort (m) {
14262
- return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
14294
+ return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)
14295
+ : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
14263
14296
  }
14264
14297
 
14265
14298
  var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
14266
14299
  function localeWeekdaysMin (m) {
14267
- return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
14300
+ return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)
14301
+ : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
14268
14302
  }
14269
14303
 
14270
14304
  function handleStrictParse$1(weekdayName, format, strict) {
@@ -15013,13 +15047,13 @@ moment.tz.load(require('./data/packed/latest.json'));
15013
15047
  weekdayOverflow = true;
15014
15048
  }
15015
15049
  } else if (w.e != null) {
15016
- // local weekday -- counting starts from begining of week
15050
+ // local weekday -- counting starts from beginning of week
15017
15051
  weekday = w.e + dow;
15018
15052
  if (w.e < 0 || w.e > 6) {
15019
15053
  weekdayOverflow = true;
15020
15054
  }
15021
15055
  } else {
15022
- // default to begining of week
15056
+ // default to beginning of week
15023
15057
  weekday = dow;
15024
15058
  }
15025
15059
  }
@@ -15613,7 +15647,7 @@ moment.tz.load(require('./data/packed/latest.json'));
15613
15647
  years = normalizedInput.year || 0,
15614
15648
  quarters = normalizedInput.quarter || 0,
15615
15649
  months = normalizedInput.month || 0,
15616
- weeks = normalizedInput.week || 0,
15650
+ weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
15617
15651
  days = normalizedInput.day || 0,
15618
15652
  hours = normalizedInput.hour || 0,
15619
15653
  minutes = normalizedInput.minute || 0,
@@ -15917,7 +15951,7 @@ moment.tz.load(require('./data/packed/latest.json'));
15917
15951
  ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
15918
15952
  };
15919
15953
  } else if (!!(match = isoRegex.exec(input))) {
15920
- sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1;
15954
+ sign = (match[1] === '-') ? -1 : 1;
15921
15955
  duration = {
15922
15956
  y : parseIso(match[2], sign),
15923
15957
  M : parseIso(match[3], sign),
@@ -15959,7 +15993,7 @@ moment.tz.load(require('./data/packed/latest.json'));
15959
15993
  }
15960
15994
 
15961
15995
  function positiveMomentsDifference(base, other) {
15962
- var res = {milliseconds: 0, months: 0};
15996
+ var res = {};
15963
15997
 
15964
15998
  res.months = other.month() - base.month() +
15965
15999
  (other.year() - base.year()) * 12;
@@ -16068,7 +16102,7 @@ moment.tz.load(require('./data/packed/latest.json'));
16068
16102
  if (!(this.isValid() && localInput.isValid())) {
16069
16103
  return false;
16070
16104
  }
16071
- units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
16105
+ units = normalizeUnits(units) || 'millisecond';
16072
16106
  if (units === 'millisecond') {
16073
16107
  return this.valueOf() > localInput.valueOf();
16074
16108
  } else {
@@ -16081,7 +16115,7 @@ moment.tz.load(require('./data/packed/latest.json'));
16081
16115
  if (!(this.isValid() && localInput.isValid())) {
16082
16116
  return false;
16083
16117
  }
16084
- units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
16118
+ units = normalizeUnits(units) || 'millisecond';
16085
16119
  if (units === 'millisecond') {
16086
16120
  return this.valueOf() < localInput.valueOf();
16087
16121
  } else {
@@ -16090,9 +16124,14 @@ moment.tz.load(require('./data/packed/latest.json'));
16090
16124
  }
16091
16125
 
16092
16126
  function isBetween (from, to, units, inclusivity) {
16127
+ var localFrom = isMoment(from) ? from : createLocal(from),
16128
+ localTo = isMoment(to) ? to : createLocal(to);
16129
+ if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
16130
+ return false;
16131
+ }
16093
16132
  inclusivity = inclusivity || '()';
16094
- return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
16095
- (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
16133
+ return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&
16134
+ (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
16096
16135
  }
16097
16136
 
16098
16137
  function isSame (input, units) {
@@ -16101,7 +16140,7 @@ moment.tz.load(require('./data/packed/latest.json'));
16101
16140
  if (!(this.isValid() && localInput.isValid())) {
16102
16141
  return false;
16103
16142
  }
16104
- units = normalizeUnits(units || 'millisecond');
16143
+ units = normalizeUnits(units) || 'millisecond';
16105
16144
  if (units === 'millisecond') {
16106
16145
  return this.valueOf() === localInput.valueOf();
16107
16146
  } else {
@@ -16111,11 +16150,11 @@ moment.tz.load(require('./data/packed/latest.json'));
16111
16150
  }
16112
16151
 
16113
16152
  function isSameOrAfter (input, units) {
16114
- return this.isSame(input, units) || this.isAfter(input,units);
16153
+ return this.isSame(input, units) || this.isAfter(input, units);
16115
16154
  }
16116
16155
 
16117
16156
  function isSameOrBefore (input, units) {
16118
- return this.isSame(input, units) || this.isBefore(input,units);
16157
+ return this.isSame(input, units) || this.isBefore(input, units);
16119
16158
  }
16120
16159
 
16121
16160
  function diff (input, units, asFloat) {
@@ -16292,62 +16331,130 @@ moment.tz.load(require('./data/packed/latest.json'));
16292
16331
  return this._locale;
16293
16332
  }
16294
16333
 
16334
+ var MS_PER_SECOND = 1000;
16335
+ var MS_PER_MINUTE = 60 * MS_PER_SECOND;
16336
+ var MS_PER_HOUR = 60 * MS_PER_MINUTE;
16337
+ var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
16338
+
16339
+ // actual modulo - handles negative numbers (for dates before 1970):
16340
+ function mod$1(dividend, divisor) {
16341
+ return (dividend % divisor + divisor) % divisor;
16342
+ }
16343
+
16344
+ function localStartOfDate(y, m, d) {
16345
+ // the date constructor remaps years 0-99 to 1900-1999
16346
+ if (y < 100 && y >= 0) {
16347
+ // preserve leap years using a full 400 year cycle, then reset
16348
+ return new Date(y + 400, m, d) - MS_PER_400_YEARS;
16349
+ } else {
16350
+ return new Date(y, m, d).valueOf();
16351
+ }
16352
+ }
16353
+
16354
+ function utcStartOfDate(y, m, d) {
16355
+ // Date.UTC remaps years 0-99 to 1900-1999
16356
+ if (y < 100 && y >= 0) {
16357
+ // preserve leap years using a full 400 year cycle, then reset
16358
+ return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
16359
+ } else {
16360
+ return Date.UTC(y, m, d);
16361
+ }
16362
+ }
16363
+
16295
16364
  function startOf (units) {
16365
+ var time;
16296
16366
  units = normalizeUnits(units);
16297
- // the following switch intentionally omits break keywords
16298
- // to utilize falling through the cases.
16367
+ if (units === undefined || units === 'millisecond' || !this.isValid()) {
16368
+ return this;
16369
+ }
16370
+
16371
+ var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
16372
+
16299
16373
  switch (units) {
16300
16374
  case 'year':
16301
- this.month(0);
16302
- /* falls through */
16375
+ time = startOfDate(this.year(), 0, 1);
16376
+ break;
16303
16377
  case 'quarter':
16378
+ time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
16379
+ break;
16304
16380
  case 'month':
16305
- this.date(1);
16306
- /* falls through */
16381
+ time = startOfDate(this.year(), this.month(), 1);
16382
+ break;
16307
16383
  case 'week':
16384
+ time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
16385
+ break;
16308
16386
  case 'isoWeek':
16387
+ time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
16388
+ break;
16309
16389
  case 'day':
16310
16390
  case 'date':
16311
- this.hours(0);
16312
- /* falls through */
16391
+ time = startOfDate(this.year(), this.month(), this.date());
16392
+ break;
16313
16393
  case 'hour':
16314
- this.minutes(0);
16315
- /* falls through */
16394
+ time = this._d.valueOf();
16395
+ time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
16396
+ break;
16316
16397
  case 'minute':
16317
- this.seconds(0);
16318
- /* falls through */
16398
+ time = this._d.valueOf();
16399
+ time -= mod$1(time, MS_PER_MINUTE);
16400
+ break;
16319
16401
  case 'second':
16320
- this.milliseconds(0);
16321
- }
16322
-
16323
- // weeks are a special case
16324
- if (units === 'week') {
16325
- this.weekday(0);
16326
- }
16327
- if (units === 'isoWeek') {
16328
- this.isoWeekday(1);
16329
- }
16330
-
16331
- // quarters are also special
16332
- if (units === 'quarter') {
16333
- this.month(Math.floor(this.month() / 3) * 3);
16402
+ time = this._d.valueOf();
16403
+ time -= mod$1(time, MS_PER_SECOND);
16404
+ break;
16334
16405
  }
16335
16406
 
16407
+ this._d.setTime(time);
16408
+ hooks.updateOffset(this, true);
16336
16409
  return this;
16337
16410
  }
16338
16411
 
16339
16412
  function endOf (units) {
16413
+ var time;
16340
16414
  units = normalizeUnits(units);
16341
- if (units === undefined || units === 'millisecond') {
16415
+ if (units === undefined || units === 'millisecond' || !this.isValid()) {
16342
16416
  return this;
16343
16417
  }
16344
16418
 
16345
- // 'date' is an alias for 'day', so it should be considered as such.
16346
- if (units === 'date') {
16347
- units = 'day';
16419
+ var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
16420
+
16421
+ switch (units) {
16422
+ case 'year':
16423
+ time = startOfDate(this.year() + 1, 0, 1) - 1;
16424
+ break;
16425
+ case 'quarter':
16426
+ time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
16427
+ break;
16428
+ case 'month':
16429
+ time = startOfDate(this.year(), this.month() + 1, 1) - 1;
16430
+ break;
16431
+ case 'week':
16432
+ time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
16433
+ break;
16434
+ case 'isoWeek':
16435
+ time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
16436
+ break;
16437
+ case 'day':
16438
+ case 'date':
16439
+ time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
16440
+ break;
16441
+ case 'hour':
16442
+ time = this._d.valueOf();
16443
+ time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
16444
+ break;
16445
+ case 'minute':
16446
+ time = this._d.valueOf();
16447
+ time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
16448
+ break;
16449
+ case 'second':
16450
+ time = this._d.valueOf();
16451
+ time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
16452
+ break;
16348
16453
  }
16349
16454
 
16350
- return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
16455
+ this._d.setTime(time);
16456
+ hooks.updateOffset(this, true);
16457
+ return this;
16351
16458
  }
16352
16459
 
16353
16460
  function valueOf () {
@@ -17053,10 +17160,14 @@ moment.tz.load(require('./data/packed/latest.json'));
17053
17160
 
17054
17161
  units = normalizeUnits(units);
17055
17162
 
17056
- if (units === 'month' || units === 'year') {
17057
- days = this._days + milliseconds / 864e5;
17163
+ if (units === 'month' || units === 'quarter' || units === 'year') {
17164
+ days = this._days + milliseconds / 864e5;
17058
17165
  months = this._months + daysToMonths(days);
17059
- return units === 'month' ? months : months / 12;
17166
+ switch (units) {
17167
+ case 'month': return months;
17168
+ case 'quarter': return months / 3;
17169
+ case 'year': return months / 12;
17170
+ }
17060
17171
  } else {
17061
17172
  // handle milliseconds separately because of floating point math errors (issue #1867)
17062
17173
  days = this._days + Math.round(monthsToDays(this._months));
@@ -17099,6 +17210,7 @@ moment.tz.load(require('./data/packed/latest.json'));
17099
17210
  var asDays = makeAs('d');
17100
17211
  var asWeeks = makeAs('w');
17101
17212
  var asMonths = makeAs('M');
17213
+ var asQuarters = makeAs('Q');
17102
17214
  var asYears = makeAs('y');
17103
17215
 
17104
17216
  function clone$1 () {
@@ -17290,6 +17402,7 @@ moment.tz.load(require('./data/packed/latest.json'));
17290
17402
  proto$2.asDays = asDays;
17291
17403
  proto$2.asWeeks = asWeeks;
17292
17404
  proto$2.asMonths = asMonths;
17405
+ proto$2.asQuarters = asQuarters;
17293
17406
  proto$2.asYears = asYears;
17294
17407
  proto$2.valueOf = valueOf$1;
17295
17408
  proto$2._bubble = bubble;
@@ -17334,7 +17447,7 @@ moment.tz.load(require('./data/packed/latest.json'));
17334
17447
  // Side effect imports
17335
17448
 
17336
17449
 
17337
- hooks.version = '2.22.2';
17450
+ hooks.version = '2.24.0';
17338
17451
 
17339
17452
  setHookCallback(createLocal);
17340
17453
 
@@ -17375,7 +17488,7 @@ moment.tz.load(require('./data/packed/latest.json'));
17375
17488
  TIME: 'HH:mm', // <input type="time" />
17376
17489
  TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
17377
17490
  TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
17378
- WEEK: 'YYYY-[W]WW', // <input type="week" />
17491
+ WEEK: 'GGGG-[W]WW', // <input type="week" />
17379
17492
  MONTH: 'YYYY-MM' // <input type="month" />
17380
17493
  };
17381
17494
 
@@ -17764,7 +17877,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17764
17877
  });
17765
17878
  });
17766
17879
 
17767
- 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', () => {
17880
+ 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', () => {
17768
17881
  let ranges;
17769
17882
 
17770
17883
  beforeEach(() => {
@@ -17817,6 +17930,164 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
17817
17930
  });
17818
17931
  });
17819
17932
 
17933
+ describe('and yearly position summary ranges are processed for a transaction set that opens in the current year', () => {
17934
+ let ranges;
17935
+
17936
+ beforeEach(() => {
17937
+ const transactions = [
17938
+ {
17939
+ date: Day.getToday(),
17940
+ snapshot: {
17941
+ open: new Decimal(1)
17942
+ },
17943
+ type: TransactionType.BUY
17944
+ }
17945
+ ];
17946
+
17947
+ ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
17948
+ });
17949
+
17950
+ it('should have zero ranges', () => {
17951
+ expect(ranges.length).toEqual(0);
17952
+ });
17953
+ });
17954
+
17955
+ describe('and monthly position summary ranges are processed for a transaction set that does not close', () => {
17956
+ let ranges;
17957
+
17958
+ beforeEach(() => {
17959
+ const transactions = [
17960
+ {
17961
+ date: new Day(2018, 12, 20),
17962
+ snapshot: {
17963
+ open: new Decimal(1)
17964
+ },
17965
+ type: TransactionType.BUY
17966
+ },
17967
+ {
17968
+ date: new Day(2019, 2, 21),
17969
+ snapshot: {
17970
+ open: new Decimal(1)
17971
+ },
17972
+ type: TransactionType.BUY
17973
+ }
17974
+ ];
17975
+
17976
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
17977
+ });
17978
+
17979
+ it('should have at least two ranges', () => {
17980
+ expect(ranges.length > 1).toEqual(true);
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
+ it('the last range should be for the previous month', () => {
17989
+ const today = Day.getToday();
17990
+
17991
+ expect(ranges[ranges.length - 1].start.format()).toEqual(today.subtractMonths(2).getEndOfMonth().format());
17992
+ expect(ranges[ranges.length - 1].end.format()).toEqual(today.subtractMonths(1).getEndOfMonth().format());
17993
+ });
17994
+ });
17995
+
17996
+ describe('and monthly position summary ranges are processed for a transaction set closes the same month', () => {
17997
+ let ranges;
17998
+
17999
+ beforeEach(() => {
18000
+ const transactions = [
18001
+ {
18002
+ date: new Day(2018, 12, 1),
18003
+ snapshot: {
18004
+ open: new Decimal(1)
18005
+ },
18006
+ type: TransactionType.BUY
18007
+ },
18008
+ {
18009
+ date: new Day(2018, 12, 31),
18010
+ snapshot: {
18011
+ open: new Decimal(0)
18012
+ },
18013
+ type: TransactionType.SELL
18014
+ }
18015
+ ];
18016
+
18017
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
18018
+ });
18019
+
18020
+ it('should have one range', () => {
18021
+ expect(ranges.length).toEqual(1);
18022
+ });
18023
+
18024
+ it('the first range should be from 11-30-2018 to 12-31-2018', () => {
18025
+ expect(ranges[0].start.format()).toEqual('2018-11-30');
18026
+ expect(ranges[0].end.format()).toEqual('2018-12-31');
18027
+ });
18028
+ });
18029
+
18030
+ describe('and monthly position summary ranges are processed for a transaction set closes the next month', () => {
18031
+ let ranges;
18032
+
18033
+ beforeEach(() => {
18034
+ const transactions = [
18035
+ {
18036
+ date: new Day(2015, 10, 20),
18037
+ snapshot: {
18038
+ open: new Decimal(1)
18039
+ },
18040
+ type: TransactionType.BUY
18041
+ },
18042
+ {
18043
+ date: new Day(2015, 11, 20),
18044
+ snapshot: {
18045
+ open: new Decimal(0)
18046
+ },
18047
+ type: TransactionType.SELL
18048
+ }
18049
+ ];
18050
+
18051
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
18052
+ });
18053
+
18054
+ it('should have two ranges', () => {
18055
+ expect(ranges.length).toEqual(2);
18056
+ });
18057
+
18058
+ it('the first range should be from 09-30-2015 to 10-31-2015', () => {
18059
+ expect(ranges[0].start.format()).toEqual('2015-09-30');
18060
+ expect(ranges[0].end.format()).toEqual('2015-10-31');
18061
+ });
18062
+
18063
+ it('the second range should be from 10-31-2015 to 11-30-2015', () => {
18064
+ expect(ranges[1].start.format()).toEqual('2015-10-31');
18065
+ expect(ranges[1].end.format()).toEqual('2015-11-30');
18066
+ });
18067
+ });
18068
+
18069
+ describe('and monthly position summary ranges are processed for a transaction set that opens in the current month', () => {
18070
+ let ranges;
18071
+
18072
+ beforeEach(() => {
18073
+ const transactions = [
18074
+ {
18075
+ date: Day.getToday(),
18076
+ snapshot: {
18077
+ open: new Decimal(1)
18078
+ },
18079
+ type: TransactionType.BUY
18080
+ }
18081
+ ];
18082
+
18083
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
18084
+ });
18085
+
18086
+ it('should have zero ranges', () => {
18087
+ expect(ranges.length).toEqual(0);
18088
+ });
18089
+ });
18090
+
17820
18091
  describe('and a year-to-date position summary ranges are processed for a transaction set that closed in 2017', () => {
17821
18092
  let ranges;
17822
18093
 
@@ -18337,12 +18608,10 @@ describe('When a position container data is gathered', () => {
18337
18608
  });
18338
18609
 
18339
18610
  },{"./../../../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){
18340
- const Currency = require('@barchart/common-js/lang/Currency'),
18341
- Day = require('@barchart/common-js/lang/Day'),
18611
+ const Day = require('@barchart/common-js/lang/Day'),
18342
18612
  Decimal = require('@barchart/common-js/lang/Decimal');
18343
18613
 
18344
- const InstrumentType = require('./../../../lib/data/InstrumentType'),
18345
- TransactionType = require('./../../../lib/data/TransactionType');
18614
+ const TransactionType = require('./../../../lib/data/TransactionType');
18346
18615
 
18347
18616
  const TransactionSchema = require('./../../../lib/serialization/TransactionSchema');
18348
18617
 
@@ -18405,4 +18674,4 @@ describe('When transactions are serialized', () => {
18405
18674
  });
18406
18675
  });
18407
18676
 
18408
- },{"./../../../lib/data/InstrumentType":1,"./../../../lib/data/TransactionType":4,"./../../../lib/serialization/TransactionSchema":12,"@barchart/common-js/lang/Currency":20,"@barchart/common-js/lang/Day":21,"@barchart/common-js/lang/Decimal":22}]},{},[52,53,54,55]);
18677
+ },{"./../../../lib/data/TransactionType":4,"./../../../lib/serialization/TransactionSchema":12,"@barchart/common-js/lang/Day":21,"@barchart/common-js/lang/Decimal":22}]},{},[52,53,54,55]);
@@ -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,164 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
226
226
  });
227
227
  });
228
228
 
229
+ describe('and yearly position summary ranges are processed for a transaction set that opens in the current year', () => {
230
+ let ranges;
231
+
232
+ beforeEach(() => {
233
+ const transactions = [
234
+ {
235
+ date: Day.getToday(),
236
+ snapshot: {
237
+ open: new Decimal(1)
238
+ },
239
+ type: TransactionType.BUY
240
+ }
241
+ ];
242
+
243
+ ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
244
+ });
245
+
246
+ it('should have zero ranges', () => {
247
+ expect(ranges.length).toEqual(0);
248
+ });
249
+ });
250
+
251
+ describe('and monthly position summary ranges are processed for a transaction set that does not close', () => {
252
+ let ranges;
253
+
254
+ beforeEach(() => {
255
+ const transactions = [
256
+ {
257
+ date: new Day(2018, 12, 20),
258
+ snapshot: {
259
+ open: new Decimal(1)
260
+ },
261
+ type: TransactionType.BUY
262
+ },
263
+ {
264
+ date: new Day(2019, 2, 21),
265
+ snapshot: {
266
+ open: new Decimal(1)
267
+ },
268
+ type: TransactionType.BUY
269
+ }
270
+ ];
271
+
272
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
273
+ });
274
+
275
+ it('should have at least two ranges', () => {
276
+ expect(ranges.length > 1).toEqual(true);
277
+ });
278
+
279
+ it('the first range should be from 11-30-2018 to 12-31-2018', () => {
280
+ expect(ranges[0].start.format()).toEqual('2018-11-30');
281
+ expect(ranges[0].end.format()).toEqual('2018-12-31');
282
+ });
283
+
284
+ it('the last range should be for the previous month', () => {
285
+ const today = Day.getToday();
286
+
287
+ expect(ranges[ranges.length - 1].start.format()).toEqual(today.subtractMonths(2).getEndOfMonth().format());
288
+ expect(ranges[ranges.length - 1].end.format()).toEqual(today.subtractMonths(1).getEndOfMonth().format());
289
+ });
290
+ });
291
+
292
+ describe('and monthly position summary ranges are processed for a transaction set closes the same month', () => {
293
+ let ranges;
294
+
295
+ beforeEach(() => {
296
+ const transactions = [
297
+ {
298
+ date: new Day(2018, 12, 1),
299
+ snapshot: {
300
+ open: new Decimal(1)
301
+ },
302
+ type: TransactionType.BUY
303
+ },
304
+ {
305
+ date: new Day(2018, 12, 31),
306
+ snapshot: {
307
+ open: new Decimal(0)
308
+ },
309
+ type: TransactionType.SELL
310
+ }
311
+ ];
312
+
313
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
314
+ });
315
+
316
+ it('should have one range', () => {
317
+ expect(ranges.length).toEqual(1);
318
+ });
319
+
320
+ it('the first range should be from 11-30-2018 to 12-31-2018', () => {
321
+ expect(ranges[0].start.format()).toEqual('2018-11-30');
322
+ expect(ranges[0].end.format()).toEqual('2018-12-31');
323
+ });
324
+ });
325
+
326
+ describe('and monthly position summary ranges are processed for a transaction set closes the next month', () => {
327
+ let ranges;
328
+
329
+ beforeEach(() => {
330
+ const transactions = [
331
+ {
332
+ date: new Day(2015, 10, 20),
333
+ snapshot: {
334
+ open: new Decimal(1)
335
+ },
336
+ type: TransactionType.BUY
337
+ },
338
+ {
339
+ date: new Day(2015, 11, 20),
340
+ snapshot: {
341
+ open: new Decimal(0)
342
+ },
343
+ type: TransactionType.SELL
344
+ }
345
+ ];
346
+
347
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
348
+ });
349
+
350
+ it('should have two ranges', () => {
351
+ expect(ranges.length).toEqual(2);
352
+ });
353
+
354
+ it('the first range should be from 09-30-2015 to 10-31-2015', () => {
355
+ expect(ranges[0].start.format()).toEqual('2015-09-30');
356
+ expect(ranges[0].end.format()).toEqual('2015-10-31');
357
+ });
358
+
359
+ it('the second range should be from 10-31-2015 to 11-30-2015', () => {
360
+ expect(ranges[1].start.format()).toEqual('2015-10-31');
361
+ expect(ranges[1].end.format()).toEqual('2015-11-30');
362
+ });
363
+ });
364
+
365
+ describe('and monthly position summary ranges are processed for a transaction set that opens in the current month', () => {
366
+ let ranges;
367
+
368
+ beforeEach(() => {
369
+ const transactions = [
370
+ {
371
+ date: Day.getToday(),
372
+ snapshot: {
373
+ open: new Decimal(1)
374
+ },
375
+ type: TransactionType.BUY
376
+ }
377
+ ];
378
+
379
+ ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
380
+ });
381
+
382
+ it('should have zero ranges', () => {
383
+ expect(ranges.length).toEqual(0);
384
+ });
385
+ });
386
+
229
387
  describe('and a year-to-date position summary ranges are processed for a transaction set that closed in 2017', () => {
230
388
  let ranges;
231
389
 
@@ -1,9 +1,7 @@
1
- const Currency = require('@barchart/common-js/lang/Currency'),
2
- Day = require('@barchart/common-js/lang/Day'),
1
+ const Day = require('@barchart/common-js/lang/Day'),
3
2
  Decimal = require('@barchart/common-js/lang/Decimal');
4
3
 
5
- const InstrumentType = require('./../../../lib/data/InstrumentType'),
6
- TransactionType = require('./../../../lib/data/TransactionType');
4
+ const TransactionType = require('./../../../lib/data/TransactionType');
7
5
 
8
6
  const TransactionSchema = require('./../../../lib/serialization/TransactionSchema');
9
7