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.
419 lines
12 KiB
419 lines
12 KiB
<gf-dialog-header
|
|
mat-dialog-title
|
|
position="center"
|
|
[deviceType]="data.deviceType"
|
|
[title]="SymbolProfile?.name ?? SymbolProfile?.symbol"
|
|
(closeButtonClicked)="onClose()"
|
|
/>
|
|
|
|
<div class="flex-grow-1" mat-dialog-content>
|
|
<div class="container p-0">
|
|
<div class="row">
|
|
<div class="col-12 d-flex justify-content-center mb-3">
|
|
<gf-value
|
|
size="large"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[unit]="data.baseCurrency"
|
|
[value]="value"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<gf-line-chart
|
|
benchmarkLabel="Average Unit Price"
|
|
class="mb-4"
|
|
[benchmarkDataItems]="benchmarkDataItems"
|
|
[colorScheme]="data.colorScheme"
|
|
[currency]="SymbolProfile?.currency"
|
|
[historicalDataItems]="historicalDataItems"
|
|
[isAnimated]="true"
|
|
[locale]="data.locale"
|
|
[showGradient]="true"
|
|
[showXAxis]="true"
|
|
[showYAxis]="true"
|
|
[symbol]="data.symbol"
|
|
/>
|
|
|
|
<div class="row">
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[colorizeSign]="true"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[precision]="netPerformanceWithCurrencyEffectPrecision"
|
|
[unit]="data.baseCurrency"
|
|
[value]="netPerformanceWithCurrencyEffect"
|
|
>
|
|
@if (
|
|
SymbolProfile?.currency &&
|
|
data.baseCurrency !== SymbolProfile?.currency
|
|
) {
|
|
Change with currency effect
|
|
} @else {
|
|
Change
|
|
}
|
|
</gf-value>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[colorizeSign]="true"
|
|
[isPercent]="true"
|
|
[locale]="data.locale"
|
|
[value]="netPerformancePercentWithCurrencyEffect"
|
|
>
|
|
@if (
|
|
SymbolProfile?.currency &&
|
|
data.baseCurrency !== SymbolProfile?.currency
|
|
) {
|
|
Performance with currency effect
|
|
} @else {
|
|
Performance
|
|
}
|
|
</gf-value>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[unit]="SymbolProfile?.currency"
|
|
[value]="averagePrice"
|
|
>Average Unit Price</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[unit]="SymbolProfile?.currency"
|
|
[value]="marketPrice"
|
|
>Market Price</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[ngClass]="{
|
|
'text-danger':
|
|
minPrice?.toFixed(2) === marketPrice?.toFixed(2) &&
|
|
maxPrice?.toFixed(2) !== minPrice?.toFixed(2)
|
|
}"
|
|
[unit]="SymbolProfile?.currency"
|
|
[value]="minPrice"
|
|
>Minimum Price</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[ngClass]="{
|
|
'text-success':
|
|
maxPrice?.toFixed(2) === marketPrice?.toFixed(2) &&
|
|
maxPrice?.toFixed(2) !== minPrice?.toFixed(2)
|
|
}"
|
|
[unit]="SymbolProfile?.currency"
|
|
[value]="maxPrice"
|
|
>Maximum Price</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[locale]="data.locale"
|
|
[precision]="quantityPrecision"
|
|
[value]="quantity"
|
|
>Quantity</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[precision]="investmentPrecision"
|
|
[unit]="data.baseCurrency"
|
|
[value]="investment"
|
|
>Investment</gf-value
|
|
>
|
|
</div>
|
|
@if (dividendInBaseCurrency && user?.settings?.isExperimentalFeatures) {
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[precision]="dividendInBaseCurrencyPrecision"
|
|
[unit]="data.baseCurrency"
|
|
[value]="dividendInBaseCurrency"
|
|
>Dividend</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isPercent]="true"
|
|
[locale]="data.locale"
|
|
[value]="dividendYieldPercentWithCurrencyEffect"
|
|
>Dividend Yield</gf-value
|
|
>
|
|
</div>
|
|
}
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isCurrency]="true"
|
|
[locale]="data.locale"
|
|
[unit]="data.baseCurrency"
|
|
[value]="feeInBaseCurrency"
|
|
>Fees</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[isDate]="true"
|
|
[locale]="data.locale"
|
|
[value]="firstBuyDate"
|
|
>First Activity</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
size="medium"
|
|
[locale]="data.locale"
|
|
[value]="transactionCount"
|
|
>
|
|
@if (transactionCount === 1) {
|
|
<ng-container i18n>Activity</ng-container>
|
|
} @else {
|
|
<ng-container i18n>Activities</ng-container>
|
|
}
|
|
</gf-value>
|
|
</div>
|
|
<div class="col-6 mb-3"></div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value i18n size="medium" [hidden]="!assetClass" [value]="assetClass"
|
|
>Asset Class</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[hidden]="!assetSubClass"
|
|
[value]="assetSubClass"
|
|
>Asset Sub Class</gf-value
|
|
>
|
|
</div>
|
|
@if (
|
|
SymbolProfile?.countries?.length > 0 ||
|
|
SymbolProfile?.sectors?.length > 0
|
|
) {
|
|
@if (
|
|
SymbolProfile?.countries?.length === 1 &&
|
|
SymbolProfile?.sectors?.length === 1
|
|
) {
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[locale]="data.locale"
|
|
[value]="SymbolProfile.sectors[0].name"
|
|
>Sector</gf-value
|
|
>
|
|
</div>
|
|
@if (SymbolProfile?.countries?.length === 1) {
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[locale]="data.locale"
|
|
[value]="SymbolProfile.countries[0].name"
|
|
>Country</gf-value
|
|
>
|
|
</div>
|
|
}
|
|
} @else {
|
|
<div class="col-md-6 mb-3">
|
|
<div class="h5" i18n>Sectors</div>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="data.baseCurrency"
|
|
[colorScheme]="data.colorScheme"
|
|
[isInPercent]="true"
|
|
[keys]="['name']"
|
|
[locale]="data.locale"
|
|
[maxItems]="10"
|
|
[positions]="sectors"
|
|
/>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<div class="h5" i18n>Countries</div>
|
|
<gf-portfolio-proportion-chart
|
|
[baseCurrency]="data.baseCurrency"
|
|
[colorScheme]="data.colorScheme"
|
|
[isInPercent]="true"
|
|
[keys]="['name']"
|
|
[locale]="data.locale"
|
|
[maxItems]="10"
|
|
[positions]="countries"
|
|
/>
|
|
</div>
|
|
}
|
|
}
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
i18n
|
|
size="medium"
|
|
[hidden]="!SymbolProfile?.symbol"
|
|
[value]="SymbolProfile?.symbol"
|
|
>Symbol</gf-value
|
|
>
|
|
</div>
|
|
<div class="col-6 mb-3">
|
|
<gf-value
|
|
size="medium"
|
|
[hidden]="!SymbolProfile?.isin"
|
|
[value]="SymbolProfile?.isin"
|
|
>ISIN</gf-value
|
|
>
|
|
</div>
|
|
|
|
@if (dataProviderInfo) {
|
|
<div class="col-md-12 mb-3 text-center">
|
|
<hr />
|
|
<gf-data-provider-credits [dataProviderInfos]="[dataProviderInfo]" />
|
|
<hr />
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
<mat-tab-group
|
|
animationDuration="0"
|
|
class="mb-5"
|
|
[mat-stretch-tabs]="false"
|
|
[ngClass]="{ 'd-none': !dataSource?.data.length }"
|
|
>
|
|
<mat-tab>
|
|
<ng-template mat-tab-label>
|
|
<ion-icon name="swap-vertical-outline" />
|
|
<div class="d-none d-sm-block ml-2" i18n>Activities</div>
|
|
</ng-template>
|
|
<gf-activities-table
|
|
[baseCurrency]="data.baseCurrency"
|
|
[dataSource]="dataSource"
|
|
[deviceType]="data.deviceType"
|
|
[hasPermissionToCreateActivity]="false"
|
|
[hasPermissionToDeleteActivity]="false"
|
|
[hasPermissionToExportActivities]="
|
|
!data.hasImpersonationId && !user?.settings?.isRestrictedView
|
|
"
|
|
[hasPermissionToFilter]="false"
|
|
[hasPermissionToOpenDetails]="false"
|
|
[locale]="data.locale"
|
|
[showActions]="
|
|
!data.hasImpersonationId &&
|
|
data.hasPermissionToCreateOrder &&
|
|
user?.settings?.isExperimentalFeatures &&
|
|
!user?.settings?.isRestrictedView
|
|
"
|
|
[showNameColumn]="false"
|
|
[sortColumn]="sortColumn"
|
|
[sortDirection]="sortDirection"
|
|
[sortDisabled]="true"
|
|
[totalItems]="totalItems"
|
|
(activityToClone)="onCloneActivity($event)"
|
|
(activityToUpdate)="onUpdateActivity($event)"
|
|
(export)="onExport()"
|
|
/>
|
|
</mat-tab>
|
|
<mat-tab>
|
|
<ng-template mat-tab-label>
|
|
<ion-icon name="wallet-outline" />
|
|
<div class="d-none d-sm-block ml-2" i18n>Accounts</div>
|
|
</ng-template>
|
|
<gf-accounts-table
|
|
[accounts]="accounts"
|
|
[baseCurrency]="user?.settings?.baseCurrency"
|
|
[deviceType]="data.deviceType"
|
|
[hasPermissionToOpenDetails]="false"
|
|
[locale]="user?.settings?.locale"
|
|
[showBalance]="false"
|
|
[showFooter]="false"
|
|
[showTransactions]="false"
|
|
[showValue]="false"
|
|
[showValueInBaseCurrency]="false"
|
|
/>
|
|
</mat-tab>
|
|
@if (
|
|
hasPermissionToReadMarketDataOfOwnAssetProfile &&
|
|
user?.settings?.isExperimentalFeatures
|
|
) {
|
|
<mat-tab>
|
|
<ng-template mat-tab-label>
|
|
<ion-icon name="server-outline" />
|
|
<div class="d-none d-sm-block ml-2" i18n>Market Data</div>
|
|
</ng-template>
|
|
<gf-historical-market-data-editor
|
|
[currency]="SymbolProfile?.currency"
|
|
[dataSource]="SymbolProfile?.dataSource"
|
|
[dateOfFirstActivity]="firstBuyDate"
|
|
[locale]="data.locale"
|
|
[marketData]="marketDataItems"
|
|
[symbol]="SymbolProfile?.symbol"
|
|
[user]="user"
|
|
(marketDataChanged)="onMarketDataChanged($event)"
|
|
/>
|
|
</mat-tab>
|
|
}
|
|
</mat-tab-group>
|
|
|
|
<gf-tags-selector
|
|
[hasPermissionToCreateTag]="hasPermissionToCreateOwnTag"
|
|
[readonly]="!data.hasPermissionToUpdateOrder"
|
|
[tags]="activityForm.get('tags')?.value"
|
|
[tagsAvailable]="tagsAvailable"
|
|
(tagsChanged)="onTagsChanged($event)"
|
|
/>
|
|
|
|
@if (
|
|
dataSource?.data.length > 0 &&
|
|
data.hasPermissionToReportDataGlitch === true
|
|
) {
|
|
<div class="row">
|
|
<div class="col">
|
|
<hr />
|
|
<a color="warn" mat-stroked-button [href]="reportDataGlitchMail"
|
|
><ion-icon class="mr-1" name="flag-outline"></ion-icon
|
|
><span i18n>Report Data Glitch</span></a
|
|
>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<gf-dialog-footer
|
|
mat-dialog-actions
|
|
[deviceType]="data.deviceType"
|
|
(closeButtonClicked)="onClose()"
|
|
/>
|
|
|