@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.
@@ -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
- shares = t.dividend.amount.divide(t.dividend.rate);
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
- shares = t.dividend.amount.divide(t.dividend.rate);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.9.1",
3
+ "version": "1.11.2",
4
4
  "description": "Common code used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
package/.jshintrc DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "esversion": 9,
3
- "validthis": true,
4
- "-W018": true,
5
- "-W093": true
6
- }
@@ -1,3 +0,0 @@
1
- **New Features**
2
-
3
- * Added new ```Schema``` for results of a query by symbol.
@@ -1,3 +0,0 @@
1
- **Configuration Changes**
2
-
3
- * The failure message for corrupt corporate actions (e.g. two instruments with same symbol) was updated to indicate an expected time to correction (of 24 to 48 hours).
@@ -1,4 +0,0 @@
1
- **Technical Enhancements**
2
-
3
- * Added a `transaction` field into `basicFormatter` function for the `TransactionFormatter` class.
4
- * Changed the way to add and remove a portfolio in `PositionContainer` to support reactive changes.
@@ -1,3 +0,0 @@
1
- **New Features**
2
-
3
- * Added a new `PortfolioFailureType` for attempting to edit a transaction's type.
@@ -1,3 +0,0 @@
1
- **New Features**
2
-
3
- * Added a new `PortfolioFailureType` for attempting to reinvest a dividend when the position is short.
@@ -1,3 +0,0 @@
1
- **New Features**
2
-
3
- * Added a new `PortfolioFailureType` for attempts to switch to dividend reinvestment when the position is short.
@@ -1,4 +0,0 @@
1
- **New Features**
2
-
3
- * Added `close` field to the `Sell` transaction schema.
4
- * Added `close` field to the `Buy Short` transaction schema.
@@ -1,4 +0,0 @@
1
- **Bug Fixes**
2
-
3
- * Made `quantity` field optional for the `Sell` transaction schema.
4
- * Made `quantity` field optional for the `Buy Short` transaction schema.
package/buildspec.yml DELETED
@@ -1,15 +0,0 @@
1
- version: 0.2
2
-
3
- phases:
4
- install:
5
- runtime-versions:
6
- nodejs: 12.x
7
-
8
- pre_build:
9
- commands:
10
- - npm install
11
-
12
- build:
13
- commands:
14
- - ./node_modules/.bin/gulp lint
15
- - ./node_modules/.bin/gulp test
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'));