mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
13 KiB
362 lines
13 KiB
<div class="container">
|
|
<div class="row">
|
|
<div class="col">
|
|
<h1 class="d-none d-sm-block h3 mb-3 text-center" i18n>Allocations</h1>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="mb-2 overflow-hidden w-100">
|
|
<mat-card-title class="m-0 text-truncate" i18n
|
|
>Proportion of Net Worth</mat-card-title
|
|
>
|
|
<gf-value
|
|
class="justify-content-end l-2"
|
|
size="medium"
|
|
[isPercent]="true"
|
|
[value]="
|
|
isLoading
|
|
? undefined
|
|
: portfolioDetails?.summary?.filteredValueInPercentage
|
|
"
|
|
/>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<mat-progress-bar
|
|
mode="determinate"
|
|
[title]="
|
|
(
|
|
portfolioDetails?.summary?.filteredValueInPercentage * 100
|
|
).toFixed(2) + '%'
|
|
"
|
|
[value]="portfolioDetails?.summary?.filteredValueInPercentage * 100"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
</div>
|
|
<div class="proportion-charts row">
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="text-truncate" i18n
|
|
>By Platform</mat-card-title
|
|
>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['id']"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="platforms"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By Currency</span>
|
|
<gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['currency']"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="positions"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By Asset Class</span
|
|
><gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['assetClassLabel', 'assetSubClassLabel']"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="positions"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-12 allocations-by-symbol">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate">
|
|
<ng-container i18n>By Holding</ng-container>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
class="mx-auto"
|
|
cursor="pointer"
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['symbol']"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="symbols"
|
|
[showLabels]="deviceType !== 'mobile'"
|
|
(proportionChartClicked)="onSymbolChartClicked($event)"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By Sector</span
|
|
><gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['name']"
|
|
[locale]="user?.settings?.locale"
|
|
[maxItems]="10"
|
|
[positions]="sectors"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By Continent</span
|
|
><gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['name']"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="continents"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By Market</span
|
|
><gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="marketsAdvanced"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
</div>
|
|
<div class="row world-map-chart">
|
|
<div class="col-lg">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>Regions</span
|
|
><gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<div class="world-map-chart-container">
|
|
<gf-world-map-chart
|
|
[countries]="countries"
|
|
[format]="worldMapChartFormat"
|
|
[isInPercent]="
|
|
hasImpersonationId || user.settings.isRestrictedView
|
|
"
|
|
[locale]="user?.settings?.locale"
|
|
/>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-xs-12 col-md my-2">
|
|
<gf-value
|
|
i18n
|
|
size="large"
|
|
[isPercent]="true"
|
|
[value]="markets?.developedMarkets?.value"
|
|
>Developed Markets</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-xs-12 col-md my-2">
|
|
<gf-value
|
|
i18n
|
|
size="large"
|
|
[isPercent]="true"
|
|
[value]="markets?.emergingMarkets?.value"
|
|
>Emerging Markets</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-xs-12 col-md my-2">
|
|
<gf-value
|
|
i18n
|
|
size="large"
|
|
[isPercent]="true"
|
|
[value]="markets?.otherMarkets?.value"
|
|
>Other Markets</gf-value
|
|
>
|
|
</div>
|
|
<div
|
|
*ngIf="markets?.[UNKNOWN_KEY]?.value > 0"
|
|
class="col-xs-12 col-md my-2"
|
|
>
|
|
<gf-value
|
|
i18n
|
|
size="large"
|
|
[isPercent]="true"
|
|
[value]="markets?.[UNKNOWN_KEY]?.value"
|
|
>No data available</gf-value
|
|
>
|
|
</div>
|
|
</div>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="text-truncate" i18n>By Account</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
cursor="pointer"
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['id']"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="accounts"
|
|
(proportionChartClicked)="onAccountChartClicked($event)"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By ETF Provider</span
|
|
><gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['etfProvider']"
|
|
[locale]="user?.settings?.locale"
|
|
[positions]="positions"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By Country</span
|
|
><gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[colorScheme]="user?.settings?.colorScheme"
|
|
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
|
|
[keys]="['name']"
|
|
[locale]="user?.settings?.locale"
|
|
[maxItems]="10"
|
|
[positions]="countries"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
@if (topHoldings?.length > 0 && user?.settings?.isExperimentalFeatures) {
|
|
<div class="col-md-12">
|
|
<mat-card appearance="outlined" class="mb-3">
|
|
<mat-card-header class="overflow-hidden w-100">
|
|
<mat-card-title class="align-items-center d-flex text-truncate"
|
|
><span i18n>By ETF Holding</span>
|
|
<gf-premium-indicator
|
|
*ngIf="user?.subscription?.type === 'Basic'"
|
|
class="ml-1"
|
|
/>
|
|
</mat-card-title>
|
|
<mat-card-subtitle>
|
|
<ng-container i18n
|
|
>Approximation based on the Top 15 holdings per
|
|
ETF</ng-container
|
|
>
|
|
</mat-card-subtitle>
|
|
</mat-card-header>
|
|
<mat-card-content>
|
|
<gf-top-holdings
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[locale]="user?.settings?.locale"
|
|
[topHoldings]="topHoldings"
|
|
/>
|
|
</mat-card-content>
|
|
</mat-card>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|