add multi-date fetch for current values

pull/239/head
Valentin Zickner 3 years ago committed by Thomas
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…
Cancel
Save