@barchart/portfolio-api-common 1.18.0 → 1.19.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.
@@ -280,6 +280,17 @@ module.exports = (() => {
280
280
  return transactionCreateFailedInstrumentCorrupt;
281
281
  }
282
282
 
283
+ /**
284
+ * The transaction failed because instrument metadata could not be resolved.
285
+ *
286
+ * @public
287
+ * @static
288
+ * @returns {FailureType}
289
+ */
290
+ static get TRANSACTION_CREATE_FAILED_INSTRUMENT_UNAVAILABLE() {
291
+ return transactionCreateFailedInstrumentUnavailable;
292
+ }
293
+
283
294
  /**
284
295
  * The transaction (of this type) cannot be deleted by a user, instead,
285
296
  * it is created and managed by the system (e.g. dividends).
@@ -449,6 +460,7 @@ module.exports = (() => {
449
460
  const transactionCreateFailedReinvestInvalid = new FailureType('TRANSACTION_CREATE_FAILED_REINVEST_INVALID', 'Unable to create transaction, short positions do not allow dividends to be reinvested.');
450
461
  const transactionCreateFailedPositionLocked = new FailureType('TRANSACTION_CREATE_FAILED_POSITION_LOCKED', 'Unable to create transaction, your {L|description} history is being recalculated. Please re-enter this transaction in a minute or two.');
451
462
  const transactionCreateFailedInstrumentCorrupt = new FailureType('TRANSACTION_CREATE_FAILED_INSTRUMENT_CORRUPT', 'Unable to create transaction, corporate action history for {U|symbol} cannot be located. The issue should be corrected within 24 to 48 hours.');
463
+ const transactionCreateFailedInstrumentUnavailable = new FailureType('TRANSACTION_CREATE_FAILED_INSTRUMENT_UNAVAILABLE', 'Unable to create transaction, no {L|description} instrument was found with the symbol {U|symbol}.');
452
464
 
453
465
  const transactionDeleteFailedOutOfSequence = new FailureType('TRANSACTION_DELETE_FAILED_OUT_OF_SEQUENCE', 'Deleting any transaction, except for the most recent, will cause transaction history to be re-written. Please confirm your intent to re-write transaction history (which could take some time and alter the historical results for this position).');
454
466
  const transactionDeleteFailedNoTransaction = new FailureType('TRANSACTION_DELETE_FAILED_NO_TRANSACTION', 'Unable to delete transaction. The referenced transaction does not exist.', false);
@@ -1,5 +1,4 @@
1
- const Enum = require('@barchart/common-js/lang/Enum'),
2
- is = require('@barchart/common-js/lang/is');
1
+ const Enum = require('@barchart/common-js/lang/Enum');
3
2
 
4
3
  module.exports = (() => {
5
4
  'use strict';
@@ -120,14 +119,14 @@ module.exports = (() => {
120
119
  }
121
120
  }
122
121
 
123
- const split = new CorporateActionType('SPLIT', 'Split', false);
124
- const dividend = new CorporateActionType('DIVIDEND', 'Dividend', false);
125
- const stockDividend = new CorporateActionType('STOCK_DIVIDEND', 'Stock Dividend', false);
126
- const symbolChange = new CorporateActionType('SYMBOL_CHANGE', 'Symbol Change', false);
127
- const nameChange = new CorporateActionType('NAME_CHANGE', 'Name Change', false);
128
- const delist = new CorporateActionType('DELIST', 'Delist', false);
129
- const merger = new CorporateActionType('MERGER', 'Merger', false);
130
- const spinoff = new CorporateActionType('SPINOFF', 'Spinoff', false);
122
+ const split = new CorporateActionType('SPLIT', 'Split');
123
+ const dividend = new CorporateActionType('DIVIDEND', 'Dividend');
124
+ const stockDividend = new CorporateActionType('STOCK_DIVIDEND', 'Stock Dividend');
125
+ const symbolChange = new CorporateActionType('SYMBOL_CHANGE', 'Symbol Change');
126
+ const nameChange = new CorporateActionType('NAME_CHANGE', 'Name Change');
127
+ const delist = new CorporateActionType('DELIST', 'Delist');
128
+ const merger = new CorporateActionType('MERGER', 'Merger');
129
+ const spinoff = new CorporateActionType('SPINOFF', 'Spinoff');
131
130
 
132
131
  return CorporateActionType;
133
132
  })();
@@ -173,6 +173,26 @@ module.exports = (() => {
173
173
  return this._roundQuantity;
174
174
  }
175
175
 
176
+ /**
177
+ * Indicates if the instrument is a futures contract.
178
+ *
179
+ * @public
180
+ * @returns {boolean}
181
+ */
182
+ get future() {
183
+ return this === future;
184
+ }
185
+
186
+ /**
187
+ * Indicates if the instrument is an option contract.
188
+ *
189
+ * @public
190
+ * @returns {boolean}
191
+ */
192
+ get option() {
193
+ return this === equityOption || this === futureOption;
194
+ }
195
+
176
196
  /**
177
197
  * Generates an identifier for the instrument.
178
198
  *
@@ -212,6 +232,17 @@ module.exports = (() => {
212
232
  return equity;
213
233
  }
214
234
 
235
+ /**
236
+ * An option on equity shares.
237
+ *
238
+ * @public
239
+ * @static
240
+ * @returns {InstrumentType}
241
+ */
242
+ static get EQUITY_OPTION() {
243
+ return equityOption;
244
+ }
245
+
215
246
  /**
216
247
  * A mutual fund.
217
248
  *
@@ -234,6 +265,17 @@ module.exports = (() => {
234
265
  return future;
235
266
  }
236
267
 
268
+ /**
269
+ * An option on a futures contract.
270
+ *
271
+ * @public
272
+ * @static
273
+ * @returns {InstrumentType}
274
+ */
275
+ static get FUTURE_OPTION() {
276
+ return futureOption;
277
+ }
278
+
237
279
  /**
238
280
  * An undefined asset (e.g. a house, or a collectible, or a salvaged alien spaceship).
239
281
  *
@@ -281,10 +323,14 @@ module.exports = (() => {
281
323
 
282
324
  if (code === 1 || code === 6 || code === 7 || code === 11) {
283
325
  return InstrumentType.EQUITY;
326
+ } else if (code === 34) {
327
+ return InstrumentType.EQUITY_OPTION;
284
328
  } else if (code === 5 || code == 15) {
285
329
  return InstrumentType.FUND;
286
330
  } else if (code === 2) {
287
331
  return InstrumentType.FUTURE;
332
+ } else if (code === 12) {
333
+ return InstrumentType.FUTURE_OPTION;
288
334
  } else {
289
335
  throw new Error(`Unable to determine InstrumentType for [ ${code} ]`);
290
336
  }
@@ -297,8 +343,10 @@ module.exports = (() => {
297
343
 
298
344
  const cash = new InstrumentType('CASH', 'cash', 'Cash', true, false, false, true, false, false, true, false, false, false, instrument => `BARCHART-${instrument.type.code}-${instrument.currency.code}`);
299
345
  const equity = new InstrumentType('EQUITY', 'equity', 'Equities', false, true, true, false, true, true, true, true, true, true, instrument => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
346
+ const equityOption = new InstrumentType('EQUITY_OPTION', 'equity option', 'Equity Option', false, false, true, false, true, false, false, false, false, true, instrument => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
300
347
  const fund = new InstrumentType('FUND', 'mutual fund', 'Funds', false, true, false, false, true, true, true,false, true, true, instrument => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
301
348
  const future = new InstrumentType('FUTURE', 'futures contract', 'Futures', false, false, true, false, true, false, false, false, false, true, instrument => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
349
+ const futureOption = new InstrumentType('FUTURE_OPTION', 'futures option', 'Futures Option', false, false, true, false, true, false, false, false, false, true, instrument => `BARCHART-${instrument.type.code}-${instrument.symbol.barchart}`);
302
350
  const other = new InstrumentType('OTHER', 'other', 'Other', false, false, false, false, false, false, true,false, true, true, instrument => `BARCHART-${instrument.type.code}-${uuid.v4()}`);
303
351
 
304
352
  return InstrumentType;
@@ -0,0 +1,61 @@
1
+ const Enum = require('@barchart/common-js/lang/Enum');
2
+
3
+ module.exports = (() => {
4
+ 'use strict';
5
+
6
+ /**
7
+ * Indicates whether an option conveys the right to buy or
8
+ * sell the underlying instrument.
9
+ *
10
+ * @public
11
+ * @extends {Enum}
12
+ * @param {String} code
13
+ * @param {String} description
14
+ */
15
+ class OptionSide extends Enum {
16
+ constructor(code, description) {
17
+ super(code, description);
18
+ }
19
+
20
+ /**
21
+ * The right to buy the underlying instrument.
22
+ *
23
+ * @public
24
+ * @static
25
+ * @returns {OptionSide}
26
+ */
27
+ static get CALL() {
28
+ return call;
29
+ }
30
+
31
+ /**
32
+ * The right to sell the underlying instrument.
33
+ *
34
+ * @public
35
+ * @static
36
+ * @returns {OptionSide}
37
+ */
38
+ static get PUT() {
39
+ return put;
40
+ }
41
+
42
+ /**
43
+ * @public
44
+ * @static
45
+ * @param {String} code
46
+ * @returns {OptionSide|null}
47
+ */
48
+ static parse(code) {
49
+ return Enum.fromCode(OptionSide, code);
50
+ }
51
+
52
+ toString() {
53
+ return `[OptionSide (code=${this.code})]`;
54
+ }
55
+ }
56
+
57
+ const put = new OptionSide('PUT', 'Put');
58
+ const call = new OptionSide('CALL', 'Call');
59
+
60
+ return OptionSide;
61
+ })();
@@ -250,6 +250,11 @@ module.exports = (() => {
250
250
  associateTypes(InstrumentType.EQUITY, TransactionType.SPINOFF, false);
251
251
  associateTypes(InstrumentType.EQUITY, TransactionType.SPINOFF_OPEN, false);
252
252
 
253
+ associateTypes(InstrumentType.EQUITY_OPTION, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
254
+ associateTypes(InstrumentType.EQUITY_OPTION, TransactionType.SELL, true, [ PositionDirection.LONG ]);
255
+ associateTypes(InstrumentType.EQUITY_OPTION, TransactionType.SELL_SHORT, true, [ PositionDirection.SHORT, PositionDirection.EVEN ]);
256
+ associateTypes(InstrumentType.EQUITY_OPTION, TransactionType.BUY_SHORT, true, [ PositionDirection.SHORT ]);
257
+
253
258
  associateTypes(InstrumentType.FUND, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
254
259
  associateTypes(InstrumentType.FUND, TransactionType.SELL, true, [ PositionDirection.LONG ]);
255
260
  associateTypes(InstrumentType.FUND, TransactionType.FEE, true, [ PositionDirection.LONG ]);
@@ -268,6 +273,11 @@ module.exports = (() => {
268
273
  associateTypes(InstrumentType.FUTURE, TransactionType.SELL_SHORT, true, [ PositionDirection.SHORT, PositionDirection.EVEN ]);
269
274
  associateTypes(InstrumentType.FUTURE, TransactionType.BUY_SHORT, true, [ PositionDirection.SHORT ]);
270
275
 
276
+ associateTypes(InstrumentType.FUTURE_OPTION, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
277
+ associateTypes(InstrumentType.FUTURE_OPTION, TransactionType.SELL, true, [ PositionDirection.LONG ]);
278
+ associateTypes(InstrumentType.FUTURE_OPTION, TransactionType.SELL_SHORT, true, [ PositionDirection.SHORT, PositionDirection.EVEN ]);
279
+ associateTypes(InstrumentType.FUTURE_OPTION, TransactionType.BUY_SHORT, true, [ PositionDirection.SHORT ]);
280
+
271
281
  associateTypes(InstrumentType.OTHER, TransactionType.BUY, true, [ PositionDirection.LONG, PositionDirection.EVEN ]);
272
282
  associateTypes(InstrumentType.OTHER, TransactionType.SELL, true, [ PositionDirection.LONG ]);
273
283
  associateTypes(InstrumentType.OTHER, TransactionType.INCOME, true, [ PositionDirection.LONG ]);
@@ -295,6 +305,10 @@ module.exports = (() => {
295
305
  associateDirections(InstrumentType.EQUITY, PositionDirection.LONG);
296
306
  associateDirections(InstrumentType.EQUITY, PositionDirection.SHORT);
297
307
 
308
+ associateDirections(InstrumentType.EQUITY_OPTION, PositionDirection.EVEN);
309
+ associateDirections(InstrumentType.EQUITY_OPTION, PositionDirection.LONG);
310
+ associateDirections(InstrumentType.EQUITY_OPTION, PositionDirection.SHORT);
311
+
298
312
  associateDirections(InstrumentType.FUND, PositionDirection.EVEN);
299
313
  associateDirections(InstrumentType.FUND, PositionDirection.LONG);
300
314
 
@@ -302,6 +316,10 @@ module.exports = (() => {
302
316
  associateDirections(InstrumentType.FUTURE, PositionDirection.LONG);
303
317
  associateDirections(InstrumentType.FUTURE, PositionDirection.SHORT);
304
318
 
319
+ associateDirections(InstrumentType.FUTURE_OPTION, PositionDirection.EVEN);
320
+ associateDirections(InstrumentType.FUTURE_OPTION, PositionDirection.LONG);
321
+ associateDirections(InstrumentType.FUTURE_OPTION, PositionDirection.SHORT);
322
+
305
323
  associateDirections(InstrumentType.OTHER, PositionDirection.EVEN);
306
324
  associateDirections(InstrumentType.OTHER, PositionDirection.LONG);
307
325
 
@@ -516,6 +516,10 @@ module.exports = (() => {
516
516
  market = snapshot.open;
517
517
  } else if (position.instrument.type === InstrumentType.FUTURE) {
518
518
  market = getFuturesValue(position.instrument, snapshot.open, price) || snapshot.value;
519
+ } else if (position.instrument.type === InstrumentType.FUTURE_OPTION) {
520
+ market = getFuturesOptionValue(position.instrument, snapshot.open, price) || snapshot.value;
521
+ } else if (position.instrument.type === InstrumentType.EQUITY_OPTION) {
522
+ market = getEquityOptionValue(position.instrument, snapshot.open, price) || snapshot.value;
519
523
  } else {
520
524
  if (price) {
521
525
  market = snapshot.open.multiply(price);
@@ -555,6 +559,10 @@ module.exports = (() => {
555
559
 
556
560
  if (position.instrument.type === InstrumentType.FUTURE) {
557
561
  unrealizedTodayBase = getFuturesValue(position.instrument, snapshot.open, data.previousPrice);
562
+ } else if (position.instrument.type === InstrumentType.FUTURE_OPTION) {
563
+ unrealizedTodayBase = getFuturesOptionValue(position.instrument, snapshot.open, data.previousPrice);
564
+ } else if (position.instrument.type === InstrumentType.EQUITY_OPTION) {
565
+ unrealizedTodayBase = getEquityOptionValue(position.instrument, snapshot.open, data.previousPrice);
558
566
  } else {
559
567
  unrealizedTodayBase = snapshot.open.multiply(data.previousPrice);
560
568
  }
@@ -595,6 +603,10 @@ module.exports = (() => {
595
603
 
596
604
  if (position.instrument.type === InstrumentType.FUTURE) {
597
605
  unrealized = getFuturesValue(position.instrument, currentSummary.end.open, priceToUse).add(currentSummary.end.basis);
606
+ } else if (position.instrument.type === InstrumentType.FUTURE_OPTION) {
607
+ unrealized = getFuturesOptionValue(position.instrument, currentSummary.end.open, priceToUse).add(currentSummary.end.basis);
608
+ } else if (position.instrument.type === InstrumentType.EQUITY_OPTION) {
609
+ unrealized = getEquityOptionValue(position.instrument, currentSummary.end.open, priceToUse).add(currentSummary.end.basis);
598
610
  } else {
599
611
  unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
600
612
  }
@@ -684,6 +696,10 @@ module.exports = (() => {
684
696
  if (overridePrice) {
685
697
  if (type === InstrumentType.FUTURE) {
686
698
  endValue = getFuturesValue(instrument, currentSummary.end.open, overridePrice);
699
+ } else if (type === InstrumentType.FUTURE_OPTION) {
700
+ endValue = getFuturesOptionValue(instrument, currentSummary.end.open, overridePrice);
701
+ } else if (type === InstrumentType.EQUITY_OPTION) {
702
+ endValue = getEquityOptionValue(instrument, currentSummary.end.open, overridePrice);
687
703
  } else {
688
704
  endValue = currentSummary.end.open.multiply(overridePrice);
689
705
  }
@@ -820,5 +836,31 @@ module.exports = (() => {
820
836
  }
821
837
  }
822
838
 
839
+ function getFuturesOptionValue(instrument, contracts, price) {
840
+ if (price || price === 0) {
841
+ const priceDecimal = new Decimal(price);
842
+
843
+ const minimumTick = instrument.option.tick;
844
+ const minimumTickValue = instrument.option.value;
845
+
846
+ const multiplier = instrument.option.multiplier;
847
+
848
+ return priceDecimal.divide(minimumTick).multiply(minimumTickValue).multiply(multiplier).multiply(contracts);
849
+ } else {
850
+ return null;
851
+ }
852
+ }
853
+
854
+ function getEquityOptionValue(instrument, contracts, price) {
855
+ if (price || price === 0) {
856
+ const priceDecimal = new Decimal(price);
857
+ const multiplier = instrument.option.multiplier;
858
+
859
+ return priceDecimal.multiply(contracts).multiply(multiplier);
860
+ } else {
861
+ return null;
862
+ }
863
+ }
864
+
823
865
  return PositionItem;
824
866
  })();
@@ -5,6 +5,7 @@ const Currency = require('@barchart/common-js/lang/Currency'),
5
5
  SchemaBuilder = require('@barchart/common-js/serialization/json/builders/SchemaBuilder');
6
6
 
7
7
  const InstrumentType = require('./../data/InstrumentType'),
8
+ OptionSide = require('./../data/OptionSide'),
8
9
  PositionDirection = require('./../data/PositionDirection'),
9
10
  ValuationType = require('./../data/ValuationType');
10
11
 
@@ -95,7 +96,11 @@ module.exports = (() => {
95
96
  .withField('instrument.future.tick', DataType.DECIMAL, true)
96
97
  .withField('instrument.future.value', DataType.DECIMAL, true)
97
98
  .withField('instrument.option.expiration', DataType.DAY, true)
99
+ .withField('instrument.option.side', DataType.forEnum(OptionSide, 'OptionSide'), true)
98
100
  .withField('instrument.option.strike', DataType.DECIMAL, true)
101
+ .withField('instrument.option.multiplier', DataType.DECIMAL, true)
102
+ .withField('instrument.option.tick', DataType.DECIMAL, true)
103
+ .withField('instrument.option.value', DataType.DECIMAL, true)
99
104
  .withField('instrument.symbol.barchart', DataType.STRING, true)
100
105
  .withField('instrument.symbol.display', DataType.STRING, true)
101
106
  .withField('position', DataType.STRING)
@@ -136,7 +141,11 @@ module.exports = (() => {
136
141
  .withField('instrument.future.tick', DataType.DECIMAL, true)
137
142
  .withField('instrument.future.value', DataType.DECIMAL, true)
138
143
  .withField('instrument.option.expiration', DataType.DAY, true)
144
+ .withField('instrument.option.side', DataType.forEnum(OptionSide, 'OptionSide'), true)
139
145
  .withField('instrument.option.strike', DataType.DECIMAL, true)
146
+ .withField('instrument.option.multiplier', DataType.DECIMAL, true)
147
+ .withField('instrument.option.tick', DataType.DECIMAL, true)
148
+ .withField('instrument.option.value', DataType.DECIMAL, true)
140
149
  .withField('instrument.symbol.barchart', DataType.STRING, true)
141
150
  .withField('instrument.symbol.display', DataType.STRING, true)
142
151
  .withField('position', DataType.STRING)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "Common JavaScript code used by Barchart's Portfolio Service",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@barchart/common-js": "^4.27.0",
19
- "@barchart/marketdata-api-js": "^6.1.0",
19
+ "@barchart/marketdata-api-js": "^6.1.1",
20
20
  "uuid": "^8.3.2"
21
21
  },
22
22
  "devDependencies": {