Feature/optimize get porfolio details endpoint (#3366)
* Eliminate getPerformance() from getSummary() function * Disable cache for getDetails() * Add hint to portfolio summary * Update changelog
This commit is contained in:
parent
3f41e5c5de
commit
f2cb671c7f
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Moved the holdings table to the holdings tab of the home page
|
||||
- Improved the performance labels (with and without currency effects) in the position detail dialog
|
||||
- Optimized the calculations of the of the portfolio details endpoint
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -165,21 +165,21 @@ export class PortfolioController {
|
||||
portfolioSummary = nullifyValuesInObject(summary, [
|
||||
'cash',
|
||||
'committedFunds',
|
||||
'currentGrossPerformance',
|
||||
'currentGrossPerformanceWithCurrencyEffect',
|
||||
'currentNetPerformance',
|
||||
'currentNetPerformanceWithCurrencyEffect',
|
||||
'currentNetWorth',
|
||||
'currentValue',
|
||||
'currentValueInBaseCurrency',
|
||||
'dividendInBaseCurrency',
|
||||
'emergencyFund',
|
||||
'excludedAccountsAndActivities',
|
||||
'fees',
|
||||
'filteredValueInBaseCurrency',
|
||||
'fireWealth',
|
||||
'grossPerformance',
|
||||
'grossPerformanceWithCurrencyEffect',
|
||||
'interest',
|
||||
'items',
|
||||
'liabilities',
|
||||
'netPerformance',
|
||||
'netPerformanceWithCurrencyEffect',
|
||||
'totalBuy',
|
||||
'totalInvestment',
|
||||
'totalSell',
|
||||
@ -449,10 +449,14 @@ export class PortfolioController {
|
||||
.div(performanceInformation.performance.totalInvestment)
|
||||
.toNumber(),
|
||||
valueInPercentage:
|
||||
performanceInformation.performance.currentValue === 0
|
||||
performanceInformation.performance.currentValueInBaseCurrency ===
|
||||
0
|
||||
? 0
|
||||
: new Big(value)
|
||||
.div(performanceInformation.performance.currentValue)
|
||||
.div(
|
||||
performanceInformation.performance
|
||||
.currentValueInBaseCurrency
|
||||
)
|
||||
.toNumber()
|
||||
};
|
||||
}
|
||||
@ -461,12 +465,12 @@ export class PortfolioController {
|
||||
performanceInformation.performance = nullifyValuesInObject(
|
||||
performanceInformation.performance,
|
||||
[
|
||||
'currentGrossPerformance',
|
||||
'currentGrossPerformanceWithCurrencyEffect',
|
||||
'currentNetPerformance',
|
||||
'currentNetPerformanceWithCurrencyEffect',
|
||||
'currentNetWorth',
|
||||
'currentValue',
|
||||
'currentValueInBaseCurrency',
|
||||
'grossPerformance',
|
||||
'grossPerformanceWithCurrencyEffect',
|
||||
'netPerformance',
|
||||
'netPerformanceWithCurrencyEffect',
|
||||
'totalInvestment'
|
||||
]
|
||||
);
|
||||
@ -483,7 +487,7 @@ export class PortfolioController {
|
||||
);
|
||||
performanceInformation.performance = nullifyValuesInObject(
|
||||
performanceInformation.performance,
|
||||
['currentNetPerformance', 'currentNetPerformancePercent']
|
||||
['netPerformance']
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ describe('PortfolioService', () => {
|
||||
portfolioService
|
||||
.getAnnualizedPerformancePercent({
|
||||
daysInMarket: NaN, // differenceInDays of date-fns returns NaN for the same day
|
||||
netPerformancePercent: new Big(0)
|
||||
netPerformancePercentage: new Big(0)
|
||||
})
|
||||
.toNumber()
|
||||
).toEqual(0);
|
||||
@ -36,7 +36,7 @@ describe('PortfolioService', () => {
|
||||
portfolioService
|
||||
.getAnnualizedPerformancePercent({
|
||||
daysInMarket: 0,
|
||||
netPerformancePercent: new Big(0)
|
||||
netPerformancePercentage: new Big(0)
|
||||
})
|
||||
.toNumber()
|
||||
).toEqual(0);
|
||||
@ -48,7 +48,7 @@ describe('PortfolioService', () => {
|
||||
portfolioService
|
||||
.getAnnualizedPerformancePercent({
|
||||
daysInMarket: 65, // < 1 year
|
||||
netPerformancePercent: new Big(0.1025)
|
||||
netPerformancePercentage: new Big(0.1025)
|
||||
})
|
||||
.toNumber()
|
||||
).toBeCloseTo(0.729705);
|
||||
@ -57,7 +57,7 @@ describe('PortfolioService', () => {
|
||||
portfolioService
|
||||
.getAnnualizedPerformancePercent({
|
||||
daysInMarket: 365, // 1 year
|
||||
netPerformancePercent: new Big(0.05)
|
||||
netPerformancePercentage: new Big(0.05)
|
||||
})
|
||||
.toNumber()
|
||||
).toBeCloseTo(0.05);
|
||||
@ -69,7 +69,7 @@ describe('PortfolioService', () => {
|
||||
portfolioService
|
||||
.getAnnualizedPerformancePercent({
|
||||
daysInMarket: 575, // > 1 year
|
||||
netPerformancePercent: new Big(0.2374)
|
||||
netPerformancePercentage: new Big(0.2374)
|
||||
})
|
||||
.toNumber()
|
||||
).toBeCloseTo(0.145);
|
||||
|
@ -208,16 +208,16 @@ export class PortfolioService {
|
||||
|
||||
public getAnnualizedPerformancePercent({
|
||||
daysInMarket,
|
||||
netPerformancePercent
|
||||
netPerformancePercentage
|
||||
}: {
|
||||
daysInMarket: number;
|
||||
netPerformancePercent: Big;
|
||||
netPerformancePercentage: Big;
|
||||
}): Big {
|
||||
if (isNumber(daysInMarket) && daysInMarket > 0) {
|
||||
const exponent = new Big(365).div(daysInMarket).toNumber();
|
||||
|
||||
return new Big(
|
||||
Math.pow(netPerformancePercent.plus(1).toNumber(), exponent)
|
||||
Math.pow(netPerformancePercentage.plus(1).toNumber(), exponent)
|
||||
).minus(1);
|
||||
}
|
||||
|
||||
@ -360,7 +360,7 @@ export class PortfolioService {
|
||||
userId,
|
||||
calculationType: PerformanceCalculationType.TWR,
|
||||
currency: userCurrency,
|
||||
hasFilters: filters?.length > 0,
|
||||
hasFilters: true, // disable cache
|
||||
isExperimentalFeatures:
|
||||
this.request.user?.Settings.settings.isExperimentalFeatures
|
||||
});
|
||||
@ -704,7 +704,7 @@ export class PortfolioService {
|
||||
|
||||
const dividendYieldPercent = this.getAnnualizedPerformancePercent({
|
||||
daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)),
|
||||
netPerformancePercent: timeWeightedInvestment.eq(0)
|
||||
netPerformancePercentage: timeWeightedInvestment.eq(0)
|
||||
? new Big(0)
|
||||
: dividendInBaseCurrency.div(timeWeightedInvestment)
|
||||
});
|
||||
@ -712,7 +712,9 @@ export class PortfolioService {
|
||||
const dividendYieldPercentWithCurrencyEffect =
|
||||
this.getAnnualizedPerformancePercent({
|
||||
daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)),
|
||||
netPerformancePercent: timeWeightedInvestmentWithCurrencyEffect.eq(0)
|
||||
netPerformancePercentage: timeWeightedInvestmentWithCurrencyEffect.eq(
|
||||
0
|
||||
)
|
||||
? new Big(0)
|
||||
: dividendInBaseCurrency.div(
|
||||
timeWeightedInvestmentWithCurrencyEffect
|
||||
@ -1108,16 +1110,16 @@ export class PortfolioService {
|
||||
firstOrderDate: undefined,
|
||||
hasErrors: false,
|
||||
performance: {
|
||||
currentGrossPerformance: 0,
|
||||
currentGrossPerformancePercent: 0,
|
||||
currentGrossPerformancePercentWithCurrencyEffect: 0,
|
||||
currentGrossPerformanceWithCurrencyEffect: 0,
|
||||
currentNetPerformance: 0,
|
||||
currentNetPerformancePercent: 0,
|
||||
currentNetPerformancePercentWithCurrencyEffect: 0,
|
||||
currentNetPerformanceWithCurrencyEffect: 0,
|
||||
currentNetWorth: 0,
|
||||
currentValue: 0,
|
||||
currentValueInBaseCurrency: 0,
|
||||
grossPerformance: 0,
|
||||
grossPerformancePercentage: 0,
|
||||
grossPerformancePercentageWithCurrencyEffect: 0,
|
||||
grossPerformanceWithCurrencyEffect: 0,
|
||||
netPerformance: 0,
|
||||
netPerformancePercentage: 0,
|
||||
netPerformancePercentageWithCurrencyEffect: 0,
|
||||
netPerformanceWithCurrencyEffect: 0,
|
||||
totalInvestment: 0
|
||||
}
|
||||
};
|
||||
@ -1152,9 +1154,9 @@ export class PortfolioService {
|
||||
|
||||
let currentNetPerformance = netPerformance;
|
||||
|
||||
let currentNetPerformancePercent = netPerformancePercentage;
|
||||
let currentNetPerformancePercentage = netPerformancePercentage;
|
||||
|
||||
let currentNetPerformancePercentWithCurrencyEffect =
|
||||
let currentNetPerformancePercentageWithCurrencyEffect =
|
||||
netPerformancePercentageWithCurrencyEffect;
|
||||
|
||||
let currentNetPerformanceWithCurrencyEffect =
|
||||
@ -1173,11 +1175,11 @@ export class PortfolioService {
|
||||
if (itemOfToday) {
|
||||
currentNetPerformance = new Big(itemOfToday.netPerformance);
|
||||
|
||||
currentNetPerformancePercent = new Big(
|
||||
currentNetPerformancePercentage = new Big(
|
||||
itemOfToday.netPerformanceInPercentage
|
||||
).div(100);
|
||||
|
||||
currentNetPerformancePercentWithCurrencyEffect = new Big(
|
||||
currentNetPerformancePercentageWithCurrencyEffect = new Big(
|
||||
itemOfToday.netPerformanceInPercentageWithCurrencyEffect
|
||||
).div(100);
|
||||
|
||||
@ -1195,19 +1197,19 @@ export class PortfolioService {
|
||||
firstOrderDate: parseDate(items[0]?.date),
|
||||
performance: {
|
||||
currentNetWorth,
|
||||
currentGrossPerformance: grossPerformance.toNumber(),
|
||||
currentGrossPerformancePercent: grossPerformancePercentage.toNumber(),
|
||||
currentGrossPerformancePercentWithCurrencyEffect:
|
||||
currentValueInBaseCurrency: currentValueInBaseCurrency.toNumber(),
|
||||
grossPerformance: grossPerformance.toNumber(),
|
||||
grossPerformancePercentage: grossPerformancePercentage.toNumber(),
|
||||
grossPerformancePercentageWithCurrencyEffect:
|
||||
grossPerformancePercentageWithCurrencyEffect.toNumber(),
|
||||
currentGrossPerformanceWithCurrencyEffect:
|
||||
grossPerformanceWithCurrencyEffect:
|
||||
grossPerformanceWithCurrencyEffect.toNumber(),
|
||||
currentNetPerformance: currentNetPerformance.toNumber(),
|
||||
currentNetPerformancePercent: currentNetPerformancePercent.toNumber(),
|
||||
currentNetPerformancePercentWithCurrencyEffect:
|
||||
currentNetPerformancePercentWithCurrencyEffect.toNumber(),
|
||||
currentNetPerformanceWithCurrencyEffect:
|
||||
netPerformance: currentNetPerformance.toNumber(),
|
||||
netPerformancePercentage: currentNetPerformancePercentage.toNumber(),
|
||||
netPerformancePercentageWithCurrencyEffect:
|
||||
currentNetPerformancePercentageWithCurrencyEffect.toNumber(),
|
||||
netPerformanceWithCurrencyEffect:
|
||||
currentNetPerformanceWithCurrencyEffect.toNumber(),
|
||||
currentValue: currentValueInBaseCurrency.toNumber(),
|
||||
totalInvestment: totalInvestment.toNumber()
|
||||
}
|
||||
};
|
||||
@ -1604,11 +1606,6 @@ export class PortfolioService {
|
||||
userId = await this.getUserId(impersonationId, userId);
|
||||
const user = await this.userService.user({ id: userId });
|
||||
|
||||
const { performance } = await this.getPerformance({
|
||||
impersonationId,
|
||||
userId
|
||||
});
|
||||
|
||||
const { activities } = await this.orderService.getOrders({
|
||||
userCurrency,
|
||||
userId,
|
||||
@ -1626,6 +1623,19 @@ export class PortfolioService {
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
currentValueInBaseCurrency,
|
||||
grossPerformance,
|
||||
grossPerformancePercentage,
|
||||
grossPerformancePercentageWithCurrencyEffect,
|
||||
grossPerformanceWithCurrencyEffect,
|
||||
netPerformance,
|
||||
netPerformancePercentage,
|
||||
netPerformancePercentageWithCurrencyEffect,
|
||||
netPerformanceWithCurrencyEffect,
|
||||
totalInvestment
|
||||
} = await portfolioCalculator.getSnapshot();
|
||||
|
||||
const dividendInBaseCurrency =
|
||||
await portfolioCalculator.getDividendInBaseCurrency();
|
||||
|
||||
@ -1694,7 +1704,7 @@ export class PortfolioService {
|
||||
.toNumber();
|
||||
|
||||
const netWorth = new Big(balanceInBaseCurrency)
|
||||
.plus(performance.currentValue)
|
||||
.plus(currentValueInBaseCurrency)
|
||||
.plus(valuables)
|
||||
.plus(excludedAccountsAndActivities)
|
||||
.minus(liabilities)
|
||||
@ -1704,19 +1714,18 @@ export class PortfolioService {
|
||||
|
||||
const annualizedPerformancePercent = this.getAnnualizedPerformancePercent({
|
||||
daysInMarket,
|
||||
netPerformancePercent: new Big(performance.currentNetPerformancePercent)
|
||||
netPerformancePercentage: new Big(netPerformancePercentage)
|
||||
})?.toNumber();
|
||||
|
||||
const annualizedPerformancePercentWithCurrencyEffect =
|
||||
this.getAnnualizedPerformancePercent({
|
||||
daysInMarket,
|
||||
netPerformancePercent: new Big(
|
||||
performance.currentNetPerformancePercentWithCurrencyEffect
|
||||
netPerformancePercentage: new Big(
|
||||
netPerformancePercentageWithCurrencyEffect
|
||||
)
|
||||
})?.toNumber();
|
||||
|
||||
return {
|
||||
...performance,
|
||||
annualizedPerformancePercent,
|
||||
annualizedPerformancePercentWithCurrencyEffect,
|
||||
cash,
|
||||
@ -1725,6 +1734,7 @@ export class PortfolioService {
|
||||
totalBuy,
|
||||
totalSell,
|
||||
committedFunds: committedFunds.toNumber(),
|
||||
currentValueInBaseCurrency: currentValueInBaseCurrency.toNumber(),
|
||||
dividendInBaseCurrency: dividendInBaseCurrency.toNumber(),
|
||||
emergencyFund: {
|
||||
assets: emergencyFundPositionsValueInBaseCurrency,
|
||||
@ -1738,15 +1748,28 @@ export class PortfolioService {
|
||||
filteredValueInPercentage: netWorth
|
||||
? filteredValueInBaseCurrency.div(netWorth).toNumber()
|
||||
: undefined,
|
||||
fireWealth: new Big(performance.currentValue)
|
||||
fireWealth: new Big(currentValueInBaseCurrency)
|
||||
.minus(emergencyFundPositionsValueInBaseCurrency)
|
||||
.toNumber(),
|
||||
grossPerformance: grossPerformance.toNumber(),
|
||||
grossPerformancePercentage: grossPerformancePercentage.toNumber(),
|
||||
grossPerformancePercentageWithCurrencyEffect:
|
||||
grossPerformancePercentageWithCurrencyEffect.toNumber(),
|
||||
grossPerformanceWithCurrencyEffect:
|
||||
grossPerformanceWithCurrencyEffect.toNumber(),
|
||||
interest: interest.toNumber(),
|
||||
items: valuables.toNumber(),
|
||||
liabilities: liabilities.toNumber(),
|
||||
netPerformance: netPerformance.toNumber(),
|
||||
netPerformancePercentage: netPerformancePercentage.toNumber(),
|
||||
netPerformancePercentageWithCurrencyEffect:
|
||||
netPerformancePercentageWithCurrencyEffect.toNumber(),
|
||||
netPerformanceWithCurrencyEffect:
|
||||
netPerformanceWithCurrencyEffect.toNumber(),
|
||||
ordersCount: activities.filter(({ type }) => {
|
||||
return type === 'BUY' || type === 'SELL';
|
||||
return ['BUY', 'SELL'].includes(type);
|
||||
}).length,
|
||||
totalInvestment: totalInvestment.toNumber(),
|
||||
totalValueInBaseCurrency: netWorth
|
||||
};
|
||||
}
|
||||
|
@ -41,9 +41,7 @@
|
||||
[isCurrency]="true"
|
||||
[locale]="locale"
|
||||
[value]="
|
||||
isLoading
|
||||
? undefined
|
||||
: performance?.currentNetPerformanceWithCurrencyEffect
|
||||
isLoading ? undefined : performance?.netPerformanceWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -55,7 +53,7 @@
|
||||
[value]="
|
||||
isLoading
|
||||
? undefined
|
||||
: performance?.currentNetPerformancePercentWithCurrencyEffect
|
||||
: performance?.netPerformancePercentageWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
@ -49,12 +49,12 @@ export class PortfolioPerformanceComponent implements OnChanges, OnInit {
|
||||
this.value.nativeElement.innerHTML = '';
|
||||
}
|
||||
} else {
|
||||
if (isNumber(this.performance?.currentValue)) {
|
||||
new CountUp('value', this.performance?.currentValue, {
|
||||
if (isNumber(this.performance?.currentValueInBaseCurrency)) {
|
||||
new CountUp('value', this.performance?.currentValueInBaseCurrency, {
|
||||
decimal: getNumberFormatDecimal(this.locale),
|
||||
decimalPlaces:
|
||||
this.deviceType === 'mobile' &&
|
||||
this.performance?.currentValue >= 100000
|
||||
this.performance?.currentValueInBaseCurrency >= 100000
|
||||
? 0
|
||||
: 2,
|
||||
duration: 1,
|
||||
@ -63,8 +63,7 @@ export class PortfolioPerformanceComponent implements OnChanges, OnInit {
|
||||
} else if (this.showDetails === false) {
|
||||
new CountUp(
|
||||
'value',
|
||||
this.performance?.currentNetPerformancePercentWithCurrencyEffect *
|
||||
100,
|
||||
this.performance?.netPerformancePercentageWithCurrencyEffect * 100,
|
||||
{
|
||||
decimal: getNumberFormatDecimal(this.locale),
|
||||
decimalPlaces: 2,
|
||||
|
@ -9,9 +9,19 @@
|
||||
class="flex-nowrap px-3 py-1 row"
|
||||
[hidden]="summary?.ordersCount === null"
|
||||
>
|
||||
<div class="flex-grow-1 ml-3 text-truncate" i18n>
|
||||
<div class="d-flex flex-grow-1 ml-3 text-truncate">
|
||||
{{ summary?.ordersCount }}
|
||||
{summary?.ordersCount, plural, =1 {transaction} other {transactions}}
|
||||
<ng-container i18n>{summary?.ordersCount, plural,
|
||||
=1 {activity}
|
||||
other {activities}
|
||||
}</ng-container>
|
||||
<span
|
||||
class="align-items-center d-flex ml-1"
|
||||
matTooltipPosition="above"
|
||||
[matTooltip]="buyAndSellActivitiesTooltip"
|
||||
>
|
||||
<ion-icon name="information-circle-outline" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@ -65,9 +75,7 @@
|
||||
[locale]="locale"
|
||||
[unit]="baseCurrency"
|
||||
[value]="
|
||||
isLoading
|
||||
? undefined
|
||||
: summary?.currentGrossPerformanceWithCurrencyEffect
|
||||
isLoading ? undefined : summary?.grossPerformanceWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -91,7 +99,7 @@
|
||||
[value]="
|
||||
isLoading
|
||||
? undefined
|
||||
: summary?.currentGrossPerformancePercentWithCurrencyEffect
|
||||
: summary?.grossPerformancePercentageWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -121,9 +129,7 @@
|
||||
[locale]="locale"
|
||||
[unit]="baseCurrency"
|
||||
[value]="
|
||||
isLoading
|
||||
? undefined
|
||||
: summary?.currentNetPerformanceWithCurrencyEffect
|
||||
isLoading ? undefined : summary?.netPerformanceWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -147,7 +153,7 @@
|
||||
[value]="
|
||||
isLoading
|
||||
? undefined
|
||||
: summary?.currentNetPerformancePercentWithCurrencyEffect
|
||||
: summary?.netPerformancePercentageWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -164,7 +170,7 @@
|
||||
[isCurrency]="true"
|
||||
[locale]="locale"
|
||||
[unit]="baseCurrency"
|
||||
[value]="isLoading ? undefined : summary?.currentValue"
|
||||
[value]="isLoading ? undefined : summary?.currentValueInBaseCurrency"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { getDateFnsLocale, getLocale } from '@ghostfolio/common/helper';
|
||||
import { PortfolioSummary } from '@ghostfolio/common/interfaces';
|
||||
import { translate } from '@ghostfolio/ui/i18n';
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
@ -28,6 +29,9 @@ export class PortfolioSummaryComponent implements OnChanges, OnInit {
|
||||
|
||||
@Output() emergencyFundChanged = new EventEmitter<number>();
|
||||
|
||||
public buyAndSellActivitiesTooltip = translate(
|
||||
'BUY_AND_SELL_ACTIVITIES_TOOLTIP'
|
||||
);
|
||||
public timeInMarket: string;
|
||||
|
||||
public constructor() {}
|
||||
|
@ -2,13 +2,14 @@ import { GfValueComponent } from '@ghostfolio/ui/value';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
|
||||
import { PortfolioSummaryComponent } from './portfolio-summary.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [PortfolioSummaryComponent],
|
||||
exports: [PortfolioSummaryComponent],
|
||||
imports: [CommonModule, GfValueComponent],
|
||||
imports: [CommonModule, GfValueComponent, MatTooltipModule],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class GfPortfolioSummaryModule {}
|
||||
|
@ -42,7 +42,7 @@
|
||||
[value]="
|
||||
isLoadingInvestmentChart
|
||||
? undefined
|
||||
: performance?.currentNetPerformance
|
||||
: performance?.netPerformance
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -61,7 +61,7 @@
|
||||
[value]="
|
||||
isLoadingInvestmentChart
|
||||
? undefined
|
||||
: performance?.currentNetPerformancePercent
|
||||
: performance?.netPerformancePercentage
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -86,10 +86,10 @@
|
||||
[value]="
|
||||
isLoadingInvestmentChart
|
||||
? undefined
|
||||
: performance?.currentNetPerformance === null
|
||||
: performance?.netPerformance === null
|
||||
? null
|
||||
: performance?.currentNetPerformanceWithCurrencyEffect -
|
||||
performance?.currentNetPerformance
|
||||
: performance?.netPerformanceWithCurrencyEffect -
|
||||
performance?.netPerformance
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -108,10 +108,10 @@
|
||||
[value]="
|
||||
isLoadingInvestmentChart
|
||||
? undefined
|
||||
: performance?.currentNetPerformancePercent === null
|
||||
: performance?.netPerformancePercentage === null
|
||||
? null
|
||||
: performance?.currentNetPerformancePercentWithCurrencyEffect -
|
||||
performance?.currentNetPerformancePercent
|
||||
: performance?.netPerformancePercentageWithCurrencyEffect -
|
||||
performance?.netPerformancePercentage
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -131,7 +131,7 @@
|
||||
[value]="
|
||||
isLoadingInvestmentChart
|
||||
? undefined
|
||||
: performance?.currentNetPerformanceWithCurrencyEffect
|
||||
: performance?.netPerformanceWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
@ -150,7 +150,7 @@
|
||||
[value]="
|
||||
isLoadingInvestmentChart
|
||||
? undefined
|
||||
: performance?.currentNetPerformancePercentWithCurrencyEffect
|
||||
: performance?.netPerformancePercentageWithCurrencyEffect
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,14 +1,14 @@
|
||||
export interface PortfolioPerformance {
|
||||
annualizedPerformancePercent?: number;
|
||||
currentGrossPerformance: number;
|
||||
currentGrossPerformancePercent: number;
|
||||
currentGrossPerformancePercentWithCurrencyEffect: number;
|
||||
currentGrossPerformanceWithCurrencyEffect: number;
|
||||
currentNetPerformance: number;
|
||||
currentNetPerformancePercent: number;
|
||||
currentNetPerformancePercentWithCurrencyEffect: number;
|
||||
currentNetPerformanceWithCurrencyEffect: number;
|
||||
currentNetWorth: number;
|
||||
currentValue: number;
|
||||
currentNetWorth?: number;
|
||||
currentValueInBaseCurrency: number;
|
||||
grossPerformance: number;
|
||||
grossPerformancePercentage: number;
|
||||
grossPerformancePercentageWithCurrencyEffect: number;
|
||||
grossPerformanceWithCurrencyEffect: number;
|
||||
netPerformance: number;
|
||||
netPerformancePercentage: number;
|
||||
netPerformancePercentageWithCurrencyEffect: number;
|
||||
netPerformanceWithCurrencyEffect: number;
|
||||
totalInvestment: number;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ const locales = {
|
||||
'Asia-Pacific': $localize`Asia-Pacific`,
|
||||
ASSET_CLASS: $localize`Asset Class`,
|
||||
ASSET_SUB_CLASS: $localize`Asset Sub Class`,
|
||||
BUY_AND_SELL_ACTIVITIES_TOOLTIP: $localize`Buy and sell`,
|
||||
CORE: $localize`Core`,
|
||||
DATA_IMPORT_AND_EXPORT_TOOLTIP_BASIC: $localize`Switch to Ghostfolio Premium or Ghostfolio Open Source easily`,
|
||||
DATA_IMPORT_AND_EXPORT_TOOLTIP_OSS: $localize`Switch to Ghostfolio Premium easily`,
|
||||
|
Loading…
x
Reference in New Issue
Block a user