@barchart/portfolio-api-common 1.0.159 → 1.0.163
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.
|
@@ -48,17 +48,9 @@ module.exports = (() => {
|
|
|
48
48
|
const currentSummaryFrame = PositionSummaryFrame.YTD;
|
|
49
49
|
const currentSummaryRange = array.last(currentSummaryFrame.getRecentRanges(0));
|
|
50
50
|
|
|
51
|
-
this.
|
|
52
|
-
|
|
53
|
-
const addGroupBinding = (group, dispoable) => {
|
|
54
|
-
const id = group.id;
|
|
55
|
-
|
|
56
|
-
if (!this._groupBindings.hasOwnProperty(id)) {
|
|
57
|
-
this._groupBindings[id] = new DisposableStack();
|
|
58
|
-
}
|
|
51
|
+
this._definitions = definitions;
|
|
59
52
|
|
|
60
|
-
|
|
61
|
-
};
|
|
53
|
+
this._groupBindings = { };
|
|
62
54
|
|
|
63
55
|
this._portfolios = portfolios.reduce((map, portfolio) => {
|
|
64
56
|
map[portfolio.portfolio] = portfolio;
|
|
@@ -164,132 +156,51 @@ module.exports = (() => {
|
|
|
164
156
|
return Rate.fromPair(Decimal.ONE, symbol);
|
|
165
157
|
});
|
|
166
158
|
|
|
167
|
-
this._trees =
|
|
159
|
+
this._trees = this._definitions.reduce((map, treeDefinition) => {
|
|
168
160
|
const tree = new Tree();
|
|
169
161
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const parent = currentTree.getValue() || null;
|
|
176
|
-
|
|
177
|
-
const levelDefinition = levelDefinitions[0];
|
|
178
|
-
|
|
179
|
-
const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
|
|
180
|
-
const populatedGroups = Object.keys(populatedObjects).reduce((list, key) => {
|
|
181
|
-
const items = populatedObjects[key];
|
|
182
|
-
const first = items[0];
|
|
183
|
-
|
|
184
|
-
list.push(new PositionGroup(this, parent, items, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.single && items.length === 1, levelDefinition.aggregateCash));
|
|
185
|
-
|
|
186
|
-
return list;
|
|
187
|
-
}, [ ]);
|
|
188
|
-
|
|
189
|
-
const missingGroups = array.difference(levelDefinition.requiredGroups.map(group => group.key), populatedGroups.map(group => group.key))
|
|
190
|
-
.map((key) => {
|
|
191
|
-
return levelDefinition.requiredGroups.find(g => g.key === key);
|
|
192
|
-
});
|
|
162
|
+
createGroups.call(this, tree, tree, this._items, treeDefinition, treeDefinition.definitions);
|
|
163
|
+
|
|
164
|
+
map[treeDefinition.name] = tree;
|
|
193
165
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
166
|
+
return map;
|
|
167
|
+
}, { });
|
|
168
|
+
}
|
|
197
169
|
|
|
198
|
-
|
|
170
|
+
addPortfolio(portfolio) {
|
|
171
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
172
|
+
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
173
|
+
assert.argumentIsRequired(portfolio.name, 'portfolio.name', String);
|
|
199
174
|
|
|
200
|
-
|
|
175
|
+
const key = portfolio.portfolio;
|
|
201
176
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
map[group.description] = index;
|
|
177
|
+
if (!this._portfolios.hasOwnProperty(key)) {
|
|
178
|
+
this._portfolios[key] = portfolio;
|
|
205
179
|
|
|
206
|
-
|
|
207
|
-
|
|
180
|
+
this._definitions.forEach((treeDefinition) => {
|
|
181
|
+
const tree = this._trees[treeDefinition.name];
|
|
208
182
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return ordering[description];
|
|
212
|
-
} else {
|
|
213
|
-
return Number.MAX_VALUE;
|
|
214
|
-
}
|
|
215
|
-
};
|
|
183
|
+
treeDefinition.definitions.forEach((levelDefinition) => {
|
|
184
|
+
const requiredGroup = levelDefinition.generateRequiredGroup(portfolio);
|
|
216
185
|
|
|
217
|
-
|
|
218
|
-
return comparators.compareNumbers(getIndex(a.description), getIndex(b.description));
|
|
219
|
-
}).thenBy((a, b) => {
|
|
220
|
-
return comparators.compareStrings(a.description, b.description);
|
|
221
|
-
});
|
|
222
|
-
} else {
|
|
223
|
-
builder = ComparatorBuilder.startWith((a, b) => {
|
|
224
|
-
return comparators.compareStrings(a.description, b.description);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
186
|
+
if (requiredGroup !== null) {
|
|
227
187
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (parentGroup) {
|
|
234
|
-
let excludedItems = [];
|
|
235
|
-
|
|
236
|
-
currentTree.walk((childGroup) => {
|
|
237
|
-
if (childGroup.excluded) {
|
|
238
|
-
excludedItems = excludedItems.concat(childGroup.items);
|
|
239
|
-
}
|
|
240
|
-
}, false, false);
|
|
241
|
-
|
|
242
|
-
parentGroup.setExcludedItems(array.unique(excludedItems));
|
|
243
|
-
}
|
|
244
|
-
}, false);
|
|
245
|
-
|
|
246
|
-
if (treeDefinition.exclusionDependencies.length > 0) {
|
|
247
|
-
const dependantTrees = treeDefinition.exclusionDependencies.reduce((trees, name) => {
|
|
248
|
-
if (this._trees.hasOwnProperty(name)) {
|
|
249
|
-
trees.push(this._trees[name]);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return trees;
|
|
253
|
-
}, [ ]);
|
|
254
|
-
|
|
255
|
-
if (dependantTrees.length > 0) {
|
|
256
|
-
let excludedItems = [ ];
|
|
257
|
-
|
|
258
|
-
tree.walk((childGroup) => {
|
|
259
|
-
if (childGroup.excluded) {
|
|
260
|
-
excludedItems = excludedItems.concat(childGroup.items);
|
|
261
|
-
}
|
|
262
|
-
}, false, false);
|
|
263
|
-
|
|
264
|
-
dependantTrees.forEach((dependantTrees) => {
|
|
265
|
-
dependantTrees.walk((childGroup) => {
|
|
266
|
-
childGroup.setExcludedItems(excludedItems);
|
|
267
|
-
}, false, false);
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}));
|
|
272
|
-
};
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
273
193
|
|
|
274
|
-
|
|
275
|
-
const childTree = currentTree.addChild(group);
|
|
194
|
+
removePortfolio(portfolio) {
|
|
276
195
|
|
|
277
|
-
|
|
196
|
+
}
|
|
278
197
|
|
|
279
|
-
|
|
280
|
-
currentTree.walk((childGroup) => childGroup.refreshMarketPercent());
|
|
281
|
-
}));
|
|
198
|
+
mutatePosition(position, summary) {
|
|
282
199
|
|
|
283
|
-
|
|
284
|
-
});
|
|
285
|
-
};
|
|
200
|
+
}
|
|
286
201
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
map[treeDefinition.name] = tree;
|
|
202
|
+
removePosition(position) {
|
|
290
203
|
|
|
291
|
-
return map;
|
|
292
|
-
}, { });
|
|
293
204
|
}
|
|
294
205
|
|
|
295
206
|
/**
|
|
@@ -523,5 +434,132 @@ module.exports = (() => {
|
|
|
523
434
|
}
|
|
524
435
|
}
|
|
525
436
|
|
|
437
|
+
function addGroupBinding(group, dispoable) {
|
|
438
|
+
const id = group.id;
|
|
439
|
+
|
|
440
|
+
if (!this._groupBindings.hasOwnProperty(id)) {
|
|
441
|
+
this._groupBindings[id] = new DisposableStack();
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
this._groupBindings[id].push(dispoable);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function createGroups(parentTree, currentTree, items, treeDefinition, levelDefinitions) {
|
|
448
|
+
if (levelDefinitions.length === 0) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const parent = currentTree.getValue() || null;
|
|
453
|
+
|
|
454
|
+
const levelDefinition = levelDefinitions[0];
|
|
455
|
+
|
|
456
|
+
const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
|
|
457
|
+
const populatedGroups = Object.keys(populatedObjects).reduce((list, key) => {
|
|
458
|
+
const items = populatedObjects[key];
|
|
459
|
+
const first = items[0];
|
|
460
|
+
|
|
461
|
+
list.push(new PositionGroup(this, parent, items, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.single && items.length === 1, levelDefinition.aggregateCash));
|
|
462
|
+
|
|
463
|
+
return list;
|
|
464
|
+
}, [ ]);
|
|
465
|
+
|
|
466
|
+
const missingGroups = array.difference(levelDefinition.requiredGroups.map(group => group.key), populatedGroups.map(group => group.key))
|
|
467
|
+
.map((key) => {
|
|
468
|
+
return levelDefinition.requiredGroups.find(g => g.key === key);
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
const empty = missingGroups.map((group) => {
|
|
472
|
+
return new PositionGroup(this, parent, [ ], group.currency, group.key, group.description);
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
const compositeGroups = populatedGroups.concat(empty);
|
|
476
|
+
|
|
477
|
+
let builder;
|
|
478
|
+
|
|
479
|
+
if (levelDefinition.requiredGroups.length !== 0) {
|
|
480
|
+
const ordering = levelDefinition.requiredGroups.reduce((map, group, index) => {
|
|
481
|
+
map[group.description] = index;
|
|
482
|
+
|
|
483
|
+
return map;
|
|
484
|
+
}, { });
|
|
485
|
+
|
|
486
|
+
const getIndex = (description) => {
|
|
487
|
+
if (ordering.hasOwnProperty(description)) {
|
|
488
|
+
return ordering[description];
|
|
489
|
+
} else {
|
|
490
|
+
return Number.MAX_VALUE;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
495
|
+
return comparators.compareNumbers(getIndex(a.description), getIndex(b.description));
|
|
496
|
+
}).thenBy((a, b) => {
|
|
497
|
+
return comparators.compareStrings(a.description, b.description);
|
|
498
|
+
});
|
|
499
|
+
} else {
|
|
500
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
501
|
+
return comparators.compareStrings(a.description, b.description);
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
compositeGroups.sort(builder.toComparator());
|
|
506
|
+
|
|
507
|
+
const initializeGroupObservers = (group, groupTree) => {
|
|
508
|
+
addGroupBinding.call(this, group, group.registerGroupExcludedChangeHandler((excluded, sender) => {
|
|
509
|
+
groupTree.climb((parentGroup) => {
|
|
510
|
+
if (parentGroup) {
|
|
511
|
+
let excludedItems = [];
|
|
512
|
+
|
|
513
|
+
currentTree.walk((childGroup) => {
|
|
514
|
+
if (childGroup.excluded) {
|
|
515
|
+
excludedItems = excludedItems.concat(childGroup.items);
|
|
516
|
+
}
|
|
517
|
+
}, false, false);
|
|
518
|
+
|
|
519
|
+
parentGroup.setExcludedItems(array.unique(excludedItems));
|
|
520
|
+
}
|
|
521
|
+
}, false);
|
|
522
|
+
|
|
523
|
+
if (treeDefinition.exclusionDependencies.length > 0) {
|
|
524
|
+
const dependantTrees = treeDefinition.exclusionDependencies.reduce((trees, name) => {
|
|
525
|
+
if (this._trees.hasOwnProperty(name)) {
|
|
526
|
+
trees.push(this._trees[name]);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
return trees;
|
|
530
|
+
}, [ ]);
|
|
531
|
+
|
|
532
|
+
if (dependantTrees.length > 0) {
|
|
533
|
+
let excludedItems = [ ];
|
|
534
|
+
|
|
535
|
+
parentTree.walk((childGroup) => {
|
|
536
|
+
if (childGroup.excluded) {
|
|
537
|
+
excludedItems = excludedItems.concat(childGroup.items);
|
|
538
|
+
}
|
|
539
|
+
}, false, false);
|
|
540
|
+
|
|
541
|
+
dependantTrees.forEach((dependantTrees) => {
|
|
542
|
+
dependantTrees.walk((childGroup) => {
|
|
543
|
+
childGroup.setExcludedItems(excludedItems);
|
|
544
|
+
}, false, false);
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}));
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
compositeGroups.forEach((group) => {
|
|
552
|
+
const childTree = currentTree.addChild(group);
|
|
553
|
+
|
|
554
|
+
initializeGroupObservers(group, childTree);
|
|
555
|
+
|
|
556
|
+
addGroupBinding.call(this, group, group.registerMarketPercentChangeHandler(() => {
|
|
557
|
+
currentTree.walk((childGroup) => childGroup.refreshMarketPercent());
|
|
558
|
+
}));
|
|
559
|
+
|
|
560
|
+
createGroups.call(this, parentTree, childTree, group.items, treeDefinition, array.dropLeft(levelDefinitions));
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
|
|
526
564
|
return PositionContainer;
|
|
527
565
|
})();
|
|
@@ -171,8 +171,8 @@ module.exports = (() => {
|
|
|
171
171
|
this._dataFormat.quoteTime = this._dataActual.quoteTime;
|
|
172
172
|
this._dataFormat.quoteVolume = formatNumber(this._dataActual.quoteVolume, 0);
|
|
173
173
|
|
|
174
|
-
const quoteChangePositive =
|
|
175
|
-
const quoteChangeNegative =
|
|
174
|
+
const quoteChangePositive = quote.lastPriceDirection === 'up';
|
|
175
|
+
const quoteChangeNegative = quote.lastPriceDirection === 'down';
|
|
176
176
|
|
|
177
177
|
setTimeout(() => this._dataFormat.quoteChangeDirection = { up: quoteChangePositive, down: quoteChangeNegative }, 0);
|
|
178
178
|
this._dataFormat.quoteChangeNegative = quoteChangeNegative;
|
|
@@ -294,6 +294,16 @@ module.exports = (() => {
|
|
|
294
294
|
return this._excluded;
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
+
addItems(items) {
|
|
298
|
+
|
|
299
|
+
this.refresh();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
removeItems(items) {
|
|
303
|
+
|
|
304
|
+
this.refresh();
|
|
305
|
+
}
|
|
306
|
+
|
|
297
307
|
/**
|
|
298
308
|
* Sets the list of items which are excluded from group aggregation calculations.
|
|
299
309
|
*
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
2
|
+
Currency = require('@barchart/common-js/lang/Currency'),
|
|
2
3
|
is = require('@barchart/common-js/lang/is');
|
|
3
4
|
|
|
5
|
+
const InstrumentType = require('./../../data/InstrumentType');
|
|
6
|
+
|
|
4
7
|
module.exports = (() => {
|
|
5
8
|
'use strict';
|
|
6
9
|
|
|
@@ -15,12 +18,12 @@ module.exports = (() => {
|
|
|
15
18
|
* @param {PositionLevelDefinition~descriptionSelector} descriptionSelector
|
|
16
19
|
* @param {PositionLevelDefinition~currencySelector} currencySelector
|
|
17
20
|
* @param {Array.<PositionLevelDefinition~RequiredGroup>=} requiredGroups
|
|
18
|
-
* @param {Array.<PositionLevelDefinition~RequiredGroup>=} requiredGroups
|
|
19
21
|
* @param {Boolean=} single
|
|
20
22
|
* @param {Boolean=} aggregateCash
|
|
23
|
+
* @param {Function=} injectPositions
|
|
21
24
|
*/
|
|
22
25
|
class PositionLevelDefinition {
|
|
23
|
-
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash) {
|
|
26
|
+
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash, requiredGroupGenerator) {
|
|
24
27
|
assert.argumentIsRequired(name, 'name', String);
|
|
25
28
|
assert.argumentIsRequired(keySelector, 'keySelector', Function);
|
|
26
29
|
assert.argumentIsRequired(descriptionSelector, 'descriptionSelector', Function);
|
|
@@ -32,6 +35,7 @@ module.exports = (() => {
|
|
|
32
35
|
|
|
33
36
|
assert.argumentIsOptional(single, 'single', Boolean);
|
|
34
37
|
assert.argumentIsOptional(aggregateCash, 'aggregateCash', Boolean);
|
|
38
|
+
assert.argumentIsOptional(requiredGroupGenerator, 'requiredGroupGenerator', Function);
|
|
35
39
|
|
|
36
40
|
this._name = name;
|
|
37
41
|
|
|
@@ -40,8 +44,11 @@ module.exports = (() => {
|
|
|
40
44
|
this._currencySelector = currencySelector;
|
|
41
45
|
|
|
42
46
|
this._requiredGroups = requiredGroups || [ ];
|
|
47
|
+
|
|
43
48
|
this._single = is.boolean(single) && single;
|
|
44
49
|
this._aggregateCash = is.boolean(aggregateCash) && aggregateCash;
|
|
50
|
+
|
|
51
|
+
this._requiredGroupGenerator = requiredGroupGenerator || (input => null);
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
/**
|
|
@@ -118,6 +125,96 @@ module.exports = (() => {
|
|
|
118
125
|
return this._aggregateCash;
|
|
119
126
|
}
|
|
120
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Given an input, potentially creates a new {@link PositionLevelDefinition~RequiredGroup}.
|
|
130
|
+
*
|
|
131
|
+
* @public
|
|
132
|
+
* @param {*} input
|
|
133
|
+
* @returns {PositionLevelDefinition~RequiredGroup|null}
|
|
134
|
+
*/
|
|
135
|
+
generateRequiredGroup(input) {
|
|
136
|
+
const requiredGroup = this._requiredGroupGenerator(input);
|
|
137
|
+
|
|
138
|
+
if (requiredGroup !== null) {
|
|
139
|
+
this._requiredGroups.push(requiredGroup);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return requiredGroup;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Builds a {@link PositionLevelDefinition~RequiredGroup} for a portfolio.
|
|
147
|
+
*
|
|
148
|
+
* @public
|
|
149
|
+
* @static
|
|
150
|
+
* @param {Object} portfolio
|
|
151
|
+
* @return {PositionLevelDefinition~RequiredGroup}
|
|
152
|
+
*/
|
|
153
|
+
static buildRequiredGroupForPortfolio(portfolio) {
|
|
154
|
+
return {
|
|
155
|
+
key: PositionLevelDefinition.getKeyForPortfolioGroup(portfolio),
|
|
156
|
+
description: PositionLevelDefinition.getDescriptionForPortfolioGroup(portfolio),
|
|
157
|
+
currency: Currency.CAD
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static getKeyForPortfolioGroup(portfolio) {
|
|
162
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
163
|
+
|
|
164
|
+
return portfolio.portfolio;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static getDescriptionForPortfolioGroup(portfolio) {
|
|
168
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
169
|
+
|
|
170
|
+
return portfolio.name;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
static getRequiredGroupGeneratorForPortfolio() {
|
|
174
|
+
return (portfolio) => {
|
|
175
|
+
let requiredGroup;
|
|
176
|
+
|
|
177
|
+
if (is.object(portfolio) && is.string(portfolio.portfolio) && is.string(portfolio.name)) {
|
|
178
|
+
requiredGroup = PositionLevelDefinition.buildRequiredGroupForPortfolio(portfolio);
|
|
179
|
+
} else {
|
|
180
|
+
requiredGroup = null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return requiredGroup;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Builds a {@link PositionLevelDefinition~RequiredGroup} for an asset class.
|
|
189
|
+
*
|
|
190
|
+
* @public
|
|
191
|
+
* @static
|
|
192
|
+
* @param {InstrumentType} type
|
|
193
|
+
* @param {Currency} currency
|
|
194
|
+
* @return {PositionLevelDefinition~RequiredGroup}
|
|
195
|
+
*/
|
|
196
|
+
static buildRequiredGroupForAssetClass(type, currency) {
|
|
197
|
+
return {
|
|
198
|
+
key: PositionLevelDefinition.getKeyForAssetClassGroup(type, currency),
|
|
199
|
+
description: PositionLevelDefinition.getDescriptionForAssetClassGroup(type, currency),
|
|
200
|
+
currency: currency
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
static getKeyForAssetClassGroup(type, currency) {
|
|
205
|
+
assert.argumentIsRequired(type, 'type', InstrumentType, 'InstrumentType');
|
|
206
|
+
assert.argumentIsRequired(currency, 'currency', Currency, 'Currency');
|
|
207
|
+
|
|
208
|
+
return `${type.code}|${currency.code}`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static getDescriptionForAssetClassGroup(type, currency) {
|
|
212
|
+
assert.argumentIsRequired(type, 'type', InstrumentType, 'InstrumentType');
|
|
213
|
+
assert.argumentIsRequired(currency, 'currency', Currency, 'Currency');
|
|
214
|
+
|
|
215
|
+
return `${type.alternateDescription}${currency.code === 'CAD' ? '' : ` (${currency.alternateDescription})`}`;
|
|
216
|
+
}
|
|
217
|
+
|
|
121
218
|
toString() {
|
|
122
219
|
return '[PositionLevelDefinition]';
|
|
123
220
|
}
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -764,17 +764,9 @@ module.exports = (() => {
|
|
|
764
764
|
const currentSummaryFrame = PositionSummaryFrame.YTD;
|
|
765
765
|
const currentSummaryRange = array.last(currentSummaryFrame.getRecentRanges(0));
|
|
766
766
|
|
|
767
|
-
this.
|
|
768
|
-
|
|
769
|
-
const addGroupBinding = (group, dispoable) => {
|
|
770
|
-
const id = group.id;
|
|
771
|
-
|
|
772
|
-
if (!this._groupBindings.hasOwnProperty(id)) {
|
|
773
|
-
this._groupBindings[id] = new DisposableStack();
|
|
774
|
-
}
|
|
767
|
+
this._definitions = definitions;
|
|
775
768
|
|
|
776
|
-
|
|
777
|
-
};
|
|
769
|
+
this._groupBindings = { };
|
|
778
770
|
|
|
779
771
|
this._portfolios = portfolios.reduce((map, portfolio) => {
|
|
780
772
|
map[portfolio.portfolio] = portfolio;
|
|
@@ -880,132 +872,51 @@ module.exports = (() => {
|
|
|
880
872
|
return Rate.fromPair(Decimal.ONE, symbol);
|
|
881
873
|
});
|
|
882
874
|
|
|
883
|
-
this._trees =
|
|
875
|
+
this._trees = this._definitions.reduce((map, treeDefinition) => {
|
|
884
876
|
const tree = new Tree();
|
|
885
877
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
const parent = currentTree.getValue() || null;
|
|
892
|
-
|
|
893
|
-
const levelDefinition = levelDefinitions[0];
|
|
894
|
-
|
|
895
|
-
const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
|
|
896
|
-
const populatedGroups = Object.keys(populatedObjects).reduce((list, key) => {
|
|
897
|
-
const items = populatedObjects[key];
|
|
898
|
-
const first = items[0];
|
|
899
|
-
|
|
900
|
-
list.push(new PositionGroup(this, parent, items, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.single && items.length === 1, levelDefinition.aggregateCash));
|
|
901
|
-
|
|
902
|
-
return list;
|
|
903
|
-
}, [ ]);
|
|
878
|
+
createGroups.call(this, tree, tree, this._items, treeDefinition, treeDefinition.definitions);
|
|
879
|
+
|
|
880
|
+
map[treeDefinition.name] = tree;
|
|
904
881
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
});
|
|
882
|
+
return map;
|
|
883
|
+
}, { });
|
|
884
|
+
}
|
|
909
885
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
886
|
+
addPortfolio(portfolio) {
|
|
887
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
888
|
+
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
889
|
+
assert.argumentIsRequired(portfolio.name, 'portfolio.name', String);
|
|
913
890
|
|
|
914
|
-
|
|
891
|
+
const key = portfolio.portfolio;
|
|
915
892
|
|
|
916
|
-
|
|
893
|
+
if (!this._portfolios.hasOwnProperty(key)) {
|
|
894
|
+
this._portfolios[key] = portfolio;
|
|
917
895
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
map[group.description] = index;
|
|
896
|
+
this._definitions.forEach((treeDefinition) => {
|
|
897
|
+
const tree = this._trees[treeDefinition.name];
|
|
921
898
|
|
|
922
|
-
|
|
923
|
-
|
|
899
|
+
treeDefinition.definitions.forEach((levelDefinition) => {
|
|
900
|
+
const requiredGroup = levelDefinition.generateRequiredGroup(portfolio);
|
|
924
901
|
|
|
925
|
-
|
|
926
|
-
if (ordering.hasOwnProperty(description)) {
|
|
927
|
-
return ordering[description];
|
|
928
|
-
} else {
|
|
929
|
-
return Number.MAX_VALUE;
|
|
930
|
-
}
|
|
931
|
-
};
|
|
902
|
+
if (requiredGroup !== null) {
|
|
932
903
|
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
} else {
|
|
939
|
-
builder = ComparatorBuilder.startWith((a, b) => {
|
|
940
|
-
return comparators.compareStrings(a.description, b.description);
|
|
941
|
-
});
|
|
942
|
-
}
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
}
|
|
943
909
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
const initializeGroupObservers = (group, groupTree) => {
|
|
947
|
-
addGroupBinding(group, group.registerGroupExcludedChangeHandler((excluded, sender) => {
|
|
948
|
-
groupTree.climb((parentGroup) => {
|
|
949
|
-
if (parentGroup) {
|
|
950
|
-
let excludedItems = [];
|
|
951
|
-
|
|
952
|
-
currentTree.walk((childGroup) => {
|
|
953
|
-
if (childGroup.excluded) {
|
|
954
|
-
excludedItems = excludedItems.concat(childGroup.items);
|
|
955
|
-
}
|
|
956
|
-
}, false, false);
|
|
957
|
-
|
|
958
|
-
parentGroup.setExcludedItems(array.unique(excludedItems));
|
|
959
|
-
}
|
|
960
|
-
}, false);
|
|
961
|
-
|
|
962
|
-
if (treeDefinition.exclusionDependencies.length > 0) {
|
|
963
|
-
const dependantTrees = treeDefinition.exclusionDependencies.reduce((trees, name) => {
|
|
964
|
-
if (this._trees.hasOwnProperty(name)) {
|
|
965
|
-
trees.push(this._trees[name]);
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
return trees;
|
|
969
|
-
}, [ ]);
|
|
970
|
-
|
|
971
|
-
if (dependantTrees.length > 0) {
|
|
972
|
-
let excludedItems = [ ];
|
|
973
|
-
|
|
974
|
-
tree.walk((childGroup) => {
|
|
975
|
-
if (childGroup.excluded) {
|
|
976
|
-
excludedItems = excludedItems.concat(childGroup.items);
|
|
977
|
-
}
|
|
978
|
-
}, false, false);
|
|
979
|
-
|
|
980
|
-
dependantTrees.forEach((dependantTrees) => {
|
|
981
|
-
dependantTrees.walk((childGroup) => {
|
|
982
|
-
childGroup.setExcludedItems(excludedItems);
|
|
983
|
-
}, false, false);
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
}));
|
|
988
|
-
};
|
|
910
|
+
removePortfolio(portfolio) {
|
|
989
911
|
|
|
990
|
-
|
|
991
|
-
const childTree = currentTree.addChild(group);
|
|
912
|
+
}
|
|
992
913
|
|
|
993
|
-
|
|
914
|
+
mutatePosition(position, summary) {
|
|
994
915
|
|
|
995
|
-
|
|
996
|
-
currentTree.walk((childGroup) => childGroup.refreshMarketPercent());
|
|
997
|
-
}));
|
|
916
|
+
}
|
|
998
917
|
|
|
999
|
-
|
|
1000
|
-
});
|
|
1001
|
-
};
|
|
918
|
+
removePosition(position) {
|
|
1002
919
|
|
|
1003
|
-
createGroups(tree, this._items, treeDefinition.definitions);
|
|
1004
|
-
|
|
1005
|
-
map[treeDefinition.name] = tree;
|
|
1006
|
-
|
|
1007
|
-
return map;
|
|
1008
|
-
}, { });
|
|
1009
920
|
}
|
|
1010
921
|
|
|
1011
922
|
/**
|
|
@@ -1239,6 +1150,133 @@ module.exports = (() => {
|
|
|
1239
1150
|
}
|
|
1240
1151
|
}
|
|
1241
1152
|
|
|
1153
|
+
function addGroupBinding(group, dispoable) {
|
|
1154
|
+
const id = group.id;
|
|
1155
|
+
|
|
1156
|
+
if (!this._groupBindings.hasOwnProperty(id)) {
|
|
1157
|
+
this._groupBindings[id] = new DisposableStack();
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
this._groupBindings[id].push(dispoable);
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
function createGroups(parentTree, currentTree, items, treeDefinition, levelDefinitions) {
|
|
1164
|
+
if (levelDefinitions.length === 0) {
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
const parent = currentTree.getValue() || null;
|
|
1169
|
+
|
|
1170
|
+
const levelDefinition = levelDefinitions[0];
|
|
1171
|
+
|
|
1172
|
+
const populatedObjects = array.groupBy(items, levelDefinition.keySelector);
|
|
1173
|
+
const populatedGroups = Object.keys(populatedObjects).reduce((list, key) => {
|
|
1174
|
+
const items = populatedObjects[key];
|
|
1175
|
+
const first = items[0];
|
|
1176
|
+
|
|
1177
|
+
list.push(new PositionGroup(this, parent, items, levelDefinition.currencySelector(first), key, levelDefinition.descriptionSelector(first), levelDefinition.single && items.length === 1, levelDefinition.aggregateCash));
|
|
1178
|
+
|
|
1179
|
+
return list;
|
|
1180
|
+
}, [ ]);
|
|
1181
|
+
|
|
1182
|
+
const missingGroups = array.difference(levelDefinition.requiredGroups.map(group => group.key), populatedGroups.map(group => group.key))
|
|
1183
|
+
.map((key) => {
|
|
1184
|
+
return levelDefinition.requiredGroups.find(g => g.key === key);
|
|
1185
|
+
});
|
|
1186
|
+
|
|
1187
|
+
const empty = missingGroups.map((group) => {
|
|
1188
|
+
return new PositionGroup(this, parent, [ ], group.currency, group.key, group.description);
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1191
|
+
const compositeGroups = populatedGroups.concat(empty);
|
|
1192
|
+
|
|
1193
|
+
let builder;
|
|
1194
|
+
|
|
1195
|
+
if (levelDefinition.requiredGroups.length !== 0) {
|
|
1196
|
+
const ordering = levelDefinition.requiredGroups.reduce((map, group, index) => {
|
|
1197
|
+
map[group.description] = index;
|
|
1198
|
+
|
|
1199
|
+
return map;
|
|
1200
|
+
}, { });
|
|
1201
|
+
|
|
1202
|
+
const getIndex = (description) => {
|
|
1203
|
+
if (ordering.hasOwnProperty(description)) {
|
|
1204
|
+
return ordering[description];
|
|
1205
|
+
} else {
|
|
1206
|
+
return Number.MAX_VALUE;
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
|
|
1210
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
1211
|
+
return comparators.compareNumbers(getIndex(a.description), getIndex(b.description));
|
|
1212
|
+
}).thenBy((a, b) => {
|
|
1213
|
+
return comparators.compareStrings(a.description, b.description);
|
|
1214
|
+
});
|
|
1215
|
+
} else {
|
|
1216
|
+
builder = ComparatorBuilder.startWith((a, b) => {
|
|
1217
|
+
return comparators.compareStrings(a.description, b.description);
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
compositeGroups.sort(builder.toComparator());
|
|
1222
|
+
|
|
1223
|
+
const initializeGroupObservers = (group, groupTree) => {
|
|
1224
|
+
addGroupBinding.call(this, group, group.registerGroupExcludedChangeHandler((excluded, sender) => {
|
|
1225
|
+
groupTree.climb((parentGroup) => {
|
|
1226
|
+
if (parentGroup) {
|
|
1227
|
+
let excludedItems = [];
|
|
1228
|
+
|
|
1229
|
+
currentTree.walk((childGroup) => {
|
|
1230
|
+
if (childGroup.excluded) {
|
|
1231
|
+
excludedItems = excludedItems.concat(childGroup.items);
|
|
1232
|
+
}
|
|
1233
|
+
}, false, false);
|
|
1234
|
+
|
|
1235
|
+
parentGroup.setExcludedItems(array.unique(excludedItems));
|
|
1236
|
+
}
|
|
1237
|
+
}, false);
|
|
1238
|
+
|
|
1239
|
+
if (treeDefinition.exclusionDependencies.length > 0) {
|
|
1240
|
+
const dependantTrees = treeDefinition.exclusionDependencies.reduce((trees, name) => {
|
|
1241
|
+
if (this._trees.hasOwnProperty(name)) {
|
|
1242
|
+
trees.push(this._trees[name]);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
return trees;
|
|
1246
|
+
}, [ ]);
|
|
1247
|
+
|
|
1248
|
+
if (dependantTrees.length > 0) {
|
|
1249
|
+
let excludedItems = [ ];
|
|
1250
|
+
|
|
1251
|
+
parentTree.walk((childGroup) => {
|
|
1252
|
+
if (childGroup.excluded) {
|
|
1253
|
+
excludedItems = excludedItems.concat(childGroup.items);
|
|
1254
|
+
}
|
|
1255
|
+
}, false, false);
|
|
1256
|
+
|
|
1257
|
+
dependantTrees.forEach((dependantTrees) => {
|
|
1258
|
+
dependantTrees.walk((childGroup) => {
|
|
1259
|
+
childGroup.setExcludedItems(excludedItems);
|
|
1260
|
+
}, false, false);
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}));
|
|
1265
|
+
};
|
|
1266
|
+
|
|
1267
|
+
compositeGroups.forEach((group) => {
|
|
1268
|
+
const childTree = currentTree.addChild(group);
|
|
1269
|
+
|
|
1270
|
+
initializeGroupObservers(group, childTree);
|
|
1271
|
+
|
|
1272
|
+
addGroupBinding.call(this, group, group.registerMarketPercentChangeHandler(() => {
|
|
1273
|
+
currentTree.walk((childGroup) => childGroup.refreshMarketPercent());
|
|
1274
|
+
}));
|
|
1275
|
+
|
|
1276
|
+
createGroups.call(this, parentTree, childTree, group.items, treeDefinition, array.dropLeft(levelDefinitions));
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1242
1280
|
return PositionContainer;
|
|
1243
1281
|
})();
|
|
1244
1282
|
|
|
@@ -1416,8 +1454,8 @@ module.exports = (() => {
|
|
|
1416
1454
|
this._dataFormat.quoteTime = this._dataActual.quoteTime;
|
|
1417
1455
|
this._dataFormat.quoteVolume = formatNumber(this._dataActual.quoteVolume, 0);
|
|
1418
1456
|
|
|
1419
|
-
const quoteChangePositive =
|
|
1420
|
-
const quoteChangeNegative =
|
|
1457
|
+
const quoteChangePositive = quote.lastPriceDirection === 'up';
|
|
1458
|
+
const quoteChangeNegative = quote.lastPriceDirection === 'down';
|
|
1421
1459
|
|
|
1422
1460
|
setTimeout(() => this._dataFormat.quoteChangeDirection = { up: quoteChangePositive, down: quoteChangeNegative }, 0);
|
|
1423
1461
|
this._dataFormat.quoteChangeNegative = quoteChangeNegative;
|
|
@@ -1539,6 +1577,16 @@ module.exports = (() => {
|
|
|
1539
1577
|
return this._excluded;
|
|
1540
1578
|
}
|
|
1541
1579
|
|
|
1580
|
+
addItems(items) {
|
|
1581
|
+
|
|
1582
|
+
this.refresh();
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
removeItems(items) {
|
|
1586
|
+
|
|
1587
|
+
this.refresh();
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1542
1590
|
/**
|
|
1543
1591
|
* Sets the list of items which are excluded from group aggregation calculations.
|
|
1544
1592
|
*
|
|
@@ -2295,8 +2343,11 @@ module.exports = (() => {
|
|
|
2295
2343
|
|
|
2296
2344
|
},{"./../data/InstrumentType":1,"@barchart/common-js/lang/Currency":14,"@barchart/common-js/lang/Decimal":16,"@barchart/common-js/lang/array":20,"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23,"@barchart/common-js/messaging/Event":25}],7:[function(require,module,exports){
|
|
2297
2345
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
2346
|
+
Currency = require('@barchart/common-js/lang/Currency'),
|
|
2298
2347
|
is = require('@barchart/common-js/lang/is');
|
|
2299
2348
|
|
|
2349
|
+
const InstrumentType = require('./../../data/InstrumentType');
|
|
2350
|
+
|
|
2300
2351
|
module.exports = (() => {
|
|
2301
2352
|
'use strict';
|
|
2302
2353
|
|
|
@@ -2311,12 +2362,12 @@ module.exports = (() => {
|
|
|
2311
2362
|
* @param {PositionLevelDefinition~descriptionSelector} descriptionSelector
|
|
2312
2363
|
* @param {PositionLevelDefinition~currencySelector} currencySelector
|
|
2313
2364
|
* @param {Array.<PositionLevelDefinition~RequiredGroup>=} requiredGroups
|
|
2314
|
-
* @param {Array.<PositionLevelDefinition~RequiredGroup>=} requiredGroups
|
|
2315
2365
|
* @param {Boolean=} single
|
|
2316
2366
|
* @param {Boolean=} aggregateCash
|
|
2367
|
+
* @param {Function=} injectPositions
|
|
2317
2368
|
*/
|
|
2318
2369
|
class PositionLevelDefinition {
|
|
2319
|
-
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash) {
|
|
2370
|
+
constructor(name, keySelector, descriptionSelector, currencySelector, requiredGroups, single, aggregateCash, requiredGroupGenerator) {
|
|
2320
2371
|
assert.argumentIsRequired(name, 'name', String);
|
|
2321
2372
|
assert.argumentIsRequired(keySelector, 'keySelector', Function);
|
|
2322
2373
|
assert.argumentIsRequired(descriptionSelector, 'descriptionSelector', Function);
|
|
@@ -2328,6 +2379,7 @@ module.exports = (() => {
|
|
|
2328
2379
|
|
|
2329
2380
|
assert.argumentIsOptional(single, 'single', Boolean);
|
|
2330
2381
|
assert.argumentIsOptional(aggregateCash, 'aggregateCash', Boolean);
|
|
2382
|
+
assert.argumentIsOptional(requiredGroupGenerator, 'requiredGroupGenerator', Function);
|
|
2331
2383
|
|
|
2332
2384
|
this._name = name;
|
|
2333
2385
|
|
|
@@ -2336,8 +2388,11 @@ module.exports = (() => {
|
|
|
2336
2388
|
this._currencySelector = currencySelector;
|
|
2337
2389
|
|
|
2338
2390
|
this._requiredGroups = requiredGroups || [ ];
|
|
2391
|
+
|
|
2339
2392
|
this._single = is.boolean(single) && single;
|
|
2340
2393
|
this._aggregateCash = is.boolean(aggregateCash) && aggregateCash;
|
|
2394
|
+
|
|
2395
|
+
this._requiredGroupGenerator = requiredGroupGenerator || (input => null);
|
|
2341
2396
|
}
|
|
2342
2397
|
|
|
2343
2398
|
/**
|
|
@@ -2414,6 +2469,96 @@ module.exports = (() => {
|
|
|
2414
2469
|
return this._aggregateCash;
|
|
2415
2470
|
}
|
|
2416
2471
|
|
|
2472
|
+
/**
|
|
2473
|
+
* Given an input, potentially creates a new {@link PositionLevelDefinition~RequiredGroup}.
|
|
2474
|
+
*
|
|
2475
|
+
* @public
|
|
2476
|
+
* @param {*} input
|
|
2477
|
+
* @returns {PositionLevelDefinition~RequiredGroup|null}
|
|
2478
|
+
*/
|
|
2479
|
+
generateRequiredGroup(input) {
|
|
2480
|
+
const requiredGroup = this._requiredGroupGenerator(input);
|
|
2481
|
+
|
|
2482
|
+
if (requiredGroup !== null) {
|
|
2483
|
+
this._requiredGroups.push(requiredGroup);
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
return requiredGroup;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
/**
|
|
2490
|
+
* Builds a {@link PositionLevelDefinition~RequiredGroup} for a portfolio.
|
|
2491
|
+
*
|
|
2492
|
+
* @public
|
|
2493
|
+
* @static
|
|
2494
|
+
* @param {Object} portfolio
|
|
2495
|
+
* @return {PositionLevelDefinition~RequiredGroup}
|
|
2496
|
+
*/
|
|
2497
|
+
static buildRequiredGroupForPortfolio(portfolio) {
|
|
2498
|
+
return {
|
|
2499
|
+
key: PositionLevelDefinition.getKeyForPortfolioGroup(portfolio),
|
|
2500
|
+
description: PositionLevelDefinition.getDescriptionForPortfolioGroup(portfolio),
|
|
2501
|
+
currency: Currency.CAD
|
|
2502
|
+
};
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
static getKeyForPortfolioGroup(portfolio) {
|
|
2506
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
2507
|
+
|
|
2508
|
+
return portfolio.portfolio;
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
static getDescriptionForPortfolioGroup(portfolio) {
|
|
2512
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
2513
|
+
|
|
2514
|
+
return portfolio.name;
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
static getRequiredGroupGeneratorForPortfolio() {
|
|
2518
|
+
return (portfolio) => {
|
|
2519
|
+
let requiredGroup;
|
|
2520
|
+
|
|
2521
|
+
if (is.object(portfolio) && is.string(portfolio.portfolio) && is.string(portfolio.name)) {
|
|
2522
|
+
requiredGroup = PositionLevelDefinition.buildRequiredGroupForPortfolio(portfolio);
|
|
2523
|
+
} else {
|
|
2524
|
+
requiredGroup = null;
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
return requiredGroup;
|
|
2528
|
+
};
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
/**
|
|
2532
|
+
* Builds a {@link PositionLevelDefinition~RequiredGroup} for an asset class.
|
|
2533
|
+
*
|
|
2534
|
+
* @public
|
|
2535
|
+
* @static
|
|
2536
|
+
* @param {InstrumentType} type
|
|
2537
|
+
* @param {Currency} currency
|
|
2538
|
+
* @return {PositionLevelDefinition~RequiredGroup}
|
|
2539
|
+
*/
|
|
2540
|
+
static buildRequiredGroupForAssetClass(type, currency) {
|
|
2541
|
+
return {
|
|
2542
|
+
key: PositionLevelDefinition.getKeyForAssetClassGroup(type, currency),
|
|
2543
|
+
description: PositionLevelDefinition.getDescriptionForAssetClassGroup(type, currency),
|
|
2544
|
+
currency: currency
|
|
2545
|
+
};
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
static getKeyForAssetClassGroup(type, currency) {
|
|
2549
|
+
assert.argumentIsRequired(type, 'type', InstrumentType, 'InstrumentType');
|
|
2550
|
+
assert.argumentIsRequired(currency, 'currency', Currency, 'Currency');
|
|
2551
|
+
|
|
2552
|
+
return `${type.code}|${currency.code}`;
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
static getDescriptionForAssetClassGroup(type, currency) {
|
|
2556
|
+
assert.argumentIsRequired(type, 'type', InstrumentType, 'InstrumentType');
|
|
2557
|
+
assert.argumentIsRequired(currency, 'currency', Currency, 'Currency');
|
|
2558
|
+
|
|
2559
|
+
return `${type.alternateDescription}${currency.code === 'CAD' ? '' : ` (${currency.alternateDescription})`}`;
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2417
2562
|
toString() {
|
|
2418
2563
|
return '[PositionLevelDefinition]';
|
|
2419
2564
|
}
|
|
@@ -2463,7 +2608,7 @@ module.exports = (() => {
|
|
|
2463
2608
|
return PositionLevelDefinition;
|
|
2464
2609
|
})();
|
|
2465
2610
|
|
|
2466
|
-
},{"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23}],8:[function(require,module,exports){
|
|
2611
|
+
},{"./../../data/InstrumentType":1,"@barchart/common-js/lang/Currency":14,"@barchart/common-js/lang/assert":21,"@barchart/common-js/lang/is":23}],8:[function(require,module,exports){
|
|
2467
2612
|
const assert = require('@barchart/common-js/lang/assert');
|
|
2468
2613
|
|
|
2469
2614
|
const PositionLevelDefinition = require('./PositionLevelDefinition');
|