Feature/add total amount chart to investment timeline (#1344)

* Add total amount chart

* Update changelog
pull/1356/head
Thomas Kaul 2 years ago committed by GitHub
parent f9cd629470
commit a65424aafa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added support to change the appearance (dark mode) in user settings
- Added the total amount chart to the investment timeline
- Setup the `prettier` plugin `prettier-plugin-organize-attributes`
### Changed
@ -971,8 +972,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Display the value in base currency in the accounts table on mobile
- Display the value in base currency in the activities table on mobile
- Displayed the value in base currency in the accounts table on mobile
- Displayed the value in base currency in the activities table on mobile
- Renamed `orders` to `activities` in import and export functionality
- Harmonized the algebraic sign of `currentGrossPerformancePercent` and `currentNetPerformancePercent` with `currentGrossPerformance` and `currentNetPerformance`
- Improved the pricing page

@ -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()
};
});
}

@ -38,6 +38,7 @@ import {
} from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import Big from 'big.js';
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface';
@ -68,7 +69,7 @@ export class PortfolioController {
@Headers('impersonation-id') impersonationId: string,
@Query('accounts') filterByAccounts?: string,
@Query('assetClasses') filterByAssetClasses?: string,
@Query('range') range?: DateRange,
@Query('range') dateRange: DateRange = 'max',
@Query('tags') filterByTags?: string
): Promise<PortfolioDetails & { hasError: boolean }> {
let hasError = false;
@ -88,9 +89,9 @@ export class PortfolioController {
summary,
totalValueInBaseCurrency
} = await this.portfolioService.getDetails({
dateRange,
filters,
impersonationId,
dateRange: range,
userId: this.request.user.id
});
@ -183,6 +184,7 @@ export class PortfolioController {
@UseGuards(AuthGuard('jwt'))
public async getInvestments(
@Headers('impersonation-id') impersonationId: string,
@Query('range') dateRange: DateRange = 'max',
@Query('groupBy') groupBy?: GroupBy
): Promise<PortfolioInvestments> {
if (
@ -198,12 +200,16 @@ export class PortfolioController {
let investments: InvestmentItem[];
if (groupBy === 'month') {
investments = await this.portfolioService.getInvestments(
investments = await this.portfolioService.getInvestments({
dateRange,
impersonationId,
'month'
);
groupBy: 'month'
});
} else {
investments = await this.portfolioService.getInvestments(impersonationId);
investments = await this.portfolioService.getInvestments({
dateRange,
impersonationId
});
}
if (
@ -221,7 +227,7 @@ export class PortfolioController {
}));
}
return { firstOrderDate: parseDate(investments[0]?.date), investments };
return { investments };
}
@Get('performance')
@ -230,7 +236,7 @@ export class PortfolioController {
@Version('2')
public async getPerformanceV2(
@Headers('impersonation-id') impersonationId: string,
@Query('range') dateRange
@Query('range') dateRange: DateRange = 'max'
): Promise<PortfolioPerformanceResponse> {
const performanceInformation = await this.portfolioService.getPerformanceV2(
{
@ -244,9 +250,29 @@ export class PortfolioController {
this.request.user.Settings.settings.viewMode === 'ZEN' ||
this.userService.isRestrictedView(this.request.user)
) {
performanceInformation.chart = performanceInformation.chart.map(
({ date, netPerformanceInPercentage, totalInvestment, value }) => {
return {
date,
netPerformanceInPercentage,
totalInvestment: new Big(totalInvestment)
.div(performanceInformation.performance.totalInvestment)
.toNumber(),
value: new Big(value)
.div(performanceInformation.performance.currentValue)
.toNumber()
};
}
);
performanceInformation.performance = nullifyValuesInObject(
performanceInformation.performance,
['currentGrossPerformance', 'currentNetPerformance', 'currentValue']
[
'currentGrossPerformance',
'currentNetPerformance',
'currentValue',
'totalInvestment'
]
);
}
@ -258,11 +284,11 @@ export class PortfolioController {
@UseInterceptors(TransformDataSourceInResponseInterceptor)
public async getPositions(
@Headers('impersonation-id') impersonationId: string,
@Query('range') range
@Query('range') dateRange: DateRange = 'max'
): Promise<PortfolioPositions> {
const result = await this.portfolioService.getPositions(
impersonationId,
range
dateRange
);
if (

@ -207,11 +207,16 @@ export class PortfolioService {
};
}
public async getInvestments(
aImpersonationId: string,
groupBy?: GroupBy
): Promise<InvestmentItem[]> {
const userId = await this.getUserId(aImpersonationId, this.request.user.id);
public async getInvestments({
dateRange,
impersonationId,
groupBy
}: {
dateRange: DateRange;
impersonationId: string;
groupBy?: GroupBy;
}): Promise<InvestmentItem[]> {
const userId = await this.getUserId(impersonationId, this.request.user.id);
const { portfolioOrders, transactionPoints } =
await this.getTransactionPoints({
@ -283,98 +288,18 @@ export class PortfolioService {
}
}
return sortBy(investments, (investment) => {
investments = sortBy(investments, (investment) => {
return investment.date;
});
}
public async getChart(
aImpersonationId: string,
aDateRange: DateRange = 'max'
): Promise<HistoricalDataContainer> {
const userId = await this.getUserId(aImpersonationId, this.request.user.id);
const { portfolioOrders, transactionPoints } =
await this.getTransactionPoints({
userId
});
const portfolioCalculator = new PortfolioCalculator({
currency: this.request.user.Settings.settings.baseCurrency,
currentRateService: this.currentRateService,
orders: portfolioOrders
});
portfolioCalculator.setTransactionPoints(transactionPoints);
if (transactionPoints.length === 0) {
return {
isAllTimeHigh: false,
isAllTimeLow: false,
items: []
};
}
let portfolioStart = parse(
transactionPoints[0].date,
DATE_FORMAT,
new Date()
);
// Get start date for the full portfolio because of because of the
// min and max calculation
portfolioStart = this.getStartDate('max', portfolioStart);
const timelineSpecification: TimelineSpecification[] = [
{
start: format(portfolioStart, DATE_FORMAT),
accuracy: 'day'
}
];
const timelineInfo = await portfolioCalculator.calculateTimeline(
timelineSpecification,
format(new Date(), DATE_FORMAT)
);
const timeline = timelineInfo.timelinePeriods;
const items = timeline
.filter((timelineItem) => timelineItem !== null)
.map((timelineItem) => ({
date: timelineItem.date,
value: timelineItem.netPerformance.toNumber()
}));
let lastItem = null;
if (timeline.length > 0) {
lastItem = timeline[timeline.length - 1];
}
let isAllTimeHigh = timelineInfo.maxNetPerformance?.eq(
lastItem?.netPerformance ?? 0
);
let isAllTimeLow = timelineInfo.minNetPerformance?.eq(
lastItem?.netPerformance ?? 0
);
if (isAllTimeHigh && isAllTimeLow) {
isAllTimeHigh = false;
isAllTimeLow = false;
}
portfolioStart = startOfDay(
this.getStartDate(
aDateRange,
parse(transactionPoints[0].date, DATE_FORMAT, new Date())
)
const startDate = this.getStartDate(
dateRange,
parseDate(investments[0]?.date)
);
return {
isAllTimeHigh,
isAllTimeLow,
items: items.filter((item) => {
// Filter items of date range
return !isAfter(portfolioStart, parseDate(item.date));
})
};
return investments.filter(({ date }) => {
return !isBefore(parseDate(date), startDate);
});
}
public async getChartV2({
@ -441,7 +366,7 @@ export class PortfolioService {
filters?: Filter[];
withExcludedAccounts?: boolean;
}): Promise<PortfolioDetails & { hasErrors: boolean }> {
// TODO:
// TODO
userId = await this.getUserId(impersonationId, userId);
const user = await this.userService.user({ id: userId });
@ -979,13 +904,15 @@ export class PortfolioService {
if (transactionPoints?.length <= 0) {
return {
chart: [],
firstOrderDate: undefined,
hasErrors: false,
performance: {
currentGrossPerformance: 0,
currentGrossPerformancePercent: 0,
currentNetPerformance: 0,
currentNetPerformancePercent: 0,
currentValue: 0
currentValue: 0,
totalInvestment: 0
}
};
}
@ -1006,6 +933,7 @@ export class PortfolioService {
let currentNetPerformance = currentPositions.netPerformance;
let currentNetPerformancePercent =
currentPositions.netPerformancePercentage;
const totalInvestment = currentPositions.totalInvestment;
// if (currentGrossPerformance.mul(currentGrossPerformancePercent).lt(0)) {
// // If algebraic sign is different, harmonize it
@ -1035,14 +963,24 @@ export class PortfolioService {
return {
chart: historicalDataContainer.items.map(
({ date, netPerformanceInPercentage }) => {
({
date,
netPerformance,
netPerformanceInPercentage,
totalInvestment,
value
}) => {
return {
date,
value: netPerformanceInPercentage
netPerformance,
netPerformanceInPercentage,
totalInvestment,
value
};
}
),
errors: currentPositions.errors,
firstOrderDate: parseDate(historicalDataContainer.items[0]?.date),
hasErrors: currentPositions.hasErrors || hasErrors,
performance: {
currentValue,
@ -1050,7 +988,8 @@ export class PortfolioService {
currentGrossPerformancePercent:
currentGrossPerformancePercent.toNumber(),
currentNetPerformance: currentNetPerformance.toNumber(),
currentNetPerformancePercent: currentNetPerformancePercent.toNumber()
currentNetPerformancePercent: currentNetPerformancePercent.toNumber(),
totalInvestment: totalInvestment.toNumber()
}
};
}

@ -1,4 +1,4 @@
<div class="row">
<div class="mb-2 row">
<div class="col-md-6 col-xs-12 d-flex">
<div class="align-items-center d-flex flex-grow-1 h5 mb-0 text-truncate">
<span i18n>Performance</span>
@ -31,14 +31,6 @@
</mat-form-field>
</div>
</div>
<div *ngIf="user.settings.viewMode !== 'ZEN'" class="my-2 text-center">
<gf-toggle
[defaultValue]="user?.settings?.dateRange"
[isLoading]="isLoading"
[options]="dateRangeOptions"
(change)="onChangeDateRange($event.value)"
></gf-toggle>
</div>
<div class="chart-container">
<ngx-skeleton-loader
*ngIf="isLoading"

@ -10,7 +10,6 @@ import {
Output,
ViewChild
} from '@angular/core';
import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.component';
import {
getTooltipOptions,
getTooltipPositionerMapTop,
@ -24,7 +23,6 @@ import {
parseDate
} from '@ghostfolio/common/helper';
import { LineChartItem, User } from '@ghostfolio/common/interfaces';
import { DateRange } from '@ghostfolio/common/types';
import {
Chart,
LineController,
@ -54,12 +52,10 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy {
@Input() user: User;
@Output() benchmarkChanged = new EventEmitter<string>();
@Output() dateRangeChanged = new EventEmitter<DateRange>();
@ViewChild('chartCanvas') chartCanvas;
public chart: Chart<any>;
public dateRangeOptions = ToggleComponent.DEFAULT_DATE_RANGE_OPTIONS;
public constructor() {
Chart.register(
@ -86,10 +82,6 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy {
this.benchmarkChanged.next(symbolProfileId);
}
public onChangeDateRange(dateRange: DateRange) {
this.dateRangeChanged.next(dateRange);
}
public ngOnDestroy() {
this.chart?.destroy();
}

@ -2,7 +2,6 @@ import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatSelectModule } from '@angular/material/select';
import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { BenchmarkComparatorComponent } from './benchmark-comparator.component';
@ -13,7 +12,6 @@ import { BenchmarkComparatorComponent } from './benchmark-comparator.component';
imports: [
CommonModule,
FormsModule,
GfToggleModule,
MatSelectModule,
NgxSkeletonLoaderModule,
ReactiveFormsModule

@ -24,7 +24,7 @@ export class HomeMarketComponent implements OnDestroy, OnInit {
public fearLabel = $localize`Fear`;
public greedLabel = $localize`Greed`;
public hasPermissionToAccessFearAndGreedIndex: boolean;
public historicalData: HistoricalDataItem[];
public historicalDataItems: HistoricalDataItem[];
public info: InfoItem;
public isLoading = true;
public readonly numberOfDays = 180;
@ -67,7 +67,7 @@ export class HomeMarketComponent implements OnDestroy, OnInit {
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ historicalData, marketPrice }) => {
this.fearAndGreedIndex = marketPrice;
this.historicalData = [
this.historicalDataItems = [
...historicalData,
{
date: resetHours(new Date()).toISOString(),

@ -10,7 +10,7 @@
symbol="Fear & Greed Index"
yMax="100"
yMin="0"
[historicalDataItems]="historicalData"
[historicalDataItems]="historicalDataItems"
[isAnimated]="true"
[locale]="user?.settings?.locale"
[showXAxis]="true"

@ -116,12 +116,14 @@ export class HomeOverviewComponent implements OnDestroy, OnInit {
this.performance = response.performance;
this.isLoadingPerformance = false;
this.historicalDataItems = response.chart.map(({ date, value }) => {
return {
date,
value
};
});
this.historicalDataItems = response.chart.map(
({ date, netPerformanceInPercentage }) => {
return {
date,
value: netPerformanceInPercentage
};
}
);
this.changeDetectorRef.markForCheck();
});

@ -15,14 +15,16 @@ import {
} from '@ghostfolio/common/chart-helper';
import { primaryColorRgb, secondaryColorRgb } from '@ghostfolio/common/config';
import {
DATE_FORMAT,
getBackgroundColor,
getDateFormatString,
getTextColor,
parseDate,
transformTickToAbbreviation
} from '@ghostfolio/common/helper';
import { LineChartItem } from '@ghostfolio/common/interfaces';
import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface';
import { GroupBy } from '@ghostfolio/common/types';
import { DateRange, GroupBy } from '@ghostfolio/common/types';
import {
BarController,
BarElement,
@ -35,7 +37,7 @@ import {
Tooltip
} from 'chart.js';
import annotationPlugin from 'chartjs-plugin-annotation';
import { addDays, isAfter, parseISO, subDays } from 'date-fns';
import { addDays, format, isAfter, parseISO, subDays } from 'date-fns';
@Component({
selector: 'gf-investment-chart',
@ -44,17 +46,19 @@ import { addDays, isAfter, parseISO, subDays } from 'date-fns';
styleUrls: ['./investment-chart.component.scss']
})
export class InvestmentChartComponent implements OnChanges, OnDestroy {
@Input() benchmarkDataItems: LineChartItem[] = [];
@Input() currency: string;
@Input() daysInMarket: number;
@Input() groupBy: GroupBy;
@Input() investments: InvestmentItem[];
@Input() isInPercent = false;
@Input() locale: string;
@Input() range: DateRange = 'max';
@Input() savingsRate = 0;
@ViewChild('chartCanvas') chartCanvas;
public chart: Chart;
public chart: Chart<any>;
public isLoading = true;
private data: InvestmentItem[];
@ -77,7 +81,7 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
}
public ngOnChanges() {
if (this.investments) {
if (this.benchmarkDataItems && this.investments) {
this.initialize();
}
}
@ -93,41 +97,44 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
this.data = this.investments.map((a) => Object.assign({}, a));
if (!this.groupBy && this.data?.length > 0) {
// Extend chart by 5% of days in market (before)
const firstItem = this.data[0];
this.data.unshift({
...firstItem,
date: subDays(
parseISO(firstItem.date),
this.daysInMarket * 0.05 || 90
).toISOString(),
investment: 0
});
if (this.range === 'max') {
// Extend chart by 5% of days in market (before)
const firstItem = this.data[0];
this.data.unshift({
...firstItem,
date: format(
subDays(parseISO(firstItem.date), this.daysInMarket * 0.05 || 90),
DATE_FORMAT
),
investment: 0
});
}
// Extend chart by 5% of days in market (after)
const lastItem = this.data[this.data.length - 1];
this.data.push({
...lastItem,
date: addDays(
parseDate(lastItem.date),
this.daysInMarket * 0.05 || 90
).toISOString()
date: format(
addDays(parseDate(lastItem.date), this.daysInMarket * 0.05 || 90),
DATE_FORMAT
)
});
}
const data = {
labels: this.data.map((investmentItem) => {
return investmentItem.date;
labels: this.benchmarkDataItems.map(({ date }) => {
return parseDate(date);
}),
datasets: [
{
backgroundColor: `rgb(${primaryColorRgb.r}, ${primaryColorRgb.g}, ${primaryColorRgb.b})`,
borderColor: `rgb(${primaryColorRgb.r}, ${primaryColorRgb.g}, ${primaryColorRgb.b})`,
borderWidth: this.groupBy ? 0 : 2,
data: this.data.map((position) => {
return this.isInPercent
? position.investment * 100
: position.investment;
data: this.data.map(({ date, investment }) => {
return {
x: parseDate(date),
y: this.isInPercent ? investment * 100 : investment
};
}),
label: $localize`Deposit`,
segment: {
@ -139,6 +146,19 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy {
borderDash: (context: unknown) => this.isInFuture(context, [2, 2])
},
stepped: true
},
{
borderColor: `rgb(${secondaryColorRgb.r}, ${secondaryColorRgb.g}, ${secondaryColorRgb.b})`,
borderWidth: 1,
data: this.benchmarkDataItems.map(({ date, value }) => {
return {
x: parseDate(date),
y: this.isInPercent ? value * 100 : value
};
}),
fill: false,
label: $localize`Total Amount`,
pointRadius: 0
}
]
};

@ -1,4 +1,5 @@
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.component';
import { DataService } from '@ghostfolio/client/services/data.service';
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
@ -26,6 +27,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public benchmarkDataItems: HistoricalDataItem[] = [];
public benchmarks: Partial<SymbolProfile>[];
public bottom3: Position[];
public dateRangeOptions = ToggleComponent.DEFAULT_DATE_RANGE_OPTIONS;
public daysInMarket: number;
public deviceType: string;
public firstOrderDate: Date;
@ -33,12 +35,12 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
public investments: InvestmentItem[];
public investmentsByMonth: InvestmentItem[];
public isLoadingBenchmarkComparator: boolean;
public mode: GroupBy;
public mode: GroupBy = 'month';
public modeOptions: ToggleOption[] = [
{ label: $localize`Monthly`, value: 'month' },
{ label: $localize`Accumulating`, value: undefined }
{ label: $localize`Monthly`, value: 'month' }
];
public performanceDataItems: HistoricalDataItem[];
public performanceDataItemsInPercentage: HistoricalDataItem[];
public top3: Position[];
public user: User;
@ -129,27 +131,41 @@ 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());
this.performanceDataItems = chart;
this.updateBenchmarkDataItems();
.subscribe(({ chart, firstOrderDate }) => {
this.firstOrderDate = firstOrderDate ?? new Date();
this.daysInMarket = differenceInDays(new Date(), firstOrderDate);
this.changeDetectorRef.markForCheck();
});
this.investments = [];
this.performanceDataItems = [];
this.performanceDataItemsInPercentage = [];
for (const {
date,
netPerformanceInPercentage,
totalInvestment,
value
} of chart) {
this.investments.push({ date, investment: totalInvestment });
this.performanceDataItems.push({
date,
value
});
this.performanceDataItemsInPercentage.push({
date,
value: netPerformanceInPercentage
});
}
this.dataService
.fetchInvestments()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ firstOrderDate, investments }) => {
this.daysInMarket = differenceInDays(new Date(), firstOrderDate);
this.investments = investments;
this.updateBenchmarkDataItems();
this.changeDetectorRef.markForCheck();
});
this.dataService
.fetchInvestmentsByMonth()
.fetchInvestments({
groupBy: 'month',
range: this.user?.settings?.dateRange
})
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ investments }) => {
this.investmentsByMonth = investments;
@ -158,7 +174,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit {
});
this.dataService
.fetchPositions({ range: 'max' })
.fetchPositions({ range: this.user?.settings?.dateRange })
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ positions }) => {
const positionsSorted = sortBy(

@ -1,5 +1,13 @@
<div class="container">
<h3 class="d-flex justify-content-center mb-3" i18n>Analysis</h3>
<h3 class="d-flex justify-content-center" i18n>Analysis</h3>
<div *ngIf="user?.settings?.viewMode !== 'ZEN'" class="my-4 text-center">
<gf-toggle
[defaultValue]="user?.settings?.dateRange"
[isLoading]="isLoadingBenchmarkComparator"
[options]="dateRangeOptions"
(change)="onChangeDateRange($event.value)"
></gf-toggle>
</div>
<div class="mb-5 row">
<div class="col-lg">
<gf-benchmark-comparator
@ -10,10 +18,9 @@
[daysInMarket]="daysInMarket"
[isLoading]="isLoadingBenchmarkComparator"
[locale]="user?.settings?.locale"
[performanceDataItems]="performanceDataItems"
[performanceDataItems]="performanceDataItemsInPercentage"
[user]="user"
(benchmarkChanged)="onChangeBenchmark($event)"
(dateRangeChanged)="onChangeDateRange($event)"
></gf-benchmark-comparator>
</div>
</div>
@ -96,6 +103,34 @@
</div>
</div>
<div class="mb-5 row">
<div class="col-lg">
<div class="align-items-center d-flex mb-4">
<div
class="align-items-center d-flex flex-grow-1 h5 mb-0 text-truncate"
>
<span i18n>Portfolio Evolution</span>
<gf-premium-indicator
*ngIf="user?.subscription?.type === 'Basic'"
class="ml-1"
></gf-premium-indicator>
</div>
</div>
<div class="chart-container">
<gf-investment-chart
class="h-100"
[benchmarkDataItems]="performanceDataItems"
[currency]="user?.settings?.baseCurrency"
[daysInMarket]="daysInMarket"
[investments]="investments"
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
[locale]="user?.settings?.locale"
[range]="user?.settings?.dateRange"
></gf-investment-chart>
</div>
</div>
</div>
<div class="row">
<div class="col-lg">
<div class="align-items-center d-flex mb-4">
@ -117,24 +152,15 @@
></gf-toggle>
</div>
<div class="chart-container">
<gf-investment-chart
class="h-100"
[currency]="user?.settings?.baseCurrency"
[daysInMarket]="daysInMarket"
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
[investments]="investments"
[locale]="user?.settings?.locale"
[ngClass]="{ 'd-none': mode }"
></gf-investment-chart>
<gf-investment-chart
class="h-100"
groupBy="month"
[currency]="user?.settings?.baseCurrency"
[daysInMarket]="daysInMarket"
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
[investments]="investmentsByMonth"
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
[locale]="user?.settings?.locale"
[ngClass]="{ 'd-none': !mode }"
[range]="user?.settings?.dateRange"
[savingsRate]="(hasImpersonationId || user.settings.isRestrictedView) ? undefined : user?.settings?.savingsRate"
></gf-investment-chart>
</div>

@ -163,34 +163,19 @@ export class DataService {
return info;
}
public fetchInvestments(): Observable<PortfolioInvestments> {
return this.http.get<any>('/api/v1/portfolio/investments').pipe(
map((response) => {
if (response.firstOrderDate) {
response.firstOrderDate = parseISO(response.firstOrderDate);
}
return response;
})
public fetchInvestments({
groupBy,
range
}: {
groupBy?: 'month';
range: DateRange;
}) {
return this.http.get<PortfolioInvestments>(
'/api/v1/portfolio/investments',
{ params: { groupBy, range } }
);
}
public fetchInvestmentsByMonth(): Observable<PortfolioInvestments> {
return this.http
.get<any>('/api/v1/portfolio/investments', {
params: { groupBy: 'month' }
})
.pipe(
map((response) => {
if (response.firstOrderDate) {
response.firstOrderDate = parseISO(response.firstOrderDate);
}
return response;
})
);
}
public fetchSymbolItem({
dataSource,
includeHistoricalData,
@ -252,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) {

@ -1722,7 +1722,7 @@
<target state="translated">Zeitstrahl der Investitionen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">105</context>
<context context-type="linenumber">140</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1730,7 +1730,7 @@
<target state="translated">Gewinner</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="6723d5c967329a3ac75524cf0c1af5ced022b9a3" datatype="html">
@ -1738,7 +1738,7 @@
<target state="translated">Verlierer</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -2054,7 +2054,7 @@
<target state="translated">Portfolio</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page-routing.module.ts</context>
@ -2498,15 +2498,7 @@
<target state="translated">Monatlich</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">38</context>
</context-group>
</trans-unit>
<trans-unit id="1975246224413290232" datatype="html">
<source>Accumulating</source>
<target state="translated">Aufsummiert</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">40</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
@ -2514,11 +2506,11 @@
<target state="translated">Einlage</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">132</context>
<context context-type="linenumber">139</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">276</context>
<context context-type="linenumber">279</context>
</context-group>
</trans-unit>
<trans-unit id="3441715041566940420" datatype="html">
@ -2526,7 +2518,7 @@
<target state="translated">Verzinsung</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">286</context>
<context context-type="linenumber">289</context>
</context-group>
</trans-unit>
<trans-unit id="1054498214311181686" datatype="html">
@ -2534,7 +2526,7 @@
<target state="translated">Ersparnisse</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">296</context>
<context context-type="linenumber">299</context>
</context-group>
</trans-unit>
<trans-unit id="aad5320acd7453f912bc8714e72c2fa71e8ab18e" datatype="html">
@ -2646,7 +2638,7 @@
<target state="translated">Benchmark</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">116</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="4210837540bca56dca96fcc451518659d06ad02a" datatype="html">
@ -2721,6 +2713,22 @@
<context context-type="linenumber">212</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
<source>Total Amount</source>
<target state="translated">Gesamtbetrag</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="f1a355a1af2e818050a3af693ac8b521fa7edc5f" datatype="html">
<source>Portfolio Evolution</source>
<target state="translated">Portfolio Wertentwicklung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1723,7 +1723,7 @@
<target state="translated">Cronología de la inversión</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">105</context>
<context context-type="linenumber">140</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1731,7 +1731,7 @@
<target state="translated">Lo mejor</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="6723d5c967329a3ac75524cf0c1af5ced022b9a3" datatype="html">
@ -1739,7 +1739,7 @@
<target state="translated">Lo peor</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -2055,7 +2055,7 @@
<target state="translated">Cartera</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page-routing.module.ts</context>
@ -2483,15 +2483,7 @@
<target state="translated">Ahorros</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">296</context>
</context-group>
</trans-unit>
<trans-unit id="1975246224413290232" datatype="html">
<source>Accumulating</source>
<target state="translated">Acumulando</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">299</context>
</context-group>
</trans-unit>
<trans-unit id="2937311350146031865" datatype="html">
@ -2507,7 +2499,7 @@
<target state="translated">Interés</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">286</context>
<context context-type="linenumber">289</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
@ -2515,11 +2507,11 @@
<target state="translated">Depósito</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">132</context>
<context context-type="linenumber">139</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">276</context>
<context context-type="linenumber">279</context>
</context-group>
</trans-unit>
<trans-unit id="6603000223840533819" datatype="html">
@ -2535,7 +2527,7 @@
<target state="translated">Mensual</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">38</context>
<context context-type="linenumber">40</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2631,7 +2623,7 @@
<target state="translated">Benchmark</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">116</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="1b25c6e22f822e07a3e4d5aae4edc5b41fe083c2" datatype="html">
@ -2722,6 +2714,22 @@
<context context-type="linenumber">212</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
<source>Total Amount</source>
<target state="new">Total Amount</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="f1a355a1af2e818050a3af693ac8b521fa7edc5f" datatype="html">
<source>Portfolio Evolution</source>
<target state="new">Portfolio Evolution</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1723,7 +1723,7 @@
<target state="translated">Cronologia degli investimenti</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">105</context>
<context context-type="linenumber">140</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1731,7 +1731,7 @@
<target state="translated">In alto</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="6723d5c967329a3ac75524cf0c1af5ced022b9a3" datatype="html">
@ -1739,7 +1739,7 @@
<target state="translated">In basso</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -2055,7 +2055,7 @@
<target state="translated">Portafoglio</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page-routing.module.ts</context>
@ -2483,15 +2483,7 @@
<target state="translated">Risparmio</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">296</context>
</context-group>
</trans-unit>
<trans-unit id="1975246224413290232" datatype="html">
<source>Accumulating</source>
<target state="translated">Accumulo</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">299</context>
</context-group>
</trans-unit>
<trans-unit id="2937311350146031865" datatype="html">
@ -2507,7 +2499,7 @@
<target state="translated">Interesse</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">286</context>
<context context-type="linenumber">289</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
@ -2515,11 +2507,11 @@
<target state="translated">Deposito</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">132</context>
<context context-type="linenumber">139</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">276</context>
<context context-type="linenumber">279</context>
</context-group>
</trans-unit>
<trans-unit id="6603000223840533819" datatype="html">
@ -2535,7 +2527,7 @@
<target state="translated">Mensile</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">38</context>
<context context-type="linenumber">40</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2631,7 +2623,7 @@
<target state="translated">Benchmark</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">116</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="1b25c6e22f822e07a3e4d5aae4edc5b41fe083c2" datatype="html">
@ -2722,6 +2714,22 @@
<context context-type="linenumber">212</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
<source>Total Amount</source>
<target state="new">Total Amount</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="f1a355a1af2e818050a3af693ac8b521fa7edc5f" datatype="html">
<source>Portfolio Evolution</source>
<target state="new">Portfolio Evolution</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1722,7 +1722,7 @@
<target state="translated">Tijdlijn investeringen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">105</context>
<context context-type="linenumber">140</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1730,7 +1730,7 @@
<target state="translated">Top</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="6723d5c967329a3ac75524cf0c1af5ced022b9a3" datatype="html">
@ -1738,7 +1738,7 @@
<target state="translated">Onder</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -2054,7 +2054,7 @@
<target state="translated">Portefeuille</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page-routing.module.ts</context>
@ -2482,15 +2482,7 @@
<target state="translated">Besparingen</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">296</context>
</context-group>
</trans-unit>
<trans-unit id="1975246224413290232" datatype="html">
<source>Accumulating</source>
<target state="translated">Accumuleren</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">299</context>
</context-group>
</trans-unit>
<trans-unit id="2937311350146031865" datatype="html">
@ -2506,7 +2498,7 @@
<target state="translated">Rente</target>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">286</context>
<context context-type="linenumber">289</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
@ -2514,11 +2506,11 @@
<target state="translated">Storting</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">132</context>
<context context-type="linenumber">139</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">276</context>
<context context-type="linenumber">279</context>
</context-group>
</trans-unit>
<trans-unit id="6603000223840533819" datatype="html">
@ -2534,7 +2526,7 @@
<target state="translated">Maandelijks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">38</context>
<context context-type="linenumber">40</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2630,7 +2622,7 @@
<target state="translated">Benchmark</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">116</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="1b25c6e22f822e07a3e4d5aae4edc5b41fe083c2" datatype="html">
@ -2721,6 +2713,22 @@
<context context-type="linenumber">212</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
<source>Total Amount</source>
<target state="new">Total Amount</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="f1a355a1af2e818050a3af693ac8b521fa7edc5f" datatype="html">
<source>Portfolio Evolution</source>
<target state="new">Portfolio Evolution</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1547,21 +1547,21 @@
<source>Investment Timeline</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">105</context>
<context context-type="linenumber">140</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
<source>Top</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">26</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="6723d5c967329a3ac75524cf0c1af5ced022b9a3" datatype="html">
<source>Bottom</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">62</context>
<context context-type="linenumber">69</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -1842,7 +1842,7 @@
<source>Portfolio</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">107</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page-routing.module.ts</context>
@ -2220,14 +2220,7 @@
<source>Savings</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">296</context>
</context-group>
</trans-unit>
<trans-unit id="1975246224413290232" datatype="html">
<source>Accumulating</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">39</context>
<context context-type="linenumber">299</context>
</context-group>
</trans-unit>
<trans-unit id="2937311350146031865" datatype="html">
@ -2241,18 +2234,18 @@
<source>Interest</source>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">286</context>
<context context-type="linenumber">289</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
<source>Deposit</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">132</context>
<context context-type="linenumber">139</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
<context context-type="linenumber">276</context>
<context context-type="linenumber">279</context>
</context-group>
</trans-unit>
<trans-unit id="6603000223840533819" datatype="html">
@ -2266,7 +2259,7 @@
<source>Monthly</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts</context>
<context context-type="linenumber">38</context>
<context context-type="linenumber">40</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2351,7 +2344,7 @@
<source>Benchmark</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts</context>
<context context-type="linenumber">116</context>
<context context-type="linenumber">108</context>
</context-group>
</trans-unit>
<trans-unit id="1b25c6e22f822e07a3e4d5aae4edc5b41fe083c2" datatype="html">
@ -2431,6 +2424,20 @@
<context context-type="linenumber">195</context>
</context-group>
</trans-unit>
<trans-unit id="112783260724635106" datatype="html">
<source>Total Amount</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">160</context>
</context-group>
</trans-unit>
<trans-unit id="f1a355a1af2e818050a3af693ac8b521fa7edc5f" datatype="html">
<source>Portfolio Evolution</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/analysis/analysis-page.html</context>
<context context-type="linenumber">112</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

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

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

@ -5,4 +5,5 @@ export interface PortfolioPerformance {
currentNetPerformance: number;
currentNetPerformancePercent: number;
currentValue: number;
totalInvestment: number;
}

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

Loading…
Cancel
Save