Browse Source

Merge pull request #89 from dandevaud/bugfix/fix-marketdata-update

Bugfix/fix marketdata update
pull/5027/head
dandevaud 1 year ago
committed by GitHub
parent
commit
4d9b62a843
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 93
      apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts

93
apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts

@ -9,6 +9,7 @@ import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper';
import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
import { DateRange } from '@ghostfolio/common/types';
import { Logger } from '@nestjs/common';
import { Big } from 'big.js';
import {
addDays,
@ -88,7 +89,7 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
start: Date;
step?: number;
}): Promise<HistoricalDataItem[]> {
let marketMapTask = this.computeMarketMap({ in: [start, end] });
let marketMapTask = this.computeMarketMap({ gte: start, lte: end });
const timelineHoldings = await this.getHoldings(start, end);
const calculationDates = Object.keys(timelineHoldings)
@ -186,42 +187,71 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
previousDate: string,
holding: string,
date: string,
totalInvestment,
totalInvestment: Big,
timelineHoldings: { [date: string]: { [symbol: string]: Big } },
netPerformanceInPercentage,
netPerformanceInPercentageWithCurrencyEffect,
newTotalInvestment
netPerformanceInPercentage: Big,
netPerformanceInPercentageWithCurrencyEffect: Big,
newTotalInvestment: Big
) {
const previousPrice = this.marketMap[previousDate][holding];
const currentPrice = this.marketMap[date][holding];
const previousPriceInBaseCurrency =
await this.exchangeRateDataService.toCurrencyAtDate(
previousPrice.toNumber(),
this.getCurrency(holding),
this.currency,
parseDate(previousDate)
const currentPrice = this.marketMap[date][holding] ?? previousPrice;
const previousHolding = timelineHoldings[previousDate][holding];
const priceInBaseCurrency = currentPrice
? new Big(
await this.exchangeRateDataService.toCurrencyAtDate(
currentPrice?.toNumber() ?? 0,
this.getCurrency(holding),
this.currency,
parseDate(date)
)
)
: new Big(0);
if (previousHolding.eq(0)) {
return {
netPerformanceInPercentage: new Big(0),
netPerformanceInPercentageWithCurrencyEffect: new Big(0),
newTotalInvestment: newTotalInvestment.plus(
timelineHoldings[date][holding].mul(priceInBaseCurrency)
)
};
}
if (previousPrice === undefined || currentPrice === undefined) {
Logger.warn(
`Missing historical market data for ${holding} (${previousPrice === undefined ? previousDate : date}})`,
'PortfolioCalculator'
);
const portfolioWeight = totalInvestment
? timelineHoldings[previousDate][holding]
.mul(previousPriceInBaseCurrency)
.div(totalInvestment)
return {
netPerformanceInPercentage: new Big(0),
netPerformanceInPercentageWithCurrencyEffect: new Big(0),
newTotalInvestment: newTotalInvestment.plus(
timelineHoldings[date][holding].mul(priceInBaseCurrency)
)
};
}
const previousPriceInBaseCurrency = previousPrice
? new Big(
await this.exchangeRateDataService.toCurrencyAtDate(
previousPrice?.toNumber() ?? 0,
this.getCurrency(holding),
this.currency,
parseDate(previousDate)
)
)
: new Big(0);
const portfolioWeight = totalInvestment.toNumber()
? previousHolding.mul(previousPriceInBaseCurrency).div(totalInvestment)
: 0;
netPerformanceInPercentage = netPerformanceInPercentage.plus(
currentPrice.div(previousPrice).minus(1).mul(portfolioWeight)
);
const priceInBaseCurrency =
await this.exchangeRateDataService.toCurrencyAtDate(
currentPrice.toNumber(),
this.getCurrency(holding),
this.currency,
parseDate(date)
);
netPerformanceInPercentageWithCurrencyEffect =
netPerformanceInPercentageWithCurrencyEffect.plus(
new Big(priceInBaseCurrency)
.div(new Big(previousPriceInBaseCurrency))
priceInBaseCurrency
.div(previousPriceInBaseCurrency)
.minus(1)
.mul(portfolioWeight)
);
@ -343,15 +373,18 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
}
@LogPerformance
private async computeMarketMap(dateQuery: { in: Date[] }) {
const dataGatheringItems: IDataGatheringItem[] = this.activities.map(
(activity) => {
private async computeMarketMap(dateQuery: { gte: Date; lte: Date }) {
const dataGatheringItems: IDataGatheringItem[] = this.activities
.map((activity) => {
return {
symbol: activity.SymbolProfile.symbol,
dataSource: activity.SymbolProfile.dataSource
};
}
);
})
.filter(
(gathering, i, arr) =>
arr.findIndex((t) => t.symbol === gathering.symbol) === i
);
const { values: marketSymbols } = await this.currentRateService.getValues({
dataGatheringItems,
dateQuery

Loading…
Cancel
Save