@barchart/portfolio-api-common 1.21.0 → 1.22.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,143 @@
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
+ /**
10
+ * Static utilities for calculating the average price of a position.
11
+ *
12
+ * @public
13
+ */
14
+ class AveragePriceCalculator {
15
+ constructor() {
16
+
17
+ }
18
+
19
+ /**
20
+ * Calculates the average price of a position.
21
+ *
22
+ * @public
23
+ * @static
24
+ * @param {Object} instrument
25
+ * @param {Decimal|Number} basis
26
+ * @param {Decimal|Number} quantity
27
+ * @returns {null|Decimal}
28
+ */
29
+ static calculate(instrument, basis, quantity) {
30
+ let basisToUse = null;
31
+
32
+ if (is.number(basis)) {
33
+ basisToUse = new Decimal(basis);
34
+ } else if (basis instanceof Decimal) {
35
+ basisToUse = basis;
36
+ }
37
+
38
+ const calculator = calculators.get(instrument.type);
39
+
40
+ return calculator(instrument, basisToUse, quantity);
41
+ }
42
+
43
+ toString() {
44
+ return `[AveragePriceCalculator]`;
45
+ }
46
+ }
47
+
48
+ function calculateForCash(instrument, basis, quantity) {
49
+ return Decimal.ONE;
50
+ }
51
+
52
+ function calculateForEquity(instrument, basis, quantity) {
53
+ if (basis === null) {
54
+ return null;
55
+ }
56
+
57
+ if (quantity === Decimal.ZERO || quantity === 0) {
58
+ return null;
59
+ }
60
+
61
+ return basis.divide(quantity).opposite();
62
+ }
63
+
64
+ function calculateForEquityOption(instrument, basis, quantity) {
65
+ if (basis === null) {
66
+ return null;
67
+ }
68
+
69
+ if (quantity === Decimal.ZERO || quantity === 0) {
70
+ return null;
71
+ }
72
+
73
+ const multiplier = instrument.option.multiplier;
74
+
75
+ return basis.divide(quantity).divide(multiplier).opposite();
76
+ }
77
+
78
+ function calculateForFund(instrument, basis, quantity) {
79
+ if (basis === null) {
80
+ return null;
81
+ }
82
+
83
+ if (quantity === Decimal.ZERO || quantity === 0) {
84
+ return null;
85
+ }
86
+
87
+ return basis.divide(quantity).opposite();
88
+ }
89
+
90
+ function calculateForFuture(instrument, basis, quantity) {
91
+ if (basis === null) {
92
+ return null;
93
+ }
94
+
95
+ if (quantity === Decimal.ZERO || quantity === 0) {
96
+ return null;
97
+ }
98
+
99
+ const minimumTick = instrument.future.tick;
100
+ const minimumTickValue = instrument.future.value;
101
+
102
+ return basis.divide(quantity).multiply(minimumTick).divide(minimumTickValue).opposite();
103
+ }
104
+
105
+ function calculateForFutureOption(instrument, basis, quantity) {
106
+ if (basis === null) {
107
+ return null;
108
+ }
109
+
110
+ if (quantity === Decimal.ZERO || quantity === 0) {
111
+ return null;
112
+ }
113
+
114
+ const minimumTick = instrument.option.tick;
115
+ const minimumTickValue = instrument.option.value;
116
+
117
+ return basis.divide(quantity).multiply(minimumTick).divide(minimumTickValue).opposite();
118
+ }
119
+
120
+ function calculateForOther(instrument, basis, quantity) {
121
+ if (basis === null) {
122
+ return null;
123
+ }
124
+
125
+ if (quantity === Decimal.ZERO || quantity === 0) {
126
+ return null;
127
+ }
128
+
129
+ return basis.divide(quantity).opposite();
130
+ }
131
+
132
+ const calculators = new Map();
133
+
134
+ calculators.set(InstrumentType.CASH, calculateForCash);
135
+ calculators.set(InstrumentType.EQUITY, calculateForEquity);
136
+ calculators.set(InstrumentType.EQUITY_OPTION, calculateForEquityOption);
137
+ calculators.set(InstrumentType.FUND, calculateForFund);
138
+ calculators.set(InstrumentType.FUTURE, calculateForFuture);
139
+ calculators.set(InstrumentType.FUTURE_OPTION, calculateForFutureOption);
140
+ calculators.set(InstrumentType.OTHER, calculateForOther);
141
+
142
+ return AveragePriceCalculator;
143
+ })();
@@ -9,6 +9,8 @@ const assert = require('@barchart/common-js/lang/assert'),
9
9
  const InstrumentType = require('./../data/InstrumentType'),
10
10
  TransactionType = require('./../data/TransactionType');
11
11
 
12
+ const AveragePriceCalculator = require('./../calculators/AveragePriceCalculator');
13
+
12
14
  module.exports = (() => {
13
15
  'use strict';
14
16
 
@@ -139,14 +141,7 @@ module.exports = (() => {
139
141
  let average;
140
142
 
141
143
  if (basis && open && !open.getIsZero()) {
142
- if (f.instrument.type === InstrumentType.FUTURE) {
143
- const minimumTick = f.instrument.future.tick;
144
- const minimumTickValue = f.instrument.future.value;
145
-
146
- average = basis.divide(open).multiply(minimumTick).divide(minimumTickValue).absolute();
147
- } else {
148
- average = basis.divide(open).absolute();
149
- }
144
+ average = AveragePriceCalculator.calculate(f.instrument, basis, open);
150
145
  } else {
151
146
  average = '';
152
147
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "Common JavaScript code used by Barchart's Portfolio Service",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",