Browse Source

Fix Calculation

pull/5027/head
Daniel Devaud 1 year ago
parent
commit
84736c51f7
  1. 73
      apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts
  2. 2
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

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

@ -3,13 +3,23 @@ import {
getFactor, getFactor,
getInterval getInterval
} from '@ghostfolio/api/helper/portfolio.helper'; } from '@ghostfolio/api/helper/portfolio.helper';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MAX_CHART_ITEMS } from '@ghostfolio/common/config'; import { MAX_CHART_ITEMS } from '@ghostfolio/common/config';
import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper';
import { HistoricalDataItem } from '@ghostfolio/common/interfaces'; import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
import { DateRange } from '@ghostfolio/common/types'; import { DateRange } from '@ghostfolio/common/types';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { addDays, differenceInDays, eachDayOfInterval, format } from 'date-fns'; import {
addDays,
differenceInDays,
eachDayOfInterval,
format,
isAfter,
isBefore,
isEqual,
subDays
} from 'date-fns';
import { PortfolioOrder } from '../../interfaces/portfolio-order.interface'; import { PortfolioOrder } from '../../interfaces/portfolio-order.interface';
import { TWRPortfolioCalculator } from '../twr/portfolio-calculator'; import { TWRPortfolioCalculator } from '../twr/portfolio-calculator';
@ -78,13 +88,18 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
start: Date; start: Date;
step?: number; step?: number;
}): Promise<HistoricalDataItem[]> { }): Promise<HistoricalDataItem[]> {
const timelineHoldings = this.getHoldings(start, end); let marketMapTask = this.computeMarketMap({ in: [start, end] });
const timelineHoldings = await this.getHoldings(start, end);
const calculationDates = Object.keys(timelineHoldings) const calculationDates = Object.keys(timelineHoldings)
.filter((date) => { .filter((date) => {
let parsed = parseDate(date); let parsed = parseDate(date);
parsed >= start && parsed <= end; return (
isAfter(parsed, subDays(start, 1)) &&
isBefore(parsed, addDays(end, 1))
);
}) })
.sort(); .sort((a, b) => parseDate(a).getTime() - parseDate(b).getTime());
let data: HistoricalDataItem[] = []; let data: HistoricalDataItem[] = [];
const startString = format(start, DATE_FORMAT); const startString = format(start, DATE_FORMAT);
@ -103,6 +118,8 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
valueWithCurrencyEffect: 0 valueWithCurrencyEffect: 0
}); });
await marketMapTask;
let totalInvestment = Object.keys(timelineHoldings[startString]).reduce( let totalInvestment = Object.keys(timelineHoldings[startString]).reduce(
(sum, holding) => { (sum, holding) => {
return sum.plus( return sum.plus(
@ -231,11 +248,15 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
} }
@LogPerformance @LogPerformance
private getHoldings(start: Date, end: Date) { private async getHoldings(start: Date, end: Date) {
if ( if (
this.holdings && this.holdings &&
Object.keys(this.holdings).some((h) => parseDate(h) >= end) && Object.keys(this.holdings).some((h) =>
Object.keys(this.holdings).some((h) => parseDate(h) <= start) isAfter(parseDate(h), subDays(end, 1))
) &&
Object.keys(this.holdings).some((h) =>
isBefore(parseDate(h), addDays(start, 1))
)
) { ) {
return this.holdings; return this.holdings;
} }
@ -245,7 +266,7 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
} }
@LogPerformance @LogPerformance
private computeHoldings(start: Date, end: Date) { private async computeHoldings(start: Date, end: Date) {
const investmentByDate = this.getInvestmentByDate(); const investmentByDate = this.getInvestmentByDate();
const transactionDates = Object.keys(investmentByDate).sort(); const transactionDates = Object.keys(investmentByDate).sort();
let dates = eachDayOfInterval({ start, end }, { step: 1 }) let dates = eachDayOfInterval({ start, end }, { step: 1 })
@ -320,4 +341,40 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator {
return groupedByDate; return groupedByDate;
}, {}); }, {});
} }
@LogPerformance
private async computeMarketMap(dateQuery: { in: Date[] }) {
const dataGatheringItems: IDataGatheringItem[] = this.activities.map(
(activity) => {
return {
symbol: activity.SymbolProfile.symbol,
dataSource: activity.SymbolProfile.dataSource
};
}
);
const { values: marketSymbols } = await this.currentRateService.getValues({
dataGatheringItems,
dateQuery
});
const marketSymbolMap: {
[date: string]: { [symbol: string]: Big };
} = {};
for (const marketSymbol of marketSymbols) {
const date = format(marketSymbol.date, DATE_FORMAT);
if (!marketSymbolMap[date]) {
marketSymbolMap[date] = {};
}
if (marketSymbol.marketPrice) {
marketSymbolMap[date][marketSymbol.symbol] = new Big(
marketSymbol.marketPrice
);
}
}
this.marketMap = marketSymbolMap;
}
} }

2
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -54,7 +54,7 @@ export abstract class PortfolioCalculator {
private configurationService: ConfigurationService; private configurationService: ConfigurationService;
protected currency: string; protected currency: string;
private currentRateService: CurrentRateService; protected currentRateService: CurrentRateService;
private dataProviderInfos: DataProviderInfo[]; private dataProviderInfos: DataProviderInfo[];
private dateRange: DateRange; private dateRange: DateRange;
private endDate: Date; private endDate: Date;

Loading…
Cancel
Save