@barchart/portfolio-api-common 1.18.0 → 1.20.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.
- package/lib/api/failures/PortfolioFailureType.js +12 -0
- package/lib/calculators/ValuationCalculator.js +84 -0
- package/lib/data/CorporateActionType.js +9 -10
- package/lib/data/InstrumentType.js +48 -0
- package/lib/data/OptionSide.js +61 -0
- package/lib/data/TransactionValidator.js +18 -0
- package/lib/processing/PositionItem.js +6 -39
- package/lib/serialization/PositionSchema.js +9 -0
- package/package.json +2 -2
|
@@ -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);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const Decimal = require('@barchart/common-js/lang/Decimal'),
|
|
2
|
+
is = require('@barchart/common-js/lang/is');
|
|
3
|
+
|
|
4
|
+
const InstrumentType = require('./../data/InstrumentType');
|
|
5
|
+
|
|
6
|
+
module.exports = (() => {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
class ValuationCalculator {
|
|
10
|
+
constructor() {
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static calculate(instrument, price, quantity) {
|
|
15
|
+
let priceToUse = null;
|
|
16
|
+
|
|
17
|
+
if (is.number(price)) {
|
|
18
|
+
priceToUse = new Decimal(price);
|
|
19
|
+
} else if (price instanceof Decimal) {
|
|
20
|
+
priceToUse = price;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (priceToUse === null) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const calculator = calculators.get(instrument.type);
|
|
28
|
+
|
|
29
|
+
return calculator(instrument, priceToUse, quantity);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
toString() {
|
|
33
|
+
return `[ValuationCalculator]`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function calculateForCash(instrument, price, quantity) {
|
|
38
|
+
return new Decimal(quantity);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function calculateForEquity(instrument, price, quantity) {
|
|
42
|
+
return price.multiply(quantity);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function calculateForEquityOption(instrument, price, quantity) {
|
|
46
|
+
const priceMultiplier = instrument.option.multiplier;
|
|
47
|
+
|
|
48
|
+
return price.multiply(priceMultiplier).multiply(quantity);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function calculateForFund(instrument, price, quantity) {
|
|
52
|
+
return price.multiply(quantity);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function calculateForFuture(instrument, price, quantity) {
|
|
56
|
+
const minimumTick = instrument.future.tick;
|
|
57
|
+
const minimumTickValue = instrument.future.value;
|
|
58
|
+
|
|
59
|
+
return price.divide(minimumTick).multiply(minimumTickValue).multiply(quantity);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function calculateForFutureOption(instrument, price, quantity) {
|
|
63
|
+
const minimumTick = instrument.option.tick;
|
|
64
|
+
const minimumTickValue = instrument.option.value;
|
|
65
|
+
|
|
66
|
+
return price.divide(minimumTick).multiply(minimumTickValue).multiply(quantity);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function calculateForOther(instrument, price, quantity) {
|
|
70
|
+
return price.multiply(quantity);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const calculators = new Map();
|
|
74
|
+
|
|
75
|
+
calculators.set(InstrumentType.CASH, calculateForCash);
|
|
76
|
+
calculators.set(InstrumentType.EQUITY, calculateForEquity);
|
|
77
|
+
calculators.set(InstrumentType.EQUITY_OPTION, calculateForEquityOption);
|
|
78
|
+
calculators.set(InstrumentType.FUND, calculateForFund);
|
|
79
|
+
calculators.set(InstrumentType.FUTURE, calculateForFuture);
|
|
80
|
+
calculators.set(InstrumentType.FUTURE_OPTION, calculateForFutureOption);
|
|
81
|
+
calculators.set(InstrumentType.OTHER, calculateForOther);
|
|
82
|
+
|
|
83
|
+
return ValuationCalculator;
|
|
84
|
+
})();
|
|
@@ -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'
|
|
124
|
-
const dividend = new CorporateActionType('DIVIDEND', 'Dividend'
|
|
125
|
-
const stockDividend = new CorporateActionType('STOCK_DIVIDEND', 'Stock Dividend'
|
|
126
|
-
const symbolChange = new CorporateActionType('SYMBOL_CHANGE', 'Symbol Change'
|
|
127
|
-
const nameChange = new CorporateActionType('NAME_CHANGE', 'Name Change'
|
|
128
|
-
const delist = new CorporateActionType('DELIST', 'Delist'
|
|
129
|
-
const merger = new CorporateActionType('MERGER', 'Merger'
|
|
130
|
-
const spinoff = new CorporateActionType('SPINOFF', 'Spinoff'
|
|
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
|
|
|
@@ -8,6 +8,8 @@ const assert = require('@barchart/common-js/lang/assert'),
|
|
|
8
8
|
const InstrumentType = require('./../data/InstrumentType'),
|
|
9
9
|
PositionDirection = require('./../data/PositionDirection');
|
|
10
10
|
|
|
11
|
+
const ValuationCalculator = require('./../calculators/ValuationCalculator');
|
|
12
|
+
|
|
11
13
|
module.exports = (() => {
|
|
12
14
|
'use strict';
|
|
13
15
|
|
|
@@ -514,14 +516,8 @@ module.exports = (() => {
|
|
|
514
516
|
market = snapshot.value;
|
|
515
517
|
} else if (position.instrument.type === InstrumentType.CASH) {
|
|
516
518
|
market = snapshot.open;
|
|
517
|
-
} else if (position.instrument.type === InstrumentType.FUTURE) {
|
|
518
|
-
market = getFuturesValue(position.instrument, snapshot.open, price) || snapshot.value;
|
|
519
519
|
} else {
|
|
520
|
-
|
|
521
|
-
market = snapshot.open.multiply(price);
|
|
522
|
-
} else {
|
|
523
|
-
market = snapshot.value;
|
|
524
|
-
}
|
|
520
|
+
market = ValuationCalculator.calculate(position.instrument, price, snapshot.open) || snapshot.value;
|
|
525
521
|
}
|
|
526
522
|
|
|
527
523
|
let marketChange;
|
|
@@ -551,13 +547,7 @@ module.exports = (() => {
|
|
|
551
547
|
let unrealizedTodayChange;
|
|
552
548
|
|
|
553
549
|
if (data.previousPrice && price) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if (position.instrument.type === InstrumentType.FUTURE) {
|
|
557
|
-
unrealizedTodayBase = getFuturesValue(position.instrument, snapshot.open, data.previousPrice);
|
|
558
|
-
} else {
|
|
559
|
-
unrealizedTodayBase = snapshot.open.multiply(data.previousPrice);
|
|
560
|
-
}
|
|
550
|
+
const unrealizedTodayBase = ValuationCalculator.calculate(position.instrument, data.previousPrice, snapshot.open);
|
|
561
551
|
|
|
562
552
|
unrealizedToday = market.subtract(unrealizedTodayBase);
|
|
563
553
|
|
|
@@ -591,13 +581,7 @@ module.exports = (() => {
|
|
|
591
581
|
}
|
|
592
582
|
|
|
593
583
|
if (priceToUse !== null) {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
if (position.instrument.type === InstrumentType.FUTURE) {
|
|
597
|
-
unrealized = getFuturesValue(position.instrument, currentSummary.end.open, priceToUse).add(currentSummary.end.basis);
|
|
598
|
-
} else {
|
|
599
|
-
unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
|
|
600
|
-
}
|
|
584
|
+
const unrealized = ValuationCalculator.calculate(position.instrument, priceToUse, currentSummary.end.open).add(currentSummary.end.basis);
|
|
601
585
|
|
|
602
586
|
let unrealizedChange;
|
|
603
587
|
|
|
@@ -682,11 +666,7 @@ module.exports = (() => {
|
|
|
682
666
|
let endValue;
|
|
683
667
|
|
|
684
668
|
if (overridePrice) {
|
|
685
|
-
|
|
686
|
-
endValue = getFuturesValue(instrument, currentSummary.end.open, overridePrice);
|
|
687
|
-
} else {
|
|
688
|
-
endValue = currentSummary.end.open.multiply(overridePrice);
|
|
689
|
-
}
|
|
669
|
+
endValue = ValuationCalculator.calculate(instrument, overridePrice, currentSummary.end.open);
|
|
690
670
|
} else {
|
|
691
671
|
endValue = currentSummary.end.value;
|
|
692
672
|
}
|
|
@@ -807,18 +787,5 @@ module.exports = (() => {
|
|
|
807
787
|
return snapshot;
|
|
808
788
|
}
|
|
809
789
|
|
|
810
|
-
function getFuturesValue(instrument, contracts, price) {
|
|
811
|
-
if (price || price === 0) {
|
|
812
|
-
const priceDecimal = new Decimal(price);
|
|
813
|
-
|
|
814
|
-
const minimumTick = instrument.future.tick;
|
|
815
|
-
const minimumTickValue = instrument.future.value;
|
|
816
|
-
|
|
817
|
-
return priceDecimal.divide(minimumTick).multiply(minimumTickValue).multiply(contracts);
|
|
818
|
-
} else {
|
|
819
|
-
return null;
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
|
|
823
790
|
return PositionItem;
|
|
824
791
|
})();
|
|
@@ -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.
|
|
3
|
+
"version": "1.20.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.
|
|
19
|
+
"@barchart/marketdata-api-js": "^6.1.1",
|
|
20
20
|
"uuid": "^8.3.2"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|