@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
|
-
|
|
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
|
}
|