@barchart/portfolio-api-common 1.0.197 → 1.0.201
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 +39 -1
- package/lib/processing/PositionContainer.js +15 -0
- package/lib/processing/PositionGroup.js +6 -0
- package/lib/processing/PositionItem.js +26 -0
- package/lib/serialization/TransactionSchema.js +18 -0
- package/package.json +1 -1
- package/test/SpecRunner.js +47 -0
|
@@ -15,6 +15,7 @@ module.exports = (() => {
|
|
|
15
15
|
/**
|
|
16
16
|
* The transaction would occur before an existing transaction.
|
|
17
17
|
*
|
|
18
|
+
* @public
|
|
18
19
|
* @static
|
|
19
20
|
* @returns {FailureType}
|
|
20
21
|
*/
|
|
@@ -22,12 +23,49 @@ module.exports = (() => {
|
|
|
22
23
|
return transactionCreateFailedOutOfSequence;
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* The transaction would cause the position to change (from long to
|
|
28
|
+
* short, or vice versa).
|
|
29
|
+
*
|
|
30
|
+
* @public
|
|
31
|
+
* @static
|
|
32
|
+
* @returns {FailureType}
|
|
33
|
+
*/
|
|
34
|
+
static get TRANSACTION_CREATE_FAILED_DIRECTION_SWITCH() {
|
|
35
|
+
return transactionCreateFailedDirectionSwitch;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static get TRANSACTION_CREATE_REWRITE_UNSUPPORTED() {
|
|
39
|
+
return transactionCreateRewriteUnsupported;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Deleting any transaction except for the most recent requires
|
|
44
|
+
* re-writing transaction history.
|
|
45
|
+
*
|
|
46
|
+
* @public
|
|
47
|
+
* @static
|
|
48
|
+
* @returns {FailureType}
|
|
49
|
+
*/
|
|
50
|
+
static get TRANSACTION_DELETE_FAILED_OUT_OF_SEQUENCE() {
|
|
51
|
+
return transactionDeleteFailedOutOfSequence;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static get TRANSACTION_DELETE_UNSUPPORTED() {
|
|
55
|
+
return transactionDeleteUnsupported;
|
|
56
|
+
}
|
|
57
|
+
|
|
25
58
|
toString() {
|
|
26
59
|
return '[PortfolioFailureType]';
|
|
27
60
|
}
|
|
28
61
|
}
|
|
29
62
|
|
|
30
|
-
const transactionCreateFailedOutOfSequence = new FailureType('TRANSACTION_CREATE_FAILED_OUT_OF_SEQUENCE', 'Unable to create transaction, the transaction date is out-of-sequence
|
|
63
|
+
const transactionCreateFailedOutOfSequence = new FailureType('TRANSACTION_CREATE_FAILED_OUT_OF_SEQUENCE', 'Unable to create transaction, because the transaction date is out-of-sequence. In other words, it would occur before an existing transaction. Please confirm your intent to re-write transaction history (which could take some time and alter the historical results for this position).');
|
|
64
|
+
const transactionCreateFailedDirectionSwitch = new FailureType('TRANSACTION_CREATE_FAILED_DIRECTION_SWITCH', 'Unable to create transaction, because the position direction would be switched (from long to short or vice versa). Please close the position (to a zero balance) first, then enter a second transaction.');
|
|
65
|
+
const transactionCreateRewriteUnsupported = new FailureType('TRANSACTION_CREATE_REWRITE_UNSUPPORTED', 'Unable to re-write transaction history. This operation is not currently supported (but will be implemented soon).');
|
|
66
|
+
|
|
67
|
+
const transactionDeleteFailedOutOfSequence = new FailureType('TRANSACTION_DELETE_FAILED_OUT_OF_SEQUENCE', 'Deleting any transaction, except for the most recent, will cause transaction history to be re-written. Please confirm your intent to re-write transaction history (which could take some time and alter the historical results for this position).');
|
|
68
|
+
const transactionDeleteUnsupported = new FailureType('TRANSACTION_DELETE_UNSUPPORTED', 'Unable to delete transaction. This operation is not currently supported (but will be implemented soon).');
|
|
31
69
|
|
|
32
70
|
return PortfolioFailureType;
|
|
33
71
|
})();
|
|
@@ -206,6 +206,21 @@ module.exports = (() => {
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Updates the portfolio data. For example, a portfolio's name might change.
|
|
211
|
+
*
|
|
212
|
+
* @public
|
|
213
|
+
* @param {Object} portfolio
|
|
214
|
+
*/
|
|
215
|
+
updatePortfolio(portfolio) {
|
|
216
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
217
|
+
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
218
|
+
|
|
219
|
+
this.startTransaction(() => {
|
|
220
|
+
getPositionItemsForPortfolio(this._items, portfolio.portfolio).forEach(item => item.updatePortfolio(portfolio));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
209
224
|
/**
|
|
210
225
|
* Removes an existing portfolio, and all of it's positions, from the container. This
|
|
211
226
|
* also triggers removal of the portfolio and it's positions from any applicable
|
|
@@ -463,6 +463,12 @@ module.exports = (() => {
|
|
|
463
463
|
});
|
|
464
464
|
}
|
|
465
465
|
|
|
466
|
+
this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio, sender) => {
|
|
467
|
+
const descriptionSelector = this._definition.descriptionSelector;
|
|
468
|
+
|
|
469
|
+
this._description = descriptionSelector(this._items[0]);
|
|
470
|
+
}));
|
|
471
|
+
|
|
466
472
|
this._disposeStack.push(quoteBinding);
|
|
467
473
|
this._disposeStack.push(newsBinding);
|
|
468
474
|
this._disposeStack.push(fundamentalBinding);
|
|
@@ -73,6 +73,7 @@ module.exports = (() => {
|
|
|
73
73
|
this._quoteChangedEvent = new Event(this);
|
|
74
74
|
this._newsExistsChangedEvent = new Event(this);
|
|
75
75
|
this._fundamentalDataChangeEvent = new Event(this);
|
|
76
|
+
this._portfolioChangedEvent = new Event(this);
|
|
76
77
|
this._positionItemDisposeEvent = new Event(this);
|
|
77
78
|
}
|
|
78
79
|
|
|
@@ -146,6 +147,19 @@ module.exports = (() => {
|
|
|
146
147
|
return this._currentQuote;
|
|
147
148
|
}
|
|
148
149
|
|
|
150
|
+
updatePortfolio(portfolio) {
|
|
151
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
152
|
+
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
153
|
+
|
|
154
|
+
if (portfolio.portfolio !== this._portfolio.portfolio) {
|
|
155
|
+
throw new Error('Unable to move position into new portfolio.');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (this._portfolio !== portfolio) {
|
|
159
|
+
this._portfolioChangedEvent.fire(this._portfolio = portfolio);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
149
163
|
/**
|
|
150
164
|
* Sets the current quote -- causing position-level data (e.g. market value) to
|
|
151
165
|
* be recalculated.
|
|
@@ -241,6 +255,17 @@ module.exports = (() => {
|
|
|
241
255
|
return this._newsExistsChangedEvent.register(handler);
|
|
242
256
|
}
|
|
243
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Registers an observer changes to portfolio metadata.
|
|
260
|
+
*
|
|
261
|
+
* @public
|
|
262
|
+
* @param {Function} handler
|
|
263
|
+
* @returns {Disposable}
|
|
264
|
+
*/
|
|
265
|
+
registerPortfolioChangeHandler(handler) {
|
|
266
|
+
return this._portfolioChangedEvent.register(handler);
|
|
267
|
+
}
|
|
268
|
+
|
|
244
269
|
/**
|
|
245
270
|
* Registers an observer for object disposal.
|
|
246
271
|
*
|
|
@@ -258,6 +283,7 @@ module.exports = (() => {
|
|
|
258
283
|
this._quoteChangedEvent.clear();
|
|
259
284
|
this._newsExistsChangedEvent.clear();
|
|
260
285
|
this._fundamentalDataChangeEvent.clear();
|
|
286
|
+
this._portfolioChangedEvent.clear();
|
|
261
287
|
this._positionItemDisposeEvent.clear();
|
|
262
288
|
}
|
|
263
289
|
|
|
@@ -254,6 +254,7 @@ module.exports = (() => {
|
|
|
254
254
|
.withField('price', DataType.DECIMAL)
|
|
255
255
|
.withField('quantity', DataType.DECIMAL)
|
|
256
256
|
.withField('fee', DataType.DECIMAL, true)
|
|
257
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
257
258
|
.schema
|
|
258
259
|
);
|
|
259
260
|
|
|
@@ -265,6 +266,7 @@ module.exports = (() => {
|
|
|
265
266
|
.withField('price', DataType.DECIMAL)
|
|
266
267
|
.withField('quantity', DataType.DECIMAL)
|
|
267
268
|
.withField('fee', DataType.DECIMAL, true)
|
|
269
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
268
270
|
.schema
|
|
269
271
|
);
|
|
270
272
|
|
|
@@ -276,6 +278,7 @@ module.exports = (() => {
|
|
|
276
278
|
.withField('price', DataType.DECIMAL)
|
|
277
279
|
.withField('quantity', DataType.DECIMAL)
|
|
278
280
|
.withField('fee', DataType.DECIMAL, true)
|
|
281
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
279
282
|
.schema
|
|
280
283
|
);
|
|
281
284
|
|
|
@@ -292,6 +295,7 @@ module.exports = (() => {
|
|
|
292
295
|
.withField('price', DataType.DECIMAL)
|
|
293
296
|
.withField('quantity', DataType.DECIMAL)
|
|
294
297
|
.withField('fee', DataType.DECIMAL, true)
|
|
298
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
295
299
|
.schema
|
|
296
300
|
);
|
|
297
301
|
|
|
@@ -303,6 +307,7 @@ module.exports = (() => {
|
|
|
303
307
|
.withField('rate', DataType.DECIMAL)
|
|
304
308
|
.withField('effective', DataType.DAY)
|
|
305
309
|
.withField('fee', DataType.DECIMAL, true)
|
|
310
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
306
311
|
.schema
|
|
307
312
|
);
|
|
308
313
|
|
|
@@ -315,6 +320,7 @@ module.exports = (() => {
|
|
|
315
320
|
.withField('effective', DataType.DAY)
|
|
316
321
|
.withField('price', DataType.DECIMAL)
|
|
317
322
|
.withField('fee', DataType.DECIMAL, true)
|
|
323
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
318
324
|
.schema
|
|
319
325
|
);
|
|
320
326
|
|
|
@@ -327,6 +333,7 @@ module.exports = (() => {
|
|
|
327
333
|
.withField('effective', DataType.DAY)
|
|
328
334
|
.withField('price', DataType.DECIMAL)
|
|
329
335
|
.withField('fee', DataType.DECIMAL, true)
|
|
336
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
330
337
|
.schema
|
|
331
338
|
);
|
|
332
339
|
|
|
@@ -338,6 +345,7 @@ module.exports = (() => {
|
|
|
338
345
|
.withField('rate', DataType.DECIMAL)
|
|
339
346
|
.withField('effective', DataType.DAY)
|
|
340
347
|
.withField('fee', DataType.DECIMAL, true)
|
|
348
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
341
349
|
.schema
|
|
342
350
|
);
|
|
343
351
|
|
|
@@ -350,6 +358,7 @@ module.exports = (() => {
|
|
|
350
358
|
.withField('effective', DataType.DAY)
|
|
351
359
|
.withField('price', DataType.DECIMAL)
|
|
352
360
|
.withField('fee', DataType.DECIMAL, true)
|
|
361
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
353
362
|
.schema
|
|
354
363
|
);
|
|
355
364
|
|
|
@@ -362,6 +371,7 @@ module.exports = (() => {
|
|
|
362
371
|
.withField('denominator', DataType.DECIMAL)
|
|
363
372
|
.withField('effective', DataType.DAY)
|
|
364
373
|
.withField('fee', DataType.DECIMAL, true)
|
|
374
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
365
375
|
.schema
|
|
366
376
|
);
|
|
367
377
|
|
|
@@ -371,6 +381,7 @@ module.exports = (() => {
|
|
|
371
381
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
372
382
|
.withField('date', DataType.DAY)
|
|
373
383
|
.withField('fee', DataType.DECIMAL)
|
|
384
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
374
385
|
.schema
|
|
375
386
|
);
|
|
376
387
|
|
|
@@ -381,6 +392,7 @@ module.exports = (() => {
|
|
|
381
392
|
.withField('date', DataType.DAY)
|
|
382
393
|
.withField('fee', DataType.DECIMAL)
|
|
383
394
|
.withField('price', DataType.DECIMAL)
|
|
395
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
384
396
|
.schema
|
|
385
397
|
);
|
|
386
398
|
|
|
@@ -393,6 +405,7 @@ module.exports = (() => {
|
|
|
393
405
|
.withField('date', DataType.DAY)
|
|
394
406
|
.withField('amount', DataType.DECIMAL)
|
|
395
407
|
.withField('fee', DataType.DECIMAL, true)
|
|
408
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
396
409
|
.schema
|
|
397
410
|
);
|
|
398
411
|
|
|
@@ -403,6 +416,7 @@ module.exports = (() => {
|
|
|
403
416
|
.withField('date', DataType.DAY)
|
|
404
417
|
.withField('amount', DataType.DECIMAL)
|
|
405
418
|
.withField('fee', DataType.DECIMAL, true)
|
|
419
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
406
420
|
.schema
|
|
407
421
|
);
|
|
408
422
|
|
|
@@ -413,6 +427,7 @@ module.exports = (() => {
|
|
|
413
427
|
.withField('date', DataType.DAY)
|
|
414
428
|
.withField('amount', DataType.DECIMAL)
|
|
415
429
|
.withField('fee', DataType.DECIMAL, true)
|
|
430
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
416
431
|
.schema
|
|
417
432
|
);
|
|
418
433
|
|
|
@@ -423,6 +438,7 @@ module.exports = (() => {
|
|
|
423
438
|
.withField('date', DataType.DAY)
|
|
424
439
|
.withField('amount', DataType.DECIMAL)
|
|
425
440
|
.withField('fee', DataType.DECIMAL, true)
|
|
441
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
426
442
|
.schema
|
|
427
443
|
);
|
|
428
444
|
|
|
@@ -433,6 +449,7 @@ module.exports = (() => {
|
|
|
433
449
|
.withField('date', DataType.DAY)
|
|
434
450
|
.withField('value', DataType.DECIMAL)
|
|
435
451
|
.withField('fee', DataType.DECIMAL, true)
|
|
452
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
436
453
|
.schema
|
|
437
454
|
);
|
|
438
455
|
|
|
@@ -443,6 +460,7 @@ module.exports = (() => {
|
|
|
443
460
|
.withField('date', DataType.DAY)
|
|
444
461
|
.withField('income', DataType.DECIMAL)
|
|
445
462
|
.withField('fee', DataType.DECIMAL, true)
|
|
463
|
+
.withField('force', DataType.BOOLEAN, true)
|
|
446
464
|
.schema
|
|
447
465
|
);
|
|
448
466
|
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -922,6 +922,21 @@ module.exports = (() => {
|
|
|
922
922
|
}
|
|
923
923
|
}
|
|
924
924
|
|
|
925
|
+
/**
|
|
926
|
+
* Updates the portfolio data. For example, a portfolio's name might change.
|
|
927
|
+
*
|
|
928
|
+
* @public
|
|
929
|
+
* @param {Object} portfolio
|
|
930
|
+
*/
|
|
931
|
+
updatePortfolio(portfolio) {
|
|
932
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
933
|
+
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
934
|
+
|
|
935
|
+
this.startTransaction(() => {
|
|
936
|
+
getPositionItemsForPortfolio(this._items, portfolio.portfolio).forEach(item => item.updatePortfolio(portfolio));
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
|
|
925
940
|
/**
|
|
926
941
|
* Removes an existing portfolio, and all of it's positions, from the container. This
|
|
927
942
|
* also triggers removal of the portfolio and it's positions from any applicable
|
|
@@ -2042,6 +2057,12 @@ module.exports = (() => {
|
|
|
2042
2057
|
});
|
|
2043
2058
|
}
|
|
2044
2059
|
|
|
2060
|
+
this._disposeStack.push(item.registerPortfolioChangeHandler((portfolio, sender) => {
|
|
2061
|
+
const descriptionSelector = this._definition.descriptionSelector;
|
|
2062
|
+
|
|
2063
|
+
this._description = descriptionSelector(this._items[0]);
|
|
2064
|
+
}));
|
|
2065
|
+
|
|
2045
2066
|
this._disposeStack.push(quoteBinding);
|
|
2046
2067
|
this._disposeStack.push(newsBinding);
|
|
2047
2068
|
this._disposeStack.push(fundamentalBinding);
|
|
@@ -2411,6 +2432,7 @@ module.exports = (() => {
|
|
|
2411
2432
|
this._quoteChangedEvent = new Event(this);
|
|
2412
2433
|
this._newsExistsChangedEvent = new Event(this);
|
|
2413
2434
|
this._fundamentalDataChangeEvent = new Event(this);
|
|
2435
|
+
this._portfolioChangedEvent = new Event(this);
|
|
2414
2436
|
this._positionItemDisposeEvent = new Event(this);
|
|
2415
2437
|
}
|
|
2416
2438
|
|
|
@@ -2484,6 +2506,19 @@ module.exports = (() => {
|
|
|
2484
2506
|
return this._currentQuote;
|
|
2485
2507
|
}
|
|
2486
2508
|
|
|
2509
|
+
updatePortfolio(portfolio) {
|
|
2510
|
+
assert.argumentIsRequired(portfolio, 'portfolio', Object);
|
|
2511
|
+
assert.argumentIsRequired(portfolio.portfolio, 'portfolio.portfolio', String);
|
|
2512
|
+
|
|
2513
|
+
if (portfolio.portfolio !== this._portfolio.portfolio) {
|
|
2514
|
+
throw new Error('Unable to move position into new portfolio.');
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
if (this._portfolio !== portfolio) {
|
|
2518
|
+
this._portfolioChangedEvent.fire(this._portfolio = portfolio);
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2487
2522
|
/**
|
|
2488
2523
|
* Sets the current quote -- causing position-level data (e.g. market value) to
|
|
2489
2524
|
* be recalculated.
|
|
@@ -2579,6 +2614,17 @@ module.exports = (() => {
|
|
|
2579
2614
|
return this._newsExistsChangedEvent.register(handler);
|
|
2580
2615
|
}
|
|
2581
2616
|
|
|
2617
|
+
/**
|
|
2618
|
+
* Registers an observer changes to portfolio metadata.
|
|
2619
|
+
*
|
|
2620
|
+
* @public
|
|
2621
|
+
* @param {Function} handler
|
|
2622
|
+
* @returns {Disposable}
|
|
2623
|
+
*/
|
|
2624
|
+
registerPortfolioChangeHandler(handler) {
|
|
2625
|
+
return this._portfolioChangedEvent.register(handler);
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2582
2628
|
/**
|
|
2583
2629
|
* Registers an observer for object disposal.
|
|
2584
2630
|
*
|
|
@@ -2596,6 +2642,7 @@ module.exports = (() => {
|
|
|
2596
2642
|
this._quoteChangedEvent.clear();
|
|
2597
2643
|
this._newsExistsChangedEvent.clear();
|
|
2598
2644
|
this._fundamentalDataChangeEvent.clear();
|
|
2645
|
+
this._portfolioChangedEvent.clear();
|
|
2599
2646
|
this._positionItemDisposeEvent.clear();
|
|
2600
2647
|
}
|
|
2601
2648
|
|