@barchart/portfolio-api-common 1.0.15 → 1.0.19
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/data/PositionSummaryFrame.js +83 -9
- package/lib/serialization/PortfolioSchema.js +3 -0
- package/lib/serialization/TransactionSchema.js +220 -0
- package/package.json +2 -1
- package/test/SpecRunner.js +3515 -1
- package/test/specs/data/PositionSummaryFrameSpec.js +228 -0
- package/lib/data/PortfolioType.js +0 -126
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const array = require('@barchart/common-js/lang/array'),
|
|
2
|
+
assert = require('@barchart/common-js/lang/assert'),
|
|
3
|
+
Day = require('@barchart/common-js/lang/Day'),
|
|
4
|
+
Enum = require('@barchart/common-js/lang/Enum'),
|
|
5
|
+
is = require('@barchart/common-js/lang/is');
|
|
3
6
|
|
|
4
7
|
module.exports = (() => {
|
|
5
8
|
'use strict';
|
|
@@ -9,13 +12,23 @@ module.exports = (() => {
|
|
|
9
12
|
*
|
|
10
13
|
* @public
|
|
11
14
|
* @extends {Enum}
|
|
12
|
-
* @param {String} description
|
|
13
15
|
* @param {String} code
|
|
14
|
-
* @param {
|
|
16
|
+
* @param {String} description
|
|
17
|
+
* @param {Function} rangeCalculator
|
|
15
18
|
*/
|
|
16
19
|
class PositionSummaryFrame extends Enum {
|
|
17
|
-
constructor(code, description) {
|
|
20
|
+
constructor(code, description, rangeCalculator) {
|
|
18
21
|
super(code, description);
|
|
22
|
+
|
|
23
|
+
assert.argumentIsRequired(rangeCalculator, 'rangeCalculator', Function);
|
|
24
|
+
|
|
25
|
+
this._rangeCalculator = rangeCalculator;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getRanges(transactions) {
|
|
29
|
+
assert.argumentIsArray(transactions, 'transactions');
|
|
30
|
+
|
|
31
|
+
return this._rangeCalculator(transactions);
|
|
19
32
|
}
|
|
20
33
|
|
|
21
34
|
/**
|
|
@@ -63,10 +76,71 @@ module.exports = (() => {
|
|
|
63
76
|
}
|
|
64
77
|
}
|
|
65
78
|
|
|
66
|
-
const yearly = new PositionSummaryFrame('
|
|
67
|
-
const quarterly = new PositionSummaryFrame('QUARTER', 'quarter');
|
|
68
|
-
const monthly = new PositionSummaryFrame('MONTH', 'month');
|
|
69
|
-
const ytd = new PositionSummaryFrame('YTD', 'year-to-date');
|
|
79
|
+
const yearly = new PositionSummaryFrame('YEARLY', 'year', getYearlyRanges);
|
|
80
|
+
const quarterly = new PositionSummaryFrame('QUARTER', 'quarter', getQuarterlyRanges);
|
|
81
|
+
const monthly = new PositionSummaryFrame('MONTH', 'month', getMonthlyRanges);
|
|
82
|
+
const ytd = new PositionSummaryFrame('YTD', 'year-to-date', getYearToDateRanges);
|
|
83
|
+
|
|
84
|
+
function getRange(start, end) {
|
|
85
|
+
return {
|
|
86
|
+
start: start,
|
|
87
|
+
end: end
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getYearlyRanges(transactions) {
|
|
92
|
+
const ranges = [ ];
|
|
93
|
+
|
|
94
|
+
if (transactions.length !== 0) {
|
|
95
|
+
const first = array.first(transactions);
|
|
96
|
+
const last = array.last(transactions);
|
|
97
|
+
|
|
98
|
+
const firstDate = first.date;
|
|
99
|
+
const lastDate = last.date;
|
|
100
|
+
|
|
101
|
+
let lastYear;
|
|
102
|
+
|
|
103
|
+
if (last.snapshot.open.getIsZero()) {
|
|
104
|
+
lastYear = last.date.year + 1;
|
|
105
|
+
} else {
|
|
106
|
+
lastYear = Day.getToday().year;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
for (let end = new Day(firstDate.year, 12, 31); end.year < lastYear; end = end.addYears(1)) {
|
|
110
|
+
ranges.push(getRange(end.subtractYears(1), end));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return ranges;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getQuarterlyRanges(transactions) {
|
|
118
|
+
return [ ];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function getMonthlyRanges(transactions) {
|
|
122
|
+
return [ ];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getYearToDateRanges(transactions) {
|
|
126
|
+
const ranges = [ ];
|
|
127
|
+
|
|
128
|
+
if (transactions.length !== 0) {
|
|
129
|
+
const first = array.first(transactions);
|
|
130
|
+
const last = array.last(transactions);
|
|
131
|
+
|
|
132
|
+
const currentYear = Day.getToday().year;
|
|
133
|
+
|
|
134
|
+
if (!last.snapshot.open.getIsZero() || last.date.year === currentYear) {
|
|
135
|
+
let end = new Day(Day.getToday().year, 12, 31);
|
|
136
|
+
let start = end.subtractYears(1);
|
|
137
|
+
|
|
138
|
+
ranges.push(getRange(start, end));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return ranges;
|
|
143
|
+
}
|
|
70
144
|
|
|
71
145
|
return PositionSummaryFrame;
|
|
72
146
|
})();
|
|
@@ -61,6 +61,7 @@ module.exports = (() => {
|
|
|
61
61
|
.withField('legacy.warnings', DataType.NUMBER, true)
|
|
62
62
|
.withField('legacy.drops', DataType.NUMBER, true)
|
|
63
63
|
.withField('system.version', DataType.NUMBER, true)
|
|
64
|
+
.withField('data', DataType.OBJECT, true)
|
|
64
65
|
.schema
|
|
65
66
|
);
|
|
66
67
|
|
|
@@ -72,6 +73,7 @@ module.exports = (() => {
|
|
|
72
73
|
.withField('defaults.currency', DataType.forEnum(Currency, 'Currency'))
|
|
73
74
|
.withField('defaults.reinvest', DataType.BOOLEAN, true)
|
|
74
75
|
.withField('defaults.valuation', DataType.forEnum(ValuationType, 'ValuationType'))
|
|
76
|
+
.withField('data', DataType.OBJECT, true)
|
|
75
77
|
.schema
|
|
76
78
|
);
|
|
77
79
|
|
|
@@ -82,6 +84,7 @@ module.exports = (() => {
|
|
|
82
84
|
.withField('defaults.currency', DataType.forEnum(Currency, 'Currency'))
|
|
83
85
|
.withField('defaults.reinvest', DataType.BOOLEAN, true)
|
|
84
86
|
.withField('defaults.valuation', DataType.forEnum(ValuationType, 'ValuationType'))
|
|
87
|
+
.withField('data', DataType.OBJECT, true)
|
|
85
88
|
.schema
|
|
86
89
|
);
|
|
87
90
|
|
|
@@ -30,6 +30,79 @@ module.exports = (() => {
|
|
|
30
30
|
return complete;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
static get BUY() {
|
|
34
|
+
return buy;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static get SELL() {
|
|
38
|
+
return sell;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static get BUY_SHORT() {
|
|
42
|
+
return buyShort;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static get SELL_SHORT() {
|
|
46
|
+
return sellShort;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static get DIVIDEND() {
|
|
50
|
+
return dividend;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static get DIVIDEND_REINVEST() {
|
|
54
|
+
return dividendReinvest;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static get DIVIDEND_STOCK() {
|
|
58
|
+
return dividendStock;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static get DISTRIBUTION_CASH() {
|
|
62
|
+
return distributionCash;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static get DISTRIBUTION_FUND() {
|
|
66
|
+
return distributionFund;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static get SPLIT() {
|
|
70
|
+
return split;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static get FEE() {
|
|
74
|
+
return fee;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static get FEE_UNITS() {
|
|
78
|
+
return feeUnits;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static get DEPOSIT() {
|
|
82
|
+
return deposit;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static get WITHDRAWAL() {
|
|
86
|
+
return withdrawal;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static get DEBIT() {
|
|
90
|
+
return debit;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static get CREDIT() {
|
|
94
|
+
return credit;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static get VALUATION() {
|
|
98
|
+
return valuation;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static get INCOME() {
|
|
102
|
+
return income;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
33
106
|
toString() {
|
|
34
107
|
return '[TransactionSchema]';
|
|
35
108
|
}
|
|
@@ -75,5 +148,152 @@ module.exports = (() => {
|
|
|
75
148
|
.schema
|
|
76
149
|
);
|
|
77
150
|
|
|
151
|
+
const buy = new TransactionSchema(SchemaBuilder.withName('B')
|
|
152
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
153
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
154
|
+
.withField('date', DataType.DAY)
|
|
155
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
156
|
+
.withField('price', DataType.DECIMAL)
|
|
157
|
+
.withField('quantity', DataType.DECIMAL)
|
|
158
|
+
.schema
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const sell = new TransactionSchema(SchemaBuilder.withName('S')
|
|
162
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
163
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
164
|
+
.withField('date', DataType.DAY)
|
|
165
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
166
|
+
.schema
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
const buyShort = new TransactionSchema(SchemaBuilder.withName('BS')
|
|
170
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
171
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
172
|
+
.withField('date', DataType.DAY)
|
|
173
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
174
|
+
.schema
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const sellShort = new TransactionSchema(SchemaBuilder.withName('SS')
|
|
178
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
179
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
180
|
+
.withField('date', DataType.DAY)
|
|
181
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
182
|
+
.schema
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
const dividend = new TransactionSchema(SchemaBuilder.withName('DV')
|
|
186
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
187
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
188
|
+
.withField('date', DataType.DAY)
|
|
189
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
190
|
+
.schema
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const dividendReinvest = new TransactionSchema(SchemaBuilder.withName('DX')
|
|
194
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
195
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
196
|
+
.withField('date', DataType.DAY)
|
|
197
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
198
|
+
.schema
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const dividendStock = new TransactionSchema(SchemaBuilder.withName('DS')
|
|
202
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
203
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
204
|
+
.withField('date', DataType.DAY)
|
|
205
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
206
|
+
.schema
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const distributionCash = new TransactionSchema(SchemaBuilder.withName('DC')
|
|
210
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
211
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
212
|
+
.withField('date', DataType.DAY)
|
|
213
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
214
|
+
.schema
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const distributionFund = new TransactionSchema(SchemaBuilder.withName('DF')
|
|
218
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
219
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
220
|
+
.withField('date', DataType.DAY)
|
|
221
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
222
|
+
.schema
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const split = new TransactionSchema(SchemaBuilder.withName('SP')
|
|
226
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
227
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
228
|
+
.withField('date', DataType.DAY)
|
|
229
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
230
|
+
.schema
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
const fee = new TransactionSchema(SchemaBuilder.withName('F')
|
|
234
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
235
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
236
|
+
.withField('date', DataType.DAY)
|
|
237
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
238
|
+
.schema
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
const feeUnits = new TransactionSchema(SchemaBuilder.withName('FU')
|
|
242
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
243
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
244
|
+
.withField('date', DataType.DAY)
|
|
245
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
246
|
+
.schema
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
const deposit = new TransactionSchema(SchemaBuilder.withName('D')
|
|
250
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
251
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
252
|
+
.withField('date', DataType.DAY)
|
|
253
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
254
|
+
.schema
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const withdrawal = new TransactionSchema(SchemaBuilder.withName('W')
|
|
258
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
259
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
260
|
+
.withField('date', DataType.DAY)
|
|
261
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
262
|
+
.schema
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const debit = new TransactionSchema(SchemaBuilder.withName('DR')
|
|
266
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
267
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
268
|
+
.withField('date', DataType.DAY)
|
|
269
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
270
|
+
.schema
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
const credit = new TransactionSchema(SchemaBuilder.withName('CR')
|
|
274
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
275
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
276
|
+
.withField('date', DataType.DAY)
|
|
277
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
278
|
+
.schema
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
const valuation = new TransactionSchema(SchemaBuilder.withName('V')
|
|
282
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
283
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
284
|
+
.withField('date', DataType.DAY)
|
|
285
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
286
|
+
.schema
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
const income = new TransactionSchema(SchemaBuilder.withName('I')
|
|
290
|
+
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
291
|
+
.withField('currency', DataType.forEnum(Currency, 'Currency'))
|
|
292
|
+
.withField('date', DataType.DAY)
|
|
293
|
+
.withField('fee', DataType.DECIMAL, true)
|
|
294
|
+
.schema
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
|
|
78
298
|
return TransactionSchema;
|
|
79
299
|
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barchart/portfolio-api-common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.19",
|
|
4
4
|
"description": "Common classes used by the Portfolio system",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bryan Ingle",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"babel-core": "^6.26.0",
|
|
16
16
|
"babel-preset-es2015": "^6.24.1",
|
|
17
|
+
"babelify": "^8.0.0",
|
|
17
18
|
"browserify": "^14.5.0",
|
|
18
19
|
"git-get-status": "^1.0.5",
|
|
19
20
|
"glob": "^6.0.1",
|