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