Browse Source

Refactoring

pull/3190/head
Thomas Kaul 1 year ago
parent
commit
4e66efaa11
  1. 16
      apps/api/src/app/order/order.service.ts
  2. 5
      apps/api/src/app/portfolio/portfolio.controller.ts
  3. 123
      apps/api/src/app/portfolio/portfolio.service.ts
  4. 2
      apps/api/src/app/user/update-user-setting.dto.ts
  5. 54
      apps/client/src/app/components/investment-chart/investment-chart.component.ts

16
apps/api/src/app/order/order.service.ts

@ -198,22 +198,26 @@ export class OrderService {
}
public async getOrders({
endDate,
filters,
includeDrafts = false,
skip,
sortColumn,
sortDirection,
startDate,
take = Number.MAX_SAFE_INTEGER,
types,
userCurrency,
userId,
withExcludedAccounts = false
}: {
endDate?: Date;
filters?: Filter[];
includeDrafts?: boolean;
skip?: number;
sortColumn?: string;
sortDirection?: Prisma.SortOrder;
startDate?: Date;
take?: number;
types?: ActivityType[];
userCurrency: string;
@ -225,6 +229,18 @@ export class OrderService {
];
const where: Prisma.OrderWhereInput = { userId };
if (endDate || startDate) {
where.AND = [];
if (endDate) {
where.AND.push({ date: { lte: endDate } });
}
if (startDate) {
where.AND.push({ date: { gt: startDate } });
}
}
const {
ACCOUNT: filtersByAccount,
ASSET_CLASS: filtersByAssetClass,

5
apps/api/src/app/portfolio/portfolio.controller.ts

@ -236,8 +236,12 @@ export class PortfolioController {
await this.impersonationService.validateImpersonationId(impersonationId);
const userCurrency = this.request.user.Settings.settings.baseCurrency;
const { endDate, startDate } = this.portfolioService.getInterval(dateRange);
const { activities } = await this.orderService.getOrders({
endDate,
filters,
startDate,
userCurrency,
userId: impersonationUserId || this.request.user.id,
types: ['DIVIDEND']
@ -245,7 +249,6 @@ export class PortfolioController {
let dividends = await this.portfolioService.getDividends({
activities,
dateRange,
groupBy
});

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

@ -87,7 +87,7 @@ import {
endOfDay,
endOfYear
} from 'date-fns';
import { isEmpty, last, uniq, uniqBy } from 'lodash';
import { first, isEmpty, last, uniq, uniqBy } from 'lodash';
import { PortfolioCalculator } from './calculator/twr/portfolio-calculator';
import {
@ -224,11 +224,9 @@ export class PortfolioService {
public async getDividends({
activities,
dateRange = 'max',
groupBy
}: {
activities: Activity[];
dateRange?: DateRange;
groupBy?: GroupBy;
}): Promise<InvestmentItem[]> {
let dividends = activities.map(({ date, valueInBaseCurrency }) => {
@ -242,14 +240,50 @@ export class PortfolioService {
dividends = this.getDividendsByGroup({ dividends, groupBy });
}
const { startDate } = this.getInterval(
dateRange,
parseDate(dividends[0]?.date)
);
return dividends;
}
return dividends.filter(({ date }) => {
return !isBefore(parseDate(date), startDate);
});
public getInterval(aDateRange: DateRange, portfolioStart = new Date(0)) {
let endDate = endOfDay(new Date());
let startDate = portfolioStart;
switch (aDateRange) {
case '1d':
startDate = max([startDate, subDays(resetHours(new Date()), 1)]);
break;
case 'mtd':
startDate = max([
startDate,
subDays(startOfMonth(resetHours(new Date())), 1)
]);
break;
case 'wtd':
startDate = max([
startDate,
subDays(startOfWeek(resetHours(new Date()), { weekStartsOn: 1 }), 1)
]);
break;
case 'ytd':
startDate = max([
startDate,
subDays(startOfYear(resetHours(new Date())), 1)
]);
break;
case '1y':
startDate = max([startDate, subYears(resetHours(new Date()), 1)]);
break;
case '5y':
startDate = max([startDate, subYears(resetHours(new Date()), 5)]);
break;
case 'max':
break;
default:
// '2024', '2023', '2022', etc.
endDate = endOfYear(new Date(aDateRange));
startDate = max([startDate, new Date(aDateRange)]);
}
return { endDate, startDate };
}
public async getInvestments({
@ -963,7 +997,10 @@ export class PortfolioService {
const userId = await this.getUserId(impersonationId, this.request.user.id);
const user = await this.userService.user({ id: userId });
const { endDate, startDate } = this.getInterval(dateRange);
const { activities } = await this.orderService.getOrders({
endDate,
filters,
userId,
types: ['BUY', 'SELL'],
@ -984,12 +1021,10 @@ export class PortfolioService {
exchangeRateDataService: this.exchangeRateDataService
});
const { startDate } = this.getInterval(
dateRange,
portfolioCalculator.getStartDate()
const currentPositions = await portfolioCalculator.getCurrentPositions(
startDate,
endDate
);
const currentPositions =
await portfolioCalculator.getCurrentPositions(startDate);
let positions = currentPositions.positions.filter(({ quantity }) => {
return !quantity.eq(0);
@ -1136,7 +1171,10 @@ export class PortfolioService {
)
);
const { endDate, startDate } = this.getInterval(dateRange);
const { activities } = await this.orderService.getOrders({
endDate,
filters,
userCurrency,
userId,
@ -1172,16 +1210,6 @@ export class PortfolioService {
exchangeRateDataService: this.exchangeRateDataService
});
const portfolioStart = min(
[
parseDate(accountBalanceItems[0]?.date),
portfolioCalculator.getStartDate()
].filter((date) => {
return isValid(date);
})
);
const { startDate } = this.getInterval(dateRange, portfolioStart);
const {
currentValueInBaseCurrency,
errors,
@ -1195,7 +1223,7 @@ export class PortfolioService {
netPerformancePercentageWithCurrencyEffect,
netPerformanceWithCurrencyEffect,
totalInvestment
} = await portfolioCalculator.getCurrentPositions(startDate); // TODO: Provide endDate
} = await portfolioCalculator.getCurrentPositions(startDate, endDate);
let currentNetPerformance = netPerformance;
@ -1620,49 +1648,6 @@ export class PortfolioService {
};
}
private getInterval(aDateRange: DateRange, portfolioStart: Date) {
let endDate = endOfDay(new Date());
let startDate = portfolioStart;
switch (aDateRange) {
case '1d':
startDate = max([startDate, subDays(resetHours(new Date()), 1)]);
break;
case 'mtd':
startDate = max([
startDate,
subDays(startOfMonth(resetHours(new Date())), 1)
]);
break;
case 'wtd':
startDate = max([
startDate,
subDays(startOfWeek(resetHours(new Date()), { weekStartsOn: 1 }), 1)
]);
break;
case 'ytd':
startDate = max([
startDate,
subDays(startOfYear(resetHours(new Date())), 1)
]);
break;
case '1y':
startDate = max([startDate, subYears(resetHours(new Date()), 1)]);
break;
case '5y':
startDate = max([startDate, subYears(resetHours(new Date()), 5)]);
break;
case 'max':
break;
default:
// '2024', '2023', '2022', etc.
endDate = endOfYear(new Date(aDateRange));
startDate = max([startDate, new Date(aDateRange)]);
}
return { endDate, startDate };
}
private getStreaks({
investments,
savingsRate

2
apps/api/src/app/user/update-user-setting.dto.ts

@ -41,7 +41,7 @@ export class UpdateUserSettingDto {
'mtd',
'wtd',
'ytd',
...eachYearOfInterval({ end: new Date(), start: new Date(1900) }).map(
...eachYearOfInterval({ end: new Date(), start: new Date(0) }).map(
(date) => {
return format(date, 'yyyy');
}

54
apps/client/src/app/components/investment-chart/investment-chart.component.ts

@ -6,7 +6,6 @@ import {
} from '@ghostfolio/common/chart-helper';
import { primaryColorRgb, secondaryColorRgb } from '@ghostfolio/common/config';
import {
DATE_FORMAT,
getBackgroundColor,
getDateFormatString,
getLocale,
@ -39,16 +38,8 @@ import {
} from 'chart.js';
import 'chartjs-adapter-date-fns';
import annotationPlugin from 'chartjs-plugin-annotation';
import {
addDays,
format,
isAfter,
isValid,
min,
parseISO,
subDays
} from 'date-fns';
import { first, last } from 'lodash';
import { isAfter, isValid, min, subDays } from 'date-fns';
import { first } from 'lodash';
@Component({
selector: 'gf-investment-chart',
@ -112,46 +103,6 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
Object.assign({}, item)
);
if (!this.groupBy && this.investments?.length > 0) {
let date: string;
if (this.range === 'max') {
// Extend chart by 5% of days in market (before)
date = format(
subDays(
parseISO(this.investments[0].date),
this.daysInMarket * 0.05 || 90
),
DATE_FORMAT
);
this.investments.unshift({
date,
investment: 0
});
this.values.unshift({
date,
value: 0
});
}
// Extend chart by 5% of days in market (after)
date = format(
addDays(
parseDate(last(this.investments).date),
this.daysInMarket * 0.05 || 90
),
DATE_FORMAT
);
this.investments.push({
date,
investment: last(this.investments).investment
});
this.values.push({
date,
value: last(this.values).value
});
}
const chartData: ChartData<'bar' | 'line'> = {
labels: this.historicalDataItems.map(({ date }) => {
return parseDate(date);
@ -303,7 +254,6 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
display: false
},
min: scaleXMin,
suggestedMax: new Date().toISOString(),
type: 'time',
time: {
tooltipFormat: getDateFormatString(this.locale),

Loading…
Cancel
Save