Browse Source

Refactoring

pull/1344/head
Thomas 3 years ago
parent
commit
9a1509b238
  1. 5
      apps/api/src/app/portfolio/portfolio-calculator.ts
  2. 2
      apps/api/src/app/portfolio/portfolio.controller.ts
  3. 14
      apps/api/src/app/portfolio/portfolio.service.ts
  4. 37
      apps/client/src/app/components/investment-chart/investment-chart.component.ts
  5. 24
      apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts
  6. 38
      apps/client/src/app/services/data.service.ts
  7. 1
      libs/common/src/lib/interfaces/historical-data-item.interface.ts
  8. 1
      libs/common/src/lib/interfaces/portfolio-investments.interface.ts
  9. 1
      libs/common/src/lib/interfaces/responses/portfolio-performance-response.interface.ts

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

@ -287,7 +287,10 @@ export class PortfolioCalculator {
date,
netPerformanceInPercentage,
netPerformance: totalNetPerformanceValues[date].toNumber(),
value: netPerformanceInPercentage
totalInvestment: totalInvestmentValues[date].toNumber(),
value: totalInvestmentValues[date]
.plus(totalNetPerformanceValues[date])
.toNumber()
};
});
}

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

@ -226,7 +226,7 @@ export class PortfolioController {
}));
}
return { firstOrderDate: parseDate(investments[0]?.date), investments };
return { investments };
}
@Get('performance')

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

@ -904,6 +904,7 @@ export class PortfolioService {
if (transactionPoints?.length <= 0) {
return {
chart: [],
firstOrderDate: undefined,
hasErrors: false,
performance: {
currentGrossPerformance: 0,
@ -960,15 +961,24 @@ export class PortfolioService {
return {
chart: historicalDataContainer.items.map(
({ date, netPerformance, netPerformanceInPercentage }) => {
({
date,
netPerformance,
netPerformanceInPercentage,
totalInvestment,
value
}) => {
return {
date,
netPerformance,
netPerformanceInPercentage
netPerformanceInPercentage,
totalInvestment,
value
};
}
),
errors: currentPositions.errors,
firstOrderDate: parseDate(historicalDataContainer.items[0]?.date),
hasErrors: currentPositions.hasErrors || hasErrors,
performance: {
currentValue,

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

@ -22,6 +22,7 @@ import {
parseDate,
transformTickToAbbreviation
} from '@ghostfolio/common/helper';
import { LineChartItem } from '@ghostfolio/common/interfaces';
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface';
import { DateRange, GroupBy } from '@ghostfolio/common/types';
import {
@ -36,15 +37,7 @@ import {
Tooltip
} from 'chart.js';
import annotationPlugin from 'chartjs-plugin-annotation';
import {
addDays,
format,
isAfter,
isBefore,
parseISO,
subDays
} from 'date-fns';
import { LineChartItem } from '@ghostfolio/common/interfaces';
import { addDays, format, isAfter, parseISO, subDays } from 'date-fns';
@Component({
selector: 'gf-investment-chart',
@ -128,26 +121,9 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
});
}
let currentIndex = 0;
const totalAmountDataItems: { x: Date; y: number }[] = [];
for (const { date, value } of this.benchmarkDataItems) {
// TODO: Improve total amount calculation
if (
isBefore(parseDate(this.data?.[currentIndex]?.date), parseDate(date))
) {
currentIndex += 1;
}
totalAmountDataItems.push({
x: parseDate(date),
y: this.data?.[currentIndex]?.investment + value
});
}
const data = {
labels: this.benchmarkDataItems.map(({ date }) => {
return date;
return parseDate(date);
}),
datasets: [
{
@ -174,7 +150,12 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
{
borderColor: `rgb(${secondaryColorRgb.r}, ${secondaryColorRgb.g}, ${secondaryColorRgb.b})`,
borderWidth: 1,
data: totalAmountDataItems,
data: this.benchmarkDataItems.map(({ date, value }) => {
return {
x: parseDate(date),
y: value
};
}),
fill: false,
label: $localize`Total Amount`,
pointRadius: 0

24
apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts

@ -130,20 +130,24 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
range: this.user?.settings?.dateRange
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ chart }) => {
this.firstOrderDate = new Date(chart?.[0]?.date ?? new Date());
.subscribe(({ chart, firstOrderDate }) => {
this.firstOrderDate = firstOrderDate ?? new Date();
this.daysInMarket = differenceInDays(new Date(), firstOrderDate);
this.investments = [];
this.performanceDataItems = [];
this.performanceDataItemsInPercentage = [];
for (const {
date,
netPerformance,
netPerformanceInPercentage
netPerformanceInPercentage,
totalInvestment,
value
} of chart) {
this.investments.push({ date, investment: totalInvestment });
this.performanceDataItems.push({
date,
value: netPerformance
value
});
this.performanceDataItemsInPercentage.push({
date,
@ -156,16 +160,6 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
this.changeDetectorRef.markForCheck();
});
this.dataService
.fetchInvestments({ range: this.user?.settings?.dateRange })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ firstOrderDate, investments }) => {
this.daysInMarket = differenceInDays(new Date(), firstOrderDate);
this.investments = investments;
this.changeDetectorRef.markForCheck();
});
this.dataService
.fetchInvestments({
groupBy: 'month',

38
apps/client/src/app/services/data.service.ts

@ -169,18 +169,11 @@ export class DataService {
}: {
groupBy?: 'month';
range: DateRange;
}): Observable<PortfolioInvestments> {
return this.http
.get<any>('/api/v1/portfolio/investments', { params: { groupBy, range } })
.pipe(
map((response) => {
if (response.firstOrderDate) {
response.firstOrderDate = parseISO(response.firstOrderDate);
}
return response;
})
);
}) {
return this.http.get<PortfolioInvestments>(
'/api/v1/portfolio/investments',
{ params: { groupBy, range } }
);
}
public fetchSymbolItem({
@ -244,11 +237,22 @@ export class DataService {
);
}
public fetchPortfolioPerformance({ range }: { range: DateRange }) {
return this.http.get<PortfolioPerformanceResponse>(
`/api/v2/portfolio/performance`,
{ params: { range } }
);
public fetchPortfolioPerformance({
range
}: {
range: DateRange;
}): Observable<PortfolioPerformanceResponse> {
return this.http
.get<any>(`/api/v2/portfolio/performance`, { params: { range } })
.pipe(
map((response) => {
if (response.firstOrderDate) {
response.firstOrderDate = parseISO(response.firstOrderDate);
}
return response;
})
);
}
public fetchPortfolioPublic(aId: string) {

1
libs/common/src/lib/interfaces/historical-data-item.interface.ts

@ -4,5 +4,6 @@ export interface HistoricalDataItem {
grossPerformancePercent?: number;
netPerformance?: number;
netPerformanceInPercentage?: number;
totalInvestment?: number;
value?: number;
}

1
libs/common/src/lib/interfaces/portfolio-investments.interface.ts

@ -1,6 +1,5 @@
import { InvestmentItem } from './investment-item.interface';
export interface PortfolioInvestments {
firstOrderDate: Date;
investments: InvestmentItem[];
}

1
libs/common/src/lib/interfaces/responses/portfolio-performance-response.interface.ts

@ -4,5 +4,6 @@ import { ResponseError } from './errors.interface';
export interface PortfolioPerformanceResponse extends ResponseError {
chart?: HistoricalDataItem[];
firstOrderDate: Date;
performance: PortfolioPerformance;
}

Loading…
Cancel
Save