@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._exchangeStatus = null;
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, today);
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, today);
131
- calculatePriceData(this, null, today, false);
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
- const today = calculateToday(this._reportDate, this._exchangeStatus);
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 {Boolean} today
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
- if (today && data.previousPrice && price) {
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
- unrealizedTodayChange = Decimal.ZERO;
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.date && position.latest.date.getIsEqual(day) && position.latest.gain) {
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 !== null) {
905
+ if (reportDate instanceof Day) {
910
906
  return reportDate;
911
907
  }
912
908
 
913
- if (exchangeStatus !== null) {
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 getQuoteIsToday(quote, today) {
921
- return quote && quote.lastDay instanceof Day && today instanceof Day && quote.lastDay.getIsEqual(today);
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "6.0.0",
3
+ "version": "6.2.0",
4
4
  "description": "Common JavaScript code used by Barchart's Portfolio Service",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",