Compare commits

...

11 Commits

Author SHA1 Message Date
c0ace51ee9 Release 1.195.0 (#1277) 2022-09-20 20:23:41 +02:00
b1b5689242 Feature/improve performance of chart calculation (#1271)
* Improve performance chart calculation

Co-Authored-By: gizmodus <11334553+gizmodus@users.noreply.github.com>

* Update changelog

Co-Authored-By: gizmodus <11334553+gizmodus@users.noreply.github.com>

* Improve chart tooltip of benchmark comparator

* Update changelog

Co-authored-by: gizmodus <11334553+gizmodus@users.noreply.github.com>
2022-09-20 20:22:01 +02:00
b68cdaf8ea Add issue template (#1275) 2022-09-19 21:22:54 +02:00
b387a80a0d Add bullet (#1270) 2022-09-17 21:29:37 +02:00
6e4660295a Release 1.194.0 (#1269) 2022-09-17 21:26:08 +02:00
d4c3a9d1e8 Feature/add percentage visualization of the current filter (#1268)
* Add percentage visualization of the active filter

* Update changelog
2022-09-17 21:24:09 +02:00
263f6b32f2 Bugfix/fix performance chart calculation (#1267)
* Respect end date in performance chart calculation

Co-Authored-By: gizmodus <11334553+gizmodus@users.noreply.github.com>

* Update changelog

Co-Authored-By: gizmodus <11334553+gizmodus@users.noreply.github.com>
2022-09-17 08:33:04 +02:00
637f31ae3b Add instruction for NODE_ENV: production (#1266) 2022-09-17 08:31:56 +02:00
547e27c7a1 Feature/set node env in docker compose files (#1261)
* Set NODE_ENV to production

* Update changelog
2022-09-15 17:20:03 +02:00
f10dc176f2 Feature/clean up german localization (#1260)
* Clean up German localization

* Set up Italian

* Update changelog
2022-09-15 16:58:00 +02:00
0a966e46cd Improve translation (#1258) 2022-09-15 10:37:07 +02:00
21 changed files with 2868 additions and 241 deletions

37
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,37 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: ''
assignees: ''
---
The Issue tracker is **ONLY** used for reporting bugs. New features should be discussed on our [Slack channel](https://ghostfolio.slack.com) or in [Discussions](https://github.com/ghostfolio/ghostfolio/discussions).
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**To Reproduce**
Steps to reproduce the behavior:
1.
2.
3.
4.
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
**Logs**
<!-- If applicable, add logs to help explain your problem. -->
**Environment (please complete the following information):**
- Ghostfolio Version [e.g. 1.194.0]
- Browser [e.g. chrome]
- OS
**Additional context**
<!-- Add any other context about the problem here. -->

View File

@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 1.195.0 - 20.09.2022
### Changed
- Improved the algorithm of the performance chart calculation
### Fixed
- Improved the chart tooltip of the benchmark comparator
## 1.194.0 - 17.09.2022
### Added
- Added `NODE_ENV: production` to the `docker-compose` files (`docker-compose.yml` and `docker-compose.build.yml`)
- Visualized the percentage of the active filter on the allocations page
### Changed
- Improved the language localization for German (`de`)
### Fixed
- Respected the end date in the performance chart calculation
### Todo
- Set `NODE_ENV: production` as in [docker-compose.yml](https://github.com/ghostfolio/ghostfolio/blob/main/docker/docker-compose.yml)
## 1.193.0 - 14.09.2022
### Changed

View File

@ -136,6 +136,10 @@
"baseHref": "/en/",
"localize": ["en"]
},
"development-it": {
"baseHref": "/it/",
"localize": ["it"]
},
"production": {
"fileReplacements": [
{
@ -180,6 +184,9 @@
"development-en": {
"browserTarget": "client:build:development-en"
},
"development-it": {
"browserTarget": "client:build:development-it"
},
"production": {
"browserTarget": "client:build:production"
}
@ -191,7 +198,7 @@
"browserTarget": "client:build",
"includeContext": true,
"outputPath": "src/locales",
"targetFiles": ["messages.de.xlf"]
"targetFiles": ["messages.de.xlf", "messages.it.xlf"]
}
},
"lint": {
@ -214,6 +221,10 @@
"de": {
"baseHref": "/de/",
"translation": "apps/client/src/locales/messages.de.xlf"
},
"it": {
"baseHref": "/it/",
"translation": "apps/client/src/locales/messages.it.xlf"
}
},
"sourceLocale": "en"

View File

@ -4,7 +4,10 @@ import { DataProviderService } from '@ghostfolio/api/services/data-provider/data
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { PROPERTY_BENCHMARKS } from '@ghostfolio/common/config';
import {
MAX_CHART_ITEMS,
PROPERTY_BENCHMARKS
} from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import {
BenchmarkMarketDataDetails,
@ -16,7 +19,6 @@ import { SymbolProfile } from '@prisma/client';
import Big from 'big.js';
import { format } from 'date-fns';
import ms from 'ms';
import { v4 as uuidv4 } from 'uuid';
@Injectable()
export class BenchmarkService {
@ -157,27 +159,38 @@ export class BenchmarkService {
})
]);
marketDataItems.push({
...currentSymbolItem,
createdAt: new Date(),
date: new Date(),
id: uuidv4()
});
const step = Math.round(
marketDataItems.length / Math.min(marketDataItems.length, MAX_CHART_ITEMS)
);
const marketPriceAtStartDate = marketDataItems?.[0]?.marketPrice ?? 0;
return {
marketData: marketDataItems.map((marketDataItem) => {
return {
date: format(marketDataItem.date, DATE_FORMAT),
marketData: [
...marketDataItems
.filter((marketDataItem, index) => {
return index % step === 0;
})
.map((marketDataItem) => {
return {
date: format(marketDataItem.date, DATE_FORMAT),
value:
marketPriceAtStartDate === 0
? 0
: this.calculateChangeInPercentage(
marketPriceAtStartDate,
marketDataItem.marketPrice
) * 100
};
}),
{
date: format(new Date(), DATE_FORMAT),
value:
marketPriceAtStartDate === 0
? 0
: this.calculateChangeInPercentage(
marketPriceAtStartDate,
marketDataItem.marketPrice
) * 100
};
})
this.calculateChangeInPercentage(
marketPriceAtStartDate,
currentSymbolItem.marketPrice
) * 100
}
]
};
}

View File

@ -16,12 +16,11 @@ import {
isBefore,
isSameMonth,
isSameYear,
isWithinInterval,
max,
min,
set
} from 'date-fns';
import { first, flatten, isNumber, sortBy } from 'lodash';
import { first, flatten, isNumber, last, sortBy } from 'lodash';
import { CurrentRateService } from './current-rate.service';
import { CurrentPositions } from './interfaces/current-positions.interface';
@ -168,6 +167,131 @@ export class PortfolioCalculator {
this.transactionPoints = transactionPoints;
}
public async getChartData(start: Date, end = new Date(Date.now()), step = 1) {
const symbols: { [symbol: string]: boolean } = {};
const transactionPointsBeforeEndDate =
this.transactionPoints?.filter((transactionPoint) => {
return isBefore(parseDate(transactionPoint.date), end);
}) ?? [];
const firstIndex = transactionPointsBeforeEndDate.length;
const dates: Date[] = [];
const dataGatheringItems: IDataGatheringItem[] = [];
const currencies: { [symbol: string]: string } = {};
let day = start;
while (isBefore(day, end)) {
dates.push(resetHours(day));
day = addDays(day, step);
}
dates.push(resetHours(end));
for (const item of transactionPointsBeforeEndDate[firstIndex - 1].items) {
dataGatheringItems.push({
dataSource: item.dataSource,
symbol: item.symbol
});
currencies[item.symbol] = item.currency;
symbols[item.symbol] = true;
}
const marketSymbols = await this.currentRateService.getValues({
currencies,
dataGatheringItems,
dateQuery: {
in: dates
},
userCurrency: this.currency
});
const marketSymbolMap: {
[date: string]: { [symbol: string]: Big };
} = {};
for (const marketSymbol of marketSymbols) {
const dateString = format(marketSymbol.date, DATE_FORMAT);
if (!marketSymbolMap[dateString]) {
marketSymbolMap[dateString] = {};
}
if (marketSymbol.marketPriceInBaseCurrency) {
marketSymbolMap[dateString][marketSymbol.symbol] = new Big(
marketSymbol.marketPriceInBaseCurrency
);
}
}
const netPerformanceValuesBySymbol: {
[symbol: string]: { [date: string]: Big };
} = {};
const investmentValuesBySymbol: {
[symbol: string]: { [date: string]: Big };
} = {};
const totalNetPerformanceValues: { [date: string]: Big } = {};
const totalInvestmentValues: { [date: string]: Big } = {};
for (const symbol of Object.keys(symbols)) {
const { netPerformanceValues, investmentValues } = this.getSymbolMetrics({
end,
marketSymbolMap,
start,
step,
symbol,
isChartMode: true
});
netPerformanceValuesBySymbol[symbol] = netPerformanceValues;
investmentValuesBySymbol[symbol] = investmentValues;
}
for (const currentDate of dates) {
const dateString = format(currentDate, DATE_FORMAT);
for (const symbol of Object.keys(netPerformanceValuesBySymbol)) {
totalNetPerformanceValues[dateString] =
totalNetPerformanceValues[dateString] ?? new Big(0);
if (netPerformanceValuesBySymbol[symbol]?.[dateString]) {
totalNetPerformanceValues[dateString] = totalNetPerformanceValues[
dateString
].add(netPerformanceValuesBySymbol[symbol][dateString]);
}
totalInvestmentValues[dateString] =
totalInvestmentValues[dateString] ?? new Big(0);
if (investmentValuesBySymbol[symbol]?.[dateString]) {
totalInvestmentValues[dateString] = totalInvestmentValues[
dateString
].add(investmentValuesBySymbol[symbol][dateString]);
}
}
}
const isInPercentage = true;
return Object.keys(totalNetPerformanceValues).map((date) => {
return isInPercentage
? {
date,
value: totalInvestmentValues[date].eq(0)
? 0
: totalNetPerformanceValues[date]
.div(totalInvestmentValues[date])
.mul(100)
.toNumber()
}
: {
date,
value: totalNetPerformanceValues[date].toNumber()
};
});
}
public async getCurrentPositions(
start: Date,
end = new Date(Date.now())
@ -710,15 +834,19 @@ export class PortfolioCalculator {
private getSymbolMetrics({
end,
isChartMode = false,
marketSymbolMap,
start,
step = 1,
symbol
}: {
end: Date;
isChartMode?: boolean;
marketSymbolMap: {
[date: string]: { [symbol: string]: Big };
};
start: Date;
step?: number;
symbol: string;
}) {
let orders: PortfolioOrderItem[] = this.orders.filter((order) => {
@ -767,10 +895,12 @@ export class PortfolioCalculator {
let grossPerformanceFromSells = new Big(0);
let initialValue: Big;
let investmentAtStartDate: Big;
const investmentValues: { [date: string]: Big } = {};
let lastAveragePrice = new Big(0);
let lastTransactionInvestment = new Big(0);
let lastValueOfInvestmentBeforeTransaction = new Big(0);
let maxTotalInvestment = new Big(0);
const netPerformanceValues: { [date: string]: Big } = {};
let timeWeightedGrossPerformancePercentage = new Big(1);
let timeWeightedNetPerformancePercentage = new Big(1);
let totalInvestment = new Big(0);
@ -805,6 +935,41 @@ export class PortfolioCalculator {
unitPrice: unitPriceAtEndDate
});
let day = start;
let lastUnitPrice: Big;
if (isChartMode) {
const datesWithOrders = {};
for (const order of orders) {
datesWithOrders[order.date] = true;
}
while (isBefore(day, end)) {
const hasDate = datesWithOrders[format(day, DATE_FORMAT)];
if (!hasDate) {
orders.push({
symbol,
currency: null,
date: format(day, DATE_FORMAT),
dataSource: null,
fee: new Big(0),
name: '',
quantity: new Big(0),
type: TypeOfOrder.BUY,
unitPrice:
marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ??
lastUnitPrice
});
}
lastUnitPrice = last(orders).unitPrice;
day = addDays(day, step);
}
}
// Sort orders so that the start and end placeholder order are at the right
// position
orders = sortBy(orders, (order) => {
@ -967,6 +1132,18 @@ export class PortfolioCalculator {
feesAtStartDate = fees;
grossPerformanceAtStartDate = grossPerformance;
}
if (isChartMode && i > indexOfStartOrder) {
netPerformanceValues[order.date] = grossPerformance
.minus(grossPerformanceAtStartDate)
.minus(fees.minus(feesAtStartDate));
investmentValues[order.date] = totalInvestment;
}
if (i === indexOfEndOrder) {
break;
}
}
timeWeightedGrossPerformancePercentage =
@ -1052,7 +1229,9 @@ export class PortfolioCalculator {
return {
initialValue,
grossPerformancePercentage,
investmentValues,
netPerformancePercentage,
netPerformanceValues,
hasErrors: totalUnits.gt(0) && (!initialValue || !unitPriceAtEndDate),
netPerformance: totalNetPerformance,
grossPerformance: totalGrossPerformance

View File

@ -168,13 +168,19 @@ export class PortfolioController {
})
];
const { accounts, holdings, hasErrors } =
await this.portfolioService.getDetails(
impersonationId,
this.request.user.id,
range,
filters
);
const {
accounts,
filteredValueInBaseCurrency,
filteredValueInPercentage,
hasErrors,
holdings,
totalValueInBaseCurrency
} = await this.portfolioService.getDetails(
impersonationId,
this.request.user.id,
range,
filters
);
if (hasErrors || hasNotDefinedValuesInObject(holdings)) {
hasError = true;
@ -234,8 +240,11 @@ export class PortfolioController {
return {
accounts,
filteredValueInBaseCurrency,
filteredValueInPercentage,
hasError,
holdings
holdings,
totalValueInBaseCurrency
};
}

View File

@ -21,6 +21,7 @@ import { ImpersonationService } from '@ghostfolio/api/services/impersonation.ser
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import {
ASSET_SUB_CLASS_EMERGENCY_FUND,
MAX_CHART_ITEMS,
UNKNOWN_KEY
} from '@ghostfolio/common/config';
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
@ -57,7 +58,6 @@ import {
} from '@prisma/client';
import Big from 'big.js';
import {
addDays,
differenceInDays,
endOfToday,
format,
@ -72,7 +72,7 @@ import {
subDays,
subYears
} from 'date-fns';
import { isEmpty, last, sortBy, uniq, uniqBy } from 'lodash';
import { isEmpty, sortBy, uniq, uniqBy } from 'lodash';
import {
HistoricalDataContainer,
@ -86,7 +86,6 @@ const emergingMarkets = require('../../assets/countries/emerging-markets.json');
@Injectable()
export class PortfolioService {
private static readonly MAX_CHART_ITEMS = 250;
private baseCurrency: string;
public constructor(
@ -388,43 +387,19 @@ export class PortfolioService {
const daysInMarket = differenceInDays(new Date(), startDate);
const step = Math.round(
daysInMarket / Math.min(daysInMarket, PortfolioService.MAX_CHART_ITEMS)
daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)
);
const items: HistoricalDataItem[] = [];
let currentEndDate = startDate;
while (isBefore(currentEndDate, endDate)) {
const currentPositions = await portfolioCalculator.getCurrentPositions(
startDate,
currentEndDate
);
items.push({
date: format(currentEndDate, DATE_FORMAT),
value: currentPositions.netPerformancePercentage.toNumber() * 100
});
currentEndDate = addDays(currentEndDate, step);
}
const today = new Date();
if (last(items)?.date !== format(today, DATE_FORMAT)) {
// Add today
const { netPerformancePercentage } =
await portfolioCalculator.getCurrentPositions(startDate, today);
items.push({
date: format(today, DATE_FORMAT),
value: netPerformancePercentage.toNumber() * 100
});
}
const items = await portfolioCalculator.getChartData(
startDate,
endDate,
step
);
return {
items,
isAllTimeHigh: false,
isAllTimeLow: false,
items: items
isAllTimeLow: false
};
}
@ -474,12 +449,21 @@ export class PortfolioService {
});
const holdings: PortfolioDetails['holdings'] = {};
const totalInvestment = currentPositions.totalInvestment.plus(
cashDetails.balanceInBaseCurrency
);
const totalValue = currentPositions.currentValue.plus(
const totalInvestmentInBaseCurrency = currentPositions.totalInvestment.plus(
cashDetails.balanceInBaseCurrency
);
let filteredValueInBaseCurrency = currentPositions.currentValue;
if (
aFilters?.length === 0 ||
(aFilters?.length === 1 &&
aFilters[0].type === 'ASSET_CLASS' &&
aFilters[0].id === 'CASH')
) {
filteredValueInBaseCurrency = filteredValueInBaseCurrency.plus(
cashDetails.balanceInBaseCurrency
);
}
const dataGatheringItems = currentPositions.positions.map((position) => {
return {
@ -540,10 +524,12 @@ export class PortfolioService {
holdings[item.symbol] = {
markets,
allocationCurrent: totalValue.eq(0)
allocationCurrent: filteredValueInBaseCurrency.eq(0)
? 0
: value.div(totalValue).toNumber(),
allocationInvestment: item.investment.div(totalInvestment).toNumber(),
: value.div(filteredValueInBaseCurrency).toNumber(),
allocationInvestment: item.investment
.div(totalInvestmentInBaseCurrency)
.toNumber(),
assetClass: symbolProfile.assetClass,
assetSubClass: symbolProfile.assetSubClass,
countries: symbolProfile.countries,
@ -577,8 +563,8 @@ export class PortfolioService {
cashDetails,
emergencyFund,
userCurrency,
investment: totalInvestment,
value: totalValue
investment: totalInvestmentInBaseCurrency,
value: filteredValueInBaseCurrency
});
for (const symbol of Object.keys(cashPositions)) {
@ -594,7 +580,18 @@ export class PortfolioService {
filters: aFilters
});
return { accounts, holdings, hasErrors: currentPositions.hasErrors };
const summary = await this.getSummary(aImpersonationId);
return {
accounts,
holdings,
filteredValueInBaseCurrency: filteredValueInBaseCurrency.toNumber(),
filteredValueInPercentage: summary.netWorth
? filteredValueInBaseCurrency.div(summary.netWorth).toNumber()
: 0,
hasErrors: currentPositions.hasErrors,
totalValueInBaseCurrency: summary.netWorth
};
}
public async getPosition(

View File

@ -41,6 +41,14 @@ export class RedactValuesInResponseInterceptor<T>
return activity;
});
}
if (data.filteredValueInBaseCurrency) {
data.filteredValueInBaseCurrency = null;
}
if (data.totalValueInBaseCurrency) {
data.totalValueInBaseCurrency = null;
}
}
return data;

View File

@ -23,11 +23,7 @@ import {
getTextColor,
parseDate
} from '@ghostfolio/common/helper';
import {
LineChartItem,
UniqueAsset,
User
} from '@ghostfolio/common/interfaces';
import { LineChartItem, User } from '@ghostfolio/common/interfaces';
import { DateRange } from '@ghostfolio/common/types';
import {
Chart,
@ -215,7 +211,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy {
locale: this.locale,
unit: '%'
}),
mode: 'index',
mode: 'x',
position: <unknown>'top',
xAlign: 'center',
yAlign: 'bottom'

View File

@ -108,7 +108,6 @@
<div class="row">
<div class="col-xs-12 col-md-4 my-2">
<gf-value
i18n
size="large"
subLabel="(Last 24 hours)"
[value]="statistics?.activeUsers1d ?? '-'"
@ -117,7 +116,6 @@
</div>
<div class="col-xs-12 col-md-4 my-2">
<gf-value
i18n
size="large"
subLabel="(Last 30 days)"
[value]="statistics?.newUsers30d ?? '-'"
@ -126,7 +124,6 @@
</div>
<div class="col-xs-12 col-md-4 my-2">
<gf-value
i18n
size="large"
subLabel="(Last 30 days)"
[value]="statistics?.activeUsers30d ?? '-'"
@ -139,7 +136,6 @@
href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"
>
<gf-value
i18n
size="large"
[value]="statistics?.slackCommunityUsers ?? '-'"
>Users in Slack community</gf-value
@ -152,7 +148,6 @@
href="https://github.com/ghostfolio/ghostfolio/graphs/contributors"
>
<gf-value
i18n
size="large"
[value]="statistics?.gitHubContributors ?? '-'"
>Contributors on GitHub</gf-value
@ -165,7 +160,6 @@
href="https://github.com/ghostfolio/ghostfolio/stargazers"
>
<gf-value
i18n
size="large"
[value]="statistics?.gitHubStargazers ?? '-'"
>Stars on GitHub</gf-value

View File

@ -10,6 +10,22 @@
></gf-activities-filter>
</div>
</div>
<div class="row">
<div class="col">
<mat-card class="mb-3">
<mat-card-header>
<mat-card-title i18n>Proportion of Net Worth</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-progress-bar
mode="determinate"
[title]="(portfolioDetails?.filteredValueInPercentage * 100).toFixed(2) + '%'"
[value]="portfolioDetails?.filteredValueInPercentage * 100"
></mat-progress-bar>
</mat-card-content>
</mat-card>
</div>
</div>
<div class="proportion-charts row">
<div class="col-md-4">
<mat-card class="mb-3">

View File

@ -1,6 +1,7 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module';
import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module';
import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter/activities-filter.module';
@ -22,7 +23,8 @@ import { AllocationsPageComponent } from './allocations-page.component';
GfToggleModule,
GfWorldMapChartModule,
GfValueModule,
MatCardModule
MatCardModule,
MatProgressBarModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})

View File

@ -28,4 +28,33 @@
}
}
}
.mat-progress-bar {
border-radius: 0.25rem;
height: 0.5rem;
::ng-deep {
.mat-progress-bar-background {
fill: rgb(var(--palette-background-unselected-chip));
}
.mat-progress-bar-buffer {
background-color: rgb(var(--palette-background-unselected-chip));
}
}
}
}
:host-context(.is-dark-theme) {
.mat-progress-bar {
::ng-deep {
.mat-progress-bar-background {
fill: rgb(var(--palette-background-unselected-chip-dark));
}
.mat-progress-bar-buffer {
background-color: rgb(var(--palette-background-unselected-chip-dark));
}
}
}
}

View File

@ -15,7 +15,7 @@
</trans-unit>
<trans-unit id="ccb2a809018b32a96c813ae69126ce05976109ce" datatype="html">
<source>The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term.</source>
<target state="translated">Das Ausfallrisiko beim Börsenhandel kann erheblich sein. Es ist nicht ratsam, Geld zu investieren, welches sie kurzfristig benötigen.</target>
<target state="translated">Das Ausfallrisiko beim Börsenhandel kann erheblich sein. Es ist nicht ratsam, Geld zu investieren, welches Sie kurzfristig benötigen.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/app.component.html</context>
<context context-type="linenumber">55,56</context>
@ -1031,7 +1031,7 @@
</trans-unit>
<trans-unit id="67251f04518ae452230c68a748b3fa2838b4db74" datatype="html">
<source>Net Worth</source>
<target state="translated">Reinvermögen</target>
<target state="translated">Gesamtvermögen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html</context>
<context context-type="linenumber">179</context>
@ -1262,7 +1262,7 @@
<target state="translated">Bitte gebe deinen Gutscheincode ein:</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">248</context>
<context context-type="linenumber">225</context>
</context-group>
</trans-unit>
<trans-unit id="4420880039966769543" datatype="html">
@ -1270,7 +1270,7 @@
<target state="translated">Gutscheincode konnte nicht eingelöst werden</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">258</context>
<context context-type="linenumber">235</context>
</context-group>
</trans-unit>
<trans-unit id="4819099731531004979" datatype="html">
@ -1278,7 +1278,7 @@
<target state="translated">Gutscheincode wurde eingelöst</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">270</context>
<context context-type="linenumber">247</context>
</context-group>
</trans-unit>
<trans-unit id="7967484035994732534" datatype="html">
@ -1286,7 +1286,7 @@
<target state="translated">Neu laden</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">271</context>
<context context-type="linenumber">248</context>
</context-group>
</trans-unit>
<trans-unit id="7963559562180316948" datatype="html">
@ -1294,7 +1294,7 @@
<target state="translated">Möchtest du diese Anmeldemethode wirklich löschen?</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">317</context>
<context context-type="linenumber">294</context>
</context-group>
</trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -1323,7 +1323,7 @@
</trans-unit>
<trans-unit id="f147d0f7f965cccee2e77294cba8e1b88021fa08" datatype="html">
<source>Upgrade</source>
<target state="new">Upgrade</target>
<target state="translated">Upgrade</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">37</context>
@ -1379,7 +1379,7 @@
</trans-unit>
<trans-unit id="6b939b00e8481ed8aa8a24d8add7a209d7116759" datatype="html">
<source>Locale</source>
<target state="new">Locale</target>
<target state="translated">Lokalität</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
<context context-type="linenumber">135</context>
@ -1618,7 +1618,7 @@
<target state="translated">Nach Konto</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">17</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="b79f5520c0cb9a00bd589e8a4c86ffcf5ae439d7" datatype="html">
@ -1626,7 +1626,7 @@
<target state="translated">Nach Währung</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">58</context>
</context-group>
</trans-unit>
<trans-unit id="8288ff761f2d259625d2e5a3d96db727926d9cd4" datatype="html">
@ -1634,7 +1634,7 @@
<target state="translated">Nach Asset Class</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">86</context>
</context-group>
</trans-unit>
<trans-unit id="b64539bb7815eb3275b55ad723d3897fc6ba8d23" datatype="html">
@ -1642,7 +1642,7 @@
<target state="translated">Nach Position</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">114</context>
</context-group>
</trans-unit>
<trans-unit id="9f86714c9a6b74e13c96ab02102ce40c34fe13b9" datatype="html">
@ -1650,7 +1650,7 @@
<target state="translated">Nach Sektor</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">126</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="7017e0e26b53ef322c3e3bbf95f06a85487a12b2" datatype="html">
@ -1658,7 +1658,7 @@
<target state="translated">Nach Kontinent</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">155</context>
<context context-type="linenumber">171</context>
</context-group>
</trans-unit>
<trans-unit id="f27e9dd8de80176286e02312e694cb8d1e485a5d" datatype="html">
@ -1666,7 +1666,7 @@
<target state="translated">Nach Land</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">199</context>
</context-group>
</trans-unit>
<trans-unit id="85780db87ac6c9f202615ac63754551c061e7236" datatype="html">
@ -1674,7 +1674,7 @@
<target state="translated">Regionen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">214</context>
<context context-type="linenumber">230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -1706,7 +1706,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">102</context>
<context context-type="linenumber">105</context>
</context-group>
</trans-unit>
<trans-unit id="6ae1c94f6bad274424f97e9bc8766242c1577447" datatype="html">
@ -1714,7 +1714,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">23</context>
<context context-type="linenumber">26</context>
</context-group>
</trans-unit>
<trans-unit id="6723d5c967329a3ac75524cf0c1af5ced022b9a3" datatype="html">
@ -1722,7 +1722,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">59</context>
<context context-type="linenumber">62</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -2036,6 +2036,10 @@
<trans-unit id="9201103587777813545" datatype="html">
<source>Portfolio</source>
<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">111</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page-routing.module.ts</context>
<context context-type="linenumber">12</context>
@ -2059,7 +2063,7 @@
</trans-unit>
<trans-unit id="a3d148b40a389fda0665eb583c9e434ec5ee1ced" datatype="html">
<source> Ghostfolio empowers you to keep track of your wealth. </source>
<target state="new"/>
<target state="translated">Ghostfolio verschafft Ihnen den Überblick über Ihr Vermögen.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
<context context-type="linenumber">132,134</context>
@ -2270,7 +2274,7 @@
<target state="translated">Beta</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html</context>
<context context-type="linenumber">4</context>
<context context-type="linenumber">5</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
@ -2414,7 +2418,7 @@
<target state="translated">Entwickelte Länder</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">240</context>
<context context-type="linenumber">256</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -2426,7 +2430,7 @@
<target state="translated">Schwellenländer</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">265</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -2438,7 +2442,7 @@
<target state="translated">Andere Länder</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">258</context>
<context context-type="linenumber">274</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -2453,50 +2457,6 @@
<context context-type="linenumber">136</context>
</context-group>
</trans-unit>
<trans-unit id="1de491c923555d6422bc6f1146357eb2b47853da" datatype="html">
<source>Active Users</source>
<target state="new">Active Users</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">115</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">133</context>
</context-group>
</trans-unit>
<trans-unit id="8c4cfd77b7b3d7917de13bec98a8a74890f95618" datatype="html">
<source>New Users</source>
<target state="new">New Users</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
<trans-unit id="c0eb011366e597e23542be386e8bc0d53470b520" datatype="html">
<source>Users in Slack community</source>
<target state="new">Users in Slack community</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">145</context>
</context-group>
</trans-unit>
<trans-unit id="be99161cc904867871ab172df77b736d3b27dfc5" datatype="html">
<source>Contributors on GitHub</source>
<target state="new">Contributors on GitHub</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">158</context>
</context-group>
</trans-unit>
<trans-unit id="8d3932a9eba50bc101c2b8c329e7b4ea033cde97" datatype="html">
<source>Stars on GitHub</source>
<target state="new">Stars on GitHub</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">171</context>
</context-group>
</trans-unit>
<trans-unit id="e34e2478d2d30c9d01758d01b7212411171b9bd5" datatype="html">
<source>Projected Total Amount</source>
<target state="translated">Projizierter Gesamtbetrag</target>
@ -2507,7 +2467,7 @@
</trans-unit>
<trans-unit id="2937311350146031865" datatype="html">
<source>Initial</source>
<target state="new">Beginn</target>
<target state="translated">Beginn</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts</context>
<context context-type="linenumber">57</context>
@ -2526,7 +2486,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">30</context>
<context context-type="linenumber">38</context>
</context-group>
</trans-unit>
<trans-unit id="1975246224413290232" datatype="html">
@ -2534,19 +2494,15 @@
<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">31</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
<source>Deposit</source>
<target state="translated">Einlage</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">131</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
@ -2563,7 +2519,7 @@
</trans-unit>
<trans-unit id="1054498214311181686" datatype="html">
<source>Savings</source>
<target state="new">Ersparnisse</target>
<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>
@ -2606,7 +2562,7 @@
<target state="translated">Filtern nach...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">129</context>
<context context-type="linenumber">128</context>
</context-group>
</trans-unit>
<trans-unit id="2078421919111943467" datatype="html">
@ -2662,7 +2618,7 @@
<target state="translated">Benchmarks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html</context>
<context context-type="linenumber">3</context>
<context context-type="linenumber">4</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
@ -2670,7 +2626,7 @@
<target state="translated">Vergleichen mit...</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html</context>
<context context-type="linenumber">12</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="1931353503905413384" datatype="html">
@ -2678,7 +2634,15 @@
<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">149</context>
<context context-type="linenumber">120</context>
</context-group>
</trans-unit>
<trans-unit id="4210837540bca56dca96fcc451518659d06ad02a" datatype="html">
<source>Proportion of Net Worth</source>
<target state="translated">Anteil am Gesamtvermögen</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">17</context>
</context-group>
</trans-unit>
</body>

File diff suppressed because it is too large Load Diff

View File

@ -1137,35 +1137,35 @@
<source>Please enter your coupon code:</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">248</context>
<context context-type="linenumber">225</context>
</context-group>
</trans-unit>
<trans-unit id="4420880039966769543" datatype="html">
<source>Could not redeem coupon code</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">258</context>
<context context-type="linenumber">235</context>
</context-group>
</trans-unit>
<trans-unit id="4819099731531004979" datatype="html">
<source>Coupon code has been redeemed</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">270</context>
<context context-type="linenumber">247</context>
</context-group>
</trans-unit>
<trans-unit id="7967484035994732534" datatype="html">
<source>Reload</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">271</context>
<context context-type="linenumber">248</context>
</context-group>
</trans-unit>
<trans-unit id="7963559562180316948" datatype="html">
<source>Do you really want to remove this sign in method?</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.component.ts</context>
<context context-type="linenumber">317</context>
<context context-type="linenumber">294</context>
</context-group>
</trans-unit>
<trans-unit id="29881a45dafbe5aa05cd9d0441a4c0c2fb06df92" datatype="html">
@ -1453,56 +1453,56 @@
<source>By Account</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">17</context>
<context context-type="linenumber">33</context>
</context-group>
</trans-unit>
<trans-unit id="b79f5520c0cb9a00bd589e8a4c86ffcf5ae439d7" datatype="html">
<source>By Currency</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">58</context>
</context-group>
</trans-unit>
<trans-unit id="8288ff761f2d259625d2e5a3d96db727926d9cd4" datatype="html">
<source>By Asset Class</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">70</context>
<context context-type="linenumber">86</context>
</context-group>
</trans-unit>
<trans-unit id="b64539bb7815eb3275b55ad723d3897fc6ba8d23" datatype="html">
<source>By Holding</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">98</context>
<context context-type="linenumber">114</context>
</context-group>
</trans-unit>
<trans-unit id="9f86714c9a6b74e13c96ab02102ce40c34fe13b9" datatype="html">
<source>By Sector</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">126</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="7017e0e26b53ef322c3e3bbf95f06a85487a12b2" datatype="html">
<source>By Continent</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">155</context>
<context context-type="linenumber">171</context>
</context-group>
</trans-unit>
<trans-unit id="f27e9dd8de80176286e02312e694cb8d1e485a5d" datatype="html">
<source>By Country</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">183</context>
<context context-type="linenumber">199</context>
</context-group>
</trans-unit>
<trans-unit id="85780db87ac6c9f202615ac63754551c061e7236" datatype="html">
<source>Regions</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">214</context>
<context context-type="linenumber">230</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -1531,21 +1531,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">102</context>
<context context-type="linenumber">105</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">23</context>
<context context-type="linenumber">26</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">59</context>
<context context-type="linenumber">62</context>
</context-group>
</trans-unit>
<trans-unit id="5857197365507636437" datatype="html">
@ -1824,6 +1824,10 @@
</trans-unit>
<trans-unit id="9201103587777813545" datatype="html">
<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">111</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page-routing.module.ts</context>
<context context-type="linenumber">12</context>
@ -2029,7 +2033,7 @@
<source>Beta</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html</context>
<context context-type="linenumber">4</context>
<context context-type="linenumber">5</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/account/account-page.html</context>
@ -2100,7 +2104,7 @@
<source>Developed Markets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">240</context>
<context context-type="linenumber">256</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -2140,7 +2144,7 @@
<source>Other Markets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">258</context>
<context context-type="linenumber">274</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -2151,7 +2155,7 @@
<source>Emerging Markets</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">249</context>
<context context-type="linenumber">265</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/public/public-page.html</context>
@ -2193,45 +2197,6 @@
<context context-type="linenumber">136</context>
</context-group>
</trans-unit>
<trans-unit id="1de491c923555d6422bc6f1146357eb2b47853da" datatype="html">
<source>Active Users</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">115</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">133</context>
</context-group>
</trans-unit>
<trans-unit id="8c4cfd77b7b3d7917de13bec98a8a74890f95618" datatype="html">
<source>New Users</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
<trans-unit id="8d3932a9eba50bc101c2b8c329e7b4ea033cde97" datatype="html">
<source>Stars on GitHub</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">171</context>
</context-group>
</trans-unit>
<trans-unit id="be99161cc904867871ab172df77b736d3b27dfc5" datatype="html">
<source>Contributors on GitHub</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">158</context>
</context-group>
</trans-unit>
<trans-unit id="c0eb011366e597e23542be386e8bc0d53470b520" datatype="html">
<source>Users in Slack community</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/about/about-page.html</context>
<context context-type="linenumber">145</context>
</context-group>
</trans-unit>
<trans-unit id="e34e2478d2d30c9d01758d01b7212411171b9bd5" datatype="html">
<source>Projected Total Amount</source>
<context-group purpose="location">
@ -2250,7 +2215,7 @@
<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">31</context>
<context context-type="linenumber">39</context>
</context-group>
</trans-unit>
<trans-unit id="2937311350146031865" datatype="html">
@ -2269,13 +2234,9 @@
</trans-unit>
<trans-unit id="5213771062241898526" datatype="html">
<source>Deposit</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">131</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/investment-chart/investment-chart.component.ts</context>
<context context-type="linenumber">130</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">libs/ui/src/lib/fire-calculator/fire-calculator.component.ts</context>
@ -2293,7 +2254,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">30</context>
<context context-type="linenumber">38</context>
</context-group>
</trans-unit>
<trans-unit id="8511b16abcf065252b350d64e337ba2447db3ffb" datatype="html">
@ -2339,7 +2300,7 @@
<source>Filter by...</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/admin-market-data/admin-market-data.component.ts</context>
<context context-type="linenumber">129</context>
<context context-type="linenumber">128</context>
</context-group>
</trans-unit>
<trans-unit id="303469635941752458" datatype="html">
@ -2378,21 +2339,28 @@
<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">149</context>
<context context-type="linenumber">120</context>
</context-group>
</trans-unit>
<trans-unit id="1b25c6e22f822e07a3e4d5aae4edc5b41fe083c2" datatype="html">
<source>Benchmarks</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html</context>
<context context-type="linenumber">3</context>
<context context-type="linenumber">4</context>
</context-group>
</trans-unit>
<trans-unit id="44fcf77e86dc038202ebad6b46d1d833d60d781b" datatype="html">
<source>Compare with...</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html</context>
<context context-type="linenumber">12</context>
<context context-type="linenumber">14</context>
</context-group>
</trans-unit>
<trans-unit id="4210837540bca56dca96fcc451518659d06ad02a" datatype="html">
<source>Proportion of Net Worth</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/allocations/allocations-page.html</context>
<context context-type="linenumber">17</context>
</context-group>
</trans-unit>
</body>

View File

@ -6,6 +6,7 @@ services:
- ../.env
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=prefer
NODE_ENV: production
REDIS_HOST: 'redis'
REDIS_PASSWORD: ${REDIS_PASSWORD}
ports:

View File

@ -6,6 +6,7 @@ services:
- ../.env
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=prefer
NODE_ENV: production
REDIS_HOST: 'redis'
REDIS_PASSWORD: ${REDIS_PASSWORD}
ports:

View File

@ -67,6 +67,8 @@ export const GATHER_HISTORICAL_MARKET_DATA_PROCESS_OPTIONS: JobOptions = {
}
};
export const MAX_CHART_ITEMS = 365;
export const PROPERTY_BENCHMARKS = 'BENCHMARKS';
export const PROPERTY_COUPONS = 'COUPONS';
export const PROPERTY_CURRENCIES = 'CURRENCIES';

View File

@ -10,5 +10,8 @@ export interface PortfolioDetails {
original: number;
};
};
filteredValueInBaseCurrency?: number;
filteredValueInPercentage: number;
holdings: { [symbol: string]: PortfolioPosition };
totalValueInBaseCurrency?: number;
}

View File

@ -1,6 +1,6 @@
{
"name": "ghostfolio",
"version": "1.193.0",
"version": "1.195.0",
"homepage": "https://ghostfol.io",
"license": "AGPL-3.0",
"scripts": {