@barchart/portfolio-api-common 1.2.38 → 1.2.42
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.
|
@@ -4,6 +4,15 @@ const Enum = require('@barchart/common-js/lang/Enum'),
|
|
|
4
4
|
module.exports = (() => {
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Types of corporate actions.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
* @extends {Enum}
|
|
12
|
+
* @param {String} code
|
|
13
|
+
* @param {String} description
|
|
14
|
+
* @param {Boolean} internal
|
|
15
|
+
*/
|
|
7
16
|
class CorporateActionType extends Enum {
|
|
8
17
|
constructor(code, description, internal) {
|
|
9
18
|
super(code, description);
|
|
@@ -11,23 +20,75 @@ module.exports = (() => {
|
|
|
11
20
|
this._internal = is.boolean(internal) && internal;
|
|
12
21
|
}
|
|
13
22
|
|
|
23
|
+
/**
|
|
24
|
+
* If true, the corporate action is fictitious -- used only for internal
|
|
25
|
+
* system purposes.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
* @returns {Boolean}
|
|
29
|
+
*/
|
|
14
30
|
get internal() {
|
|
15
31
|
return this._internal;
|
|
16
32
|
}
|
|
17
33
|
|
|
34
|
+
/**
|
|
35
|
+
* A symbol change.
|
|
36
|
+
*
|
|
37
|
+
* @public
|
|
38
|
+
* @static
|
|
39
|
+
* @returns {CorporateActionType}
|
|
40
|
+
*/
|
|
41
|
+
static get SYMBOL_CHANGE() {
|
|
42
|
+
return symbolChange;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A name change.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
* @static
|
|
50
|
+
* @returns {CorporateActionType}
|
|
51
|
+
*/
|
|
52
|
+
static get NAME_CHANGE() {
|
|
53
|
+
return nameChange;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A dividend.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
* @static
|
|
61
|
+
* @returns {CorporateActionType}
|
|
62
|
+
*/
|
|
18
63
|
static get DIVIDEND() {
|
|
19
64
|
return dividend;
|
|
20
65
|
}
|
|
21
66
|
|
|
67
|
+
/**
|
|
68
|
+
* A split.
|
|
69
|
+
*
|
|
70
|
+
* @public
|
|
71
|
+
* @static
|
|
72
|
+
* @returns {CorporateActionType}
|
|
73
|
+
*/
|
|
22
74
|
static get SPLIT() {
|
|
23
75
|
return split;
|
|
24
76
|
}
|
|
25
77
|
|
|
78
|
+
/**
|
|
79
|
+
* A fictitious event, used for internal system purposes.
|
|
80
|
+
*
|
|
81
|
+
* @public
|
|
82
|
+
* @static
|
|
83
|
+
* @returns {CorporateActionType}
|
|
84
|
+
*/
|
|
26
85
|
static get JOB() {
|
|
27
86
|
return job;
|
|
28
87
|
}
|
|
29
88
|
}
|
|
30
89
|
|
|
90
|
+
const symbolChange = new CorporateActionType('SYMBOL_CHANGE', 'Symbol Change', false);
|
|
91
|
+
const nameChange = new CorporateActionType('NAME_CHANGE', 'Name Change', false);
|
|
31
92
|
const dividend = new CorporateActionType('DIVIDEND', 'Dividend', false);
|
|
32
93
|
const split = new CorporateActionType('SPLIT', 'Split', false);
|
|
33
94
|
const job = new CorporateActionType('JOB', 'Job', true);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
2
|
-
array = require('@barchart/common-js/lang/array')
|
|
2
|
+
array = require('@barchart/common-js/lang/array'),
|
|
3
|
+
is = require('@barchart/common-js/lang/is');
|
|
3
4
|
|
|
4
5
|
const InstrumentType = require('./InstrumentType'),
|
|
5
6
|
PositionDirection = require('./PositionDirection'),
|
|
@@ -31,6 +32,44 @@ module.exports = (() => {
|
|
|
31
32
|
return TransactionValidator.getInvalidIndex(transactions) < 0;
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Given a set of transaction, when transaction references are present, ensures
|
|
37
|
+
* that no transactions within the set reference the same transaction.
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
* @static
|
|
41
|
+
* @param {Array.<Object>} transactions
|
|
42
|
+
* @returns {Boolean}
|
|
43
|
+
*/
|
|
44
|
+
static validateReferences(transactions) {
|
|
45
|
+
assert.argumentIsArray(transactions, 'transactions');
|
|
46
|
+
|
|
47
|
+
const references = { };
|
|
48
|
+
|
|
49
|
+
return transactions.every((t) => {
|
|
50
|
+
let valid = true;
|
|
51
|
+
|
|
52
|
+
if (is.object(t.reference) && is.string(t.reference.root) && is.number(t.reference.sequence)) {
|
|
53
|
+
const root = t.reference.root;
|
|
54
|
+
const sequence = t.reference.sequence;
|
|
55
|
+
|
|
56
|
+
if (!references.hasOwnProperty(root)) {
|
|
57
|
+
references[root] = [ ];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const sequences = references[root];
|
|
61
|
+
|
|
62
|
+
if (sequences.some(s => s === sequence)) {
|
|
63
|
+
valid = false;
|
|
64
|
+
} else {
|
|
65
|
+
sequences.push(sequence);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return valid;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
34
73
|
/**
|
|
35
74
|
* Given a set of transaction, returns the index of the first transaction that with an invalid
|
|
36
75
|
* sequence number or date.
|
|
@@ -198,7 +237,6 @@ module.exports = (() => {
|
|
|
198
237
|
|
|
199
238
|
associateTypes(InstrumentType.CASH, TransactionType.DEPOSIT, true);
|
|
200
239
|
associateTypes(InstrumentType.CASH, TransactionType.WITHDRAWAL, true);
|
|
201
|
-
associateTypes(InstrumentType.CASH, TransactionType.FEE, true);
|
|
202
240
|
associateTypes(InstrumentType.CASH, TransactionType.DEBIT, false);
|
|
203
241
|
associateTypes(InstrumentType.CASH, TransactionType.CREDIT, false);
|
|
204
242
|
|
|
@@ -216,7 +216,7 @@ module.exports = (() => {
|
|
|
216
216
|
.withField('instrument.symbol.barchart', DataType.STRING, true)
|
|
217
217
|
.withField('instrument.symbol.display', DataType.STRING, true)
|
|
218
218
|
.withField('date', DataType.DAY)
|
|
219
|
-
.withField('price', DataType.DECIMAL)
|
|
219
|
+
.withField('price', DataType.DECIMAL, true)
|
|
220
220
|
.withField('quantity', DataType.DECIMAL)
|
|
221
221
|
.withField('fee', DataType.DECIMAL, true)
|
|
222
222
|
.withField('reinvest', DataType.BOOLEAN, true)
|
|
@@ -231,7 +231,7 @@ module.exports = (() => {
|
|
|
231
231
|
.withField('sequence', DataType.NUMBER, true)
|
|
232
232
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
233
233
|
.withField('date', DataType.DAY)
|
|
234
|
-
.withField('price', DataType.DECIMAL)
|
|
234
|
+
.withField('price', DataType.DECIMAL, true)
|
|
235
235
|
.withField('quantity', DataType.DECIMAL)
|
|
236
236
|
.withField('fee', DataType.DECIMAL, true)
|
|
237
237
|
.withField('force', DataType.BOOLEAN, true)
|
|
@@ -291,7 +291,6 @@ module.exports = (() => {
|
|
|
291
291
|
.withField('instrument.currency', DataType.forEnum(Currency, 'Currency'), true)
|
|
292
292
|
.withField('date', DataType.DAY)
|
|
293
293
|
.withField('amount', DataType.DECIMAL)
|
|
294
|
-
.withField('fee', DataType.DECIMAL, true)
|
|
295
294
|
.withField('force', DataType.BOOLEAN, true)
|
|
296
295
|
.schema
|
|
297
296
|
);
|
|
@@ -305,7 +304,6 @@ module.exports = (() => {
|
|
|
305
304
|
.withField('instrument.currency', DataType.forEnum(Currency, 'Currency'), true)
|
|
306
305
|
.withField('date', DataType.DAY)
|
|
307
306
|
.withField('amount', DataType.DECIMAL)
|
|
308
|
-
.withField('fee', DataType.DECIMAL, true)
|
|
309
307
|
.withField('force', DataType.BOOLEAN, true)
|
|
310
308
|
.schema
|
|
311
309
|
);
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -1027,7 +1027,8 @@ module.exports = (() => {
|
|
|
1027
1027
|
|
|
1028
1028
|
},{"@barchart/common-js/lang/Enum":21,"@barchart/common-js/lang/assert":24}],5:[function(require,module,exports){
|
|
1029
1029
|
const assert = require('@barchart/common-js/lang/assert'),
|
|
1030
|
-
array = require('@barchart/common-js/lang/array')
|
|
1030
|
+
array = require('@barchart/common-js/lang/array'),
|
|
1031
|
+
is = require('@barchart/common-js/lang/is');
|
|
1031
1032
|
|
|
1032
1033
|
const InstrumentType = require('./InstrumentType'),
|
|
1033
1034
|
PositionDirection = require('./PositionDirection'),
|
|
@@ -1059,6 +1060,44 @@ module.exports = (() => {
|
|
|
1059
1060
|
return TransactionValidator.getInvalidIndex(transactions) < 0;
|
|
1060
1061
|
}
|
|
1061
1062
|
|
|
1063
|
+
/**
|
|
1064
|
+
* Given a set of transaction, when transaction references are present, ensures
|
|
1065
|
+
* that no transactions within the set reference the same transaction.
|
|
1066
|
+
*
|
|
1067
|
+
* @public
|
|
1068
|
+
* @static
|
|
1069
|
+
* @param {Array.<Object>} transactions
|
|
1070
|
+
* @returns {Boolean}
|
|
1071
|
+
*/
|
|
1072
|
+
static validateReferences(transactions) {
|
|
1073
|
+
assert.argumentIsArray(transactions, 'transactions');
|
|
1074
|
+
|
|
1075
|
+
const references = { };
|
|
1076
|
+
|
|
1077
|
+
return transactions.every((t) => {
|
|
1078
|
+
let valid = true;
|
|
1079
|
+
|
|
1080
|
+
if (is.object(t.reference) && is.string(t.reference.root) && is.number(t.reference.sequence)) {
|
|
1081
|
+
const root = t.reference.root;
|
|
1082
|
+
const sequence = t.reference.sequence;
|
|
1083
|
+
|
|
1084
|
+
if (!references.hasOwnProperty(root)) {
|
|
1085
|
+
references[root] = [ ];
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
const sequences = references[root];
|
|
1089
|
+
|
|
1090
|
+
if (sequences.some(s => s === sequence)) {
|
|
1091
|
+
valid = false;
|
|
1092
|
+
} else {
|
|
1093
|
+
sequences.push(sequence);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
return valid;
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1062
1101
|
/**
|
|
1063
1102
|
* Given a set of transaction, returns the index of the first transaction that with an invalid
|
|
1064
1103
|
* sequence number or date.
|
|
@@ -1226,7 +1265,6 @@ module.exports = (() => {
|
|
|
1226
1265
|
|
|
1227
1266
|
associateTypes(InstrumentType.CASH, TransactionType.DEPOSIT, true);
|
|
1228
1267
|
associateTypes(InstrumentType.CASH, TransactionType.WITHDRAWAL, true);
|
|
1229
|
-
associateTypes(InstrumentType.CASH, TransactionType.FEE, true);
|
|
1230
1268
|
associateTypes(InstrumentType.CASH, TransactionType.DEBIT, false);
|
|
1231
1269
|
associateTypes(InstrumentType.CASH, TransactionType.CREDIT, false);
|
|
1232
1270
|
|
|
@@ -1259,7 +1297,7 @@ module.exports = (() => {
|
|
|
1259
1297
|
return TransactionValidator;
|
|
1260
1298
|
})();
|
|
1261
1299
|
|
|
1262
|
-
},{"./InstrumentType":1,"./PositionDirection":2,"./TransactionType":4,"@barchart/common-js/lang/array":23,"@barchart/common-js/lang/assert":24}],6:[function(require,module,exports){
|
|
1300
|
+
},{"./InstrumentType":1,"./PositionDirection":2,"./TransactionType":4,"@barchart/common-js/lang/array":23,"@barchart/common-js/lang/assert":24,"@barchart/common-js/lang/is":26}],6:[function(require,module,exports){
|
|
1263
1301
|
const array = require('@barchart/common-js/lang/array'),
|
|
1264
1302
|
assert = require('@barchart/common-js/lang/assert'),
|
|
1265
1303
|
ComparatorBuilder = require('@barchart/common-js/collections/sorting/ComparatorBuilder'),
|
|
@@ -9318,6 +9356,30 @@ describe('When validating transaction order', () => {
|
|
|
9318
9356
|
});
|
|
9319
9357
|
});
|
|
9320
9358
|
|
|
9359
|
+
describe('When validating transaction references', () => {
|
|
9360
|
+
'use strict';
|
|
9361
|
+
|
|
9362
|
+
const build = (root, sequence) => {
|
|
9363
|
+
return { reference: { root: root, sequence: sequence } };
|
|
9364
|
+
};
|
|
9365
|
+
|
|
9366
|
+
it('An array of zero transactions should be valid', () => {
|
|
9367
|
+
expect(TransactionValidator.validateReferences([])).toEqual(true);
|
|
9368
|
+
});
|
|
9369
|
+
|
|
9370
|
+
it('An array with no references should be valid', () => {
|
|
9371
|
+
expect(TransactionValidator.validateReferences([ { }, { } ])).toEqual(true);
|
|
9372
|
+
});
|
|
9373
|
+
|
|
9374
|
+
it('An array with distinct references should be valid', () => {
|
|
9375
|
+
expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1) ])).toEqual(true);
|
|
9376
|
+
});
|
|
9377
|
+
|
|
9378
|
+
it('An array with non-distinct references should be not valid', () => {
|
|
9379
|
+
expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1), build('a', 2) ])).toEqual(false);
|
|
9380
|
+
});
|
|
9381
|
+
});
|
|
9382
|
+
|
|
9321
9383
|
describe('When requesting all the user-initiated transaction types', () => {
|
|
9322
9384
|
'use strict';
|
|
9323
9385
|
|
|
@@ -9331,13 +9393,6 @@ describe('When requesting all the user-initiated transaction types', () => {
|
|
|
9331
9393
|
expect(userInitiated.length).toEqual(9);
|
|
9332
9394
|
});
|
|
9333
9395
|
});
|
|
9334
|
-
|
|
9335
|
-
describe('When validating direction', () => {
|
|
9336
|
-
'use strict';
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
});
|
|
9340
|
-
|
|
9341
9396
|
},{"./../../../lib/data/TransactionValidator":5,"@barchart/common-js/lang/Day":18}],37:[function(require,module,exports){
|
|
9342
9397
|
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
9343
9398
|
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
@@ -42,6 +42,30 @@ describe('When validating transaction order', () => {
|
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
+
describe('When validating transaction references', () => {
|
|
46
|
+
'use strict';
|
|
47
|
+
|
|
48
|
+
const build = (root, sequence) => {
|
|
49
|
+
return { reference: { root: root, sequence: sequence } };
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
it('An array of zero transactions should be valid', () => {
|
|
53
|
+
expect(TransactionValidator.validateReferences([])).toEqual(true);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('An array with no references should be valid', () => {
|
|
57
|
+
expect(TransactionValidator.validateReferences([ { }, { } ])).toEqual(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('An array with distinct references should be valid', () => {
|
|
61
|
+
expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1) ])).toEqual(true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('An array with non-distinct references should be not valid', () => {
|
|
65
|
+
expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1), build('a', 2) ])).toEqual(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
45
69
|
describe('When requesting all the user-initiated transaction types', () => {
|
|
46
70
|
'use strict';
|
|
47
71
|
|
|
@@ -54,10 +78,4 @@ describe('When requesting all the user-initiated transaction types', () => {
|
|
|
54
78
|
it('Only nine types should be returned', () => {
|
|
55
79
|
expect(userInitiated.length).toEqual(9);
|
|
56
80
|
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('When validating direction', () => {
|
|
60
|
-
'use strict';
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
});
|
|
81
|
+
});
|