@barchart/portfolio-api-common 1.19.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.
|
@@ -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
|
+
})();
|
|
@@ -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,18 +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
|
-
} 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;
|
|
523
519
|
} else {
|
|
524
|
-
|
|
525
|
-
market = snapshot.open.multiply(price);
|
|
526
|
-
} else {
|
|
527
|
-
market = snapshot.value;
|
|
528
|
-
}
|
|
520
|
+
market = ValuationCalculator.calculate(position.instrument, price, snapshot.open) || snapshot.value;
|
|
529
521
|
}
|
|
530
522
|
|
|
531
523
|
let marketChange;
|
|
@@ -555,17 +547,7 @@ module.exports = (() => {
|
|
|
555
547
|
let unrealizedTodayChange;
|
|
556
548
|
|
|
557
549
|
if (data.previousPrice && price) {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
if (position.instrument.type === InstrumentType.FUTURE) {
|
|
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);
|
|
566
|
-
} else {
|
|
567
|
-
unrealizedTodayBase = snapshot.open.multiply(data.previousPrice);
|
|
568
|
-
}
|
|
550
|
+
const unrealizedTodayBase = ValuationCalculator.calculate(position.instrument, data.previousPrice, snapshot.open);
|
|
569
551
|
|
|
570
552
|
unrealizedToday = market.subtract(unrealizedTodayBase);
|
|
571
553
|
|
|
@@ -599,17 +581,7 @@ module.exports = (() => {
|
|
|
599
581
|
}
|
|
600
582
|
|
|
601
583
|
if (priceToUse !== null) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
if (position.instrument.type === InstrumentType.FUTURE) {
|
|
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);
|
|
610
|
-
} else {
|
|
611
|
-
unrealized = currentSummary.end.open.multiply(priceToUse).add(currentSummary.end.basis);
|
|
612
|
-
}
|
|
584
|
+
const unrealized = ValuationCalculator.calculate(position.instrument, priceToUse, currentSummary.end.open).add(currentSummary.end.basis);
|
|
613
585
|
|
|
614
586
|
let unrealizedChange;
|
|
615
587
|
|
|
@@ -694,15 +666,7 @@ module.exports = (() => {
|
|
|
694
666
|
let endValue;
|
|
695
667
|
|
|
696
668
|
if (overridePrice) {
|
|
697
|
-
|
|
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);
|
|
703
|
-
} else {
|
|
704
|
-
endValue = currentSummary.end.open.multiply(overridePrice);
|
|
705
|
-
}
|
|
669
|
+
endValue = ValuationCalculator.calculate(instrument, overridePrice, currentSummary.end.open);
|
|
706
670
|
} else {
|
|
707
671
|
endValue = currentSummary.end.value;
|
|
708
672
|
}
|
|
@@ -823,44 +787,5 @@ module.exports = (() => {
|
|
|
823
787
|
return snapshot;
|
|
824
788
|
}
|
|
825
789
|
|
|
826
|
-
function getFuturesValue(instrument, contracts, price) {
|
|
827
|
-
if (price || price === 0) {
|
|
828
|
-
const priceDecimal = new Decimal(price);
|
|
829
|
-
|
|
830
|
-
const minimumTick = instrument.future.tick;
|
|
831
|
-
const minimumTickValue = instrument.future.value;
|
|
832
|
-
|
|
833
|
-
return priceDecimal.divide(minimumTick).multiply(minimumTickValue).multiply(contracts);
|
|
834
|
-
} else {
|
|
835
|
-
return null;
|
|
836
|
-
}
|
|
837
|
-
}
|
|
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
|
-
|
|
865
790
|
return PositionItem;
|
|
866
791
|
})();
|