@barchart/portfolio-api-common 6.0.0 → 6.2.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.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
2
2
|
array = require('@barchart/common-js/lang/array'),
|
|
3
|
+
Decimal = require('@barchart/common-js/lang/Decimal'),
|
|
3
4
|
is = require('@barchart/common-js/lang/is');
|
|
4
5
|
|
|
5
6
|
const InstrumentType = require('./InstrumentType'),
|
|
@@ -107,6 +108,49 @@ module.exports = (() => {
|
|
|
107
108
|
return transactions.findIndex((t, i, a) => t.sequence !== (i + 1) || (i !== 0 && t.date.getIsBefore(a[ i - 1 ].date)) || (i !== 0 && is.boolean(strict) && strict && t.date.getIsEqual(a[i - 1].date) && t.type.sequence < a[i - 1].type.sequence));
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
static getSwitchIndex(transactions, position) {
|
|
112
|
+
assert.argumentIsArray(transactions, 'transactions');
|
|
113
|
+
assert.argumentIsOptional(position, 'position');
|
|
114
|
+
|
|
115
|
+
let open;
|
|
116
|
+
|
|
117
|
+
if (position) {
|
|
118
|
+
open = position.snapshot.open;
|
|
119
|
+
} else {
|
|
120
|
+
open = Decimal.ZERO;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let initial;
|
|
124
|
+
|
|
125
|
+
if (open.getIsZero()) {
|
|
126
|
+
initial = null;
|
|
127
|
+
} else {
|
|
128
|
+
initial = PositionDirection.for(open);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return transactions.findIndex((t) => {
|
|
132
|
+
let quantity = t.quantity.absolute();
|
|
133
|
+
|
|
134
|
+
if (t.type.sale) {
|
|
135
|
+
quantity = quantity.opposite();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
open = open.add(quantity);
|
|
139
|
+
|
|
140
|
+
const current = PositionDirection.for(open);
|
|
141
|
+
|
|
142
|
+
if (initial !== null && initial !== current && current !== PositionDirection.EVEN) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (initial === null && !open.getIsZero()) {
|
|
147
|
+
initial = current;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return false;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
110
154
|
/**
|
|
111
155
|
* Given an instrument type, returns all valid transaction types.
|
|
112
156
|
*
|
|
@@ -684,6 +684,27 @@ module.exports = (() => {
|
|
|
684
684
|
return price;
|
|
685
685
|
}
|
|
686
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
|
+
|
|
687
708
|
/**
|
|
688
709
|
* Returns all forex symbols that are required to do currency translations.
|
|
689
710
|
*
|
|
@@ -40,20 +40,20 @@ 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
49
|
this._reportDate = reportDate || null;
|
|
48
50
|
|
|
49
|
-
this.
|
|
51
|
+
this._today = calculateToday(this._reportDate, this._exchangeStatus);
|
|
50
52
|
|
|
51
53
|
this._currentQuote = null;
|
|
52
54
|
this._previousQuote = null;
|
|
53
55
|
this._currentPrice = null;
|
|
54
56
|
|
|
55
|
-
const today = calculateToday(this._reportDate, this._exchangeStatus);
|
|
56
|
-
|
|
57
57
|
this._data = { };
|
|
58
58
|
|
|
59
59
|
this._data.basis = null;
|
|
@@ -117,7 +117,7 @@ module.exports = (() => {
|
|
|
117
117
|
this._data.fundamental = { };
|
|
118
118
|
this._data.calculating = getIsCalculating(position);
|
|
119
119
|
this._data.locked = getIsLocked(position);
|
|
120
|
-
this._data.expired = getIsExpired(position,
|
|
120
|
+
this._data.expired = getIsExpired(position, this._today);
|
|
121
121
|
|
|
122
122
|
this._quoteChangedEvent = new Event(this);
|
|
123
123
|
this._newsExistsChangedEvent = new Event(this);
|
|
@@ -127,8 +127,8 @@ module.exports = (() => {
|
|
|
127
127
|
this._portfolioChangedEvent = new Event(this);
|
|
128
128
|
this._positionItemDisposeEvent = new Event(this);
|
|
129
129
|
|
|
130
|
-
calculateStaticData(this,
|
|
131
|
-
calculatePriceData(this, null,
|
|
130
|
+
calculateStaticData(this, this._today);
|
|
131
|
+
calculatePriceData(this, null, null, this._today);
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
/**
|
|
@@ -224,6 +224,7 @@ module.exports = (() => {
|
|
|
224
224
|
/**
|
|
225
225
|
* The current price.
|
|
226
226
|
*
|
|
227
|
+
* @public
|
|
227
228
|
* @return {null|Number}
|
|
228
229
|
*/
|
|
229
230
|
get currentPrice() {
|
|
@@ -264,9 +265,7 @@ module.exports = (() => {
|
|
|
264
265
|
this._data.previousPrice = quote.previousPrice;
|
|
265
266
|
}
|
|
266
267
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
calculatePriceData(this, quote.lastPrice, today, getQuoteIsToday(quote, today));
|
|
268
|
+
calculatePriceData(this, quote.lastPrice, calculateQuoteDay(quote), this._today);
|
|
270
269
|
|
|
271
270
|
this._currentPrice = quote.lastPrice;
|
|
272
271
|
|
|
@@ -293,6 +292,8 @@ module.exports = (() => {
|
|
|
293
292
|
if (this._exchangeStatus === null || !(exchange.currentDay.getIsEqual(this._exchangeStatus.currentDay) && exchange.currentOpened === this._exchangeStatus.currentOpened)) {
|
|
294
293
|
this._exchangeStatus = exchange;
|
|
295
294
|
|
|
295
|
+
this._today = calculateToday(this._reportDate, this._exchangeStatus);
|
|
296
|
+
|
|
296
297
|
if (this._currentQuote) {
|
|
297
298
|
this.setQuote(this._currentQuote, true);
|
|
298
299
|
}
|
|
@@ -505,12 +506,6 @@ module.exports = (() => {
|
|
|
505
506
|
data.realized = snapshot.gain;
|
|
506
507
|
data.unrealized = Decimal.ZERO;
|
|
507
508
|
|
|
508
|
-
if (position.latest && position.latest.date && position.latest.date.getIsEqual(day) && position.latest.gain) {
|
|
509
|
-
data.realizedToday = position.latest.gain;
|
|
510
|
-
} else {
|
|
511
|
-
data.realizedToday = Decimal.ZERO;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
509
|
data.income = snapshot.income;
|
|
515
510
|
|
|
516
511
|
data.marketPrevious = previousSummary1 === null ? Decimal.ZERO : previousSummary1.end.value;
|
|
@@ -550,9 +545,9 @@ module.exports = (() => {
|
|
|
550
545
|
/**
|
|
551
546
|
* @private
|
|
552
547
|
* @param {PositionItem} item
|
|
553
|
-
* @param {Decimal|number} price
|
|
554
|
-
* @param {Day} day
|
|
555
|
-
* @param {
|
|
548
|
+
* @param {Decimal|number|null} price
|
|
549
|
+
* @param {Day|null} day
|
|
550
|
+
* @param {Day} today
|
|
556
551
|
*/
|
|
557
552
|
function calculatePriceData(item, price, day, today) {
|
|
558
553
|
const position = item.position;
|
|
@@ -617,19 +612,20 @@ module.exports = (() => {
|
|
|
617
612
|
// price change (e.g. friday, last week, sometime in the past when the instrument
|
|
618
613
|
// was delisted, etc).
|
|
619
614
|
|
|
620
|
-
|
|
615
|
+
const priceIsToday = day && today.getIsEqual(day);
|
|
616
|
+
|
|
617
|
+
if (priceIsToday && data.previousPrice && price) {
|
|
621
618
|
const unrealizedTodayBase = ValuationCalculator.calculate(position.instrument, data.previousPrice, snapshot.open);
|
|
622
619
|
|
|
623
620
|
unrealizedToday = market.subtract(unrealizedTodayBase);
|
|
624
|
-
|
|
625
|
-
if (data.unrealizedToday !== null) {
|
|
626
|
-
unrealizedTodayChange = unrealizedToday.subtract(data.unrealizedToday);
|
|
627
|
-
} else {
|
|
628
|
-
unrealizedTodayChange = unrealizedToday;
|
|
629
|
-
}
|
|
630
621
|
} else {
|
|
631
622
|
unrealizedToday = Decimal.ZERO;
|
|
632
|
-
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (data.unrealizedToday !== null) {
|
|
626
|
+
unrealizedTodayChange = unrealizedToday.subtract(data.unrealizedToday);
|
|
627
|
+
} else {
|
|
628
|
+
unrealizedTodayChange = unrealizedToday;
|
|
633
629
|
}
|
|
634
630
|
|
|
635
631
|
data.unrealizedToday = unrealizedToday;
|
|
@@ -638,7 +634,7 @@ module.exports = (() => {
|
|
|
638
634
|
let realizedToday;
|
|
639
635
|
let realizedTodayChange;
|
|
640
636
|
|
|
641
|
-
if (position.latest && position.latest.
|
|
637
|
+
if (position.latest && position.latest.gain && position.latest.date && day && position.latest.date.getIsEqual(day)) {
|
|
642
638
|
realizedToday = position.latest.gain;
|
|
643
639
|
} else {
|
|
644
640
|
realizedToday = Decimal.ZERO;
|
|
@@ -906,19 +902,23 @@ module.exports = (() => {
|
|
|
906
902
|
}
|
|
907
903
|
|
|
908
904
|
function calculateToday(reportDate, exchangeStatus) {
|
|
909
|
-
if (reportDate
|
|
905
|
+
if (reportDate instanceof Day) {
|
|
910
906
|
return reportDate;
|
|
911
907
|
}
|
|
912
908
|
|
|
913
|
-
if (exchangeStatus
|
|
909
|
+
if (exchangeStatus && exchangeStatus.currentDay instanceof Day) {
|
|
914
910
|
return exchangeStatus.currentDay;
|
|
915
911
|
}
|
|
916
912
|
|
|
917
913
|
return Day.getToday();
|
|
918
914
|
}
|
|
919
915
|
|
|
920
|
-
function
|
|
921
|
-
|
|
916
|
+
function calculateQuoteDay(quote) {
|
|
917
|
+
if (quote && quote.lastDay instanceof Day) {
|
|
918
|
+
return quote.lastDay;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
return null;
|
|
922
922
|
}
|
|
923
923
|
|
|
924
924
|
return PositionItem;
|