@barchart/portfolio-api-common 1.2.93 → 1.2.97
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 +2 -2
- package/lib/processing/PositionContainer.js +8 -6
- package/lib/processing/PositionGroup.js +35 -29
- package/lib/processing/PositionItem.js +37 -7
- package/lib/processing/definitions/PositionTreeDefinition.js +1 -0
- package/lib/serialization/{PositionSummaryDefinitionSchema.js → reports/BrokerageReportAvailabilitySchema.js} +6 -6
- package/package.json +1 -1
- package/test/SpecRunner.js +83 -44
|
@@ -8,7 +8,7 @@ module.exports = (() => {
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* An enumeration used to define
|
|
11
|
+
* An enumeration used to define time frames for position summaries.
|
|
12
12
|
*
|
|
13
13
|
* @public
|
|
14
14
|
* @extends {Enum}
|
|
@@ -286,7 +286,7 @@ module.exports = (() => {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
function getYearlyRangeDescription(start, end) {
|
|
289
|
-
return end.year.toString()
|
|
289
|
+
return `Year ended ${end.year.toString()}`;
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
function getQuarterlyRangeDescription(start, end) {
|
|
@@ -42,20 +42,22 @@ module.exports = (() => {
|
|
|
42
42
|
* @param {Array.<Object>} portfolios - The portfolios.
|
|
43
43
|
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
44
44
|
* @param {Array.<Object>} summaries - The positions summaries (for all of the positions).
|
|
45
|
-
* @param {PositionSummaryFrame=} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
45
|
+
* @param {PositionSummaryFrame=} reportFrame - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
46
46
|
*/
|
|
47
47
|
class PositionContainer {
|
|
48
|
-
constructor(definitions, portfolios, positions, summaries,
|
|
48
|
+
constructor(definitions, portfolios, positions, summaries, reportFrame) {
|
|
49
49
|
assert.argumentIsArray(definitions, 'definitions', PositionTreeDefinition, 'PositionTreeDefinition');
|
|
50
50
|
assert.argumentIsArray(portfolios, 'portfolios');
|
|
51
51
|
assert.argumentIsArray(positions, 'positions');
|
|
52
52
|
assert.argumentIsArray(summaries, 'summaries');
|
|
53
|
-
assert.argumentIsOptional(
|
|
53
|
+
assert.argumentIsOptional(reportFrame, 'reportFrame', PositionSummaryFrame, 'PositionSummaryFrame');
|
|
54
54
|
|
|
55
55
|
this._definitions = definitions;
|
|
56
56
|
|
|
57
57
|
this._groupBindings = { };
|
|
58
58
|
|
|
59
|
+
this._reporting = reportFrame instanceof PositionSummaryFrame;
|
|
60
|
+
|
|
59
61
|
this._positionSymbolAddedEvent = new Event(this);
|
|
60
62
|
this._positionSymbolRemovedEvent = new Event(this);
|
|
61
63
|
|
|
@@ -65,10 +67,10 @@ module.exports = (() => {
|
|
|
65
67
|
return map;
|
|
66
68
|
}, { });
|
|
67
69
|
|
|
68
|
-
this._currentSummaryFrame =
|
|
70
|
+
this._currentSummaryFrame = reportFrame || PositionSummaryFrame.YTD;
|
|
69
71
|
this._currentSummaryRange = array.last(this._currentSummaryFrame.getRecentRanges(0));
|
|
70
72
|
|
|
71
|
-
this._previousSummaryFrame =
|
|
73
|
+
this._previousSummaryFrame = reportFrame || PositionSummaryFrame.YEARLY;
|
|
72
74
|
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(3);
|
|
73
75
|
|
|
74
76
|
if (this._currentSummaryFrame === this._previousSummaryFrame) {
|
|
@@ -942,7 +944,7 @@ module.exports = (() => {
|
|
|
942
944
|
const currentSummary = this._summariesCurrent[ position.position ] || null;
|
|
943
945
|
const previousSummaries = this._summariesPrevious[ position.position ] || getSummaryArray(this._previousSummaryRanges);
|
|
944
946
|
|
|
945
|
-
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries);
|
|
947
|
+
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries, this._reporting);
|
|
946
948
|
} else {
|
|
947
949
|
returnRef = null;
|
|
948
950
|
}
|
|
@@ -75,12 +75,14 @@ module.exports = (() => {
|
|
|
75
75
|
this._dataFormat.locked = false;
|
|
76
76
|
this._dataFormat.newsExists = false;
|
|
77
77
|
this._dataFormat.quantity = null;
|
|
78
|
+
this._dataFormat.quantityPrevious = null;
|
|
78
79
|
this._dataFormat.basisPrice = null;
|
|
79
80
|
|
|
80
81
|
this._dataActual.key = this._key;
|
|
81
82
|
this._dataActual.description = this._description;
|
|
82
83
|
this._dataActual.newsExists = false;
|
|
83
84
|
this._dataActual.quantity = null;
|
|
85
|
+
this._dataActual.quantityPrevious = null;
|
|
84
86
|
this._dataActual.basisPrice = null;
|
|
85
87
|
|
|
86
88
|
if (this._single && items.length === 1) {
|
|
@@ -130,10 +132,10 @@ module.exports = (() => {
|
|
|
130
132
|
this._dataActual.summaryTotalCurrent = null;
|
|
131
133
|
this._dataActual.summaryTotalPrevious = null;
|
|
132
134
|
this._dataActual.summaryTotalPrevious2 = null;
|
|
133
|
-
this._dataActual.
|
|
134
|
-
this._dataActual.
|
|
135
|
-
this._dataActual.
|
|
136
|
-
this._dataActual.
|
|
135
|
+
this._dataActual.marketPrevious = null;
|
|
136
|
+
this._dataActual.marketPrevious2 = null;
|
|
137
|
+
this._dataActual.marketChange = null;
|
|
138
|
+
this._dataActual.marketChangePercent = null;
|
|
137
139
|
this._dataActual.cashTotal = null;
|
|
138
140
|
|
|
139
141
|
this._dataFormat.currentPrice = null;
|
|
@@ -157,10 +159,10 @@ module.exports = (() => {
|
|
|
157
159
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
158
160
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
159
161
|
this._dataFormat.summaryTotalPrevious2Negative = false;
|
|
160
|
-
this._dataFormat.
|
|
161
|
-
this._dataFormat.
|
|
162
|
-
this._dataFormat.
|
|
163
|
-
this._dataFormat.
|
|
162
|
+
this._dataFormat.marketPrevious = null;
|
|
163
|
+
this._dataFormat.marketPrevious2 = null;
|
|
164
|
+
this._dataFormat.marketChange = null;
|
|
165
|
+
this._dataFormat.marketChangePercent = null;
|
|
164
166
|
this._dataFormat.cashTotal = null;
|
|
165
167
|
this._dataFormat.portfolioType = null;
|
|
166
168
|
|
|
@@ -657,8 +659,8 @@ module.exports = (() => {
|
|
|
657
659
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
|
|
658
660
|
updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
|
|
659
661
|
updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
|
|
660
|
-
updates.
|
|
661
|
-
updates.
|
|
662
|
+
updates.marketPrevious = updates.marketPrevious.add(translate(item, item.data.marketPrevious));
|
|
663
|
+
updates.marketPrevious2 = updates.marketPrevious2.add(translate(item, item.data.marketPrevious2));
|
|
662
664
|
|
|
663
665
|
if (item.position.instrument.type === InstrumentType.CASH) {
|
|
664
666
|
updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
|
|
@@ -673,8 +675,8 @@ module.exports = (() => {
|
|
|
673
675
|
summaryTotalCurrent: Decimal.ZERO,
|
|
674
676
|
summaryTotalPrevious: Decimal.ZERO,
|
|
675
677
|
summaryTotalPrevious2: Decimal.ZERO,
|
|
676
|
-
|
|
677
|
-
|
|
678
|
+
marketPrevious: Decimal.ZERO,
|
|
679
|
+
marketPrevious2: Decimal.ZERO,
|
|
678
680
|
cashTotal: Decimal.ZERO
|
|
679
681
|
});
|
|
680
682
|
|
|
@@ -685,8 +687,8 @@ module.exports = (() => {
|
|
|
685
687
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
686
688
|
actual.summaryTotalPrevious = updates.summaryTotalPrevious;
|
|
687
689
|
actual.summaryTotalPrevious2 = updates.summaryTotalPrevious2;
|
|
688
|
-
actual.
|
|
689
|
-
actual.
|
|
690
|
+
actual.marketPrevious = updates.marketPrevious;
|
|
691
|
+
actual.marketPrevious2 = updates.marketPrevious2;
|
|
690
692
|
actual.cashTotal = updates.cashTotal;
|
|
691
693
|
|
|
692
694
|
format.basis = formatCurrency(actual.basis, currency);
|
|
@@ -698,8 +700,8 @@ module.exports = (() => {
|
|
|
698
700
|
format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
|
|
699
701
|
format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
|
|
700
702
|
format.summaryTotalPrevious2Negative = updates.summaryTotalPrevious2.getIsNegative();
|
|
701
|
-
format.
|
|
702
|
-
format.
|
|
703
|
+
format.marketPrevious = formatCurrency(updates.marketPrevious, currency);
|
|
704
|
+
format.marketPrevious2 = formatCurrency(updates.marketPrevious2, currency);
|
|
703
705
|
format.cashTotal = formatCurrency(updates.cashTotal, currency);
|
|
704
706
|
|
|
705
707
|
calculateUnrealizedPercent(group);
|
|
@@ -708,9 +710,13 @@ module.exports = (() => {
|
|
|
708
710
|
const item = group._items[0];
|
|
709
711
|
|
|
710
712
|
actual.quantity = item.position.snapshot.open;
|
|
713
|
+
actual.quantityPrevious = item.data.quantityPrevious;
|
|
714
|
+
|
|
711
715
|
actual.basisPrice = item.data.basisPrice;
|
|
712
716
|
|
|
713
717
|
format.quantity = formatDecimal(actual.quantity, 2);
|
|
718
|
+
format.quantityPrevious = formatDecimal(actual.quantityPrevious, 2);
|
|
719
|
+
|
|
714
720
|
format.basisPrice = formatCurrency(actual.basisPrice, currency);
|
|
715
721
|
|
|
716
722
|
format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
|
|
@@ -797,23 +803,23 @@ module.exports = (() => {
|
|
|
797
803
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
798
804
|
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
799
805
|
|
|
800
|
-
let
|
|
801
|
-
let
|
|
806
|
+
let marketChange = updates.market.subtract(actual.marketPrevious);
|
|
807
|
+
let marketChangePercent;
|
|
802
808
|
|
|
803
|
-
if (actual.
|
|
804
|
-
if (
|
|
805
|
-
|
|
806
|
-
} else if (
|
|
807
|
-
|
|
809
|
+
if (actual.marketPrevious.getIsZero()) {
|
|
810
|
+
if (marketChange.getIsPositive()) {
|
|
811
|
+
marketChangePercent = Decimal.ONE;
|
|
812
|
+
} else if (marketChange.getIsNegative()) {
|
|
813
|
+
marketChangePercent = Decimal.NEGATIVE_ONE;
|
|
808
814
|
} else {
|
|
809
|
-
|
|
815
|
+
marketChangePercent = Decimal.ZERO;
|
|
810
816
|
}
|
|
811
817
|
} else {
|
|
812
|
-
|
|
818
|
+
marketChangePercent = marketChange.divide(actual.marketPrevious);
|
|
813
819
|
}
|
|
814
820
|
|
|
815
|
-
actual.
|
|
816
|
-
actual.
|
|
821
|
+
actual.marketChange = marketChange;
|
|
822
|
+
actual.marketChangePercent = marketChangePercent;
|
|
817
823
|
|
|
818
824
|
format.market = formatCurrency(actual.market, currency);
|
|
819
825
|
|
|
@@ -834,8 +840,8 @@ module.exports = (() => {
|
|
|
834
840
|
format.total = formatCurrency(actual.total, currency);
|
|
835
841
|
format.totalNegative = actual.total.getIsNegative();
|
|
836
842
|
|
|
837
|
-
format.
|
|
838
|
-
format.
|
|
843
|
+
format.marketChange = formatCurrency(actual.marketChange, currency);
|
|
844
|
+
format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
|
|
839
845
|
|
|
840
846
|
calculateUnrealizedPercent(group);
|
|
841
847
|
}
|
|
@@ -20,9 +20,10 @@ module.exports = (() => {
|
|
|
20
20
|
* @param {Object} position
|
|
21
21
|
* @param {Object} currentSummary
|
|
22
22
|
* @param {Array.<Object>} previousSummaries
|
|
23
|
+
* @param {Boolean} reporting
|
|
23
24
|
*/
|
|
24
25
|
class PositionItem extends Disposable {
|
|
25
|
-
constructor(portfolio, position, currentSummary, previousSummaries) {
|
|
26
|
+
constructor(portfolio, position, currentSummary, previousSummaries, reporting) {
|
|
26
27
|
super();
|
|
27
28
|
|
|
28
29
|
this._portfolio = portfolio;
|
|
@@ -36,6 +37,8 @@ module.exports = (() => {
|
|
|
36
37
|
this._currentSummary = currentSummary || null;
|
|
37
38
|
this._previousSummaries = previousSummaries || [ ];
|
|
38
39
|
|
|
40
|
+
this._reporting = reporting;
|
|
41
|
+
|
|
39
42
|
this._data = { };
|
|
40
43
|
|
|
41
44
|
this._data.basis = null;
|
|
@@ -65,9 +68,12 @@ module.exports = (() => {
|
|
|
65
68
|
this._data.summaryTotalPrevious = null;
|
|
66
69
|
this._data.summaryTotalPrevious2 = null;
|
|
67
70
|
|
|
68
|
-
this._data.
|
|
69
|
-
this._data.
|
|
71
|
+
this._data.marketPrevious = null;
|
|
72
|
+
this._data.marketPrevious2 = null;
|
|
70
73
|
|
|
74
|
+
this._data.quantityPrevious = null;
|
|
75
|
+
this._data.quantityPrevious2 = null;
|
|
76
|
+
|
|
71
77
|
this._data.realized = null;
|
|
72
78
|
this._data.income = null;
|
|
73
79
|
this._data.basisPrice = null;
|
|
@@ -361,7 +367,7 @@ module.exports = (() => {
|
|
|
361
367
|
|
|
362
368
|
function calculateStaticData(item) {
|
|
363
369
|
const position = item.position;
|
|
364
|
-
const snapshot = item.
|
|
370
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
365
371
|
const previousSummaries = item.previousSummaries;
|
|
366
372
|
|
|
367
373
|
const data = item._data;
|
|
@@ -391,8 +397,10 @@ module.exports = (() => {
|
|
|
391
397
|
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
392
398
|
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
393
399
|
|
|
394
|
-
data.
|
|
395
|
-
data.
|
|
400
|
+
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
401
|
+
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
402
|
+
|
|
403
|
+
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
396
404
|
|
|
397
405
|
if (snapshot.open.getIsZero()) {
|
|
398
406
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -403,7 +411,7 @@ module.exports = (() => {
|
|
|
403
411
|
|
|
404
412
|
function calculatePriceData(item, price) {
|
|
405
413
|
const position = item.position;
|
|
406
|
-
const snapshot = item.
|
|
414
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
407
415
|
const previousSummaries = item.previousSummaries;
|
|
408
416
|
|
|
409
417
|
const data = item._data;
|
|
@@ -555,5 +563,27 @@ module.exports = (() => {
|
|
|
555
563
|
return is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
|
|
556
564
|
}
|
|
557
565
|
|
|
566
|
+
function getSnapshot(position, currentSummary, reporting) {
|
|
567
|
+
let snapshot;
|
|
568
|
+
|
|
569
|
+
if (reporting) {
|
|
570
|
+
snapshot = { };
|
|
571
|
+
|
|
572
|
+
snapshot.date = currentSummary.end.date;
|
|
573
|
+
snapshot.open = currentSummary.end.open;
|
|
574
|
+
snapshot.direction = currentSummary.end.direction;
|
|
575
|
+
snapshot.buys = currentSummary.period.buys;
|
|
576
|
+
snapshot.sells = currentSummary.period.sells;
|
|
577
|
+
snapshot.gain = currentSummary.period.realized;
|
|
578
|
+
snapshot.basis = currentSummary.end.basis;
|
|
579
|
+
snapshot.income = currentSummary.period.income;
|
|
580
|
+
snapshot.value = currentSummary.end.value;
|
|
581
|
+
} else {
|
|
582
|
+
snapshot = position.snapshot;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return snapshot;
|
|
586
|
+
}
|
|
587
|
+
|
|
558
588
|
return PositionItem;
|
|
559
589
|
})();
|
|
@@ -11,6 +11,7 @@ module.exports = (() => {
|
|
|
11
11
|
* @public
|
|
12
12
|
* @param {String} name
|
|
13
13
|
* @param {Array.<PositionLevelDefinition>} definitions
|
|
14
|
+
* @oaram {Array.<String>=} exclusionDependencies
|
|
14
15
|
*/
|
|
15
16
|
class PositionTreeDefinitions {
|
|
16
17
|
constructor(name, definitions, exclusionDependencies) {
|
|
@@ -9,12 +9,12 @@ module.exports = (() => {
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Schema used to represent availability of a brokerage report.
|
|
13
13
|
*
|
|
14
14
|
* @public
|
|
15
15
|
* @extends {Enum}
|
|
16
16
|
*/
|
|
17
|
-
class
|
|
17
|
+
class BrokerageReportAvailabilitySchema extends Enum {
|
|
18
18
|
constructor(schema) {
|
|
19
19
|
super(schema.name, schema.name);
|
|
20
20
|
|
|
@@ -36,23 +36,23 @@ module.exports = (() => {
|
|
|
36
36
|
*
|
|
37
37
|
* @static
|
|
38
38
|
* @public
|
|
39
|
-
* @returns {
|
|
39
|
+
* @returns {BrokerageReportAvailabilitySchema}
|
|
40
40
|
*/
|
|
41
41
|
static get COMPLETE() {
|
|
42
42
|
return complete;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
toString() {
|
|
46
|
-
return '[
|
|
46
|
+
return '[BrokerageReportAvailabilitySchema]';
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
const complete = new
|
|
50
|
+
const complete = new BrokerageReportAvailabilitySchema(SchemaBuilder.withName('complete')
|
|
51
51
|
.withField('start', DataType.DAY)
|
|
52
52
|
.withField('end', DataType.DAY)
|
|
53
53
|
.withField('frame', DataType.forEnum(PositionSummaryFrame, 'PositionSummaryFrame'))
|
|
54
54
|
.schema
|
|
55
55
|
);
|
|
56
56
|
|
|
57
|
-
return
|
|
57
|
+
return BrokerageReportAvailabilitySchema;
|
|
58
58
|
})();
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -399,7 +399,7 @@ module.exports = (() => {
|
|
|
399
399
|
'use strict';
|
|
400
400
|
|
|
401
401
|
/**
|
|
402
|
-
* An enumeration used to define
|
|
402
|
+
* An enumeration used to define time frames for position summaries.
|
|
403
403
|
*
|
|
404
404
|
* @public
|
|
405
405
|
* @extends {Enum}
|
|
@@ -677,7 +677,7 @@ module.exports = (() => {
|
|
|
677
677
|
}
|
|
678
678
|
|
|
679
679
|
function getYearlyRangeDescription(start, end) {
|
|
680
|
-
return end.year.toString()
|
|
680
|
+
return `Year ended ${end.year.toString()}`;
|
|
681
681
|
}
|
|
682
682
|
|
|
683
683
|
function getQuarterlyRangeDescription(start, end) {
|
|
@@ -1466,20 +1466,22 @@ module.exports = (() => {
|
|
|
1466
1466
|
* @param {Array.<Object>} portfolios - The portfolios.
|
|
1467
1467
|
* @param {Array.<Object>} positions - The positions (for all of the portfolios).
|
|
1468
1468
|
* @param {Array.<Object>} summaries - The positions summaries (for all of the positions).
|
|
1469
|
-
* @param {PositionSummaryFrame=} - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
1469
|
+
* @param {PositionSummaryFrame=} reportFrame - If specified, locks the current (and previous) periods to a specific frame, use for reporting.
|
|
1470
1470
|
*/
|
|
1471
1471
|
class PositionContainer {
|
|
1472
|
-
constructor(definitions, portfolios, positions, summaries,
|
|
1472
|
+
constructor(definitions, portfolios, positions, summaries, reportFrame) {
|
|
1473
1473
|
assert.argumentIsArray(definitions, 'definitions', PositionTreeDefinition, 'PositionTreeDefinition');
|
|
1474
1474
|
assert.argumentIsArray(portfolios, 'portfolios');
|
|
1475
1475
|
assert.argumentIsArray(positions, 'positions');
|
|
1476
1476
|
assert.argumentIsArray(summaries, 'summaries');
|
|
1477
|
-
assert.argumentIsOptional(
|
|
1477
|
+
assert.argumentIsOptional(reportFrame, 'reportFrame', PositionSummaryFrame, 'PositionSummaryFrame');
|
|
1478
1478
|
|
|
1479
1479
|
this._definitions = definitions;
|
|
1480
1480
|
|
|
1481
1481
|
this._groupBindings = { };
|
|
1482
1482
|
|
|
1483
|
+
this._reporting = reportFrame instanceof PositionSummaryFrame;
|
|
1484
|
+
|
|
1483
1485
|
this._positionSymbolAddedEvent = new Event(this);
|
|
1484
1486
|
this._positionSymbolRemovedEvent = new Event(this);
|
|
1485
1487
|
|
|
@@ -1489,10 +1491,10 @@ module.exports = (() => {
|
|
|
1489
1491
|
return map;
|
|
1490
1492
|
}, { });
|
|
1491
1493
|
|
|
1492
|
-
this._currentSummaryFrame =
|
|
1494
|
+
this._currentSummaryFrame = reportFrame || PositionSummaryFrame.YTD;
|
|
1493
1495
|
this._currentSummaryRange = array.last(this._currentSummaryFrame.getRecentRanges(0));
|
|
1494
1496
|
|
|
1495
|
-
this._previousSummaryFrame =
|
|
1497
|
+
this._previousSummaryFrame = reportFrame || PositionSummaryFrame.YEARLY;
|
|
1496
1498
|
this._previousSummaryRanges = this._previousSummaryFrame.getRecentRanges(3);
|
|
1497
1499
|
|
|
1498
1500
|
if (this._currentSummaryFrame === this._previousSummaryFrame) {
|
|
@@ -2366,7 +2368,7 @@ module.exports = (() => {
|
|
|
2366
2368
|
const currentSummary = this._summariesCurrent[ position.position ] || null;
|
|
2367
2369
|
const previousSummaries = this._summariesPrevious[ position.position ] || getSummaryArray(this._previousSummaryRanges);
|
|
2368
2370
|
|
|
2369
|
-
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries);
|
|
2371
|
+
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries, this._reporting);
|
|
2370
2372
|
} else {
|
|
2371
2373
|
returnRef = null;
|
|
2372
2374
|
}
|
|
@@ -2505,12 +2507,14 @@ module.exports = (() => {
|
|
|
2505
2507
|
this._dataFormat.locked = false;
|
|
2506
2508
|
this._dataFormat.newsExists = false;
|
|
2507
2509
|
this._dataFormat.quantity = null;
|
|
2510
|
+
this._dataFormat.quantityPrevious = null;
|
|
2508
2511
|
this._dataFormat.basisPrice = null;
|
|
2509
2512
|
|
|
2510
2513
|
this._dataActual.key = this._key;
|
|
2511
2514
|
this._dataActual.description = this._description;
|
|
2512
2515
|
this._dataActual.newsExists = false;
|
|
2513
2516
|
this._dataActual.quantity = null;
|
|
2517
|
+
this._dataActual.quantityPrevious = null;
|
|
2514
2518
|
this._dataActual.basisPrice = null;
|
|
2515
2519
|
|
|
2516
2520
|
if (this._single && items.length === 1) {
|
|
@@ -2560,10 +2564,10 @@ module.exports = (() => {
|
|
|
2560
2564
|
this._dataActual.summaryTotalCurrent = null;
|
|
2561
2565
|
this._dataActual.summaryTotalPrevious = null;
|
|
2562
2566
|
this._dataActual.summaryTotalPrevious2 = null;
|
|
2563
|
-
this._dataActual.
|
|
2564
|
-
this._dataActual.
|
|
2565
|
-
this._dataActual.
|
|
2566
|
-
this._dataActual.
|
|
2567
|
+
this._dataActual.marketPrevious = null;
|
|
2568
|
+
this._dataActual.marketPrevious2 = null;
|
|
2569
|
+
this._dataActual.marketChange = null;
|
|
2570
|
+
this._dataActual.marketChangePercent = null;
|
|
2567
2571
|
this._dataActual.cashTotal = null;
|
|
2568
2572
|
|
|
2569
2573
|
this._dataFormat.currentPrice = null;
|
|
@@ -2587,10 +2591,10 @@ module.exports = (() => {
|
|
|
2587
2591
|
this._dataFormat.summaryTotalPreviousNegative = false;
|
|
2588
2592
|
this._dataFormat.summaryTotalPrevious2 = null;
|
|
2589
2593
|
this._dataFormat.summaryTotalPrevious2Negative = false;
|
|
2590
|
-
this._dataFormat.
|
|
2591
|
-
this._dataFormat.
|
|
2592
|
-
this._dataFormat.
|
|
2593
|
-
this._dataFormat.
|
|
2594
|
+
this._dataFormat.marketPrevious = null;
|
|
2595
|
+
this._dataFormat.marketPrevious2 = null;
|
|
2596
|
+
this._dataFormat.marketChange = null;
|
|
2597
|
+
this._dataFormat.marketChangePercent = null;
|
|
2594
2598
|
this._dataFormat.cashTotal = null;
|
|
2595
2599
|
this._dataFormat.portfolioType = null;
|
|
2596
2600
|
|
|
@@ -3087,8 +3091,8 @@ module.exports = (() => {
|
|
|
3087
3091
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.summaryTotalCurrent));
|
|
3088
3092
|
updates.summaryTotalPrevious = updates.summaryTotalPrevious.add(translate(item, item.data.summaryTotalPrevious));
|
|
3089
3093
|
updates.summaryTotalPrevious2 = updates.summaryTotalPrevious2.add(translate(item, item.data.summaryTotalPrevious2));
|
|
3090
|
-
updates.
|
|
3091
|
-
updates.
|
|
3094
|
+
updates.marketPrevious = updates.marketPrevious.add(translate(item, item.data.marketPrevious));
|
|
3095
|
+
updates.marketPrevious2 = updates.marketPrevious2.add(translate(item, item.data.marketPrevious2));
|
|
3092
3096
|
|
|
3093
3097
|
if (item.position.instrument.type === InstrumentType.CASH) {
|
|
3094
3098
|
updates.cashTotal = updates.cashTotal.add(translate(item, item.data.market));
|
|
@@ -3103,8 +3107,8 @@ module.exports = (() => {
|
|
|
3103
3107
|
summaryTotalCurrent: Decimal.ZERO,
|
|
3104
3108
|
summaryTotalPrevious: Decimal.ZERO,
|
|
3105
3109
|
summaryTotalPrevious2: Decimal.ZERO,
|
|
3106
|
-
|
|
3107
|
-
|
|
3110
|
+
marketPrevious: Decimal.ZERO,
|
|
3111
|
+
marketPrevious2: Decimal.ZERO,
|
|
3108
3112
|
cashTotal: Decimal.ZERO
|
|
3109
3113
|
});
|
|
3110
3114
|
|
|
@@ -3115,8 +3119,8 @@ module.exports = (() => {
|
|
|
3115
3119
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3116
3120
|
actual.summaryTotalPrevious = updates.summaryTotalPrevious;
|
|
3117
3121
|
actual.summaryTotalPrevious2 = updates.summaryTotalPrevious2;
|
|
3118
|
-
actual.
|
|
3119
|
-
actual.
|
|
3122
|
+
actual.marketPrevious = updates.marketPrevious;
|
|
3123
|
+
actual.marketPrevious2 = updates.marketPrevious2;
|
|
3120
3124
|
actual.cashTotal = updates.cashTotal;
|
|
3121
3125
|
|
|
3122
3126
|
format.basis = formatCurrency(actual.basis, currency);
|
|
@@ -3128,8 +3132,8 @@ module.exports = (() => {
|
|
|
3128
3132
|
format.summaryTotalPreviousNegative = updates.summaryTotalPrevious.getIsNegative();
|
|
3129
3133
|
format.summaryTotalPrevious2 = formatCurrency(updates.summaryTotalPrevious2, currency);
|
|
3130
3134
|
format.summaryTotalPrevious2Negative = updates.summaryTotalPrevious2.getIsNegative();
|
|
3131
|
-
format.
|
|
3132
|
-
format.
|
|
3135
|
+
format.marketPrevious = formatCurrency(updates.marketPrevious, currency);
|
|
3136
|
+
format.marketPrevious2 = formatCurrency(updates.marketPrevious2, currency);
|
|
3133
3137
|
format.cashTotal = formatCurrency(updates.cashTotal, currency);
|
|
3134
3138
|
|
|
3135
3139
|
calculateUnrealizedPercent(group);
|
|
@@ -3138,9 +3142,13 @@ module.exports = (() => {
|
|
|
3138
3142
|
const item = group._items[0];
|
|
3139
3143
|
|
|
3140
3144
|
actual.quantity = item.position.snapshot.open;
|
|
3145
|
+
actual.quantityPrevious = item.data.quantityPrevious;
|
|
3146
|
+
|
|
3141
3147
|
actual.basisPrice = item.data.basisPrice;
|
|
3142
3148
|
|
|
3143
3149
|
format.quantity = formatDecimal(actual.quantity, 2);
|
|
3150
|
+
format.quantityPrevious = formatDecimal(actual.quantityPrevious, 2);
|
|
3151
|
+
|
|
3144
3152
|
format.basisPrice = formatCurrency(actual.basisPrice, currency);
|
|
3145
3153
|
|
|
3146
3154
|
format.invalid = definition.type === PositionLevelType.POSITION && item.invalid;
|
|
@@ -3227,23 +3235,23 @@ module.exports = (() => {
|
|
|
3227
3235
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
3228
3236
|
actual.total = updates.unrealized.add(actual.realized).add(actual.income);
|
|
3229
3237
|
|
|
3230
|
-
let
|
|
3231
|
-
let
|
|
3238
|
+
let marketChange = updates.market.subtract(actual.marketPrevious);
|
|
3239
|
+
let marketChangePercent;
|
|
3232
3240
|
|
|
3233
|
-
if (actual.
|
|
3234
|
-
if (
|
|
3235
|
-
|
|
3236
|
-
} else if (
|
|
3237
|
-
|
|
3241
|
+
if (actual.marketPrevious.getIsZero()) {
|
|
3242
|
+
if (marketChange.getIsPositive()) {
|
|
3243
|
+
marketChangePercent = Decimal.ONE;
|
|
3244
|
+
} else if (marketChange.getIsNegative()) {
|
|
3245
|
+
marketChangePercent = Decimal.NEGATIVE_ONE;
|
|
3238
3246
|
} else {
|
|
3239
|
-
|
|
3247
|
+
marketChangePercent = Decimal.ZERO;
|
|
3240
3248
|
}
|
|
3241
3249
|
} else {
|
|
3242
|
-
|
|
3250
|
+
marketChangePercent = marketChange.divide(actual.marketPrevious);
|
|
3243
3251
|
}
|
|
3244
3252
|
|
|
3245
|
-
actual.
|
|
3246
|
-
actual.
|
|
3253
|
+
actual.marketChange = marketChange;
|
|
3254
|
+
actual.marketChangePercent = marketChangePercent;
|
|
3247
3255
|
|
|
3248
3256
|
format.market = formatCurrency(actual.market, currency);
|
|
3249
3257
|
|
|
@@ -3264,8 +3272,8 @@ module.exports = (() => {
|
|
|
3264
3272
|
format.total = formatCurrency(actual.total, currency);
|
|
3265
3273
|
format.totalNegative = actual.total.getIsNegative();
|
|
3266
3274
|
|
|
3267
|
-
format.
|
|
3268
|
-
format.
|
|
3275
|
+
format.marketChange = formatCurrency(actual.marketChange, currency);
|
|
3276
|
+
format.marketChangePercent = formatPercent(actual.marketChangePercent, 2);
|
|
3269
3277
|
|
|
3270
3278
|
calculateUnrealizedPercent(group);
|
|
3271
3279
|
}
|
|
@@ -3354,9 +3362,10 @@ module.exports = (() => {
|
|
|
3354
3362
|
* @param {Object} position
|
|
3355
3363
|
* @param {Object} currentSummary
|
|
3356
3364
|
* @param {Array.<Object>} previousSummaries
|
|
3365
|
+
* @param {Boolean} reporting
|
|
3357
3366
|
*/
|
|
3358
3367
|
class PositionItem extends Disposable {
|
|
3359
|
-
constructor(portfolio, position, currentSummary, previousSummaries) {
|
|
3368
|
+
constructor(portfolio, position, currentSummary, previousSummaries, reporting) {
|
|
3360
3369
|
super();
|
|
3361
3370
|
|
|
3362
3371
|
this._portfolio = portfolio;
|
|
@@ -3370,6 +3379,8 @@ module.exports = (() => {
|
|
|
3370
3379
|
this._currentSummary = currentSummary || null;
|
|
3371
3380
|
this._previousSummaries = previousSummaries || [ ];
|
|
3372
3381
|
|
|
3382
|
+
this._reporting = reporting;
|
|
3383
|
+
|
|
3373
3384
|
this._data = { };
|
|
3374
3385
|
|
|
3375
3386
|
this._data.basis = null;
|
|
@@ -3399,9 +3410,12 @@ module.exports = (() => {
|
|
|
3399
3410
|
this._data.summaryTotalPrevious = null;
|
|
3400
3411
|
this._data.summaryTotalPrevious2 = null;
|
|
3401
3412
|
|
|
3402
|
-
this._data.
|
|
3403
|
-
this._data.
|
|
3413
|
+
this._data.marketPrevious = null;
|
|
3414
|
+
this._data.marketPrevious2 = null;
|
|
3404
3415
|
|
|
3416
|
+
this._data.quantityPrevious = null;
|
|
3417
|
+
this._data.quantityPrevious2 = null;
|
|
3418
|
+
|
|
3405
3419
|
this._data.realized = null;
|
|
3406
3420
|
this._data.income = null;
|
|
3407
3421
|
this._data.basisPrice = null;
|
|
@@ -3695,7 +3709,7 @@ module.exports = (() => {
|
|
|
3695
3709
|
|
|
3696
3710
|
function calculateStaticData(item) {
|
|
3697
3711
|
const position = item.position;
|
|
3698
|
-
const snapshot = item.
|
|
3712
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
3699
3713
|
const previousSummaries = item.previousSummaries;
|
|
3700
3714
|
|
|
3701
3715
|
const data = item._data;
|
|
@@ -3725,8 +3739,10 @@ module.exports = (() => {
|
|
|
3725
3739
|
data.summaryTotalPrevious = calculateSummaryTotal(previousSummary1, previousSummary2);
|
|
3726
3740
|
data.summaryTotalPrevious2 = calculateSummaryTotal(previousSummary2, previousSummary3);
|
|
3727
3741
|
|
|
3728
|
-
data.
|
|
3729
|
-
data.
|
|
3742
|
+
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
3743
|
+
data.marketPrevious2 = previousSummary2 === null ? Decimal.ZERO : previousSummary2.end.value;
|
|
3744
|
+
|
|
3745
|
+
data.quantityPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.open;
|
|
3730
3746
|
|
|
3731
3747
|
if (snapshot.open.getIsZero()) {
|
|
3732
3748
|
data.basisPrice = Decimal.ZERO;
|
|
@@ -3737,7 +3753,7 @@ module.exports = (() => {
|
|
|
3737
3753
|
|
|
3738
3754
|
function calculatePriceData(item, price) {
|
|
3739
3755
|
const position = item.position;
|
|
3740
|
-
const snapshot = item.
|
|
3756
|
+
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
3741
3757
|
const previousSummaries = item.previousSummaries;
|
|
3742
3758
|
|
|
3743
3759
|
const data = item._data;
|
|
@@ -3889,6 +3905,28 @@ module.exports = (() => {
|
|
|
3889
3905
|
return is.object(position.system) && is.boolean(position.system.locked) && position.system.locked;
|
|
3890
3906
|
}
|
|
3891
3907
|
|
|
3908
|
+
function getSnapshot(position, currentSummary, reporting) {
|
|
3909
|
+
let snapshot;
|
|
3910
|
+
|
|
3911
|
+
if (reporting) {
|
|
3912
|
+
snapshot = { };
|
|
3913
|
+
|
|
3914
|
+
snapshot.date = currentSummary.end.date;
|
|
3915
|
+
snapshot.open = currentSummary.end.open;
|
|
3916
|
+
snapshot.direction = currentSummary.end.direction;
|
|
3917
|
+
snapshot.buys = currentSummary.period.buys;
|
|
3918
|
+
snapshot.sells = currentSummary.period.sells;
|
|
3919
|
+
snapshot.gain = currentSummary.period.realized;
|
|
3920
|
+
snapshot.basis = currentSummary.end.basis;
|
|
3921
|
+
snapshot.income = currentSummary.period.income;
|
|
3922
|
+
snapshot.value = currentSummary.end.value;
|
|
3923
|
+
} else {
|
|
3924
|
+
snapshot = position.snapshot;
|
|
3925
|
+
}
|
|
3926
|
+
|
|
3927
|
+
return snapshot;
|
|
3928
|
+
}
|
|
3929
|
+
|
|
3892
3930
|
return PositionItem;
|
|
3893
3931
|
})();
|
|
3894
3932
|
|
|
@@ -4216,6 +4254,7 @@ module.exports = (() => {
|
|
|
4216
4254
|
* @public
|
|
4217
4255
|
* @param {String} name
|
|
4218
4256
|
* @param {Array.<PositionLevelDefinition>} definitions
|
|
4257
|
+
* @oaram {Array.<String>=} exclusionDependencies
|
|
4219
4258
|
*/
|
|
4220
4259
|
class PositionTreeDefinitions {
|
|
4221
4260
|
constructor(name, definitions, exclusionDependencies) {
|