@barchart/portfolio-api-common 1.2.118 → 1.2.123
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/CorporateActionType.js +5 -8
- package/lib/data/TransactionValidator.js +0 -17
- package/lib/formatters/TransactionFormatter.js +137 -153
- package/package.json +1 -1
- package/test/SpecRunner.js +31 -154
- package/test/specs/data/PositionSummaryFrameSpec.js +31 -115
- package/test/specs/data/TransactionValidatorSpec.js +0 -22
|
@@ -11,13 +11,10 @@ module.exports = (() => {
|
|
|
11
11
|
* @extends {Enum}
|
|
12
12
|
* @param {String} code
|
|
13
13
|
* @param {String} description
|
|
14
|
-
* @param {Boolean} internal
|
|
15
14
|
*/
|
|
16
15
|
class CorporateActionType extends Enum {
|
|
17
|
-
constructor(code, description
|
|
16
|
+
constructor(code, description) {
|
|
18
17
|
super(code, description);
|
|
19
|
-
|
|
20
|
-
this._internal = is.boolean(internal) && internal;
|
|
21
18
|
}
|
|
22
19
|
|
|
23
20
|
/**
|
|
@@ -76,14 +73,14 @@ module.exports = (() => {
|
|
|
76
73
|
}
|
|
77
74
|
|
|
78
75
|
/**
|
|
79
|
-
* A
|
|
76
|
+
* A delisting.
|
|
80
77
|
*
|
|
81
78
|
* @public
|
|
82
79
|
* @static
|
|
83
80
|
* @returns {CorporateActionType}
|
|
84
81
|
*/
|
|
85
|
-
static get
|
|
86
|
-
return
|
|
82
|
+
static get DELIST() {
|
|
83
|
+
return delist;
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
86
|
|
|
@@ -91,7 +88,7 @@ module.exports = (() => {
|
|
|
91
88
|
const nameChange = new CorporateActionType('NAME_CHANGE', 'Name Change', false);
|
|
92
89
|
const dividend = new CorporateActionType('DIVIDEND', 'Dividend', false);
|
|
93
90
|
const split = new CorporateActionType('SPLIT', 'Split', false);
|
|
94
|
-
const
|
|
91
|
+
const delist = new CorporateActionType('DELIST', 'Delist', false);
|
|
95
92
|
|
|
96
93
|
return CorporateActionType;
|
|
97
94
|
})();
|
|
@@ -218,23 +218,6 @@ module.exports = (() => {
|
|
|
218
218
|
static validateDirectionSwitch(instrumentType, currentDirection, proposedDirection) {
|
|
219
219
|
return currentDirection === null || instrumentType.canSwitchDirection || (currentDirection.closed || proposedDirection.closed || currentDirection.positive === proposedDirection.positive);
|
|
220
220
|
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Assuming the transaction list is ordered by sequence, validates that
|
|
224
|
-
* no opening transactions exist after delisting date.
|
|
225
|
-
*
|
|
226
|
-
* @static
|
|
227
|
-
* @public
|
|
228
|
-
* @param {Array.<Object>} transactions
|
|
229
|
-
* @returns {Boolean}
|
|
230
|
-
*/
|
|
231
|
-
static validateDelisting(transactions) {
|
|
232
|
-
assert.argumentIsArray(transactions, 'transactions');
|
|
233
|
-
|
|
234
|
-
const delistIndex = transactions.findIndex(t => t.type === TransactionType.DELIST);
|
|
235
|
-
|
|
236
|
-
return delistIndex < 0 || !transactions.some((t, i) => delistIndex < i && t.type.opening);
|
|
237
|
-
}
|
|
238
221
|
|
|
239
222
|
toString() {
|
|
240
223
|
return '[TransactionValidator]';
|
|
@@ -46,32 +46,33 @@ module.exports = (() => {
|
|
|
46
46
|
return map;
|
|
47
47
|
}, { });
|
|
48
48
|
|
|
49
|
-
const
|
|
49
|
+
const list = transactions.reduce((accumulator, transaction) => {
|
|
50
50
|
const position = transaction.position;
|
|
51
51
|
|
|
52
52
|
if (instruments.hasOwnProperty(position)) {
|
|
53
53
|
let instrument = instruments[position];
|
|
54
|
-
let formatted =
|
|
54
|
+
let formatted = { instrument: instrument };
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
const formatterFunction = formatters.get(transaction.type);
|
|
58
|
-
const formattedTransaction = formatterFunction(transaction);
|
|
56
|
+
const formatterFunctions = formatters.get(transaction.type);
|
|
59
57
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
formatterFunctions.forEach((formatterFunction) => {
|
|
59
|
+
formatterFunction(transaction, formatted);
|
|
60
|
+
});
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
});
|
|
62
|
+
Object.keys(formatted).forEach((key) => {
|
|
63
|
+
const value = formatted[key];
|
|
67
64
|
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
if (value instanceof Decimal) {
|
|
66
|
+
const precision = instrument.currency.precision;
|
|
70
67
|
|
|
71
|
-
|
|
68
|
+
formatted[key] = formatter.numberToString(value.toFloat(), precision, ',');
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
accumulator.push(formatted);
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
return
|
|
75
|
+
return accumulator;
|
|
75
76
|
}, [ ]);
|
|
76
77
|
|
|
77
78
|
let comparator;
|
|
@@ -82,13 +83,13 @@ module.exports = (() => {
|
|
|
82
83
|
comparator = comparatorAscending;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
list.sort(comparator);
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
list.forEach((t) => {
|
|
88
89
|
delete t.instrument.id;
|
|
89
90
|
});
|
|
90
91
|
|
|
91
|
-
return
|
|
92
|
+
return list;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
/**
|
|
@@ -120,126 +121,105 @@ module.exports = (() => {
|
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
instrument: i,
|
|
130
|
-
position: t.position
|
|
131
|
-
};
|
|
124
|
+
const basicFormatter = (t, f) => {
|
|
125
|
+
f.date = t.date;
|
|
126
|
+
f.type = t.type.display;
|
|
127
|
+
f.code = t.type.code;
|
|
128
|
+
f.sequence = t.sequence;
|
|
129
|
+
f.position = t.position;
|
|
132
130
|
};
|
|
133
131
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
132
|
+
const averageCostFormatter = (t, f) => {
|
|
133
|
+
const basis = t.snapshot.basis;
|
|
134
|
+
const open = t.snapshot.open;
|
|
135
|
+
|
|
136
|
+
let average;
|
|
137
|
+
|
|
138
|
+
if (basis && open && !open.getIsZero()) {
|
|
139
|
+
average = basis.divide(open).absolute();
|
|
140
|
+
} else {
|
|
141
|
+
average = '';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
f.average = average;
|
|
143
145
|
};
|
|
144
146
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
fee: t.fee
|
|
162
|
-
};
|
|
147
|
+
const buySellFormatter = (t, f) => {
|
|
148
|
+
f.boughtSold = t.quantity;
|
|
149
|
+
f.price = t.trade.price;
|
|
150
|
+
f.fee = t.fee;
|
|
151
|
+
f.total = t.amount;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const dividendFormatter = (t, f) => {
|
|
155
|
+
f.shares = t.snapshot.open;
|
|
156
|
+
f.total = t.dividend.amount;
|
|
157
|
+
f.rate = t.dividend.rate;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const dividendStockFormatter = (t, f) => {
|
|
161
|
+
f.boughtSold = t.quantity;
|
|
162
|
+
f.fee = t.fee;
|
|
163
163
|
|
|
164
164
|
if (t.dividend && t.dividend.rate && t.dividend.price) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
f.shares = t.snapshot.open.subtract(t.quantity);
|
|
166
|
+
f.price = t.dividend.price;
|
|
167
|
+
f.rate = t.dividend.rate;
|
|
168
168
|
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const dividendReinvestFormatter = (t, f) => {
|
|
172
|
+
f.boughtSold = t.quantity;
|
|
173
|
+
f.shares = t.snapshot.open.subtract(t.quantity);
|
|
174
|
+
f.price = t.dividend.price;
|
|
175
|
+
f.fee = t.fee;
|
|
176
|
+
f.rate = t.dividend.rate;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const distributionCashFormatter = (t, f) => {
|
|
180
|
+
f.shares = t.snapshot.open;
|
|
181
|
+
f.total = t.dividend.amount;
|
|
182
|
+
f.rate = t.dividend.rate;
|
|
183
|
+
};
|
|
169
184
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
formatters.set(TransactionType.DIVIDEND_REINVEST, (t) => {
|
|
174
|
-
return {
|
|
175
|
-
boughtSold: t.quantity,
|
|
176
|
-
shares: t.snapshot.open.subtract(t.quantity),
|
|
177
|
-
price: t.dividend.price,
|
|
178
|
-
fee: t.fee,
|
|
179
|
-
rate: t.dividend.rate
|
|
180
|
-
};
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
formatters.set(TransactionType.DISTRIBUTION_CASH, (t) => {
|
|
184
|
-
return {
|
|
185
|
-
shares: t.snapshot.open,
|
|
186
|
-
total: t.dividend.amount,
|
|
187
|
-
rate: t.dividend.rate
|
|
188
|
-
};
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
formatters.set(TransactionType.DISTRIBUTION_FUND, (t) => {
|
|
192
|
-
const data = {
|
|
193
|
-
boughtSold: t.quantity,
|
|
194
|
-
fee: t.fee
|
|
195
|
-
};
|
|
185
|
+
const distributionFundFormatter = (t, f) => {
|
|
186
|
+
f.boughtSold =t.quantity;
|
|
187
|
+
f.fee = t.fee;
|
|
196
188
|
|
|
197
189
|
if (t.dividend && t.dividend.rate && t.dividend.price) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
190
|
+
f.shares = t.snapshot.open.subtract(t.quantity);
|
|
191
|
+
f.price = t.dividend.price;
|
|
192
|
+
f.rate = t.dividend.rate;
|
|
201
193
|
}
|
|
194
|
+
};
|
|
202
195
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return {
|
|
231
|
-
boughtSold: t.quantity
|
|
232
|
-
};
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
formatters.set(TransactionType.SPLIT, (t) => {
|
|
236
|
-
return {
|
|
237
|
-
shares: t.quantity,
|
|
238
|
-
rate: t.split.numerator.divide(t.split.denominator)
|
|
239
|
-
};
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
formatters.set(TransactionType.VALUATION, (t) => {
|
|
196
|
+
const distributionReinvestFormatter = (t, f) => {
|
|
197
|
+
f.boughtSold = t.quantity;
|
|
198
|
+
f.shares = t.snapshot.open.subtract(t.quantity);
|
|
199
|
+
f.price = t.dividend.price;
|
|
200
|
+
f.fee = t.fee;
|
|
201
|
+
f.rate = t.dividend.rate;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const incomeFormatter = (t, f) => {
|
|
205
|
+
f.total = t.income.amount;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const feeFormatter = (t, f) => {
|
|
209
|
+
f.fee = t.charge.amount;
|
|
210
|
+
f.total = t.charge.amount;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const feeUnitsFormatter = (t, f) => {
|
|
214
|
+
f.boughtSold = t.quantity;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const splitFormatter = (t, f) => {
|
|
218
|
+
f.shares = t.quantity;
|
|
219
|
+
f.rate = t.split.numerator.divide(t.split.denominator);
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
const valuationFormatter = (t, f) => {
|
|
243
223
|
let rate;
|
|
244
224
|
|
|
245
225
|
if (t.valuation.rate) {
|
|
@@ -250,39 +230,43 @@ module.exports = (() => {
|
|
|
250
230
|
rate = t.valuation.value.divide(t.snapshot.open);
|
|
251
231
|
}
|
|
252
232
|
|
|
253
|
-
|
|
254
|
-
price: rate
|
|
255
|
-
};
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
formatters.set(TransactionType.DELIST, () => {
|
|
259
|
-
return { };
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
const cashFormatter = (t) => {
|
|
263
|
-
return {
|
|
264
|
-
total: t.quantity
|
|
265
|
-
};
|
|
233
|
+
f.price = rate;
|
|
266
234
|
};
|
|
267
235
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
formatters.set(TransactionType.DEBIT, (t) => {
|
|
272
|
-
const formatted = cashFormatter(t);
|
|
273
|
-
|
|
274
|
-
formatted.description = t.description;
|
|
236
|
+
const cashFormatter = (t, f) => {
|
|
237
|
+
f.total = t.quantity;
|
|
238
|
+
};
|
|
275
239
|
|
|
276
|
-
|
|
277
|
-
|
|
240
|
+
const debitFormatter = (t, f) => {
|
|
241
|
+
f.description = t.description;
|
|
242
|
+
};
|
|
278
243
|
|
|
279
|
-
|
|
280
|
-
|
|
244
|
+
const creditFormatter = (t, f) => {
|
|
245
|
+
f.description = t.description;
|
|
246
|
+
};
|
|
281
247
|
|
|
282
|
-
|
|
248
|
+
const formatters = new Map();
|
|
283
249
|
|
|
284
|
-
|
|
285
|
-
|
|
250
|
+
formatters.set(TransactionType.BUY, [ basicFormatter, buySellFormatter, averageCostFormatter ]);
|
|
251
|
+
formatters.set(TransactionType.SELL, [ basicFormatter, buySellFormatter, averageCostFormatter ]);
|
|
252
|
+
formatters.set(TransactionType.BUY_SHORT, [ basicFormatter, buySellFormatter, averageCostFormatter ]);
|
|
253
|
+
formatters.set(TransactionType.SELL_SHORT, [ basicFormatter, buySellFormatter, averageCostFormatter ]);
|
|
254
|
+
formatters.set(TransactionType.DIVIDEND, [ basicFormatter, dividendFormatter, averageCostFormatter ]);
|
|
255
|
+
formatters.set(TransactionType.DIVIDEND_STOCK, [ basicFormatter, dividendStockFormatter, averageCostFormatter ]);
|
|
256
|
+
formatters.set(TransactionType.DIVIDEND_REINVEST, [ basicFormatter, dividendReinvestFormatter, averageCostFormatter ]);
|
|
257
|
+
formatters.set(TransactionType.DISTRIBUTION_CASH, [ basicFormatter, distributionCashFormatter, averageCostFormatter ]);
|
|
258
|
+
formatters.set(TransactionType.DISTRIBUTION_FUND, [ basicFormatter, distributionFundFormatter, averageCostFormatter ]);
|
|
259
|
+
formatters.set(TransactionType.DISTRIBUTION_REINVEST, [ basicFormatter, distributionReinvestFormatter, averageCostFormatter ]);
|
|
260
|
+
formatters.set(TransactionType.INCOME, [ basicFormatter, incomeFormatter, averageCostFormatter ]);
|
|
261
|
+
formatters.set(TransactionType.FEE, [ basicFormatter, feeFormatter, averageCostFormatter ]);
|
|
262
|
+
formatters.set(TransactionType.FEE_UNITS, [ basicFormatter, feeUnitsFormatter, averageCostFormatter ]);
|
|
263
|
+
formatters.set(TransactionType.SPLIT, [ basicFormatter, splitFormatter, averageCostFormatter ]);
|
|
264
|
+
formatters.set(TransactionType.VALUATION, [ basicFormatter, valuationFormatter, averageCostFormatter ]);
|
|
265
|
+
formatters.set(TransactionType.DELIST, [ basicFormatter, averageCostFormatter ]);
|
|
266
|
+
formatters.set(TransactionType.DEPOSIT, [ basicFormatter, cashFormatter ]);
|
|
267
|
+
formatters.set(TransactionType.WITHDRAWAL, [ basicFormatter, cashFormatter ]);
|
|
268
|
+
formatters.set(TransactionType.DEBIT, [ basicFormatter, cashFormatter, debitFormatter ]);
|
|
269
|
+
formatters.set(TransactionType.CREDIT, [ basicFormatter, cashFormatter, creditFormatter ]);
|
|
286
270
|
|
|
287
271
|
function getInstrumentTypePriority(type) {
|
|
288
272
|
if (type === InstrumentType.CASH) {
|
package/package.json
CHANGED
package/test/SpecRunner.js
CHANGED
|
@@ -1386,23 +1386,6 @@ module.exports = (() => {
|
|
|
1386
1386
|
static validateDirectionSwitch(instrumentType, currentDirection, proposedDirection) {
|
|
1387
1387
|
return currentDirection === null || instrumentType.canSwitchDirection || (currentDirection.closed || proposedDirection.closed || currentDirection.positive === proposedDirection.positive);
|
|
1388
1388
|
}
|
|
1389
|
-
|
|
1390
|
-
/**
|
|
1391
|
-
* Assuming the transaction list is ordered by sequence, validates that
|
|
1392
|
-
* no opening transactions exist after delisting date.
|
|
1393
|
-
*
|
|
1394
|
-
* @static
|
|
1395
|
-
* @public
|
|
1396
|
-
* @param {Array.<Object>} transactions
|
|
1397
|
-
* @returns {Boolean}
|
|
1398
|
-
*/
|
|
1399
|
-
static validateDelisting(transactions) {
|
|
1400
|
-
assert.argumentIsArray(transactions, 'transactions');
|
|
1401
|
-
|
|
1402
|
-
const delistIndex = transactions.findIndex(t => t.type === TransactionType.DELIST);
|
|
1403
|
-
|
|
1404
|
-
return delistIndex < 0 || !transactions.some((t, i) => delistIndex < i && t.type.opening);
|
|
1405
|
-
}
|
|
1406
1389
|
|
|
1407
1390
|
toString() {
|
|
1408
1391
|
return '[TransactionValidator]';
|
|
@@ -17639,8 +17622,8 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17639
17622
|
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
17640
17623
|
});
|
|
17641
17624
|
|
|
17642
|
-
it('should have
|
|
17643
|
-
expect(ranges.length).toEqual(
|
|
17625
|
+
it('should have four ranges (assuming the current year is 2019)', () => {
|
|
17626
|
+
expect(ranges.length).toEqual(4);
|
|
17644
17627
|
});
|
|
17645
17628
|
|
|
17646
17629
|
it('the first range should be from 12-31-2014 to 12-31-2015', () => {
|
|
@@ -17657,6 +17640,11 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17657
17640
|
expect(ranges[2].start.format()).toEqual('2016-12-31');
|
|
17658
17641
|
expect(ranges[2].end.format()).toEqual('2017-12-31');
|
|
17659
17642
|
});
|
|
17643
|
+
|
|
17644
|
+
it('the fourth range should be from 12-31-2017 to 12-31-2018', () => {
|
|
17645
|
+
expect(ranges[3].start.format()).toEqual('2017-12-31');
|
|
17646
|
+
expect(ranges[3].end.format()).toEqual('2018-12-31');
|
|
17647
|
+
});
|
|
17660
17648
|
});
|
|
17661
17649
|
|
|
17662
17650
|
describe('and yearly position summary ranges are processed for a transaction set closes the same year', () => {
|
|
@@ -17732,7 +17720,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17732
17720
|
});
|
|
17733
17721
|
});
|
|
17734
17722
|
|
|
17735
|
-
describe('and yearly position summary ranges are processed for a transaction set
|
|
17723
|
+
describe('and yearly position summary ranges are processed for a transaction set that opens in 2015 and closes in 2017', () => {
|
|
17736
17724
|
let ranges;
|
|
17737
17725
|
|
|
17738
17726
|
beforeEach(() => {
|
|
@@ -17756,7 +17744,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17756
17744
|
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
17757
17745
|
});
|
|
17758
17746
|
|
|
17759
|
-
it('should have
|
|
17747
|
+
it('should have three ranges', () => {
|
|
17760
17748
|
expect(ranges.length).toEqual(3);
|
|
17761
17749
|
});
|
|
17762
17750
|
|
|
@@ -17776,7 +17764,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17776
17764
|
});
|
|
17777
17765
|
});
|
|
17778
17766
|
|
|
17779
|
-
describe('and yearly position summary ranges are processed for a transaction set
|
|
17767
|
+
describe('and yearly position summary ranges are processed for a transaction set that opens in 2019 and closes in 2016, but has after-the-fact superfluous valuations in 2017 and 2018', () => {
|
|
17780
17768
|
let ranges;
|
|
17781
17769
|
|
|
17782
17770
|
beforeEach(() => {
|
|
@@ -17829,7 +17817,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17829
17817
|
});
|
|
17830
17818
|
});
|
|
17831
17819
|
|
|
17832
|
-
describe('and a year-to-date position summary ranges are processed for a transaction set that closed
|
|
17820
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that closed in 2017', () => {
|
|
17833
17821
|
let ranges;
|
|
17834
17822
|
|
|
17835
17823
|
beforeEach(() => {
|
|
@@ -17858,13 +17846,13 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17858
17846
|
});
|
|
17859
17847
|
});
|
|
17860
17848
|
|
|
17861
|
-
describe('and a year-to-date position summary ranges are processed for a transaction set that opened this year and has not yet closed', () => {
|
|
17849
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that opened this year and has not yet closed (assuming its 2019)', () => {
|
|
17862
17850
|
let ranges;
|
|
17863
17851
|
|
|
17864
17852
|
beforeEach(() => {
|
|
17865
17853
|
const transactions = [
|
|
17866
17854
|
{
|
|
17867
|
-
date: new Day(
|
|
17855
|
+
date: new Day(2019, 1, 1),
|
|
17868
17856
|
snapshot: {
|
|
17869
17857
|
open: new Decimal(100)
|
|
17870
17858
|
},
|
|
@@ -17879,26 +17867,26 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17879
17867
|
expect(ranges.length).toEqual(1);
|
|
17880
17868
|
});
|
|
17881
17869
|
|
|
17882
|
-
it('the first range should be from 12-31-
|
|
17883
|
-
expect(ranges[0].start.format()).toEqual('
|
|
17884
|
-
expect(ranges[0].end.format()).toEqual('
|
|
17870
|
+
it('the first range should be from 12-31-2018 to 12-31-2019', () => {
|
|
17871
|
+
expect(ranges[0].start.format()).toEqual('2018-12-31');
|
|
17872
|
+
expect(ranges[0].end.format()).toEqual('2019-12-31');
|
|
17885
17873
|
});
|
|
17886
17874
|
});
|
|
17887
17875
|
|
|
17888
|
-
describe('and a year-to-date position summary ranges are processed for a transaction set that opened and closed
|
|
17876
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that that opened and closed in 2019', () => {
|
|
17889
17877
|
let ranges;
|
|
17890
17878
|
|
|
17891
17879
|
beforeEach(() => {
|
|
17892
17880
|
const transactions = [
|
|
17893
17881
|
{
|
|
17894
|
-
date: new Day(
|
|
17882
|
+
date: new Day(2019, 1, 1),
|
|
17895
17883
|
snapshot: {
|
|
17896
17884
|
open: new Decimal(1)
|
|
17897
17885
|
},
|
|
17898
17886
|
type: TransactionType.BUY
|
|
17899
17887
|
},
|
|
17900
17888
|
{
|
|
17901
|
-
date: new Day(
|
|
17889
|
+
date: new Day(2019, 1, 2),
|
|
17902
17890
|
snapshot: {
|
|
17903
17891
|
open: new Decimal(0)
|
|
17904
17892
|
},
|
|
@@ -17913,62 +17901,20 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17913
17901
|
expect(ranges.length).toEqual(1);
|
|
17914
17902
|
});
|
|
17915
17903
|
|
|
17916
|
-
it('the first range should be from 12-31-
|
|
17917
|
-
expect(ranges[0].start.format()).toEqual('
|
|
17918
|
-
expect(ranges[0].end.format()).toEqual('
|
|
17919
|
-
});
|
|
17920
|
-
});
|
|
17921
|
-
|
|
17922
|
-
describe('and month position summary ranges are processed for a transaction set that does not close', () => {
|
|
17923
|
-
let ranges;
|
|
17924
|
-
|
|
17925
|
-
beforeEach(() => {
|
|
17926
|
-
const transactions = [
|
|
17927
|
-
{
|
|
17928
|
-
date: new Day(2018, 10, 20),
|
|
17929
|
-
snapshot: {
|
|
17930
|
-
open: new Decimal(1)
|
|
17931
|
-
},
|
|
17932
|
-
type: TransactionType.BUY
|
|
17933
|
-
},
|
|
17934
|
-
{
|
|
17935
|
-
date: new Day(2018, 11, 21),
|
|
17936
|
-
snapshot: {
|
|
17937
|
-
open: new Decimal(1)
|
|
17938
|
-
},
|
|
17939
|
-
type: TransactionType.BUY
|
|
17940
|
-
}
|
|
17941
|
-
];
|
|
17942
|
-
|
|
17943
|
-
ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
|
|
17944
|
-
});
|
|
17945
|
-
|
|
17946
|
-
it('should have three ranges (assuming the current year is 2018 and the current month is December)', () => {
|
|
17947
|
-
expect(ranges.length).toEqual(3);
|
|
17948
|
-
});
|
|
17949
|
-
|
|
17950
|
-
it('the first range should be from 2018-09-30 to 2018-10-31', () => {
|
|
17951
|
-
expect(ranges[0].start.format()).toEqual('2018-09-30');
|
|
17952
|
-
expect(ranges[0].end.format()).toEqual('2018-10-31');
|
|
17953
|
-
});
|
|
17954
|
-
|
|
17955
|
-
it('the second range should be from 2018-10-31 to 2018-11-30', () => {
|
|
17956
|
-
expect(ranges[1].start.format()).toEqual('2018-10-31');
|
|
17957
|
-
expect(ranges[1].end.format()).toEqual('2018-11-30');
|
|
17958
|
-
});
|
|
17959
|
-
|
|
17960
|
-
it('the third range should be from 2018-10-31 to 2018-11-30', () => {
|
|
17961
|
-
expect(ranges[2].start.format()).toEqual('2018-11-30');
|
|
17962
|
-
expect(ranges[2].end.format()).toEqual('2018-12-31');
|
|
17904
|
+
it('the first range should be from 12-31-2018 to 12-31-2019', () => {
|
|
17905
|
+
expect(ranges[0].start.format()).toEqual('2018-12-31');
|
|
17906
|
+
expect(ranges[0].end.format()).toEqual('2019-12-31');
|
|
17963
17907
|
});
|
|
17964
17908
|
});
|
|
17965
17909
|
|
|
17966
17910
|
describe('and getting the start date for yearly frames', () => {
|
|
17967
|
-
describe('for one year ago',
|
|
17911
|
+
describe('for one year ago', () => {
|
|
17968
17912
|
let start;
|
|
17913
|
+
let today;
|
|
17969
17914
|
|
|
17970
17915
|
beforeEach(() => {
|
|
17971
17916
|
start = PositionSummaryFrame.YEARLY.getStartDate(1);
|
|
17917
|
+
today = new Date();
|
|
17972
17918
|
});
|
|
17973
17919
|
|
|
17974
17920
|
it('should be in December', () => {
|
|
@@ -17980,15 +17926,17 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17980
17926
|
});
|
|
17981
17927
|
|
|
17982
17928
|
it('should be two years ago', () => {
|
|
17983
|
-
expect(start.year).toEqual(
|
|
17929
|
+
expect(start.year).toEqual(today.getFullYear() - 2);
|
|
17984
17930
|
});
|
|
17985
17931
|
});
|
|
17986
17932
|
|
|
17987
|
-
describe('for two years ago',
|
|
17933
|
+
describe('for two years ago', () => {
|
|
17988
17934
|
let start;
|
|
17935
|
+
let today;
|
|
17989
17936
|
|
|
17990
17937
|
beforeEach(() => {
|
|
17991
17938
|
start = PositionSummaryFrame.YEARLY.getStartDate(2);
|
|
17939
|
+
today = new Date();
|
|
17992
17940
|
});
|
|
17993
17941
|
|
|
17994
17942
|
it('should be in December', () => {
|
|
@@ -17999,61 +17947,12 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
17999
17947
|
expect(start.day).toEqual(31);
|
|
18000
17948
|
});
|
|
18001
17949
|
|
|
18002
|
-
it('should be
|
|
18003
|
-
expect(start.year).toEqual(
|
|
18004
|
-
});
|
|
18005
|
-
});
|
|
18006
|
-
});
|
|
18007
|
-
|
|
18008
|
-
|
|
18009
|
-
|
|
18010
|
-
|
|
18011
|
-
////
|
|
18012
|
-
|
|
18013
|
-
describe('and getting the start date for monthly frames', () => {
|
|
18014
|
-
describe('for one month ago', function () {
|
|
18015
|
-
let start;
|
|
18016
|
-
|
|
18017
|
-
beforeEach(() => {
|
|
18018
|
-
start = PositionSummaryFrame.MONTHLY.getStartDate(1);
|
|
18019
|
-
});
|
|
18020
|
-
|
|
18021
|
-
it('should be on the last day of month', () => {
|
|
18022
|
-
const today = Day.getToday();
|
|
18023
|
-
|
|
18024
|
-
expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 2));
|
|
18025
|
-
});
|
|
18026
|
-
|
|
18027
|
-
it('should be month ago', () => {
|
|
18028
|
-
expect(start.month).toEqual(Day.getToday().month - 2);
|
|
17950
|
+
it('should be three years ago', () => {
|
|
17951
|
+
expect(start.year).toEqual(today.getFullYear() - 3);
|
|
18029
17952
|
});
|
|
18030
17953
|
});
|
|
18031
|
-
|
|
18032
|
-
describe('for three months ago', function () {
|
|
18033
|
-
let start;
|
|
18034
|
-
|
|
18035
|
-
beforeEach(() => {
|
|
18036
|
-
start = PositionSummaryFrame.MONTHLY.getStartDate(3);
|
|
18037
|
-
});
|
|
18038
|
-
|
|
18039
|
-
it('should be on the last day of month', () => {
|
|
18040
|
-
const today = Day.getToday();
|
|
18041
|
-
|
|
18042
|
-
expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 4));
|
|
18043
|
-
});
|
|
18044
|
-
|
|
18045
|
-
it('should be 3 month ago', () => {
|
|
18046
|
-
expect(start.month).toEqual(Day.getToday().month - 4);
|
|
18047
|
-
});
|
|
18048
|
-
});
|
|
18049
17954
|
});
|
|
18050
17955
|
|
|
18051
|
-
////
|
|
18052
|
-
|
|
18053
|
-
|
|
18054
|
-
|
|
18055
|
-
|
|
18056
|
-
|
|
18057
17956
|
describe('and recent ranges are calculated', () => {
|
|
18058
17957
|
let todayYear;
|
|
18059
17958
|
let todayMonth;
|
|
@@ -18239,28 +18138,6 @@ describe('When validating transaction references', () => {
|
|
|
18239
18138
|
});
|
|
18240
18139
|
});
|
|
18241
18140
|
|
|
18242
|
-
describe('When validating transactions which could include instrument delisting', () => {
|
|
18243
|
-
const build = (type) => {
|
|
18244
|
-
return { type: type };
|
|
18245
|
-
};
|
|
18246
|
-
|
|
18247
|
-
it('An array without a DELSIT transaction should be valid', () => {
|
|
18248
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL) ])).toEqual(true);
|
|
18249
|
-
});
|
|
18250
|
-
|
|
18251
|
-
it('An array with a final DELSIT transaction should be valid', () => {
|
|
18252
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL), build(TransactionType.DELIST) ])).toEqual(true);
|
|
18253
|
-
});
|
|
18254
|
-
|
|
18255
|
-
it('An array with a closing transaction after a DELIST transaction should be valid', () => {
|
|
18256
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL), build(TransactionType.DELIST), build(TransactionType.SELL) ])).toEqual(true);
|
|
18257
|
-
});
|
|
18258
|
-
|
|
18259
|
-
it('An array with an opening transaction after a DELIST transaction should not be valid', () => {
|
|
18260
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL), build(TransactionType.DELIST), build(TransactionType.BUY) ])).toEqual(false);
|
|
18261
|
-
});
|
|
18262
|
-
});
|
|
18263
|
-
|
|
18264
18141
|
describe('When requesting all the user-initiated transaction types', () => {
|
|
18265
18142
|
'use strict';
|
|
18266
18143
|
|
|
@@ -31,8 +31,8 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
31
31
|
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
it('should have
|
|
35
|
-
expect(ranges.length).toEqual(
|
|
34
|
+
it('should have four ranges (assuming the current year is 2019)', () => {
|
|
35
|
+
expect(ranges.length).toEqual(4);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
it('the first range should be from 12-31-2014 to 12-31-2015', () => {
|
|
@@ -49,6 +49,11 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
49
49
|
expect(ranges[2].start.format()).toEqual('2016-12-31');
|
|
50
50
|
expect(ranges[2].end.format()).toEqual('2017-12-31');
|
|
51
51
|
});
|
|
52
|
+
|
|
53
|
+
it('the fourth range should be from 12-31-2017 to 12-31-2018', () => {
|
|
54
|
+
expect(ranges[3].start.format()).toEqual('2017-12-31');
|
|
55
|
+
expect(ranges[3].end.format()).toEqual('2018-12-31');
|
|
56
|
+
});
|
|
52
57
|
});
|
|
53
58
|
|
|
54
59
|
describe('and yearly position summary ranges are processed for a transaction set closes the same year', () => {
|
|
@@ -124,7 +129,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
124
129
|
});
|
|
125
130
|
});
|
|
126
131
|
|
|
127
|
-
describe('and yearly position summary ranges are processed for a transaction set
|
|
132
|
+
describe('and yearly position summary ranges are processed for a transaction set that opens in 2015 and closes in 2017', () => {
|
|
128
133
|
let ranges;
|
|
129
134
|
|
|
130
135
|
beforeEach(() => {
|
|
@@ -148,7 +153,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
148
153
|
ranges = PositionSummaryFrame.YEARLY.getRanges(transactions);
|
|
149
154
|
});
|
|
150
155
|
|
|
151
|
-
it('should have
|
|
156
|
+
it('should have three ranges', () => {
|
|
152
157
|
expect(ranges.length).toEqual(3);
|
|
153
158
|
});
|
|
154
159
|
|
|
@@ -168,7 +173,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
168
173
|
});
|
|
169
174
|
});
|
|
170
175
|
|
|
171
|
-
describe('and yearly position summary ranges are processed for a transaction set
|
|
176
|
+
describe('and yearly position summary ranges are processed for a transaction set that opens in 2019 and closes in 2016, but has after-the-fact superfluous valuations in 2017 and 2018', () => {
|
|
172
177
|
let ranges;
|
|
173
178
|
|
|
174
179
|
beforeEach(() => {
|
|
@@ -221,7 +226,7 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
221
226
|
});
|
|
222
227
|
});
|
|
223
228
|
|
|
224
|
-
describe('and a year-to-date position summary ranges are processed for a transaction set that closed
|
|
229
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that closed in 2017', () => {
|
|
225
230
|
let ranges;
|
|
226
231
|
|
|
227
232
|
beforeEach(() => {
|
|
@@ -250,13 +255,13 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
250
255
|
});
|
|
251
256
|
});
|
|
252
257
|
|
|
253
|
-
describe('and a year-to-date position summary ranges are processed for a transaction set that opened this year and has not yet closed', () => {
|
|
258
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that opened this year and has not yet closed (assuming its 2019)', () => {
|
|
254
259
|
let ranges;
|
|
255
260
|
|
|
256
261
|
beforeEach(() => {
|
|
257
262
|
const transactions = [
|
|
258
263
|
{
|
|
259
|
-
date: new Day(
|
|
264
|
+
date: new Day(2019, 1, 1),
|
|
260
265
|
snapshot: {
|
|
261
266
|
open: new Decimal(100)
|
|
262
267
|
},
|
|
@@ -271,26 +276,26 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
271
276
|
expect(ranges.length).toEqual(1);
|
|
272
277
|
});
|
|
273
278
|
|
|
274
|
-
it('the first range should be from 12-31-
|
|
275
|
-
expect(ranges[0].start.format()).toEqual('
|
|
276
|
-
expect(ranges[0].end.format()).toEqual('
|
|
279
|
+
it('the first range should be from 12-31-2018 to 12-31-2019', () => {
|
|
280
|
+
expect(ranges[0].start.format()).toEqual('2018-12-31');
|
|
281
|
+
expect(ranges[0].end.format()).toEqual('2019-12-31');
|
|
277
282
|
});
|
|
278
283
|
});
|
|
279
284
|
|
|
280
|
-
describe('and a year-to-date position summary ranges are processed for a transaction set that opened and closed
|
|
285
|
+
describe('and a year-to-date position summary ranges are processed for a transaction set that that opened and closed in 2019', () => {
|
|
281
286
|
let ranges;
|
|
282
287
|
|
|
283
288
|
beforeEach(() => {
|
|
284
289
|
const transactions = [
|
|
285
290
|
{
|
|
286
|
-
date: new Day(
|
|
291
|
+
date: new Day(2019, 1, 1),
|
|
287
292
|
snapshot: {
|
|
288
293
|
open: new Decimal(1)
|
|
289
294
|
},
|
|
290
295
|
type: TransactionType.BUY
|
|
291
296
|
},
|
|
292
297
|
{
|
|
293
|
-
date: new Day(
|
|
298
|
+
date: new Day(2019, 1, 2),
|
|
294
299
|
snapshot: {
|
|
295
300
|
open: new Decimal(0)
|
|
296
301
|
},
|
|
@@ -305,62 +310,20 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
305
310
|
expect(ranges.length).toEqual(1);
|
|
306
311
|
});
|
|
307
312
|
|
|
308
|
-
it('the first range should be from 12-31-
|
|
309
|
-
expect(ranges[0].start.format()).toEqual('
|
|
310
|
-
expect(ranges[0].end.format()).toEqual('
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
describe('and month position summary ranges are processed for a transaction set that does not close', () => {
|
|
315
|
-
let ranges;
|
|
316
|
-
|
|
317
|
-
beforeEach(() => {
|
|
318
|
-
const transactions = [
|
|
319
|
-
{
|
|
320
|
-
date: new Day(2018, 10, 20),
|
|
321
|
-
snapshot: {
|
|
322
|
-
open: new Decimal(1)
|
|
323
|
-
},
|
|
324
|
-
type: TransactionType.BUY
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
date: new Day(2018, 11, 21),
|
|
328
|
-
snapshot: {
|
|
329
|
-
open: new Decimal(1)
|
|
330
|
-
},
|
|
331
|
-
type: TransactionType.BUY
|
|
332
|
-
}
|
|
333
|
-
];
|
|
334
|
-
|
|
335
|
-
ranges = PositionSummaryFrame.MONTHLY.getRanges(transactions);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
it('should have three ranges (assuming the current year is 2018 and the current month is December)', () => {
|
|
339
|
-
expect(ranges.length).toEqual(3);
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
it('the first range should be from 2018-09-30 to 2018-10-31', () => {
|
|
343
|
-
expect(ranges[0].start.format()).toEqual('2018-09-30');
|
|
344
|
-
expect(ranges[0].end.format()).toEqual('2018-10-31');
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
it('the second range should be from 2018-10-31 to 2018-11-30', () => {
|
|
348
|
-
expect(ranges[1].start.format()).toEqual('2018-10-31');
|
|
349
|
-
expect(ranges[1].end.format()).toEqual('2018-11-30');
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
it('the third range should be from 2018-10-31 to 2018-11-30', () => {
|
|
353
|
-
expect(ranges[2].start.format()).toEqual('2018-11-30');
|
|
354
|
-
expect(ranges[2].end.format()).toEqual('2018-12-31');
|
|
313
|
+
it('the first range should be from 12-31-2018 to 12-31-2019', () => {
|
|
314
|
+
expect(ranges[0].start.format()).toEqual('2018-12-31');
|
|
315
|
+
expect(ranges[0].end.format()).toEqual('2019-12-31');
|
|
355
316
|
});
|
|
356
317
|
});
|
|
357
318
|
|
|
358
319
|
describe('and getting the start date for yearly frames', () => {
|
|
359
|
-
describe('for one year ago',
|
|
320
|
+
describe('for one year ago', () => {
|
|
360
321
|
let start;
|
|
322
|
+
let today;
|
|
361
323
|
|
|
362
324
|
beforeEach(() => {
|
|
363
325
|
start = PositionSummaryFrame.YEARLY.getStartDate(1);
|
|
326
|
+
today = new Date();
|
|
364
327
|
});
|
|
365
328
|
|
|
366
329
|
it('should be in December', () => {
|
|
@@ -372,15 +335,17 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
372
335
|
});
|
|
373
336
|
|
|
374
337
|
it('should be two years ago', () => {
|
|
375
|
-
expect(start.year).toEqual(
|
|
338
|
+
expect(start.year).toEqual(today.getFullYear() - 2);
|
|
376
339
|
});
|
|
377
340
|
});
|
|
378
341
|
|
|
379
|
-
describe('for two years ago',
|
|
342
|
+
describe('for two years ago', () => {
|
|
380
343
|
let start;
|
|
344
|
+
let today;
|
|
381
345
|
|
|
382
346
|
beforeEach(() => {
|
|
383
347
|
start = PositionSummaryFrame.YEARLY.getStartDate(2);
|
|
348
|
+
today = new Date();
|
|
384
349
|
});
|
|
385
350
|
|
|
386
351
|
it('should be in December', () => {
|
|
@@ -391,61 +356,12 @@ describe('After the PositionSummaryFrame enumeration is initialized', () => {
|
|
|
391
356
|
expect(start.day).toEqual(31);
|
|
392
357
|
});
|
|
393
358
|
|
|
394
|
-
it('should be
|
|
395
|
-
expect(start.year).toEqual(
|
|
359
|
+
it('should be three years ago', () => {
|
|
360
|
+
expect(start.year).toEqual(today.getFullYear() - 3);
|
|
396
361
|
});
|
|
397
362
|
});
|
|
398
363
|
});
|
|
399
364
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
////
|
|
404
|
-
|
|
405
|
-
describe('and getting the start date for monthly frames', () => {
|
|
406
|
-
describe('for one month ago', function () {
|
|
407
|
-
let start;
|
|
408
|
-
|
|
409
|
-
beforeEach(() => {
|
|
410
|
-
start = PositionSummaryFrame.MONTHLY.getStartDate(1);
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
it('should be on the last day of month', () => {
|
|
414
|
-
const today = Day.getToday();
|
|
415
|
-
|
|
416
|
-
expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 2));
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
it('should be month ago', () => {
|
|
420
|
-
expect(start.month).toEqual(Day.getToday().month - 2);
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
describe('for three months ago', function () {
|
|
425
|
-
let start;
|
|
426
|
-
|
|
427
|
-
beforeEach(() => {
|
|
428
|
-
start = PositionSummaryFrame.MONTHLY.getStartDate(3);
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
it('should be on the last day of month', () => {
|
|
432
|
-
const today = Day.getToday();
|
|
433
|
-
|
|
434
|
-
expect(start.day).toEqual(Day.getDaysInMonth(today.year, today.month - 4));
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
it('should be 3 month ago', () => {
|
|
438
|
-
expect(start.month).toEqual(Day.getToday().month - 4);
|
|
439
|
-
});
|
|
440
|
-
});
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
////
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
365
|
describe('and recent ranges are calculated', () => {
|
|
450
366
|
let todayYear;
|
|
451
367
|
let todayMonth;
|
|
@@ -79,28 +79,6 @@ describe('When validating transaction references', () => {
|
|
|
79
79
|
});
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
describe('When validating transactions which could include instrument delisting', () => {
|
|
83
|
-
const build = (type) => {
|
|
84
|
-
return { type: type };
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
it('An array without a DELSIT transaction should be valid', () => {
|
|
88
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL) ])).toEqual(true);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('An array with a final DELSIT transaction should be valid', () => {
|
|
92
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL), build(TransactionType.DELIST) ])).toEqual(true);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('An array with a closing transaction after a DELIST transaction should be valid', () => {
|
|
96
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL), build(TransactionType.DELIST), build(TransactionType.SELL) ])).toEqual(true);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('An array with an opening transaction after a DELIST transaction should not be valid', () => {
|
|
100
|
-
expect(TransactionValidator.validateDelisting([ build(TransactionType.BUY), build(TransactionType.SELL), build(TransactionType.DELIST), build(TransactionType.BUY) ])).toEqual(false);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
82
|
describe('When requesting all the user-initiated transaction types', () => {
|
|
105
83
|
'use strict';
|
|
106
84
|
|