@barchart/portfolio-api-common 1.0.33 → 1.0.37

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.
@@ -15,20 +15,28 @@ module.exports = (() => {
15
15
  * @param {String} code
16
16
  * @param {String} description
17
17
  * @param {Function} rangeCalculator
18
+ * @param {Function} startDateCalculator
18
19
  */
19
20
  class PositionSummaryFrame extends Enum {
20
- constructor(code, description, rangeCalculator) {
21
+ constructor(code, description, rangeCalculator, startDateCalculator) {
21
22
  super(code, description);
22
23
 
23
24
  assert.argumentIsRequired(rangeCalculator, 'rangeCalculator', Function);
24
25
 
25
26
  this._rangeCalculator = rangeCalculator;
27
+ this._startDateCalculator = startDateCalculator;
26
28
  }
27
29
 
28
30
  getRanges(transactions) {
29
31
  assert.argumentIsArray(transactions, 'transactions');
30
32
 
31
- return this._rangeCalculator(transactions);
33
+ return this._rangeCalculator(getFilteredTransactions(transactions));
34
+ }
35
+
36
+ getStartDate(periods) {
37
+ assert.argumentIsRequired(periods, 'periods', Number);
38
+
39
+ return this._startDateCalculator(periods);
32
40
  }
33
41
 
34
42
  /**
@@ -76,10 +84,10 @@ module.exports = (() => {
76
84
  }
77
85
  }
78
86
 
79
- const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges);
80
- const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges);
81
- const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges);
82
- const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges);
87
+ const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges, getYearlyStartDate);
88
+ const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges, getQuarterlyStartDate);
89
+ const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges, getMonthlyStartDate);
90
+ const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges, getYearToDateStartDate);
83
91
 
84
92
  function getRange(start, end) {
85
93
  return {
@@ -142,5 +150,36 @@ module.exports = (() => {
142
150
  return ranges;
143
151
  }
144
152
 
153
+ function getYearlyStartDate(periods) {
154
+ const today = Day.getToday();
155
+
156
+ return Day.getToday()
157
+ .subtractMonths(today.month - 1)
158
+ .subtractDays(today.day)
159
+ .subtractYears(periods);
160
+ }
161
+
162
+ function getQuarterlyStartDate(periods) {
163
+ return null;
164
+ }
165
+
166
+ function getMonthlyStartDate(periods) {
167
+ return null;
168
+ }
169
+
170
+ function getYearToDateStartDate(periods) {
171
+ return null;
172
+ }
173
+
174
+ function getFilteredTransactions(transactions) {
175
+ return transactions.reduce((filtered, transaction) => {
176
+ if (!transaction.snapshot.open.getIsZero() || transaction.type.closing) {
177
+ filtered.push(transaction);
178
+ }
179
+
180
+ return filtered;
181
+ }, [ ]);
182
+ }
183
+
145
184
  return PositionSummaryFrame;
146
185
  })();
@@ -57,6 +57,17 @@ module.exports = (() => {
57
57
  return client;
58
58
  }
59
59
 
60
+ /**
61
+ * Only returns identifiers and portfolio name.
62
+ *
63
+ * @static
64
+ * @public
65
+ * @returns {PortfolioSchema}
66
+ */
67
+ static get NAME() {
68
+ return name;
69
+ }
70
+
60
71
  /**
61
72
  * Data required to create a portfolio.
62
73
  *
@@ -125,6 +136,13 @@ module.exports = (() => {
125
136
  .schema
126
137
  );
127
138
 
139
+ const name = new PortfolioSchema(SchemaBuilder.withName('name')
140
+ .withField('user', DataType.STRING)
141
+ .withField('portfolio', DataType.STRING)
142
+ .withField('name', DataType.STRING)
143
+ .schema
144
+ );
145
+
128
146
  const create = new PortfolioSchema(SchemaBuilder.withName('create')
129
147
  .withField('name', DataType.STRING)
130
148
  .withField('timezone', DataType.forEnum(Timezones, 'Timezone'))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.0.33",
3
+ "version": "1.0.37",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -16,20 +16,28 @@ module.exports = (() => {
16
16
  * @param {String} code
17
17
  * @param {String} description
18
18
  * @param {Function} rangeCalculator
19
+ * @param {Function} startDateCalculator
19
20
  */
20
21
  class PositionSummaryFrame extends Enum {
21
- constructor(code, description, rangeCalculator) {
22
+ constructor(code, description, rangeCalculator, startDateCalculator) {
22
23
  super(code, description);
23
24
 
24
25
  assert.argumentIsRequired(rangeCalculator, 'rangeCalculator', Function);
25
26
 
26
27
  this._rangeCalculator = rangeCalculator;
28
+ this._startDateCalculator = startDateCalculator;
27
29
  }
28
30
 
29
31
  getRanges(transactions) {
30
32
  assert.argumentIsArray(transactions, 'transactions');
31
33
 
32
- return this._rangeCalculator(transactions);
34
+ return this._rangeCalculator(getFilteredTransactions(transactions));
35
+ }
36
+
37
+ getStartDate(periods) {
38
+ assert.argumentIsRequired(periods, 'periods', Number);
39
+
40
+ return this._startDateCalculator(periods);
33
41
  }
34
42
 
35
43
  /**
@@ -77,10 +85,10 @@ module.exports = (() => {
77
85
  }
78
86
  }
79
87
 
80
- const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges);
81
- const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges);
82
- const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges);
83
- const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges);
88
+ const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges, getYearlyStartDate);
89
+ const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges, getQuarterlyStartDate);
90
+ const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges, getMonthlyStartDate);
91
+ const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges, getYearToDateStartDate);
84
92
 
85
93
  function getRange(start, end) {
86
94
  return {
@@ -143,10 +151,368 @@ module.exports = (() => {
143
151
  return ranges;
144
152
  }
145
153
 
154
+ function getYearlyStartDate(periods) {
155
+ const today = Day.getToday();
156
+
157
+ return Day.getToday()
158
+ .subtractMonths(today.month - 1)
159
+ .subtractDays(today.day)
160
+ .subtractYears(periods);
161
+ }
162
+
163
+ function getQuarterlyStartDate(periods) {
164
+ return null;
165
+ }
166
+
167
+ function getMonthlyStartDate(periods) {
168
+ return null;
169
+ }
170
+
171
+ function getYearToDateStartDate(periods) {
172
+ return null;
173
+ }
174
+
175
+ function getFilteredTransactions(transactions) {
176
+ return transactions.reduce((filtered, transaction) => {
177
+ if (!transaction.snapshot.open.getIsZero() || transaction.type.closing) {
178
+ filtered.push(transaction);
179
+ }
180
+
181
+ return filtered;
182
+ }, [ ]);
183
+ }
184
+
146
185
  return PositionSummaryFrame;
147
186
  })();
148
187
 
149
- },{"@barchart/common-js/lang/Day":4,"@barchart/common-js/lang/Enum":6,"@barchart/common-js/lang/array":7,"@barchart/common-js/lang/assert":8,"@barchart/common-js/lang/is":9}],2:[function(require,module,exports){
188
+ },{"@barchart/common-js/lang/Day":5,"@barchart/common-js/lang/Enum":7,"@barchart/common-js/lang/array":8,"@barchart/common-js/lang/assert":9,"@barchart/common-js/lang/is":10}],2:[function(require,module,exports){
189
+ const assert = require('@barchart/common-js/lang/assert'),
190
+ Enum = require('@barchart/common-js/lang/Enum');
191
+
192
+ module.exports = (() => {
193
+ 'use strict';
194
+
195
+ /**
196
+ * An enumeration item that describes a type of transaction.
197
+ *
198
+ * @public
199
+ * @extends {Enum}
200
+ * @param {String} code
201
+ * @param {String} description
202
+ * @param {Boolean} purchase
203
+ * @param {Boolean} sale
204
+ * @param {Boolean} income
205
+ * @param {Boolean} opening
206
+ * @param {Boolean} closing
207
+ */
208
+ class TransactionType extends Enum {
209
+ constructor(code, description, purchase, sale, income, opening, closing) {
210
+ super(code, description);
211
+
212
+ assert.argumentIsRequired(purchase, 'purchase', Boolean);
213
+ assert.argumentIsRequired(sale, 'sale', Boolean);
214
+ assert.argumentIsRequired(income, 'income', Boolean);
215
+ assert.argumentIsRequired(opening, 'opening', Boolean);
216
+ assert.argumentIsRequired(closing, 'closing', Boolean);
217
+
218
+ this._purchase = purchase;
219
+ this._sale = sale;
220
+ this._income = income;
221
+ this._opening = opening;
222
+ this._closing = closing;
223
+ }
224
+
225
+ /**
226
+ * Indicates if the transaction was a trade.
227
+ *
228
+ * @public
229
+ * @returns {Boolean}
230
+ */
231
+ get trade() {
232
+ return this._purchase || this._sale;
233
+ }
234
+
235
+ /**
236
+ * Indicates if the trade was a purchase.
237
+ *
238
+ * @public
239
+ * @returns {Boolean}
240
+ */
241
+ get purchase() {
242
+ return this._purchase;
243
+ }
244
+
245
+ /**
246
+ * Indicates if the trade was a sale.
247
+ *
248
+ * @public
249
+ * @returns {Boolean}
250
+ */
251
+ get sale() {
252
+ return this._sale;
253
+ }
254
+
255
+ /**
256
+ * Indicates if the transaction was an income payment.
257
+ *
258
+ * @public
259
+ * @returns {Boolean}
260
+ */
261
+ get income() {
262
+ return this._income;
263
+ }
264
+
265
+ /**
266
+ * Indicates if the transactions opens the position (i.e. increases its
267
+ * magnitude).
268
+ *
269
+ * @public
270
+ * @returns {Boolean}
271
+ */
272
+ get opening() {
273
+ return this._opening;
274
+ }
275
+
276
+ /**
277
+ * Indicates if the transactions closes the position (i.e. decreases its
278
+ * magnitude).
279
+ *
280
+ * @public
281
+ * @returns {Boolean}
282
+ */
283
+ get closing() {
284
+ return this._closing;
285
+ }
286
+
287
+ /**
288
+ * A purchase.
289
+ *
290
+ * @public
291
+ * @static
292
+ * @returns {TransactionType}
293
+ */
294
+ static get BUY() {
295
+ return buy;
296
+ }
297
+
298
+ /**
299
+ * A sale.
300
+ *
301
+ * @public
302
+ * @static
303
+ * @returns {TransactionType}
304
+ */
305
+ static get SELL() {
306
+ return sell;
307
+ }
308
+
309
+ /**
310
+ * A purchase (in a short position).
311
+ *
312
+ * @public
313
+ * @static
314
+ * @returns {TransactionType}
315
+ */
316
+ static get BUY_SHORT() {
317
+ return buyShort;
318
+ }
319
+
320
+ /**
321
+ * A short sale.
322
+ *
323
+ * @public
324
+ * @static
325
+ * @returns {TransactionType}
326
+ */
327
+ static get SELL_SHORT() {
328
+ return sellShort;
329
+ }
330
+
331
+ /**
332
+ * A cash dividend.
333
+ *
334
+ * @public
335
+ * @static
336
+ * @returns {TransactionType}
337
+ */
338
+ static get DIVIDEND() {
339
+ return dividend;
340
+ }
341
+
342
+ /**
343
+ * A cash dividend, reinvested.
344
+ *
345
+ * @public
346
+ * @static
347
+ * @returns {TransactionType}
348
+ */
349
+ static get DIVIDEND_REINVEST() {
350
+ return dividendReinvest;
351
+ }
352
+
353
+ /**
354
+ * A stock dividend.
355
+ *
356
+ * @public
357
+ * @static
358
+ * @returns {TransactionType}
359
+ */
360
+ static get DIVIDEND_STOCK() {
361
+ return dividendStock;
362
+ }
363
+
364
+ /**
365
+ * A mutual fund distribution in cash.
366
+ *
367
+ * @public
368
+ * @static
369
+ * @returns {TransactionType}
370
+ */
371
+ static get DISTRIBUTION_CASH() {
372
+ return distributionCash;
373
+ }
374
+
375
+ /**
376
+ * A mutual fund distribution in units.
377
+ *
378
+ * @public
379
+ * @static
380
+ * @returns {TransactionType}
381
+ */
382
+ static get DISTRIBUTION_FUND() {
383
+ return distributionFund;
384
+ }
385
+
386
+ /**
387
+ * A split.
388
+ *
389
+ * @public
390
+ * @static
391
+ * @returns {TransactionType}
392
+ */
393
+ static get SPLIT() {
394
+ return split;
395
+ }
396
+
397
+ /**
398
+ * A fee.
399
+ *
400
+ * @public
401
+ * @static
402
+ * @returns {TransactionType}
403
+ */
404
+ static get FEE() {
405
+ return fee;
406
+ }
407
+
408
+ /**
409
+ * A mutual fund fee, which is paid in units.
410
+ *
411
+ * @public
412
+ * @static
413
+ * @returns {TransactionType}
414
+ */
415
+ static get FEE_UNITS() {
416
+ return feeUnits;
417
+ }
418
+
419
+ /**
420
+ * A deposit.
421
+ *
422
+ * @public
423
+ * @static
424
+ * @returns {TransactionType}
425
+ */
426
+ static get DEPOSIT() {
427
+ return deposit;
428
+ }
429
+
430
+ /**
431
+ * A withdrawal.
432
+ *
433
+ * @public
434
+ * @static
435
+ * @returns {TransactionType}
436
+ */
437
+ static get WITHDRAWAL() {
438
+ return withdrawal;
439
+ }
440
+
441
+ /**
442
+ * A system-generated withdrawal, arising from another transaction.
443
+ *
444
+ * @public
445
+ * @static
446
+ * @returns {TransactionType}
447
+ */
448
+ static get DEBIT() {
449
+ return debit;
450
+ }
451
+
452
+ /**
453
+ * A system-generated deposit, arising from another transaction.
454
+ *
455
+ * @public
456
+ * @static
457
+ * @returns {TransactionType}
458
+ */
459
+ static get CREDIT() {
460
+ return credit;
461
+ }
462
+
463
+ /**
464
+ * A valuation event.
465
+ *
466
+ * @public
467
+ * @static
468
+ * @returns {TransactionType}
469
+ */
470
+ static get VALUATION() {
471
+ return valuation;
472
+ }
473
+
474
+ /**
475
+ * Other Income.
476
+ *
477
+ * @public
478
+ * @static
479
+ * @returns {TransactionType}
480
+ */
481
+ static get INCOME() {
482
+ return income;
483
+ }
484
+
485
+ toString() {
486
+ return '[TransactionType]';
487
+ }
488
+ }
489
+
490
+ const buy = new TransactionType('B', 'Buy', true, false, false, true, false);
491
+ const sell = new TransactionType('S', 'Sell', false, true, false, false, true);
492
+ const buyShort = new TransactionType('BS', 'Buy To Cover', true, false, false, false, true);
493
+ const sellShort = new TransactionType('SS', 'Sell Short', false, true, false, true, false);
494
+ const dividend = new TransactionType('DV', 'Dividend', false, false, true, false, false);
495
+ const dividendReinvest = new TransactionType('DX', 'Dividend (Reinvested)', false, false, false, true, false);
496
+ const dividendStock = new TransactionType('DS', 'Dividend (Stock)', false, false, false, true, false);
497
+ const split = new TransactionType('SP', 'Split', false, false, false, true, false);
498
+ const fee = new TransactionType('F', 'Fee', false, false, false, true, false);
499
+ const feeUnits = new TransactionType('FU', 'Fee', false, false, false, false, false);
500
+
501
+ const distributionCash = new TransactionType('DC', 'Distribution (Cash)', false, false, true, false, false);
502
+ const distributionFund = new TransactionType('DF', 'Distribution (Units)', false, false, false, true, false);
503
+
504
+ const deposit = new TransactionType('D', 'Deposit', false, false, false, true, false);
505
+ const withdrawal = new TransactionType('W', 'Withdrawal', false, false, false, false, true);
506
+ const debit = new TransactionType('DR', 'Debit', false, false, false, false, true);
507
+ const credit = new TransactionType('CR', 'Credit', false, false, false, true, false);
508
+
509
+ const valuation = new TransactionType('V', 'Valuation', false, false, false, false, false);
510
+ const income = new TransactionType('I', 'Income', false, false, true, false, false);
511
+
512
+ return TransactionType;
513
+ })();
514
+
515
+ },{"@barchart/common-js/lang/Enum":7,"@barchart/common-js/lang/assert":9}],3:[function(require,module,exports){
150
516
  'use strict';
151
517
 
152
518
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -290,7 +656,7 @@ module.exports = function () {
290
656
  return ComparatorBuilder;
291
657
  }();
292
658
 
293
- },{"./../../lang/assert":8,"./comparators":3}],3:[function(require,module,exports){
659
+ },{"./../../lang/assert":9,"./comparators":4}],4:[function(require,module,exports){
294
660
  'use strict';
295
661
 
296
662
  var assert = require('./../../lang/assert');
@@ -365,7 +731,7 @@ module.exports = function () {
365
731
  };
366
732
  }();
367
733
 
368
- },{"./../../lang/assert":8}],4:[function(require,module,exports){
734
+ },{"./../../lang/assert":9}],5:[function(require,module,exports){
369
735
  'use strict';
370
736
 
371
737
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -918,7 +1284,7 @@ module.exports = function () {
918
1284
  return Day;
919
1285
  }();
920
1286
 
921
- },{"./../collections/sorting/ComparatorBuilder":2,"./../collections/sorting/comparators":3,"./assert":8,"./is":9}],5:[function(require,module,exports){
1287
+ },{"./../collections/sorting/ComparatorBuilder":3,"./../collections/sorting/comparators":4,"./assert":9,"./is":10}],6:[function(require,module,exports){
922
1288
  'use strict';
923
1289
 
924
1290
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -1498,7 +1864,7 @@ module.exports = function () {
1498
1864
  return Decimal;
1499
1865
  }();
1500
1866
 
1501
- },{"./Enum":6,"./assert":8,"./is":9,"big.js":10}],6:[function(require,module,exports){
1867
+ },{"./Enum":7,"./assert":9,"./is":10,"big.js":11}],7:[function(require,module,exports){
1502
1868
  'use strict';
1503
1869
 
1504
1870
  var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
@@ -1640,7 +2006,7 @@ module.exports = function () {
1640
2006
  return Enum;
1641
2007
  }();
1642
2008
 
1643
- },{"./assert":8}],7:[function(require,module,exports){
2009
+ },{"./assert":9}],8:[function(require,module,exports){
1644
2010
  'use strict';
1645
2011
 
1646
2012
  var assert = require('./assert'),
@@ -2001,7 +2367,7 @@ module.exports = function () {
2001
2367
  };
2002
2368
  }();
2003
2369
 
2004
- },{"./assert":8,"./is":9}],8:[function(require,module,exports){
2370
+ },{"./assert":9,"./is":10}],9:[function(require,module,exports){
2005
2371
  'use strict';
2006
2372
 
2007
2373
  var is = require('./is');
@@ -2149,7 +2515,7 @@ module.exports = function () {
2149
2515
  };
2150
2516
  }();
2151
2517
 
2152
- },{"./is":9}],9:[function(require,module,exports){
2518
+ },{"./is":10}],10:[function(require,module,exports){
2153
2519
  'use strict';
2154
2520
 
2155
2521
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
@@ -2372,7 +2738,7 @@ module.exports = function () {
2372
2738
  };
2373
2739
  }();
2374
2740
 
2375
- },{}],10:[function(require,module,exports){
2741
+ },{}],11:[function(require,module,exports){
2376
2742
  /*
2377
2743
  * big.js v5.0.3
2378
2744
  * A small, fast, easy-to-use library for arbitrary-precision decimal arithmetic.
@@ -3313,11 +3679,12 @@ module.exports = function () {
3313
3679
  }
3314
3680
  })(this);
3315
3681
 
3316
- },{}],11:[function(require,module,exports){
3682
+ },{}],12:[function(require,module,exports){
3317
3683
  const Day = require('@barchart/common-js/lang/Day'),
3318
3684
  Decimal = require('@barchart/common-js/lang/Decimal');
3319
3685
 
3320
- const PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame');
3686
+ const PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame'),
3687
+ TransactionType = require('./../../../lib/data/TransactionType');
3321
3688
 
3322
3689
  describe('After the PositionSummaryFrame enumeration is initialized', () => {
3323
3690
  'use strict';
@@ -3328,13 +3695,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3328
3695
  beforeEach(() => {
3329
3696
  const transactions = [
3330
3697
  {
3331
- date: new Day(2015, 10, 20)
3698
+ date: new Day(2015, 10, 20),
3699
+ snapshot: {
3700
+ open: new Decimal(1)
3701
+ },
3702
+ type: TransactionType.BUY
3332
3703
  },
3333
3704
  {
3334
3705
  date: new Day(2016, 11, 21),
3335
3706
  snapshot: {
3336
3707
  open: new Decimal(1)
3337
- }
3708
+ },
3709
+ type: TransactionType.BUY
3338
3710
  }
3339
3711
  ];
3340
3712
 
@@ -3367,13 +3739,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3367
3739
  beforeEach(() => {
3368
3740
  const transactions = [
3369
3741
  {
3370
- date: new Day(2015, 10, 20)
3742
+ date: new Day(2015, 10, 20),
3743
+ snapshot: {
3744
+ open: new Decimal(1)
3745
+ },
3746
+ type: TransactionType.BUY
3371
3747
  },
3372
3748
  {
3373
3749
  date: new Day(2015, 11, 21),
3374
3750
  snapshot: {
3375
3751
  open: new Decimal(0)
3376
- }
3752
+ },
3753
+ type: TransactionType.SELL
3377
3754
  }
3378
3755
  ];
3379
3756
 
@@ -3396,13 +3773,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3396
3773
  beforeEach(() => {
3397
3774
  const transactions = [
3398
3775
  {
3399
- date: new Day(2015, 10, 20)
3776
+ date: new Day(2015, 10, 20),
3777
+ snapshot: {
3778
+ open: new Decimal(1)
3779
+ },
3780
+ type: TransactionType.BUY
3400
3781
  },
3401
3782
  {
3402
3783
  date: new Day(2016, 11, 21),
3403
3784
  snapshot: {
3404
3785
  open: new Decimal(0)
3405
- }
3786
+ },
3787
+ type: TransactionType.SELL
3406
3788
  }
3407
3789
  ];
3408
3790
 
@@ -3430,13 +3812,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3430
3812
  beforeEach(() => {
3431
3813
  const transactions = [
3432
3814
  {
3433
- date: new Day(2015, 10, 20)
3815
+ date: new Day(2015, 10, 20),
3816
+ snapshot: {
3817
+ open: new Decimal(1)
3818
+ },
3819
+ type: TransactionType.BUY
3434
3820
  },
3435
3821
  {
3436
3822
  date: new Day(2017, 11, 21),
3437
3823
  snapshot: {
3438
3824
  open: new Decimal(0)
3439
- }
3825
+ },
3826
+ type: TransactionType.SELL
3440
3827
  }
3441
3828
  ];
3442
3829
 
@@ -3463,19 +3850,77 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3463
3850
  });
3464
3851
  });
3465
3852
 
3853
+ describe('and yearly position summary ranges are processed for a transaction set closed in 2016, but has after-the-face superfluous valuations in 2017 and 2018', () => {
3854
+ let ranges;
3855
+
3856
+ beforeEach(() => {
3857
+ const transactions = [
3858
+ {
3859
+ date: new Day(2015, 10, 20),
3860
+ snapshot: {
3861
+ open: new Decimal(1)
3862
+ },
3863
+ type: TransactionType.BUY
3864
+ },
3865
+ {
3866
+ date: new Day(2016, 11, 21),
3867
+ snapshot: {
3868
+ open: new Decimal(0)
3869
+ },
3870
+ type: TransactionType.SELL
3871
+ },
3872
+ {
3873
+ date: new Day(2017, 11, 21),
3874
+ snapshot: {
3875
+ open: new Decimal(0)
3876
+ },
3877
+ type: TransactionType.VALUATION
3878
+ },
3879
+ {
3880
+ date: new Day(2017, 11, 21),
3881
+ snapshot: {
3882
+ open: new Decimal(0)
3883
+ },
3884
+ type: TransactionType.VALUATION
3885
+ }
3886
+ ];
3887
+
3888
+ ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
3889
+ });
3890
+
3891
+ it('should have two ranges', () => {
3892
+ expect(ranges.length).toEqual(2);
3893
+ });
3894
+
3895
+ it('the first range should be from 12-31-2014 to 12-31-2015', () => {
3896
+ expect(ranges[0].start.format()).toEqual('2014-12-31');
3897
+ expect(ranges[0].end.format()).toEqual('2015-12-31');
3898
+ });
3899
+
3900
+ it('the second range should be from 12-31-2015 to 12-31-2016', () => {
3901
+ expect(ranges[1].start.format()).toEqual('2015-12-31');
3902
+ expect(ranges[1].end.format()).toEqual('2016-12-31');
3903
+ });
3904
+ });
3905
+
3466
3906
  describe('and a year-to-date position summary ranges are processed for a transaction set that closed last year', () => {
3467
3907
  let ranges;
3468
3908
 
3469
3909
  beforeEach(() => {
3470
3910
  const transactions = [
3471
3911
  {
3472
- date: new Day(2017, 1, 1)
3912
+ date: new Day(2017, 1, 1),
3913
+ snapshot: {
3914
+ open: new Decimal(1)
3915
+ },
3916
+ type: TransactionType.BUY
3473
3917
  },
3474
3918
  {
3475
3919
  date: new Day(2017, 1, 2),
3476
3920
  snapshot: {
3477
3921
  open: new Decimal(0)
3478
- }
3922
+ },
3923
+ type: TransactionType.SELL
3479
3924
  }
3480
3925
  ];
3481
3926
 
@@ -3495,8 +3940,9 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3495
3940
  {
3496
3941
  date: new Day(2018, 1, 1),
3497
3942
  snapshot: {
3498
- open: new Decimal(0)
3499
- }
3943
+ open: new Decimal(100)
3944
+ },
3945
+ type: TransactionType.BUY
3500
3946
  }
3501
3947
  ];
3502
3948
 
@@ -3519,13 +3965,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3519
3965
  beforeEach(() => {
3520
3966
  const transactions = [
3521
3967
  {
3522
- date: new Day(2018, 1, 1)
3968
+ date: new Day(2018, 1, 1),
3969
+ snapshot: {
3970
+ open: new Decimal(1)
3971
+ },
3972
+ type: TransactionType.BUY
3523
3973
  },
3524
3974
  {
3525
3975
  date: new Day(2018, 1, 2),
3526
3976
  snapshot: {
3527
3977
  open: new Decimal(0)
3528
- }
3978
+ },
3979
+ type: TransactionType.SELL
3529
3980
  }
3530
3981
  ];
3531
3982
 
@@ -3541,6 +3992,48 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
3541
3992
  expect(ranges[0].end.format()).toEqual('2018-12-31');
3542
3993
  });
3543
3994
  });
3995
+
3996
+ describe('and getting the start date for yearly frames', () => {
3997
+ describe('for one year ago', function() {
3998
+ let start;
3999
+
4000
+ beforeEach(() => {
4001
+ start = PositionSummaryFrame.YEARLY.getStartDate(1);
4002
+ });
4003
+
4004
+ it('should be in December', () => {
4005
+ expect(start.month).toEqual(12);
4006
+ });
4007
+
4008
+ it('should be on the 31st', () => {
4009
+ expect(start.day).toEqual(31);
4010
+ });
4011
+
4012
+ it('should be two years ago', () => {
4013
+ expect(start.year).toEqual(Day.getToday().year - 2);
4014
+ });
4015
+ });
4016
+
4017
+ describe('for two years ago', function() {
4018
+ let start;
4019
+
4020
+ beforeEach(() => {
4021
+ start = PositionSummaryFrame.YEARLY.getStartDate(2);
4022
+ });
4023
+
4024
+ it('should be in December', () => {
4025
+ expect(start.month).toEqual(12);
4026
+ });
4027
+
4028
+ it('should be on the 31st', () => {
4029
+ expect(start.day).toEqual(31);
4030
+ });
4031
+
4032
+ it('should be two years ago', () => {
4033
+ expect(start.year).toEqual(Day.getToday().year - 3);
4034
+ });
4035
+ });
4036
+ });
3544
4037
  });
3545
4038
 
3546
- },{"./../../../lib/data/PositionSummaryFrame":1,"@barchart/common-js/lang/Day":4,"@barchart/common-js/lang/Decimal":5}]},{},[11]);
4039
+ },{"./../../../lib/data/PositionSummaryFrame":1,"./../../../lib/data/TransactionType":2,"@barchart/common-js/lang/Day":5,"@barchart/common-js/lang/Decimal":6}]},{},[12]);
@@ -1,7 +1,8 @@
1
1
  const Day = require('@barchart/common-js/lang/Day'),
2
2
  Decimal = require('@barchart/common-js/lang/Decimal');
3
3
 
4
- const PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame');
4
+ const PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame'),
5
+ TransactionType = require('./../../../lib/data/TransactionType');
5
6
 
6
7
  describe('After the PositionSummaryFrame enumeration is initialized', () => {
7
8
  'use strict';
@@ -12,13 +13,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
12
13
  beforeEach(() => {
13
14
  const transactions = [
14
15
  {
15
- date: new Day(2015, 10, 20)
16
+ date: new Day(2015, 10, 20),
17
+ snapshot: {
18
+ open: new Decimal(1)
19
+ },
20
+ type: TransactionType.BUY
16
21
  },
17
22
  {
18
23
  date: new Day(2016, 11, 21),
19
24
  snapshot: {
20
25
  open: new Decimal(1)
21
- }
26
+ },
27
+ type: TransactionType.BUY
22
28
  }
23
29
  ];
24
30
 
@@ -51,13 +57,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
51
57
  beforeEach(() => {
52
58
  const transactions = [
53
59
  {
54
- date: new Day(2015, 10, 20)
60
+ date: new Day(2015, 10, 20),
61
+ snapshot: {
62
+ open: new Decimal(1)
63
+ },
64
+ type: TransactionType.BUY
55
65
  },
56
66
  {
57
67
  date: new Day(2015, 11, 21),
58
68
  snapshot: {
59
69
  open: new Decimal(0)
60
- }
70
+ },
71
+ type: TransactionType.SELL
61
72
  }
62
73
  ];
63
74
 
@@ -80,13 +91,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
80
91
  beforeEach(() => {
81
92
  const transactions = [
82
93
  {
83
- date: new Day(2015, 10, 20)
94
+ date: new Day(2015, 10, 20),
95
+ snapshot: {
96
+ open: new Decimal(1)
97
+ },
98
+ type: TransactionType.BUY
84
99
  },
85
100
  {
86
101
  date: new Day(2016, 11, 21),
87
102
  snapshot: {
88
103
  open: new Decimal(0)
89
- }
104
+ },
105
+ type: TransactionType.SELL
90
106
  }
91
107
  ];
92
108
 
@@ -114,13 +130,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
114
130
  beforeEach(() => {
115
131
  const transactions = [
116
132
  {
117
- date: new Day(2015, 10, 20)
133
+ date: new Day(2015, 10, 20),
134
+ snapshot: {
135
+ open: new Decimal(1)
136
+ },
137
+ type: TransactionType.BUY
118
138
  },
119
139
  {
120
140
  date: new Day(2017, 11, 21),
121
141
  snapshot: {
122
142
  open: new Decimal(0)
123
- }
143
+ },
144
+ type: TransactionType.SELL
124
145
  }
125
146
  ];
126
147
 
@@ -147,19 +168,77 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
147
168
  });
148
169
  });
149
170
 
171
+ describe('and yearly position summary ranges are processed for a transaction set closed in 2016, but has after-the-face superfluous valuations in 2017 and 2018', () => {
172
+ let ranges;
173
+
174
+ beforeEach(() => {
175
+ const transactions = [
176
+ {
177
+ date: new Day(2015, 10, 20),
178
+ snapshot: {
179
+ open: new Decimal(1)
180
+ },
181
+ type: TransactionType.BUY
182
+ },
183
+ {
184
+ date: new Day(2016, 11, 21),
185
+ snapshot: {
186
+ open: new Decimal(0)
187
+ },
188
+ type: TransactionType.SELL
189
+ },
190
+ {
191
+ date: new Day(2017, 11, 21),
192
+ snapshot: {
193
+ open: new Decimal(0)
194
+ },
195
+ type: TransactionType.VALUATION
196
+ },
197
+ {
198
+ date: new Day(2017, 11, 21),
199
+ snapshot: {
200
+ open: new Decimal(0)
201
+ },
202
+ type: TransactionType.VALUATION
203
+ }
204
+ ];
205
+
206
+ ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
207
+ });
208
+
209
+ it('should have two ranges', () => {
210
+ expect(ranges.length).toEqual(2);
211
+ });
212
+
213
+ it('the first range should be from 12-31-2014 to 12-31-2015', () => {
214
+ expect(ranges[0].start.format()).toEqual('2014-12-31');
215
+ expect(ranges[0].end.format()).toEqual('2015-12-31');
216
+ });
217
+
218
+ it('the second range should be from 12-31-2015 to 12-31-2016', () => {
219
+ expect(ranges[1].start.format()).toEqual('2015-12-31');
220
+ expect(ranges[1].end.format()).toEqual('2016-12-31');
221
+ });
222
+ });
223
+
150
224
  describe('and a year-to-date position summary ranges are processed for a transaction set that closed last year', () => {
151
225
  let ranges;
152
226
 
153
227
  beforeEach(() => {
154
228
  const transactions = [
155
229
  {
156
- date: new Day(2017, 1, 1)
230
+ date: new Day(2017, 1, 1),
231
+ snapshot: {
232
+ open: new Decimal(1)
233
+ },
234
+ type: TransactionType.BUY
157
235
  },
158
236
  {
159
237
  date: new Day(2017, 1, 2),
160
238
  snapshot: {
161
239
  open: new Decimal(0)
162
- }
240
+ },
241
+ type: TransactionType.SELL
163
242
  }
164
243
  ];
165
244
 
@@ -179,8 +258,9 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
179
258
  {
180
259
  date: new Day(2018, 1, 1),
181
260
  snapshot: {
182
- open: new Decimal(0)
183
- }
261
+ open: new Decimal(100)
262
+ },
263
+ type: TransactionType.BUY
184
264
  }
185
265
  ];
186
266
 
@@ -203,13 +283,18 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
203
283
  beforeEach(() => {
204
284
  const transactions = [
205
285
  {
206
- date: new Day(2018, 1, 1)
286
+ date: new Day(2018, 1, 1),
287
+ snapshot: {
288
+ open: new Decimal(1)
289
+ },
290
+ type: TransactionType.BUY
207
291
  },
208
292
  {
209
293
  date: new Day(2018, 1, 2),
210
294
  snapshot: {
211
295
  open: new Decimal(0)
212
- }
296
+ },
297
+ type: TransactionType.SELL
213
298
  }
214
299
  ];
215
300
 
@@ -225,4 +310,46 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
225
310
  expect(ranges[0].end.format()).toEqual('2018-12-31');
226
311
  });
227
312
  });
313
+
314
+ describe('and getting the start date for yearly frames', () => {
315
+ describe('for one year ago', function() {
316
+ let start;
317
+
318
+ beforeEach(() => {
319
+ start = PositionSummaryFrame.YEARLY.getStartDate(1);
320
+ });
321
+
322
+ it('should be in December', () => {
323
+ expect(start.month).toEqual(12);
324
+ });
325
+
326
+ it('should be on the 31st', () => {
327
+ expect(start.day).toEqual(31);
328
+ });
329
+
330
+ it('should be two years ago', () => {
331
+ expect(start.year).toEqual(Day.getToday().year - 2);
332
+ });
333
+ });
334
+
335
+ describe('for two years ago', function() {
336
+ let start;
337
+
338
+ beforeEach(() => {
339
+ start = PositionSummaryFrame.YEARLY.getStartDate(2);
340
+ });
341
+
342
+ it('should be in December', () => {
343
+ expect(start.month).toEqual(12);
344
+ });
345
+
346
+ it('should be on the 31st', () => {
347
+ expect(start.day).toEqual(31);
348
+ });
349
+
350
+ it('should be two years ago', () => {
351
+ expect(start.year).toEqual(Day.getToday().year - 3);
352
+ });
353
+ });
354
+ });
228
355
  });