@barchart/portfolio-api-common 5.0.0 → 6.1.0
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.
|
@@ -92,6 +92,8 @@ module.exports = (() => {
|
|
|
92
92
|
this._positionSymbolAddedEvent = new Event(this);
|
|
93
93
|
this._positionSymbolRemovedEvent = new Event(this);
|
|
94
94
|
|
|
95
|
+
this._exchanges = { };
|
|
96
|
+
|
|
95
97
|
this._portfolios = portfolios.reduce((map, portfolio) => {
|
|
96
98
|
map[portfolio.portfolio] = portfolio;
|
|
97
99
|
|
|
@@ -99,7 +101,7 @@ module.exports = (() => {
|
|
|
99
101
|
}, { });
|
|
100
102
|
|
|
101
103
|
if (reportFrame) {
|
|
102
|
-
this.
|
|
104
|
+
this._reportDate = reportDate;
|
|
103
105
|
|
|
104
106
|
this._currentSummaryFrame = reportFrame;
|
|
105
107
|
this._currentSummaryRange = array.last(this._currentSummaryFrame.getPriorRanges(reportDate, 0));
|
|
@@ -109,7 +111,7 @@ module.exports = (() => {
|
|
|
109
111
|
|
|
110
112
|
this._previousSummaryRanges.pop();
|
|
111
113
|
} else {
|
|
112
|
-
this.
|
|
114
|
+
this._reportDate = null;
|
|
113
115
|
|
|
114
116
|
this._currentSummaryFrame = PositionSummaryFrame.YTD;
|
|
115
117
|
this._currentSummaryRange = array.first(this._currentSummaryFrame.getRecentRanges(0));
|
|
@@ -374,12 +376,24 @@ module.exports = (() => {
|
|
|
374
376
|
|
|
375
377
|
const existingBarchartSymbols = this.getPositionSymbols(false);
|
|
376
378
|
|
|
377
|
-
let
|
|
379
|
+
let exchange;
|
|
380
|
+
|
|
381
|
+
if (extractExchangeCode(position)) {
|
|
382
|
+
const code = extractExchangeCode(position);
|
|
383
|
+
|
|
384
|
+
exchange = this._exchanges[code] || null;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
let currentQuote = null;
|
|
388
|
+
let previousQuote = null;
|
|
378
389
|
|
|
379
390
|
if (extractSymbolForBarchart(position)) {
|
|
380
|
-
similarPositionItem = this._items.find(item => extractSymbolForBarchart(item.position) === extractSymbolForBarchart(position)) || null;
|
|
381
|
-
|
|
382
|
-
similarPositionItem
|
|
391
|
+
const similarPositionItem = this._items.find(item => extractSymbolForBarchart(item.position) === extractSymbolForBarchart(position)) || null;
|
|
392
|
+
|
|
393
|
+
if (similarPositionItem !== null) {
|
|
394
|
+
currentQuote = similarPositionItem.quote || null;
|
|
395
|
+
previousQuote = similarPositionItem.previousQuote || null;
|
|
396
|
+
}
|
|
383
397
|
}
|
|
384
398
|
|
|
385
399
|
removePositionItem.call(this, this._items.find(item => item.position.position === position.position));
|
|
@@ -429,14 +443,16 @@ module.exports = (() => {
|
|
|
429
443
|
this._positionSymbolAddedEvent.fire(addedBarchartSymbol);
|
|
430
444
|
}
|
|
431
445
|
|
|
432
|
-
if (
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
}
|
|
446
|
+
if (exchange) {
|
|
447
|
+
item.setExchangeStatus(exchange);
|
|
448
|
+
}
|
|
436
449
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
450
|
+
if (previousQuote !== null) {
|
|
451
|
+
item.setQuote(previousQuote);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (currentQuote !== null) {
|
|
455
|
+
item.setQuote(currentQuote);
|
|
440
456
|
}
|
|
441
457
|
|
|
442
458
|
recalculatePercentages.call(this);
|
|
@@ -581,8 +597,8 @@ module.exports = (() => {
|
|
|
581
597
|
* triggering updates to position(s) and data aggregation(s).
|
|
582
598
|
*
|
|
583
599
|
* @public
|
|
584
|
-
* @param {
|
|
585
|
-
* @param {
|
|
600
|
+
* @param {Quote[]} positionQuotes
|
|
601
|
+
* @param {Quote[]} forexQuotes
|
|
586
602
|
* @param {Boolean=} force
|
|
587
603
|
*/
|
|
588
604
|
setQuotes(positionQuotes, forexQuotes, force) {
|
|
@@ -612,7 +628,7 @@ module.exports = (() => {
|
|
|
612
628
|
|
|
613
629
|
if (symbol) {
|
|
614
630
|
if (this._symbols.hasOwnProperty(symbol)) {
|
|
615
|
-
this._symbols[
|
|
631
|
+
this._symbols[symbol].forEach(item => item.setQuote(quote, force || false));
|
|
616
632
|
}
|
|
617
633
|
}
|
|
618
634
|
});
|
|
@@ -624,18 +640,26 @@ module.exports = (() => {
|
|
|
624
640
|
}
|
|
625
641
|
|
|
626
642
|
/**
|
|
627
|
-
*
|
|
643
|
+
* Performs an update of an exchange's status, triggering updates to position(s) and
|
|
644
|
+
* data aggregation(s).
|
|
628
645
|
*
|
|
629
646
|
* @public
|
|
630
|
-
* @param {
|
|
647
|
+
* @param {ExchangeStatus} exchange
|
|
631
648
|
*/
|
|
632
|
-
|
|
633
|
-
assert.argumentIsRequired(
|
|
649
|
+
setExchangeStatus(exchange) {
|
|
650
|
+
assert.argumentIsRequired(exchange, 'exchange', Object);
|
|
651
|
+
assert.argumentIsRequired(exchange.code, 'exchange.code', String);
|
|
652
|
+
assert.argumentIsRequired(exchange.currentDay, 'exchange.currentDay', Day, 'Day');
|
|
653
|
+
assert.argumentIsRequired(exchange.currentOpened, 'exchange.currentOpened', Boolean);
|
|
654
|
+
|
|
655
|
+
const code = exchange.code;
|
|
634
656
|
|
|
635
|
-
this.
|
|
657
|
+
this._exchanges[code] = exchange;
|
|
636
658
|
|
|
637
659
|
this._items.forEach((item) => {
|
|
638
|
-
item.
|
|
660
|
+
if (extractExchangeCode(item.position) === code) {
|
|
661
|
+
item.setExchangeStatus(exchange);
|
|
662
|
+
}
|
|
639
663
|
});
|
|
640
664
|
}
|
|
641
665
|
|
|
@@ -660,6 +684,27 @@ module.exports = (() => {
|
|
|
660
684
|
return price;
|
|
661
685
|
}
|
|
662
686
|
|
|
687
|
+
/**
|
|
688
|
+
* Returns the exchange code for the symbol
|
|
689
|
+
*
|
|
690
|
+
* @public
|
|
691
|
+
* @param {string} symbol
|
|
692
|
+
* @returns {string|null}
|
|
693
|
+
*/
|
|
694
|
+
getExchangeCode(symbol) {
|
|
695
|
+
assert.argumentIsRequired(symbol, 'symbol', String);
|
|
696
|
+
|
|
697
|
+
let code;
|
|
698
|
+
|
|
699
|
+
if (this._symbols.hasOwnProperty(symbol) && this._symbols[symbol].length > 0) {
|
|
700
|
+
code = extractExchangeCode(this._symbols[symbol][0].position);
|
|
701
|
+
} else {
|
|
702
|
+
code = null;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
return code;
|
|
706
|
+
}
|
|
707
|
+
|
|
663
708
|
/**
|
|
664
709
|
* Returns all forex symbols that are required to do currency translations.
|
|
665
710
|
*
|
|
@@ -903,6 +948,14 @@ module.exports = (() => {
|
|
|
903
948
|
}
|
|
904
949
|
}
|
|
905
950
|
|
|
951
|
+
function extractExchangeCode(position) {
|
|
952
|
+
if (position.instrument && position.instrument.exchange) {
|
|
953
|
+
return position.instrument.exchange;
|
|
954
|
+
} else {
|
|
955
|
+
return null;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
|
|
906
959
|
function addGroupBinding(group, dispoable) {
|
|
907
960
|
const id = group.id;
|
|
908
961
|
|
|
@@ -1127,7 +1180,7 @@ module.exports = (() => {
|
|
|
1127
1180
|
const previousSummaries = this._summariesPrevious[ position.position ] || getSummaryArray(this._previousSummaryRanges);
|
|
1128
1181
|
|
|
1129
1182
|
if (!requireCurrentSummary || currentSummary !== null) {
|
|
1130
|
-
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries, this._reporting, this.
|
|
1183
|
+
returnRef = new PositionItem(portfolio, position, currentSummary, previousSummaries, this._reporting, this._reportDate);
|
|
1131
1184
|
} else {
|
|
1132
1185
|
returnRef = null;
|
|
1133
1186
|
}
|
|
@@ -1182,5 +1235,36 @@ module.exports = (() => {
|
|
|
1182
1235
|
});
|
|
1183
1236
|
}
|
|
1184
1237
|
|
|
1238
|
+
/**
|
|
1239
|
+
* @namespace Schema
|
|
1240
|
+
*/
|
|
1241
|
+
|
|
1242
|
+
/**
|
|
1243
|
+
* @typedef Quote
|
|
1244
|
+
* @memberOf Schema
|
|
1245
|
+
* @type Object
|
|
1246
|
+
* @property {string} symbol
|
|
1247
|
+
* @property {number} lastPrice
|
|
1248
|
+
* @property {string} lastPriceDirection
|
|
1249
|
+
* @property {number} previousPrice
|
|
1250
|
+
* @property {number} priceChange
|
|
1251
|
+
* @property {number} percentChange
|
|
1252
|
+
* @property {number} openPrice
|
|
1253
|
+
* @property {number} highPrice
|
|
1254
|
+
* @property {number} lowPrice
|
|
1255
|
+
* @property {number} volume
|
|
1256
|
+
* @property {string} timeDisplay
|
|
1257
|
+
* @property {Day|null} lastDay
|
|
1258
|
+
*/
|
|
1259
|
+
|
|
1260
|
+
/**
|
|
1261
|
+
* @typedef ExchangeStatus
|
|
1262
|
+
* @memberOf Schema
|
|
1263
|
+
* @type Object
|
|
1264
|
+
* @property {string} code
|
|
1265
|
+
* @property {Day} currentDay
|
|
1266
|
+
* @property {boolean} currentOpened
|
|
1267
|
+
*/
|
|
1268
|
+
|
|
1185
1269
|
return PositionContainer;
|
|
1186
1270
|
})();
|
|
@@ -681,10 +681,6 @@ module.exports = (() => {
|
|
|
681
681
|
this.changeCurrency(currencySelector({ portfolio }));
|
|
682
682
|
});
|
|
683
683
|
|
|
684
|
-
const referenceDateBinding = item.registerReferenceDateChangeHandler(() => {
|
|
685
|
-
this.refresh();
|
|
686
|
-
});
|
|
687
|
-
|
|
688
684
|
let disposalBinding = null;
|
|
689
685
|
|
|
690
686
|
disposalBinding = item.registerPositionItemDisposeHandler(() => {
|
|
@@ -696,7 +692,6 @@ module.exports = (() => {
|
|
|
696
692
|
calculatingBinding.dispose();
|
|
697
693
|
|
|
698
694
|
portfolioChangeBinding.dispose();
|
|
699
|
-
referenceDateBinding.dispose();
|
|
700
695
|
|
|
701
696
|
disposalBinding.dispose();
|
|
702
697
|
|
|
@@ -1009,6 +1004,7 @@ module.exports = (() => {
|
|
|
1009
1004
|
updates.marketAbsolute = updates.marketAbsolute.add(translate(item, item.data.marketAbsolute));
|
|
1010
1005
|
updates.unrealized = updates.unrealized.add(translate(item, item.data.unrealized));
|
|
1011
1006
|
updates.unrealizedToday = updates.unrealizedToday.add(translate(item, item.data.unrealizedToday));
|
|
1007
|
+
updates.realizedToday = updates.realizedToday.add(translate(item, item.data.realizedToday));
|
|
1012
1008
|
updates.gainToday = updates.gainToday.add(translate(item, item.data.unrealizedToday.add(item.data.realizedToday)));
|
|
1013
1009
|
updates.summaryTotalCurrent = updates.summaryTotalCurrent.add(translate(item, item.data.periodGain));
|
|
1014
1010
|
updates.periodUnrealized = updates.periodUnrealized.add(translate(item, item.data.periodUnrealized));
|
|
@@ -1021,6 +1017,7 @@ module.exports = (() => {
|
|
|
1021
1017
|
marketDirection: unchanged,
|
|
1022
1018
|
unrealized: Decimal.ZERO,
|
|
1023
1019
|
unrealizedToday: Decimal.ZERO,
|
|
1020
|
+
realizedToday: Decimal.ZERO,
|
|
1024
1021
|
gainToday: Decimal.ZERO,
|
|
1025
1022
|
summaryTotalCurrent: Decimal.ZERO,
|
|
1026
1023
|
periodUnrealized: Decimal.ZERO
|
|
@@ -1040,7 +1037,8 @@ module.exports = (() => {
|
|
|
1040
1037
|
updates.marketDirection = { up: item.data.marketChange.getIsPositive(), down: item.data.marketChange.getIsNegative() };
|
|
1041
1038
|
updates.unrealized = actual.unrealized.add(translate(item, item.data.unrealizedChange));
|
|
1042
1039
|
updates.unrealizedToday = actual.unrealizedToday.add(translate(item, item.data.unrealizedTodayChange));
|
|
1043
|
-
updates.
|
|
1040
|
+
updates.realizedToday = actual.realizedToday.add(translate(item, item.data.realizedTodayChange));
|
|
1041
|
+
updates.gainToday = actual.gainToday.add(translate(item, item.data.unrealizedTodayChange).add(item.data.realizedTodayChange));
|
|
1044
1042
|
updates.summaryTotalCurrent = actual.summaryTotalCurrent.add(translate(item, item.data.periodGainChange));
|
|
1045
1043
|
updates.periodUnrealized = actual.periodUnrealized.add(translate(item, item.data.periodUnrealizedChange));
|
|
1046
1044
|
}
|
|
@@ -1050,6 +1048,7 @@ module.exports = (() => {
|
|
|
1050
1048
|
actual.marketAbsolute = updates.marketAbsolute;
|
|
1051
1049
|
actual.unrealized = updates.unrealized;
|
|
1052
1050
|
actual.unrealizedToday = updates.unrealizedToday;
|
|
1051
|
+
actual.realizedToday = updates.realizedToday;
|
|
1053
1052
|
actual.gainToday = updates.gainToday;
|
|
1054
1053
|
actual.summaryTotalCurrent = updates.summaryTotalCurrent;
|
|
1055
1054
|
actual.periodUnrealized = updates.periodUnrealized;
|
|
@@ -1089,6 +1088,8 @@ module.exports = (() => {
|
|
|
1089
1088
|
format.unrealizedToday = formatCurrency(actual.unrealizedToday, currency);
|
|
1090
1089
|
format.unrealizedTodayNegative = actual.unrealizedToday.getIsNegative();
|
|
1091
1090
|
|
|
1091
|
+
format.realizedToday = formatCurrency(actual.realizedToday, currency);
|
|
1092
|
+
|
|
1092
1093
|
format.gainToday = formatCurrency(actual.gainToday, currency);
|
|
1093
1094
|
format.gainTodayNegative = actual.gainToday.getIsNegative();
|
|
1094
1095
|
|
|
@@ -26,10 +26,10 @@ module.exports = (() => {
|
|
|
26
26
|
* @param {Object} currentSummary
|
|
27
27
|
* @param {Object[]} previousSummaries
|
|
28
28
|
* @param {Boolean} reporting
|
|
29
|
-
* @param {Day}
|
|
29
|
+
* @param {Day|null} reportDate
|
|
30
30
|
*/
|
|
31
31
|
class PositionItem extends Disposable {
|
|
32
|
-
constructor(portfolio, position, currentSummary, previousSummaries, reporting,
|
|
32
|
+
constructor(portfolio, position, currentSummary, previousSummaries, reporting, reportDate) {
|
|
33
33
|
super();
|
|
34
34
|
|
|
35
35
|
this._portfolio = portfolio;
|
|
@@ -40,11 +40,15 @@ module.exports = (() => {
|
|
|
40
40
|
this._currency = instrument.currency || Currency.CAD;
|
|
41
41
|
this._invalid = instrument.type.usesSymbols && (!is.object(instrument.symbol) || !is.string(instrument.symbol.barchart));
|
|
42
42
|
|
|
43
|
+
this._exchangeStatus = null;
|
|
44
|
+
|
|
43
45
|
this._currentSummary = currentSummary || null;
|
|
44
46
|
this._previousSummaries = previousSummaries || [ ];
|
|
45
47
|
|
|
46
48
|
this._reporting = reporting;
|
|
47
|
-
this.
|
|
49
|
+
this._reportDate = reportDate || null;
|
|
50
|
+
|
|
51
|
+
this._today = calculateToday(this._reportDate, this._exchangeStatus);
|
|
48
52
|
|
|
49
53
|
this._currentQuote = null;
|
|
50
54
|
this._previousQuote = null;
|
|
@@ -64,6 +68,7 @@ module.exports = (() => {
|
|
|
64
68
|
this._data.marketAbsoluteChange = null;
|
|
65
69
|
|
|
66
70
|
this._data.realizedToday = null;
|
|
71
|
+
this._data.realizedTodayChange = null;
|
|
67
72
|
|
|
68
73
|
this._data.unrealizedToday = null;
|
|
69
74
|
this._data.unrealizedTodayChange = null;
|
|
@@ -112,7 +117,7 @@ module.exports = (() => {
|
|
|
112
117
|
this._data.fundamental = { };
|
|
113
118
|
this._data.calculating = getIsCalculating(position);
|
|
114
119
|
this._data.locked = getIsLocked(position);
|
|
115
|
-
this._data.expired = getIsExpired(position,
|
|
120
|
+
this._data.expired = getIsExpired(position, this._today);
|
|
116
121
|
|
|
117
122
|
this._quoteChangedEvent = new Event(this);
|
|
118
123
|
this._newsExistsChangedEvent = new Event(this);
|
|
@@ -120,11 +125,10 @@ module.exports = (() => {
|
|
|
120
125
|
this._lockChangedEvent = new Event(this);
|
|
121
126
|
this._calculatingChangedEvent = new Event(this);
|
|
122
127
|
this._portfolioChangedEvent = new Event(this);
|
|
123
|
-
this._referenceDateChangedEvent = new Event(this);
|
|
124
128
|
this._positionItemDisposeEvent = new Event(this);
|
|
125
129
|
|
|
126
|
-
calculateStaticData(this, this.
|
|
127
|
-
calculatePriceData(this, null, null);
|
|
130
|
+
calculateStaticData(this, this._today);
|
|
131
|
+
calculatePriceData(this, null, null, this._today);
|
|
128
132
|
}
|
|
129
133
|
|
|
130
134
|
/**
|
|
@@ -220,6 +224,7 @@ module.exports = (() => {
|
|
|
220
224
|
/**
|
|
221
225
|
* The current price.
|
|
222
226
|
*
|
|
227
|
+
* @public
|
|
223
228
|
* @return {null|Number}
|
|
224
229
|
*/
|
|
225
230
|
get currentPrice() {
|
|
@@ -244,7 +249,7 @@ module.exports = (() => {
|
|
|
244
249
|
* be recalculated.
|
|
245
250
|
*
|
|
246
251
|
* @public
|
|
247
|
-
* @param {
|
|
252
|
+
* @param {Quote} quote
|
|
248
253
|
* @param {Boolean=} force
|
|
249
254
|
*/
|
|
250
255
|
setQuote(quote, force) {
|
|
@@ -260,7 +265,7 @@ module.exports = (() => {
|
|
|
260
265
|
this._data.previousPrice = quote.previousPrice;
|
|
261
266
|
}
|
|
262
267
|
|
|
263
|
-
calculatePriceData(this, quote.lastPrice,
|
|
268
|
+
calculatePriceData(this, quote.lastPrice, calculateQuoteDay(quote), this._today);
|
|
264
269
|
|
|
265
270
|
this._currentPrice = quote.lastPrice;
|
|
266
271
|
|
|
@@ -271,6 +276,30 @@ module.exports = (() => {
|
|
|
271
276
|
}
|
|
272
277
|
}
|
|
273
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Sets the current exchange status -- causing position-level data (e.g. today's gain) to
|
|
281
|
+
* be recalculated.
|
|
282
|
+
*
|
|
283
|
+
* @public
|
|
284
|
+
* @param {ExchangeStatus} exchange
|
|
285
|
+
*/
|
|
286
|
+
setExchangeStatus(exchange) {
|
|
287
|
+
assert.argumentIsRequired(exchange, 'exchange', Object);
|
|
288
|
+
assert.argumentIsRequired(exchange.code, 'exchange.code', String);
|
|
289
|
+
assert.argumentIsRequired(exchange.currentDay, 'exchange.currentDay', Day, 'Day');
|
|
290
|
+
assert.argumentIsRequired(exchange.currentOpened, 'exchange.currentOpened', Boolean);
|
|
291
|
+
|
|
292
|
+
if (this._exchangeStatus === null || !(exchange.currentDay.getIsEqual(this._exchangeStatus.currentDay) && exchange.currentOpened === this._exchangeStatus.currentOpened)) {
|
|
293
|
+
this._exchangeStatus = exchange;
|
|
294
|
+
|
|
295
|
+
this._today = calculateToday(this._reportDate, this._exchangeStatus);
|
|
296
|
+
|
|
297
|
+
if (this._currentQuote) {
|
|
298
|
+
this.setQuote(this._currentQuote, true);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
274
303
|
/**
|
|
275
304
|
* Sets a flag which indicates if news article(s) exist for the encapsulated position's
|
|
276
305
|
* symbol.
|
|
@@ -346,31 +375,6 @@ module.exports = (() => {
|
|
|
346
375
|
}
|
|
347
376
|
}
|
|
348
377
|
|
|
349
|
-
/**
|
|
350
|
-
* Sets the reference date (today).
|
|
351
|
-
*
|
|
352
|
-
* @public
|
|
353
|
-
* @param {Day} referenceDate
|
|
354
|
-
*/
|
|
355
|
-
setReferenceDate(referenceDate) {
|
|
356
|
-
assert.argumentIsRequired(referenceDate, 'referenceDate', Day, 'Day');
|
|
357
|
-
|
|
358
|
-
if (this.getIsDisposed()) {
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
if (this._referenceDate.getIsEqual(referenceDate)) {
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
this._referenceDate = referenceDate;
|
|
367
|
-
|
|
368
|
-
calculateStaticData(this, this._referenceDate);
|
|
369
|
-
calculatePriceData(this, this._currentPrice, getQuoteIsToday(this._currentQuote, this._referenceDate));
|
|
370
|
-
|
|
371
|
-
this._referenceDateChangedEvent.fire(this._referenceDate);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
378
|
/**
|
|
375
379
|
* Registers an observer for quote changes, which is fired after internal recalculations
|
|
376
380
|
* of position data are complete.
|
|
@@ -438,17 +442,6 @@ module.exports = (() => {
|
|
|
438
442
|
return this._portfolioChangedEvent.register(handler);
|
|
439
443
|
}
|
|
440
444
|
|
|
441
|
-
/**
|
|
442
|
-
* Registers an observer for changes to the reference date (today).
|
|
443
|
-
*
|
|
444
|
-
* @public
|
|
445
|
-
* @param {Function} handler
|
|
446
|
-
* @returns {Disposable}
|
|
447
|
-
*/
|
|
448
|
-
registerReferenceDateChangeHandler(handler) {
|
|
449
|
-
return this._referenceDateChangedEvent.register(handler);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
445
|
/**
|
|
453
446
|
* Registers an observer for object disposal.
|
|
454
447
|
*
|
|
@@ -469,7 +462,6 @@ module.exports = (() => {
|
|
|
469
462
|
this._lockChangedEvent.clear();
|
|
470
463
|
this._calculatingChangedEvent.clear();
|
|
471
464
|
this._portfolioChangedEvent.clear();
|
|
472
|
-
this._referenceDateChangedEvent.clear();
|
|
473
465
|
this._positionItemDisposeEvent.clear();
|
|
474
466
|
}
|
|
475
467
|
|
|
@@ -478,7 +470,12 @@ module.exports = (() => {
|
|
|
478
470
|
}
|
|
479
471
|
}
|
|
480
472
|
|
|
481
|
-
|
|
473
|
+
/**
|
|
474
|
+
* @private
|
|
475
|
+
* @param {PositionItem} item
|
|
476
|
+
* @param {Day|null} day
|
|
477
|
+
*/
|
|
478
|
+
function calculateStaticData(item, day) {
|
|
482
479
|
const position = item.position;
|
|
483
480
|
|
|
484
481
|
const currentSummary = item.currentSummary;
|
|
@@ -509,12 +506,6 @@ module.exports = (() => {
|
|
|
509
506
|
data.realized = snapshot.gain;
|
|
510
507
|
data.unrealized = Decimal.ZERO;
|
|
511
508
|
|
|
512
|
-
if (position.latest && position.latest.date && position.latest.date.getIsEqual(referenceDate) && position.latest.gain) {
|
|
513
|
-
data.realizedToday = position.latest.gain;
|
|
514
|
-
} else {
|
|
515
|
-
data.realizedToday = Decimal.ZERO;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
509
|
data.income = snapshot.income;
|
|
519
510
|
|
|
520
511
|
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
@@ -551,7 +542,14 @@ module.exports = (() => {
|
|
|
551
542
|
data.totalDivisor = calculateTotalDivisor(position.instrument.type, data.initiate, position);
|
|
552
543
|
}
|
|
553
544
|
|
|
554
|
-
|
|
545
|
+
/**
|
|
546
|
+
* @private
|
|
547
|
+
* @param {PositionItem} item
|
|
548
|
+
* @param {Decimal|number|null} price
|
|
549
|
+
* @param {Day|null} day
|
|
550
|
+
* @param {Day} today
|
|
551
|
+
*/
|
|
552
|
+
function calculatePriceData(item, price, day, today) {
|
|
555
553
|
const position = item.position;
|
|
556
554
|
const snapshot = getSnapshot(position, item.currentSummary, item._reporting);
|
|
557
555
|
|
|
@@ -614,24 +612,43 @@ module.exports = (() => {
|
|
|
614
612
|
// price change (e.g. friday, last week, sometime in the past when the instrument
|
|
615
613
|
// was delisted, etc).
|
|
616
614
|
|
|
617
|
-
|
|
615
|
+
const priceIsToday = day && today.getIsEqual(day);
|
|
616
|
+
|
|
617
|
+
if (priceIsToday && data.previousPrice && price) {
|
|
618
618
|
const unrealizedTodayBase = ValuationCalculator.calculate(position.instrument, data.previousPrice, snapshot.open);
|
|
619
619
|
|
|
620
620
|
unrealizedToday = market.subtract(unrealizedTodayBase);
|
|
621
|
-
|
|
622
|
-
if (data.unrealizedToday !== null) {
|
|
623
|
-
unrealizedTodayChange = unrealizedToday.subtract(data.unrealizedToday);
|
|
624
|
-
} else {
|
|
625
|
-
unrealizedTodayChange = unrealizedToday;
|
|
626
|
-
}
|
|
627
621
|
} else {
|
|
628
622
|
unrealizedToday = Decimal.ZERO;
|
|
629
|
-
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (data.unrealizedToday !== null) {
|
|
626
|
+
unrealizedTodayChange = unrealizedToday.subtract(data.unrealizedToday);
|
|
627
|
+
} else {
|
|
628
|
+
unrealizedTodayChange = unrealizedToday;
|
|
630
629
|
}
|
|
631
630
|
|
|
632
631
|
data.unrealizedToday = unrealizedToday;
|
|
633
632
|
data.unrealizedTodayChange = unrealizedTodayChange;
|
|
634
633
|
|
|
634
|
+
let realizedToday;
|
|
635
|
+
let realizedTodayChange;
|
|
636
|
+
|
|
637
|
+
if (position.latest && position.latest.gain && position.latest.date && day && position.latest.date.getIsEqual(day)) {
|
|
638
|
+
realizedToday = position.latest.gain;
|
|
639
|
+
} else {
|
|
640
|
+
realizedToday = Decimal.ZERO;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (data.realizedToday) {
|
|
644
|
+
realizedTodayChange = realizedToday.subtract(data.realizedToday);
|
|
645
|
+
} else {
|
|
646
|
+
realizedTodayChange = realizedToday;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
data.realizedToday = realizedToday;
|
|
650
|
+
data.realizedTodayChange = realizedTodayChange;
|
|
651
|
+
|
|
635
652
|
const currentSummary = item.currentSummary;
|
|
636
653
|
const previousSummary = getPreviousSummary(item.previousSummaries, 1);
|
|
637
654
|
|
|
@@ -884,8 +901,24 @@ module.exports = (() => {
|
|
|
884
901
|
return snapshot;
|
|
885
902
|
}
|
|
886
903
|
|
|
887
|
-
function
|
|
888
|
-
|
|
904
|
+
function calculateToday(reportDate, exchangeStatus) {
|
|
905
|
+
if (reportDate instanceof Day) {
|
|
906
|
+
return reportDate;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
if (exchangeStatus && exchangeStatus.currentDay instanceof Day) {
|
|
910
|
+
return exchangeStatus.currentDay;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
return Day.getToday();
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
function calculateQuoteDay(quote) {
|
|
917
|
+
if (quote && quote.lastDay instanceof Day) {
|
|
918
|
+
return quote.lastDay;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
return null;
|
|
889
922
|
}
|
|
890
923
|
|
|
891
924
|
return PositionItem;
|
|
@@ -229,6 +229,7 @@ module.exports = (() => {
|
|
|
229
229
|
.withField('instrument.code', DataType.NUMBER, true) // Not intended to be the unit code. Same value as [profile] table [type] column. See `InstrumentType.fromSymbolType` function.
|
|
230
230
|
.withField('instrument.type', DataType.forEnum(InstrumentType, 'InstrumentType'), true)
|
|
231
231
|
.withField('instrument.currency', DataType.forEnum(Currency, 'Currency'), true)
|
|
232
|
+
.withField('instrument.exchange', DataType.STRING, true)
|
|
232
233
|
.withField('instrument.symbol.barchart', DataType.STRING, true)
|
|
233
234
|
.withField('instrument.symbol.display', DataType.STRING, true)
|
|
234
235
|
.withField('date', DataType.DAY)
|
|
@@ -279,6 +280,7 @@ module.exports = (() => {
|
|
|
279
280
|
.withField('instrument.code', DataType.NUMBER, true) // Not intended to be the unit code. Same value as [profile] table [type] column. See `InstrumentType.fromSymbolType` function.
|
|
280
281
|
.withField('instrument.type', DataType.forEnum(InstrumentType, 'InstrumentType'), true)
|
|
281
282
|
.withField('instrument.currency', DataType.forEnum(Currency, 'Currency'), true)
|
|
283
|
+
.withField('instrument.exchange', DataType.STRING, true)
|
|
282
284
|
.withField('instrument.symbol.barchart', DataType.STRING, true)
|
|
283
285
|
.withField('instrument.symbol.display', DataType.STRING, true)
|
|
284
286
|
.withField('date', DataType.DAY)
|