add multi-date fetch for current values
This commit is contained in:
parent
66e7ad3fd2
commit
04e03bd080
@ -937,230 +937,232 @@ describe('PortfolioCalculator', () => {
|
|||||||
'2021-06-30'
|
'2021-06-30'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(timeline).toEqual([
|
expect(timeline).toEqual(
|
||||||
{
|
expect.objectContaining([
|
||||||
date: '2019-01-01',
|
{
|
||||||
grossPerformance: new Big('0'),
|
date: '2019-01-01',
|
||||||
investment: new Big('0'),
|
grossPerformance: new Big('0'),
|
||||||
value: new Big('0')
|
investment: new Big('0'),
|
||||||
},
|
value: new Big('0')
|
||||||
{
|
},
|
||||||
date: '2020-01-01',
|
{
|
||||||
grossPerformance: new Big('498.3'),
|
date: '2020-01-01',
|
||||||
investment: new Big('2923.7'),
|
grossPerformance: new Big('498.3'),
|
||||||
value: new Big('3422') // 20 * (144.38 + days=335 * 0.08)
|
investment: new Big('2923.7'),
|
||||||
},
|
value: new Big('3422') // 20 * (144.38 + days=335 * 0.08)
|
||||||
{
|
},
|
||||||
date: '2021-01-01',
|
{
|
||||||
grossPerformance: new Big('349.35'),
|
date: '2021-01-01',
|
||||||
investment: new Big('652.55'),
|
grossPerformance: new Big('349.35'),
|
||||||
value: new Big('1001.9') // 5 * (144.38 + days=700 * 0.08)
|
investment: new Big('652.55'),
|
||||||
},
|
value: new Big('1001.9') // 5 * (144.38 + days=700 * 0.08)
|
||||||
{
|
},
|
||||||
date: '2021-02-01',
|
{
|
||||||
grossPerformance: new Big('358.85'),
|
date: '2021-02-01',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('358.85'),
|
||||||
value: new Big('3042.9') // 15 * (144.38 + days=731 * 0.08)
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3042.9') // 15 * (144.38 + days=731 * 0.08)
|
||||||
{
|
},
|
||||||
date: '2021-03-01',
|
{
|
||||||
grossPerformance: new Big('392.45'),
|
date: '2021-03-01',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('392.45'),
|
||||||
value: new Big('3076.5') // 15 * (144.38 + days=759 * 0.08)
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3076.5') // 15 * (144.38 + days=759 * 0.08)
|
||||||
{
|
},
|
||||||
date: '2021-04-01',
|
{
|
||||||
grossPerformance: new Big('429.65'),
|
date: '2021-04-01',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('429.65'),
|
||||||
value: new Big('3113.7') // 15 * (144.38 + days=790 * 0.08)
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3113.7') // 15 * (144.38 + days=790 * 0.08)
|
||||||
{
|
},
|
||||||
date: '2021-05-01',
|
{
|
||||||
grossPerformance: new Big('465.65'),
|
date: '2021-05-01',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('465.65'),
|
||||||
value: new Big('3149.7') // 15 * (144.38 + days=820 * 0.08)
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3149.7') // 15 * (144.38 + days=820 * 0.08)
|
||||||
{
|
},
|
||||||
date: '2021-06-01',
|
{
|
||||||
grossPerformance: new Big('502.85'),
|
date: '2021-06-01',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('502.85'),
|
||||||
value: new Big('3186.9') // 15 * (144.38 + days=851 * 0.08)
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3186.9') // 15 * (144.38 + days=851 * 0.08)
|
||||||
{
|
},
|
||||||
date: '2021-06-02',
|
{
|
||||||
grossPerformance: new Big('504.05'),
|
date: '2021-06-02',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('504.05'),
|
||||||
value: new Big('3188.1') // 15 * (144.38 + days=852 * 0.08) / +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3188.1') // 15 * (144.38 + days=852 * 0.08) / +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-03',
|
{
|
||||||
grossPerformance: new Big('505.25'),
|
date: '2021-06-03',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('505.25'),
|
||||||
value: new Big('3189.3') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3189.3') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-04',
|
{
|
||||||
grossPerformance: new Big('506.45'),
|
date: '2021-06-04',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('506.45'),
|
||||||
value: new Big('3190.5') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3190.5') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-05',
|
{
|
||||||
grossPerformance: new Big('507.65'),
|
date: '2021-06-05',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('507.65'),
|
||||||
value: new Big('3191.7') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3191.7') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-06',
|
{
|
||||||
grossPerformance: new Big('508.85'),
|
date: '2021-06-06',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('508.85'),
|
||||||
value: new Big('3192.9') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3192.9') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-07',
|
{
|
||||||
grossPerformance: new Big('510.05'),
|
date: '2021-06-07',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('510.05'),
|
||||||
value: new Big('3194.1') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3194.1') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-08',
|
{
|
||||||
grossPerformance: new Big('511.25'),
|
date: '2021-06-08',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('511.25'),
|
||||||
value: new Big('3195.3') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3195.3') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-09',
|
{
|
||||||
grossPerformance: new Big('512.45'),
|
date: '2021-06-09',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('512.45'),
|
||||||
value: new Big('3196.5') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3196.5') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-10',
|
{
|
||||||
grossPerformance: new Big('513.65'),
|
date: '2021-06-10',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('513.65'),
|
||||||
value: new Big('3197.7') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3197.7') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-11',
|
{
|
||||||
grossPerformance: new Big('514.85'),
|
date: '2021-06-11',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('514.85'),
|
||||||
value: new Big('3198.9') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3198.9') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-12',
|
{
|
||||||
grossPerformance: new Big('516.05'),
|
date: '2021-06-12',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('516.05'),
|
||||||
value: new Big('3200.1') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3200.1') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-13',
|
{
|
||||||
grossPerformance: new Big('517.25'),
|
date: '2021-06-13',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('517.25'),
|
||||||
value: new Big('3201.3') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3201.3') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-14',
|
{
|
||||||
grossPerformance: new Big('518.45'),
|
date: '2021-06-14',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('518.45'),
|
||||||
value: new Big('3202.5') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3202.5') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-15',
|
{
|
||||||
grossPerformance: new Big('519.65'),
|
date: '2021-06-15',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('519.65'),
|
||||||
value: new Big('3203.7') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3203.7') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-16',
|
{
|
||||||
grossPerformance: new Big('520.85'),
|
date: '2021-06-16',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('520.85'),
|
||||||
value: new Big('3204.9') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3204.9') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-17',
|
{
|
||||||
grossPerformance: new Big('522.05'),
|
date: '2021-06-17',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('522.05'),
|
||||||
value: new Big('3206.1') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3206.1') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-18',
|
{
|
||||||
grossPerformance: new Big('523.25'),
|
date: '2021-06-18',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('523.25'),
|
||||||
value: new Big('3207.3') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3207.3') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-19',
|
{
|
||||||
grossPerformance: new Big('524.45'),
|
date: '2021-06-19',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('524.45'),
|
||||||
value: new Big('3208.5') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3208.5') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-20',
|
{
|
||||||
grossPerformance: new Big('525.65'),
|
date: '2021-06-20',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('525.65'),
|
||||||
value: new Big('3209.7') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3209.7') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-21',
|
{
|
||||||
grossPerformance: new Big('526.85'),
|
date: '2021-06-21',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('526.85'),
|
||||||
value: new Big('3210.9') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3210.9') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-22',
|
{
|
||||||
grossPerformance: new Big('528.05'),
|
date: '2021-06-22',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('528.05'),
|
||||||
value: new Big('3212.1') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3212.1') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-23',
|
{
|
||||||
grossPerformance: new Big('529.25'),
|
date: '2021-06-23',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('529.25'),
|
||||||
value: new Big('3213.3') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3213.3') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-24',
|
{
|
||||||
grossPerformance: new Big('530.45'),
|
date: '2021-06-24',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('530.45'),
|
||||||
value: new Big('3214.5') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3214.5') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-25',
|
{
|
||||||
grossPerformance: new Big('531.65'),
|
date: '2021-06-25',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('531.65'),
|
||||||
value: new Big('3215.7') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3215.7') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-26',
|
{
|
||||||
grossPerformance: new Big('532.85'),
|
date: '2021-06-26',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('532.85'),
|
||||||
value: new Big('3216.9') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3216.9') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-27',
|
{
|
||||||
grossPerformance: new Big('534.05'),
|
date: '2021-06-27',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('534.05'),
|
||||||
value: new Big('3218.1') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3218.1') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-28',
|
{
|
||||||
grossPerformance: new Big('535.25'),
|
date: '2021-06-28',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('535.25'),
|
||||||
value: new Big('3219.3') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3219.3') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-29',
|
{
|
||||||
grossPerformance: new Big('536.45'),
|
date: '2021-06-29',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('536.45'),
|
||||||
value: new Big('3220.5') // +1.2
|
investment: new Big('2684.05'),
|
||||||
},
|
value: new Big('3220.5') // +1.2
|
||||||
{
|
},
|
||||||
date: '2021-06-30',
|
{
|
||||||
grossPerformance: new Big('537.65'),
|
date: '2021-06-30',
|
||||||
investment: new Big('2684.05'),
|
grossPerformance: new Big('537.65'),
|
||||||
value: new Big('3221.7') // +1.2
|
investment: new Big('2684.05'),
|
||||||
}
|
value: new Big('3221.7') // +1.2
|
||||||
]);
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with mixed portfolio', async () => {
|
it('with mixed portfolio', async () => {
|
||||||
|
@ -193,22 +193,23 @@ export class PortfolioCalculator {
|
|||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
let endDate = endOfDay(currentDate);
|
let periodEndDate = currentDate;
|
||||||
if (timelineSpecification[i].accuracy === 'day') {
|
if (timelineSpecification[i].accuracy === 'day') {
|
||||||
let nextEndDate: Date = end;
|
let nextEndDate = end;
|
||||||
if (j + 1 < this.transactionPoints.length) {
|
if (j + 1 < this.transactionPoints.length) {
|
||||||
nextEndDate = dparse(this.transactionPoints[j + 1].date);
|
nextEndDate = dparse(this.transactionPoints[j + 1].date);
|
||||||
}
|
}
|
||||||
endDate = min([
|
periodEndDate = min([
|
||||||
addMonths(currentDate, 1),
|
addMonths(currentDate, 3),
|
||||||
max([currentDate, nextEndDate])
|
max([currentDate, nextEndDate])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
const timePeriodForDates = this.getTimePeriodForDate(
|
const timePeriodForDates = this.getTimePeriodForDate(
|
||||||
j,
|
j,
|
||||||
currentDate,
|
currentDate,
|
||||||
endDate
|
endOfDay(periodEndDate)
|
||||||
);
|
);
|
||||||
|
currentDate = periodEndDate;
|
||||||
if (timePeriodForDates != null) {
|
if (timePeriodForDates != null) {
|
||||||
timelinePeriodPromises.push(timePeriodForDates);
|
timelinePeriodPromises.push(timePeriodForDates);
|
||||||
}
|
}
|
||||||
@ -234,8 +235,9 @@ export class PortfolioCalculator {
|
|||||||
): Promise<TimelinePeriod[]> {
|
): Promise<TimelinePeriod[]> {
|
||||||
let investment: Big = new Big(0);
|
let investment: Big = new Big(0);
|
||||||
|
|
||||||
let value = new Big(0);
|
const marketSymbolMap: {
|
||||||
const currentDateAsString = format(startDate, DATE_FORMAT);
|
[date: string]: { [symbol: string]: Big };
|
||||||
|
} = {};
|
||||||
if (j >= 0) {
|
if (j >= 0) {
|
||||||
const currencies: { [name: string]: Currency } = {};
|
const currencies: { [name: string]: Currency } = {};
|
||||||
const symbols: string[] = [];
|
const symbols: string[] = [];
|
||||||
@ -250,8 +252,8 @@ export class PortfolioCalculator {
|
|||||||
if (symbols.length > 0) {
|
if (symbols.length > 0) {
|
||||||
try {
|
try {
|
||||||
marketSymbols = await this.currentRateService.getValues({
|
marketSymbols = await this.currentRateService.getValues({
|
||||||
dateRangeStart: resetHours(startDate),
|
dateRangeStart: startDate,
|
||||||
dateRangeEnd: resetHours(startDate),
|
dateRangeEnd: endDate,
|
||||||
symbols,
|
symbols,
|
||||||
currencies,
|
currencies,
|
||||||
userCurrency: this.currency
|
userCurrency: this.currency
|
||||||
@ -265,9 +267,6 @@ export class PortfolioCalculator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const marketSymbolMap: {
|
|
||||||
[date: string]: { [symbol: string]: Big };
|
|
||||||
} = {};
|
|
||||||
for (const marketSymbol of marketSymbols) {
|
for (const marketSymbol of marketSymbols) {
|
||||||
const date = format(marketSymbol.date, DATE_FORMAT);
|
const date = format(marketSymbol.date, DATE_FORMAT);
|
||||||
if (!marketSymbolMap[date]) {
|
if (!marketSymbolMap[date]) {
|
||||||
@ -277,27 +276,42 @@ export class PortfolioCalculator {
|
|||||||
marketSymbol.marketPrice
|
marketSymbol.marketPrice
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const item of this.transactionPoints[j].items) {
|
const results = [];
|
||||||
if (
|
for (
|
||||||
!marketSymbolMap[currentDateAsString]?.hasOwnProperty(item.symbol)
|
let currentDate = startDate;
|
||||||
) {
|
isBefore(currentDate, endDate);
|
||||||
return null;
|
currentDate = addDays(currentDate, 1)
|
||||||
|
) {
|
||||||
|
let value = new Big(0);
|
||||||
|
const currentDateAsString = format(currentDate, DATE_FORMAT);
|
||||||
|
let invalid = false;
|
||||||
|
if (j >= 0) {
|
||||||
|
for (const item of this.transactionPoints[j].items) {
|
||||||
|
if (
|
||||||
|
!marketSymbolMap[currentDateAsString]?.hasOwnProperty(item.symbol)
|
||||||
|
) {
|
||||||
|
invalid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value = value.add(
|
||||||
|
item.quantity.mul(marketSymbolMap[currentDateAsString][item.symbol])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
value = value.add(
|
}
|
||||||
item.quantity.mul(marketSymbolMap[currentDateAsString][item.symbol])
|
if (!invalid) {
|
||||||
);
|
const result = {
|
||||||
|
date: currentDateAsString,
|
||||||
|
grossPerformance: value.minus(investment),
|
||||||
|
investment,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
results.push(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return results;
|
||||||
{
|
|
||||||
date: currentDateAsString,
|
|
||||||
grossPerformance: value.minus(investment),
|
|
||||||
investment,
|
|
||||||
value
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFactor(type: OrderType) {
|
private getFactor(type: OrderType) {
|
||||||
|
@ -174,10 +174,6 @@ export class PortfolioService {
|
|||||||
const timelineSpecification: TimelineSpecification[] = [
|
const timelineSpecification: TimelineSpecification[] = [
|
||||||
{
|
{
|
||||||
start: format(portfolioStart, dateFormat),
|
start: format(portfolioStart, dateFormat),
|
||||||
accuracy: 'month'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
start: format(subYears(new Date(), 1), dateFormat),
|
|
||||||
accuracy: 'day'
|
accuracy: 'day'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user