@barchart/portfolio-api-common 1.0.35 → 1.0.40

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,14 +15,16 @@ 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) {
@@ -31,6 +33,12 @@ module.exports = (() => {
31
33
  return this._rangeCalculator(getFilteredTransactions(transactions));
32
34
  }
33
35
 
36
+ getStartDate(periods) {
37
+ assert.argumentIsRequired(periods, 'periods', Number);
38
+
39
+ return this._startDateCalculator(periods);
40
+ }
41
+
34
42
  /**
35
43
  * A summary for a calendar year.
36
44
  *
@@ -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,6 +150,27 @@ 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
+
145
174
  function getFilteredTransactions(transactions) {
146
175
  return transactions.reduce((filtered, transaction) => {
147
176
  if (!transaction.snapshot.open.getIsZero() || transaction.type.closing) {
@@ -0,0 +1,137 @@
1
+ const array = require('@barchart/common-js/lang/array'),
2
+ assert = require('@barchart/common-js/lang/assert'),
3
+ is = require('@barchart/common-js/lang/is'),
4
+ Tree = require('@barchart/common-js/collections/Tree');
5
+
6
+ const PositionGroup = require('./PositionGroup'),
7
+ PositionGroupDefinition = require('./PositionGroupDefinition'),
8
+ PositionItem = require('./PositionItem');
9
+
10
+ module.exports = (() => {
11
+ 'use strict';
12
+
13
+ /**
14
+ * @public
15
+ */
16
+ class PositionContainer {
17
+ constructor(portfolios, positions, summaries, definitions) {
18
+ this._portfolios = portfolios.reduce((map, portfolio) => {
19
+ map[portfolio.portfolio] = portfolio;
20
+
21
+ return map;
22
+ }, { });
23
+
24
+ this._summaries = summaries.reduce((map, summary) => {
25
+ const key = summary.position;
26
+
27
+ if (!map.hasOwnProperty(key)) {
28
+ map[key] = [ ];
29
+ }
30
+
31
+ map[key].push(summary);
32
+
33
+ return map;
34
+ }, { });
35
+
36
+ this._items = positions.reduce((items, position) => {
37
+ const portfolio = this._portfolios[position.portfolio];
38
+
39
+ if (position) {
40
+ const summaries = this._summaries[position.position] || [ ];
41
+
42
+ items.push(new PositionItem(portfolio, position, summaries));
43
+ }
44
+
45
+ return items;
46
+ }, [ ]);
47
+
48
+ this._symbols = this._items.reduce((map, item) => {
49
+ let position = item.position;
50
+ let symbol = null;
51
+
52
+ if (position.instrument && position.instrument.symbol && position.instrument.barchart) {
53
+ symbol = position.instrument.barchart;
54
+
55
+ if (!map.hasOwnProperty(symbol)) {
56
+ map[symbol] = [ ];
57
+ }
58
+
59
+ map[symbol].push(item);
60
+ }
61
+
62
+ return map;
63
+ }, { });
64
+
65
+ this._definitions = definitions || [ new PositionGroupDefinition('Totals', i => true, i => 'Totals', [ 'Totals' ]) ];
66
+
67
+ this._tree = new Tree();
68
+
69
+ const createGroups = (tree, items, definitions) => {
70
+ if (definitions.length === 0) {
71
+ return;
72
+ }
73
+
74
+ const currentDefinition = definitions[0];
75
+ const additionalDefinitions = array.dropLeft(definitions);
76
+
77
+ const populatedGroups = array.batchBy(items, currentDefinition.keySelector).map((items) => {
78
+ const first = items[0];
79
+
80
+ return new PositionGroup(items, currentDefinition.descriptionSelector(first), currentDefinition.single && items.length === 1);
81
+ });
82
+
83
+ const missingGroups = array.difference(currentDefinition.requiredGroups, populatedGroups.map(group => group.description));
84
+
85
+ const empty = missingGroups.map((description) => {
86
+ return new PositionGroup(description, [ ]);
87
+ });
88
+
89
+ const compositeGroups = populatedGroups.concat(empty);
90
+
91
+ compositeGroups.forEach((group) => {
92
+ const child = tree.addChild(group);
93
+
94
+ createGroups(child, group.items, additionalDefinitions);
95
+ });
96
+ };
97
+
98
+ createGroups(this._tree, this._items, this._definitions);
99
+ }
100
+
101
+ getSymbols() {
102
+ return Object.keys(this._symbols);
103
+ }
104
+
105
+ setPrice(symbol, price) {
106
+ if (this._symbols.hasOwnProperty(symbol)) {
107
+ this._symbols.forEach(item.setPrice(price));
108
+ }
109
+ }
110
+
111
+ getGroup(keys) {
112
+ const node = keys.reduce((tree, key) => {
113
+ tree = tree.findChild((group) => group.description === key);
114
+
115
+ return tree;
116
+ }, this._tree);
117
+
118
+ return node.getValue();
119
+ }
120
+
121
+ getGroups(keys) {
122
+ const node = keys.reduce((tree, key) => {
123
+ tree = tree.findChild((group) => group.description === key);
124
+
125
+ return tree;
126
+ }, this._tree);
127
+
128
+ return node.getChildren().map((node) => node.getValue());
129
+ }
130
+
131
+ toString() {
132
+ return '[PositionContainer]';
133
+ }
134
+ }
135
+
136
+ return PositionContainer;
137
+ })();
@@ -0,0 +1,66 @@
1
+ const assert = require('@barchart/common-js/lang/assert'),
2
+ is = require('@barchart/common-js/lang/is');
3
+
4
+ module.exports = (() => {
5
+ 'use strict';
6
+
7
+ /**
8
+ * @public
9
+ */
10
+ class PositionGroup {
11
+ constructor(items, description, single) {
12
+ this._description = description;
13
+ this._items = items;
14
+
15
+ this._single = is.boolean(single) && single;
16
+
17
+ this._data = { };
18
+
19
+ this._data.description = this._description;
20
+
21
+ this._data.previous = null;
22
+ this._data.current = null;
23
+
24
+ this._items.forEach((item) => {
25
+ item.registerPriceChangeHandler((price, sender) => {
26
+ if (this._single) {
27
+ data.current = price;
28
+ } else {
29
+ data.current = null;
30
+ }
31
+ });
32
+ });
33
+
34
+ calculateStaticData(this);
35
+ }
36
+
37
+ get description() {
38
+ return this._description;
39
+ }
40
+
41
+ get data() {
42
+ return this._data;
43
+ }
44
+
45
+ get items() {
46
+ return this._items;
47
+ }
48
+
49
+ toString() {
50
+ return '[PositionGroup]';
51
+ }
52
+ }
53
+
54
+ function calculateStaticData(group) {
55
+ const items = group._items;
56
+ const data = group._data;
57
+
58
+ const updates = items.reduce(function(updates, item) {
59
+
60
+ }, { });
61
+
62
+
63
+ }
64
+
65
+ return PositionGroup;
66
+ })();
@@ -0,0 +1,43 @@
1
+ const assert = require('@barchart/common-js/lang/assert'),
2
+ is = require('@barchart/common-js/lang/is');
3
+
4
+ module.exports = (() => {
5
+ 'use strict';
6
+
7
+ /**
8
+ * @public
9
+ */
10
+ class PositionGroupDefinition {
11
+ constructor(name, keySelector, descriptionSelector, requiredGroups, single) {
12
+ this._name = name;
13
+
14
+ this._keySelector = keySelector;
15
+ this._descriptionSelector = descriptionSelector;
16
+
17
+ this._requiredGroups = requiredGroups || [ ];
18
+ this._single = is.boolean(single) && single;
19
+ }
20
+
21
+ get name() {
22
+ return this._name;
23
+ }
24
+
25
+ get keySelector() {
26
+ return this._keySelector;
27
+ }
28
+
29
+ get descriptionSelector() {
30
+ return this._descriptionSelector;
31
+ }
32
+
33
+ get requiredGroups() {
34
+ return this._requiredGroups;
35
+ }
36
+
37
+ toString() {
38
+ return '[PositionGroupDefinition]';
39
+ }
40
+ }
41
+
42
+ return PositionGroupDefinition;
43
+ })();
@@ -0,0 +1,51 @@
1
+ const assert = require('@barchart/common-js/lang/assert'),
2
+ Event = require('@barchart/common-js/messaging/Event'),
3
+ is = require('@barchart/common-js/lang/is');
4
+
5
+ module.exports = (() => {
6
+ 'use strict';
7
+
8
+ /**
9
+ * @public
10
+ */
11
+ class PositionItem {
12
+ constructor(portfolio, position, summaries) {
13
+ this._portfolio = portfolio;
14
+ this._position = position;
15
+ this._summaries = summaries || [ ];
16
+
17
+ this._price = null;
18
+ this._priceChangeEvent = new Event(this);
19
+ }
20
+
21
+ get portfolio() {
22
+ return this._portfolio;
23
+ }
24
+
25
+ get position() {
26
+ return this._position;
27
+ }
28
+
29
+ get summaries() {
30
+ return this._summaries;
31
+ }
32
+
33
+ setPrice(price) {
34
+ if (this._price !== price) {
35
+ this._priceChangeEvent.fire(this._price = price);
36
+ }
37
+ }
38
+
39
+ registerPriceChangeHandler(handler) {
40
+ assert.argumentIsRequired(handler, 'handler', Function);
41
+
42
+ this._priceChangeEvent.register(handler);
43
+ }
44
+
45
+ toString() {
46
+ return '[PositionItem]';
47
+ }
48
+ }
49
+
50
+ return PositionItem;
51
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.0.35",
3
+ "version": "1.0.40",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",