Browse Source

Move getChart() to portfolio calculator (#3255)

pull/3258/head
Thomas Kaul 12 months ago
committed by GitHub
parent
commit
2b97bbd05d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 34
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  2. 6
      apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts
  3. 68
      apps/api/src/app/portfolio/portfolio.service.ts

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

@ -4,9 +4,13 @@ import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/curre
import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface';
import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface';
import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface';
import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import {
getFactor,
getInterval
} from '@ghostfolio/api/helper/portfolio.helper';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
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 { import {
DataProviderInfo, DataProviderInfo,
@ -17,10 +21,11 @@ import {
TimelinePosition, TimelinePosition,
UniqueAsset UniqueAsset
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { GroupBy } from '@ghostfolio/common/types'; import { DateRange, GroupBy } from '@ghostfolio/common/types';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { import {
differenceInDays,
eachDayOfInterval, eachDayOfInterval,
endOfDay, endOfDay,
format, format,
@ -81,6 +86,31 @@ export abstract class PortfolioCalculator {
positions: TimelinePosition[] positions: TimelinePosition[]
): CurrentPositions; ): CurrentPositions;
public async getChart({
dateRange = 'max',
withDataDecimation = true
}: {
dateRange?: DateRange;
withDataDecimation?: boolean;
}): Promise<HistoricalDataItem[]> {
if (this.getTransactionPoints().length === 0) {
return [];
}
const { endDate, startDate } = getInterval(dateRange, this.getStartDate());
const daysInMarket = differenceInDays(endDate, startDate) + 1;
const step = withDataDecimation
? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS))
: 1;
return this.getChartData({
step,
end: endDate,
start: startDate
});
}
public async getChartData({ public async getChartData({
end = new Date(Date.now()), end = new Date(Date.now()),
start, start,

6
apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts

@ -36,9 +36,3 @@ export interface PortfolioPositionDetail {
transactionCount: number; transactionCount: number;
value: number; value: number;
} }
export interface HistoricalDataContainer {
isAllTimeHigh: boolean;
isAllTimeLow: boolean;
items: HistoricalDataItem[];
}

68
apps/api/src/app/portfolio/portfolio.service.ts

@ -21,7 +21,6 @@ import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/sy
import { import {
DEFAULT_CURRENCY, DEFAULT_CURRENCY,
EMERGENCY_FUND_TAG_ID, EMERGENCY_FUND_TAG_ID,
MAX_CHART_ITEMS,
UNKNOWN_KEY UNKNOWN_KEY
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { import {
@ -63,8 +62,7 @@ import {
DataSource, DataSource,
Order, Order,
Platform, Platform,
Prisma, Prisma
SymbolProfile
} from '@prisma/client'; } from '@prisma/client';
import { Big } from 'big.js'; import { Big } from 'big.js';
import { isUUID } from 'class-validator'; import { isUUID } from 'class-validator';
@ -80,15 +78,11 @@ import {
} from 'date-fns'; } from 'date-fns';
import { isEmpty, isNumber, last, uniq, uniqBy } from 'lodash'; import { isEmpty, isNumber, last, uniq, uniqBy } from 'lodash';
import { PortfolioCalculator } from './calculator/portfolio-calculator';
import { import {
PerformanceCalculationType, PerformanceCalculationType,
PortfolioCalculatorFactory PortfolioCalculatorFactory
} from './calculator/portfolio-calculator.factory'; } from './calculator/portfolio-calculator.factory';
import { import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface';
HistoricalDataContainer,
PortfolioPositionDetail
} from './interfaces/portfolio-position-detail.interface';
import { RulesService } from './rules.service'; import { RulesService } from './rules.service';
const asiaPacificMarkets = require('../../assets/countries/asia-pacific-markets.json'); const asiaPacificMarkets = require('../../assets/countries/asia-pacific-markets.json');
@ -292,11 +286,8 @@ export class PortfolioService {
currency: this.request.user.Settings.settings.baseCurrency currency: this.request.user.Settings.settings.baseCurrency
}); });
const { items } = await this.getChart({ const items = await portfolioCalculator.getChart({
dateRange, dateRange,
impersonationId,
portfolioCalculator,
userId,
withDataDecimation: false withDataDecimation: false
}); });
@ -1161,11 +1152,8 @@ export class PortfolioService {
let currentNetPerformanceWithCurrencyEffect = let currentNetPerformanceWithCurrencyEffect =
netPerformanceWithCurrencyEffect; netPerformanceWithCurrencyEffect;
const { items } = await this.getChart({ const items = await portfolioCalculator.getChart({
dateRange, dateRange
impersonationId,
portfolioCalculator,
userId
}); });
const itemOfToday = items.find(({ date }) => { const itemOfToday = items.find(({ date }) => {
@ -1381,52 +1369,6 @@ export class PortfolioService {
return cashPositions; return cashPositions;
} }
private async getChart({
dateRange = 'max',
impersonationId,
portfolioCalculator,
userId,
withDataDecimation = true
}: {
dateRange?: DateRange;
impersonationId: string;
portfolioCalculator: PortfolioCalculator;
userId: string;
withDataDecimation?: boolean;
}): Promise<HistoricalDataContainer> {
if (portfolioCalculator.getTransactionPoints().length === 0) {
return {
isAllTimeHigh: false,
isAllTimeLow: false,
items: []
};
}
userId = await this.getUserId(impersonationId, userId);
const { endDate, startDate } = getInterval(
dateRange,
portfolioCalculator.getStartDate()
);
const daysInMarket = differenceInDays(endDate, startDate) + 1;
const step = withDataDecimation
? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS))
: 1;
const items = await portfolioCalculator.getChartData({
step,
end: endDate,
start: startDate
});
return {
items,
isAllTimeHigh: false,
isAllTimeLow: false
};
}
private getDividendsByGroup({ private getDividendsByGroup({
dividends, dividends,
groupBy groupBy

Loading…
Cancel
Save