@barchart/portfolio-api-common 1.9.1 → 1.11.2
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/api/failures/PortfolioFailureType.js +14 -2
- package/lib/formatters/TransactionFormatter.js +54 -2
- package/package.json +1 -1
- package/.jshintrc +0 -6
- package/.releases/1.5.0.md +0 -3
- package/.releases/1.5.1.md +0 -3
- package/.releases/1.5.2.md +0 -4
- package/.releases/1.6.0.md +0 -3
- package/.releases/1.7.0.md +0 -3
- package/.releases/1.8.0.md +0 -3
- package/.releases/1.9.0.md +0 -4
- package/.releases/1.9.1.md +0 -4
- package/buildspec.yml +0 -15
- package/gulpfile.js +0 -122
- package/test/SpecRunner.js +0 -18636
- package/test/SpecRunnner.html +0 -19
- package/test/specs/data/PositionSummaryFrameSpec.js +0 -629
- package/test/specs/data/TransactionValidatorSpec.js +0 -94
- package/test/specs/processing/PositionContainerSpec.js +0 -185
- package/test/specs/serialization/PositionSchemaSpec.js +0 -64
- package/test/specs/serialization/TransactionSchemaSpec.js +0 -65
|
@@ -154,6 +154,17 @@ module.exports = (() => {
|
|
|
154
154
|
return transactionCreateFailedInvalidInitialType;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
/**
|
|
158
|
+
* A transaction quantity cannot have a negative amount.
|
|
159
|
+
*
|
|
160
|
+
* @public
|
|
161
|
+
* @static
|
|
162
|
+
* @returns {FailureType}
|
|
163
|
+
*/
|
|
164
|
+
static get TRANSACTION_CREATE_FAILED_QUANTITY_NEGATIVE() {
|
|
165
|
+
return transactionCreateFailedQuantityNegative;
|
|
166
|
+
}
|
|
167
|
+
|
|
157
168
|
/**
|
|
158
169
|
* A valuation transaction cannot have a negative rate (or amount).
|
|
159
170
|
*
|
|
@@ -348,7 +359,7 @@ module.exports = (() => {
|
|
|
348
359
|
static get TRANSACTION_EDIT_FAILED_TYPE_CHANGED() {
|
|
349
360
|
return transactionEditFailedTypeChanged;
|
|
350
361
|
}
|
|
351
|
-
|
|
362
|
+
|
|
352
363
|
/**
|
|
353
364
|
* Conversion of transaction type is unsupported.
|
|
354
365
|
*
|
|
@@ -371,7 +382,7 @@ module.exports = (() => {
|
|
|
371
382
|
static get TRANSACTION_SWITCH_FAILED_INVALID_REINVEST() {
|
|
372
383
|
return transactionSwitchFailedInvalidReinvest;
|
|
373
384
|
}
|
|
374
|
-
|
|
385
|
+
|
|
375
386
|
toString() {
|
|
376
387
|
return '[PortfolioFailureType]';
|
|
377
388
|
}
|
|
@@ -392,6 +403,7 @@ module.exports = (() => {
|
|
|
392
403
|
const transactionCreateFailedTypeInvalidForDirection = new FailureType('TRANSACTION_CREATE_FAILED_TYPE_INVALID_FOR_DIRECTION', 'Unable to process transaction, a {L|positionDirection.description} position would be created (i.e. you would have {L|positionDirection.sign} shares/units). {u|instrumentType.description} positions cannot have {L|positionDirection.description} positions.', false);
|
|
393
404
|
const transactionCreateFailedInvalidDirectionSwitch = new FailureType('TRANSACTION_CREATE_FAILED_INVALID_DIRECTION_SWITCH', 'Unable to process transaction, the transaction would switch the position from {L|currentDirection.description} to {L|proposedDirection.description} (i.e. {L|currentDirection.sign} to {L|proposedDirection.sign} shares/units). This is not allowed. Please close the current position (i.e. zero it out) and then enter a second transaction.', false);
|
|
394
405
|
const transactionCreateFailedInvalidInitialType = new FailureType('TRANSACTION_CREATE_FAILED_INVALID_INITIAL_TYPE', 'Unable to process operation because the first transaction would to be a {U|transactionType.description}, which is not allowed -- since {U|transactionType.description} transactions cannot open a position.', false);
|
|
406
|
+
const transactionCreateFailedQuantityNegative = new FailureType('TRANSACTION_CREATE_FAILED_QUANTITY_NEGATIVE', 'Unable to process transaction, quantity cannot be negative.');
|
|
395
407
|
const transactionCreateFailedValuationNegative = new FailureType('TRANSACTION_CREATE_FAILED_VALUATION_NEGATIVE', 'Unable to process operation, valuations cannot be negative.', false);
|
|
396
408
|
const transactionCreateFailedInvalidTermination = new FailureType('TRANSACTION_CREATE_FAILED_INVALID_TERMINATION', 'Unable to process operation, a {U|transactionType.description} must be the final transaction in the position history.', false);
|
|
397
409
|
const transactionCreateFailedAfterTermination = new FailureType('TRANSACTION_CREATE_FAILED_AFTER_TERMINATION', 'Unable to process operation, one or more transactions would exist after {L|termination}, the final day of trading for this instrument', false);
|
|
@@ -159,12 +159,34 @@ module.exports = (() => {
|
|
|
159
159
|
let shares;
|
|
160
160
|
|
|
161
161
|
if (!t.dividend.rate.getIsZero()) {
|
|
162
|
-
|
|
162
|
+
if (t.dividend.native) {
|
|
163
|
+
shares = t.dividend.native.divide(t.dividend.rate);
|
|
164
|
+
} else {
|
|
165
|
+
shares = t.dividend.amount.divide(t.dividend.rate);
|
|
166
|
+
}
|
|
163
167
|
} else {
|
|
164
168
|
shares = '';
|
|
165
169
|
}
|
|
166
170
|
|
|
171
|
+
if (shares) {
|
|
172
|
+
const rounded = shares.round(0);
|
|
173
|
+
|
|
174
|
+
if (rounded.subtract(shares).absolute().getIsLessThan(0.01)) {
|
|
175
|
+
shares = rounded;
|
|
176
|
+
} else {
|
|
177
|
+
shares = shares.round(2);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
167
181
|
f.shares = shares;
|
|
182
|
+
|
|
183
|
+
if (t.dividend.currency) {
|
|
184
|
+
f.currency = t.dividend.currency;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (t.dividend.native) {
|
|
188
|
+
f.native = t.dividend.native;
|
|
189
|
+
}
|
|
168
190
|
};
|
|
169
191
|
|
|
170
192
|
const distributionCashFormatter = (t, f) => {
|
|
@@ -174,12 +196,34 @@ module.exports = (() => {
|
|
|
174
196
|
let shares;
|
|
175
197
|
|
|
176
198
|
if (!t.dividend.rate.getIsZero()) {
|
|
177
|
-
|
|
199
|
+
if (t.dividend.native) {
|
|
200
|
+
shares = t.dividend.native.divide(t.dividend.rate);
|
|
201
|
+
} else {
|
|
202
|
+
shares = t.dividend.amount.divide(t.dividend.rate);
|
|
203
|
+
}
|
|
178
204
|
} else {
|
|
179
205
|
shares = '';
|
|
180
206
|
}
|
|
181
207
|
|
|
208
|
+
if (shares) {
|
|
209
|
+
const rounded = shares.round(0);
|
|
210
|
+
|
|
211
|
+
if (rounded.subtract(shares).absolute().getIsLessThan(0.01)) {
|
|
212
|
+
shares = rounded;
|
|
213
|
+
} else {
|
|
214
|
+
shares = shares.round(2);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
182
218
|
f.shares = shares;
|
|
219
|
+
|
|
220
|
+
if (t.dividend.currency) {
|
|
221
|
+
f.currency = t.dividend.currency;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (t.dividend.native) {
|
|
225
|
+
f.native = t.dividend.native;
|
|
226
|
+
}
|
|
183
227
|
};
|
|
184
228
|
|
|
185
229
|
const dividendReinvestFormatter = (t, f) => {
|
|
@@ -189,6 +233,10 @@ module.exports = (() => {
|
|
|
189
233
|
f.fee = t.fee;
|
|
190
234
|
}
|
|
191
235
|
|
|
236
|
+
if (t.dividend.currency) {
|
|
237
|
+
f.currency = t.dividend.currency;
|
|
238
|
+
}
|
|
239
|
+
|
|
192
240
|
f.price = t.dividend.price;
|
|
193
241
|
f.rate = t.dividend.rate;
|
|
194
242
|
|
|
@@ -202,6 +250,10 @@ module.exports = (() => {
|
|
|
202
250
|
f.fee = t.fee;
|
|
203
251
|
}
|
|
204
252
|
|
|
253
|
+
if (t.dividend.currency) {
|
|
254
|
+
f.currency = t.dividend.currency;
|
|
255
|
+
}
|
|
256
|
+
|
|
205
257
|
f.price = t.dividend.price;
|
|
206
258
|
f.rate = t.dividend.rate;
|
|
207
259
|
|
package/package.json
CHANGED
package/.jshintrc
DELETED
package/.releases/1.5.0.md
DELETED
package/.releases/1.5.1.md
DELETED
package/.releases/1.5.2.md
DELETED
package/.releases/1.6.0.md
DELETED
package/.releases/1.7.0.md
DELETED
package/.releases/1.8.0.md
DELETED
package/.releases/1.9.0.md
DELETED
package/.releases/1.9.1.md
DELETED
package/buildspec.yml
DELETED
package/gulpfile.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
const gulp = require('gulp');
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
|
|
5
|
-
const browserify = require('browserify'),
|
|
6
|
-
buffer = require('vinyl-buffer'),
|
|
7
|
-
exec = require('child_process').exec,
|
|
8
|
-
git = require('gulp-git'),
|
|
9
|
-
gitStatus = require('git-get-status'),
|
|
10
|
-
glob = require('glob'),
|
|
11
|
-
jasmine = require('gulp-jasmine'),
|
|
12
|
-
jshint = require('gulp-jshint'),
|
|
13
|
-
prompt = require('gulp-prompt'),
|
|
14
|
-
source = require('vinyl-source-stream');
|
|
15
|
-
|
|
16
|
-
function getVersionFromPackage() {
|
|
17
|
-
return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
gulp.task('ensure-clean-working-directory', (cb) => {
|
|
21
|
-
gitStatus((err, status) => {
|
|
22
|
-
if (err, !status.clean) {
|
|
23
|
-
throw new Error('Unable to proceed, your working directory is not clean.');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
cb();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
gulp.task('bump-choice', (cb) => {
|
|
31
|
-
const processor = prompt.prompt({
|
|
32
|
-
type: 'list',
|
|
33
|
-
name: 'bump',
|
|
34
|
-
message: 'What type of bump would you like to do?',
|
|
35
|
-
choices: ['patch', 'minor', 'major'],
|
|
36
|
-
}, (res) => {
|
|
37
|
-
global.bump = res.bump;
|
|
38
|
-
|
|
39
|
-
return cb();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
return gulp.src(['./package.json']).pipe(processor);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
gulp.task('bump-version', (cb) => {
|
|
46
|
-
exec(`npm version ${global.bump || 'patch'} --no-git-tag-version`, {
|
|
47
|
-
cwd: './'
|
|
48
|
-
}, (error) => {
|
|
49
|
-
if (error) {
|
|
50
|
-
cb(error);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
cb();
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
gulp.task('commit-changes', () => {
|
|
58
|
-
return gulp.src([ './', './test/', './package.json' ])
|
|
59
|
-
.pipe(git.add())
|
|
60
|
-
.pipe(git.commit('Release. Bump version number'));
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
gulp.task('push-changes', (cb) => {
|
|
64
|
-
git.push('origin', 'master', cb);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
gulp.task('create-tag', (cb) => {
|
|
68
|
-
const version = getVersionFromPackage();
|
|
69
|
-
|
|
70
|
-
git.tag(version, 'Release ' + version, (error) => {
|
|
71
|
-
if (error) {
|
|
72
|
-
return cb(error);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
git.push('origin', 'master', { args: '--tags' }, cb);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
gulp.task('build-test-bundle', () => {
|
|
80
|
-
return browserify({ entries: glob.sync('test/specs/**/*.js') })
|
|
81
|
-
.bundle()
|
|
82
|
-
.pipe(source('SpecRunner.js'))
|
|
83
|
-
.pipe(buffer())
|
|
84
|
-
.pipe(gulp.dest('test'));
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
gulp.task('execute-browser-tests', () => {
|
|
88
|
-
return gulp.src('test/SpecRunner.js')
|
|
89
|
-
.pipe(jasmine());
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
gulp.task('execute-node-tests', () => {
|
|
93
|
-
return gulp.src(['test/specs/**/*.js'])
|
|
94
|
-
.pipe(jasmine());
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
gulp.task('execute-tests', gulp.series(
|
|
98
|
-
'build-test-bundle',
|
|
99
|
-
'execute-browser-tests',
|
|
100
|
-
'execute-node-tests'
|
|
101
|
-
));
|
|
102
|
-
|
|
103
|
-
gulp.task('release', gulp.series(
|
|
104
|
-
'ensure-clean-working-directory',
|
|
105
|
-
'execute-tests',
|
|
106
|
-
'bump-choice',
|
|
107
|
-
'bump-version',
|
|
108
|
-
'commit-changes',
|
|
109
|
-
'push-changes',
|
|
110
|
-
'create-tag'
|
|
111
|
-
));
|
|
112
|
-
|
|
113
|
-
gulp.task('lint', () => {
|
|
114
|
-
return gulp.src([ './**/*.js', './test/specs/**/*.js', '!./node_modules/**', '!./test/SpecRunner.js' ])
|
|
115
|
-
.pipe(jshint({'esversion': 9}))
|
|
116
|
-
.pipe(jshint.reporter('default'))
|
|
117
|
-
.pipe(jshint.reporter('fail'));
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
gulp.task('test', gulp.series('execute-tests'));
|
|
121
|
-
|
|
122
|
-
gulp.task('default', gulp.series('lint'));
|