@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
- if (price) {
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
- let unrealizedTodayBase;
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
- let unrealized;
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
- if (type === InstrumentType.FUTURE) {
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
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.19.0",
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",