@barchart/portfolio-api-common 1.0.37 → 1.0.42

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.
@@ -10,16 +10,22 @@ module.exports = (() => {
10
10
  * @public
11
11
  * @extends {Enum}
12
12
  * @param {String} description
13
+ * @param {String} alternateDescription
13
14
  * @param {String} code
14
15
  * @param {Boolean} canReinvest
15
16
  */
16
17
  class InstrumentType extends Enum {
17
- constructor(code, description, canReinvest) {
18
+ constructor(code, description, alternateDescription, canReinvest) {
18
19
  super(code, description);
19
20
 
21
+ this._alternateDescription = alternateDescription;
20
22
  this._canReinvest = canReinvest;
21
23
  }
22
24
 
25
+ get alternateDescription() {
26
+ return this._alternateDescription;
27
+ }
28
+
23
29
  /**
24
30
  * Indicates if the instrument type allows automatic reinvestment.
25
31
  *
@@ -74,10 +80,10 @@ module.exports = (() => {
74
80
  }
75
81
  }
76
82
 
77
- const cash = new InstrumentType('CASH', 'cash', false);
78
- const equity = new InstrumentType('EQUITY', 'equity', true);
79
- const fund = new InstrumentType('FUND', 'mutual fund', true);
80
- const other = new InstrumentType('OTHER', 'other', false);
83
+ const cash = new InstrumentType('CASH', 'cash', 'Cash', false);
84
+ const equity = new InstrumentType('EQUITY', 'equity', 'Equities', true);
85
+ const fund = new InstrumentType('FUND', 'mutual fund', 'Funds', true);
86
+ const other = new InstrumentType('OTHER', 'other', 'Other', false);
81
87
 
82
88
  return InstrumentType;
83
89
  })();
@@ -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,95 @@
1
+ const assert = require('@barchart/common-js/lang/assert'),
2
+ Decimal = require('@barchart/common-js/lang/Decimal'),
3
+ is = require('@barchart/common-js/lang/is');
4
+
5
+ module.exports = (() => {
6
+ 'use strict';
7
+
8
+ /**
9
+ * @public
10
+ */
11
+ class PositionGroup {
12
+ constructor(items, description, single) {
13
+ this._description = description;
14
+ this._items = items;
15
+
16
+ this._single = is.boolean(single) && single;
17
+
18
+ this._data = { };
19
+
20
+ this._data.description = this._description;
21
+
22
+ this._data.current = null;
23
+ this._data.previous = null;
24
+
25
+ this._data.basis = null;
26
+ this._data.market = null;
27
+
28
+ this._items.forEach((item) => {
29
+ item.registerPriceChangeHandler((data, sender) => {
30
+ if (this._single) {
31
+ data.current = data.current;
32
+ } else {
33
+ data.current = null;
34
+ }
35
+
36
+ calculateVariablePriceData(this, item, price);
37
+ });
38
+ });
39
+
40
+ calculateStaticData(this);
41
+ }
42
+
43
+ get description() {
44
+ return this._description;
45
+ }
46
+
47
+ get data() {
48
+ return this._data;
49
+ }
50
+
51
+ get items() {
52
+ return this._items;
53
+ }
54
+
55
+ get single() {
56
+ return this._single;
57
+ }
58
+
59
+ toString() {
60
+ return '[PositionGroup]';
61
+ }
62
+ }
63
+
64
+ function calculateStaticData(group) {
65
+ const items = group._items;
66
+ const data = group._data;
67
+
68
+ let updates;
69
+
70
+ if (group.single) {
71
+ const item = items[0];
72
+
73
+ updates.basis = item.basis;
74
+ } else {
75
+ updates = items.reduce(function(updates, item) {
76
+ const position = item.position;
77
+ const snapshot = item.position.snapshot;
78
+
79
+ updates.value = updates.basis.add(snapshot.basis);
80
+
81
+ return updates;
82
+ }, {
83
+ basis: Decimal.ZERO
84
+ });
85
+ }
86
+
87
+ data.basis = updates.basis;
88
+ }
89
+
90
+ function calculateVariablePriceData(group, item, price) {
91
+
92
+ }
93
+
94
+ return PositionGroup;
95
+ })();
@@ -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,57 @@
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._data = { };
18
+
19
+ this._data.current = null;
20
+ this._data.previous = position.previous || null;
21
+
22
+ this._priceChangeEvent = new Event(this);
23
+ }
24
+
25
+ get portfolio() {
26
+ return this._portfolio;
27
+ }
28
+
29
+ get position() {
30
+ return this._position;
31
+ }
32
+
33
+ get summaries() {
34
+ return this._summaries;
35
+ }
36
+
37
+ setPrice(price) {
38
+ if (this._data.price !== price) {
39
+ this._data.price = price;
40
+
41
+ this._priceChangeEvent.fire(this._data);
42
+ }
43
+ }
44
+
45
+ registerPriceChangeHandler(handler) {
46
+ assert.argumentIsRequired(handler, 'handler', Function);
47
+
48
+ this._priceChangeEvent.register(handler);
49
+ }
50
+
51
+ toString() {
52
+ return '[PositionItem]';
53
+ }
54
+ }
55
+
56
+ return PositionItem;
57
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.0.37",
3
+ "version": "1.0.42",
4
4
  "description": "Common classes used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",