From 51203ec96ee1687b2772b416c85dd74a0c180d45 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 31 Mar 2024 10:46:30 +0200 Subject: [PATCH 01/14] Feature/setup chinese (#3220) * Set up chinese * Update changelog --- CHANGELOG.md | 6 ++++++ apps/api/src/assets/sitemap.xml | 8 ++++++++ apps/client/project.json | 14 +++++++++++++- apps/client/src/app/app.component.html | 5 +++++ .../user-account-settings.component.ts | 3 ++- .../user-account-settings.html | 16 ++++++++++++---- .../src/app/pages/features/features-page.html | 4 ++-- apps/client/src/locales/messages.zh.xlf | 6 ++++++ libs/common/src/lib/config.ts | 3 ++- libs/common/src/lib/helper.ts | 4 +++- 10 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 apps/client/src/locales/messages.zh.xlf diff --git a/CHANGELOG.md b/CHANGELOG.md index fec72562e..39cefd95f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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). +## Unreleased + +### Added + +- Set up the language localization for Chinese (`zh`) + ## 2.69.0 - 2024-03-30 ### Added diff --git a/apps/api/src/assets/sitemap.xml b/apps/api/src/assets/sitemap.xml index 3aeadc035..e527df8d0 100644 --- a/apps/api/src/assets/sitemap.xml +++ b/apps/api/src/assets/sitemap.xml @@ -1232,10 +1232,12 @@ https://ghostfol.io/nl/veelgestelde-vragen ${currentDate}T00:00:00+00:00 + https://ghostfol.io/pt ${currentDate}T00:00:00+00:00 @@ -1296,4 +1298,10 @@ https://ghostfol.io/tr ${currentDate}T00:00:00+00:00 + diff --git a/apps/client/project.json b/apps/client/project.json index 8d778bef4..0cd576e16 100644 --- a/apps/client/project.json +++ b/apps/client/project.json @@ -72,6 +72,10 @@ "baseHref": "/tr/", "localize": ["tr"] }, + "development-zh": { + "baseHref": "/zh/", + "localize": ["zh"] + }, "production": { "fileReplacements": [ { @@ -190,6 +194,9 @@ "development-tr": { "buildTarget": "client:build:development-tr" }, + "development-zh": { + "buildTarget": "client:build:development-zh" + }, "production": { "buildTarget": "client:build:production" } @@ -209,7 +216,8 @@ "messages.nl.xlf", "messages.pl.xlf", "messages.pt.xlf", - "messages.tr.xlf" + "messages.tr.xlf", + "messages.zh.xlf" ] } }, @@ -260,6 +268,10 @@ "tr": { "baseHref": "/tr/", "translation": "apps/client/src/locales/messages.tr.xlf" + }, + "zh": { + "baseHref": "/zh/", + "translation": "apps/client/src/locales/messages.zh.xlf" } }, "sourceLocale": "en" diff --git a/apps/client/src/app/app.component.html b/apps/client/src/app/app.component.html index 713eb1a94..29541962b 100644 --- a/apps/client/src/app/app.component.html +++ b/apps/client/src/app/app.component.html @@ -163,6 +163,11 @@ Türkçe --> + diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts index f176c0847..c6d7f8e89 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts @@ -48,7 +48,8 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit { 'nl', 'pl', 'pt', - 'tr' + 'tr', + 'zh' ]; public user: User; diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.html b/apps/client/src/app/components/user-account-settings/user-account-settings.html index df423ba16..1ad24e22e 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.html +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -76,6 +76,12 @@ Deutsch English + @if (user?.settings?.isExperimentalFeatures) { + Chinese (Community) + } Español (Community)Nederlands (Community) - Polski (Community) + @if (user?.settings?.isExperimentalFeatures) { + Polski (Community) + } Português (Community)

Multi-Language

- Use Ghostfolio in multiple languages: English, Dutch, French, - German, Italian, + Use Ghostfolio in multiple languages: English, + Dutch, French, German, Italian, Portuguese, Spanish and Turkish are currently supported.

diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf new file mode 100644 index 000000000..f1e528dd0 --- /dev/null +++ b/apps/client/src/locales/messages.zh.xlf @@ -0,0 +1,6 @@ + + + + + + diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 3bbe0ff8c..293f77488 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -137,7 +137,8 @@ export const SUPPORTED_LANGUAGE_CODES = [ 'nl', 'pl', 'pt', - 'tr' + 'tr', + 'zh' ]; export const UNKNOWN_KEY = 'UNKNOWN'; diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index b49589aab..e03ea1a1f 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -11,7 +11,7 @@ import { parseISO, subDays } from 'date-fns'; -import { de, es, fr, it, nl, pl, pt, tr } from 'date-fns/locale'; +import { de, es, fr, it, nl, pl, pt, tr, zhCN } from 'date-fns/locale'; import { ghostfolioScraperApiSymbolPrefix, locale } from './config'; import { Benchmark, UniqueAsset } from './interfaces'; @@ -178,6 +178,8 @@ export function getDateFnsLocale(aLanguageCode: string) { return pt; } else if (aLanguageCode === 'tr') { return tr; + } else if (aLanguageCode === 'zh') { + return zhCN; } return undefined; From af47889d6544001864069f9faabd8ae962eb0d25 Mon Sep 17 00:00:00 2001 From: qiaoy Date: Sun, 31 Mar 2024 17:24:32 +0800 Subject: [PATCH 02/14] Add Chinese translations (#3215) * Add Chinese translations --- apps/client/src/locales/messages.zh.xlf | 14997 +++++++++++++++++++++- 1 file changed, 14996 insertions(+), 1 deletion(-) diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index f1e528dd0..2887d5724 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -1,6 +1,15001 @@ + - + + + about + 关于 + + apps/client/src/app/app-routing.module.ts + 9 + + + apps/client/src/app/app.component.ts + 47 + + + apps/client/src/app/app.component.ts + 48 + + + apps/client/src/app/app.component.ts + 49 + + + apps/client/src/app/app.component.ts + 51 + + + apps/client/src/app/components/header/header.component.ts + 76 + + + apps/client/src/app/components/header/header.component.ts + 81 + + + apps/client/src/app/pages/about/about-page.component.ts + 45 + + + apps/client/src/app/pages/about/about-page.component.ts + 50 + + + apps/client/src/app/pages/about/about-page.component.ts + 55 + + + apps/client/src/app/pages/about/about-page.component.ts + 63 + + + apps/client/src/app/pages/about/about-page.component.ts + 74 + + + apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts + 13 + + + apps/client/src/app/pages/landing/landing-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts + 22 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allinvestview-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allvue-systems-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/basil-finance-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/beanvest-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capitally-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/compound-planning-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/de.fi-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/delta-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/eightfigures-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/empower-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/fina-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finwise-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/gospatz-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/intuit-mint-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/magnifi-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monarch-money-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/plannix-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/rocket-money-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/tiller-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/vyzer-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthfolio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthica-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/whal-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/ynab-page.component.ts + 26 + + + + faq + 常见问题 + + apps/client/src/app/app-routing.module.ts + 10 + + + apps/client/src/app/app.component.ts + 54 + + + apps/client/src/app/pages/about/overview/about-overview-page.component.ts + 19 + + + apps/client/src/app/pages/faq/faq-page.component.ts + 37 + + + apps/client/src/app/pages/faq/faq-page.component.ts + 42 + + + apps/client/src/app/pages/faq/faq-page.component.ts + 48 + + + apps/client/src/app/pages/resources/resources-page.component.ts + 17 + + + + features + 功能 + + apps/client/src/app/app-routing.module.ts + 11 + + + apps/client/src/app/app.component.ts + 55 + + + apps/client/src/app/components/header/header.component.ts + 77 + + + apps/client/src/app/components/header/header.component.ts + 82 + + + apps/client/src/app/pages/about/overview/about-overview-page.component.ts + 20 + + + apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts + 15 + + + apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 15 + + + apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts + 15 + + + apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts + 14 + + + apps/client/src/app/pages/faq/overview/faq-overview-page.component.ts + 14 + + + apps/client/src/app/pages/pricing/pricing-page.component.ts + 35 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allinvestview-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allvue-systems-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/basil-finance-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/beanvest-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capitally-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/compound-planning-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/de.fi-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/delta-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/eightfigures-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/empower-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/fina-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finwise-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/gospatz-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/intuit-mint-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/magnifi-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monarch-money-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/plannix-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/rocket-money-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/tiller-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/vyzer-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthfolio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthica-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/whal-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/ynab-page.component.ts + 27 + + + + license + 许可 + + apps/client/src/app/app-routing.module.ts + 12 + + + apps/client/src/app/app.component.ts + 49 + + + apps/client/src/app/pages/about/about-page.component.ts + 55 + + + + markets + 市场 + + apps/client/src/app/app-routing.module.ts + 13 + + + apps/client/src/app/app.component.ts + 56 + + + apps/client/src/app/components/header/header.component.ts + 78 + + + apps/client/src/app/components/header/header.component.ts + 83 + + + apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 16 + + + apps/client/src/app/pages/faq/saas/saas-page.component.ts + 14 + + + + pricing + 价钱 + + apps/client/src/app/app-routing.module.ts + 14 + + + apps/client/src/app/app.component.ts + 57 + + + apps/client/src/app/components/header/header.component.ts + 79 + + + apps/client/src/app/components/header/header.component.ts + 84 + + + apps/client/src/app/components/home-summary/home-summary.component.ts + 125 + + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts + 14 + + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 38 + + + apps/client/src/app/core/http-response.interceptor.ts + 81 + + + apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts + 16 + + + apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts + 16 + + + apps/client/src/app/pages/faq/saas/saas-page.component.ts + 15 + + + libs/ui/src/lib/membership-card/membership-card.component.ts + 13 + + + + privacy-policy + 隐私政策 + + apps/client/src/app/app-routing.module.ts + 15 + + + apps/client/src/app/app.component.ts + 52 + + + apps/client/src/app/pages/about/about-page.component.ts + 63 + + + + register + 注册 + + apps/client/src/app/app-routing.module.ts + 16 + + + apps/client/src/app/app.component.ts + 58 + + + apps/client/src/app/components/header/header.component.ts + 85 + + + apps/client/src/app/core/auth.guard.ts + 54 + + + apps/client/src/app/pages/faq/saas/saas-page.component.ts + 16 + + + apps/client/src/app/pages/features/features-page.component.ts + 18 + + + apps/client/src/app/pages/landing/landing-page.component.ts + 27 + + + apps/client/src/app/pages/pricing/pricing-page.component.ts + 36 + + + + resources + 资源 + + apps/client/src/app/app-routing.module.ts + 17 + + + apps/client/src/app/app.component.ts + 59 + + + apps/client/src/app/components/header/header.component.ts + 80 + + + apps/client/src/app/components/header/header.component.ts + 86 + + + apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts + 14 + + + apps/client/src/app/pages/features/features-page.component.ts + 19 + + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts + 14 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allinvestview-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allvue-systems-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/basil-finance-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/beanvest-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capitally-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/compound-planning-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/de.fi-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/delta-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/eightfigures-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/empower-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/fina-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finwise-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/gospatz-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/intuit-mint-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/magnifi-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monarch-money-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/plannix-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/rocket-money-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/tiller-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/vyzer-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthfolio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthica-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/whal-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/ynab-page.component.ts + 29 + + + apps/client/src/app/pages/resources/resources-page.component.ts + 19 + + + + You are using the Live Demo. + 您正在使用现场演示。 + + apps/client/src/app/app.component.html + 17 + + + + Create Account + 创建账户 + + apps/client/src/app/app.component.html + 18 + + + apps/client/src/app/pages/register/register-page.html + 26 + + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 2 + + + + Personal Finance + 个人财务 + + apps/client/src/app/app.component.html + 55 + + + + Markets + 市场 + + apps/client/src/app/app.component.html + 58 + + + apps/client/src/app/components/header/header.component.html + 381 + + + apps/client/src/app/components/home-market/home-market.html + 2 + + + apps/client/src/app/pages/resources/resources-page.html + 56 + + + + Resources + 资源 + + apps/client/src/app/app.component.html + 60 + + + apps/client/src/app/components/header/header.component.html + 80 + + + apps/client/src/app/components/header/header.component.html + 284 + + + apps/client/src/app/pages/resources/resources-page.html + 4 + + + + About + 关于 + + apps/client/src/app/app.component.html + 66 + + + apps/client/src/app/components/header/header.component.html + 111 + + + apps/client/src/app/components/header/header.component.html + 352 + + + + Blog + 博客 + + apps/client/src/app/app.component.html + 68 + + + apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.html + 204 + + + apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.html + 183 + + + apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.html + 183 + + + apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.html + 183 + + + apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.html + 209 + + + apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.html + 195 + + + apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.html + 181 + + + apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.html + 141 + + + apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.html + 168 + + + apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.html + 178 + + + apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.html + 202 + + + apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.html + 252 + + + apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.html + 233 + + + apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.html + 243 + + + apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.html + 154 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html + 273 + + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + + + apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.html + 148 + + + apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.html + 270 + + + apps/client/src/app/pages/blog/blog-page.html + 5 + + + + Changelog + 变更日志 + + apps/client/src/app/app.component.html + 71 + + + apps/client/src/app/pages/about/changelog/changelog-page.html + 4 + + + + Features + 功能 + + apps/client/src/app/app.component.html + 73 + + + apps/client/src/app/components/header/header.component.html + 339 + + + apps/client/src/app/pages/features/features-page.html + 5 + + + + Frequently Asked Questions (FAQ) + 常见问题 (FAQ) + + apps/client/src/app/app.component.html + 76 + + + apps/client/src/app/pages/about/overview/about-overview-page.html + 146 + + + + License + 许可 + + apps/client/src/app/app.component.html + 80 + + + apps/client/src/app/pages/about/license/license-page.html + 4 + + + + Pricing + 价钱 + + apps/client/src/app/app.component.html + 86 + + + apps/client/src/app/components/header/header.component.html + 98 + + + apps/client/src/app/components/header/header.component.html + 296 + + + apps/client/src/app/components/header/header.component.html + 365 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + + Privacy Policy + 隐私政策 + + apps/client/src/app/app.component.html + 90 + + + apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.html + 4 + + + + Community + 社区 + + apps/client/src/app/app.component.html + 105 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 80 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 84 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 88 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 92 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 96 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 100 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 104 + + + apps/client/src/app/pages/features/features-page.html + 256 + + + + The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term. + 交易损失的风险可能很大。不建议将短期内可能需要的资金进行投资。 + + apps/client/src/app/app.component.html + 179 + + + + Alias + 别名 + + apps/client/src/app/components/access-table/access-table.component.html + 3 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 11 + + + + Grantee + 受赠者 + + apps/client/src/app/components/access-table/access-table.component.html + 10 + + + + Type + 类型 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 28 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 22 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 12 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 159 + + + + Details + 细节 + + apps/client/src/app/components/access-table/access-table.component.html + 32 + + + + Revoke + 撤销 + + apps/client/src/app/components/access-table/access-table.component.html + 59 + + + + Do you really want to revoke this granted access? + 您真的要撤销此授予的访问权限吗? + + apps/client/src/app/components/access-table/access-table.component.ts + 50 + + + + Cash Balance + 现金余额 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 45 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 117 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 34 + + + + Equity + 公平 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 56 + + + + Activities + 活动 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 61 + + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 90 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 100 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 122 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + + + apps/client/src/app/components/admin-users/admin-users.html + 134 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 178 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 287 + + + apps/client/src/app/pages/portfolio/activities/activities-page.html + 4 + + + + Platform + 平台 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 65 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 72 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 48 + + + + Cash Balances + 现金余额 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 114 + + + + Transfer Cash Balance + 转移现金余额 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 9 + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 7 + + + + Name + 名称 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 34 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 197 + + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 30 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 7 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 15 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 138 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 136 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 28 + + + + Total + 全部的 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 45 + + + + Currency + 货币 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 55 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 103 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 203 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 25 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 144 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 274 + + + + Value + 价值 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 152 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 187 + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 45 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 198 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 199 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 201 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 263 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 264 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 265 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + + + libs/ui/src/lib/account-balances/account-balances.component.html + 20 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 255 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 291 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 74 + + + + Edit + 编辑 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 254 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 175 + + + apps/client/src/app/components/admin-overview/admin-overview.html + 80 + + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 91 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 71 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 428 + + + + Delete + 删除 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 264 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 190 + + + apps/client/src/app/components/admin-overview/admin-overview.html + 90 + + + apps/client/src/app/components/admin-overview/admin-overview.html + 199 + + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 101 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 81 + + + libs/ui/src/lib/account-balances/account-balances.component.html + 51 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 450 + + + + Do you really want to delete this account? + 您真的要删除该帐户吗? + + apps/client/src/app/components/accounts-table/accounts-table.component.ts + 101 + + + + Asset Profile + 资产概况 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 31 + + + + Historical Market Data + 历史市场数据 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 37 + + + + Symbol + 符号 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 45 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 24 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 98 + + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 34 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 257 + + + + Data Source + 数据源 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 54 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 51 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 154 + + + + Attempts + 尝试 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + Created + 创建 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 72 + + + + Finished + 完成的 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 81 + + + + Status + 状况 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 90 + + + + Delete Jobs + 删除作业 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 126 + + + + View Data + 查看数据 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 141 + + + + View Stacktrace + 查看堆栈跟踪 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 148 + + + + Delete Job + 删除作业 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + + + Details for + 详细信息 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 2 + + + + Date + 日期 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 6 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 160 + + + libs/ui/src/lib/account-balances/account-balances.component.html + 11 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 168 + + + + Market Price + 市场价 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 26 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 81 + + + + Cancel + 取消 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 46 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 330 + + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 40 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 19 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 60 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 103 + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 57 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 412 + + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 38 + + + + Save + 保存 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 48 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 337 + + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 47 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 26 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 67 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 110 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 419 + + + + Currencies + 货币 + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 67 + + + + ETFs without Countries + 没有国家的 ETF + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 72 + + + + ETFs without Sectors + 无行业类别的 ETF + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 77 + + + + Do you really want to delete this asset profile? + 您确实要删除此资产配置文件吗? + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 185 + + + + Filter by... + 过滤... + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 282 + + + + Asset Class + 资产类别 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 60 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 131 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 212 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 184 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 338 + + + + Asset Sub Class + 资产子类别 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 69 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 140 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 225 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 193 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 354 + + + + First Activity + 第一个活动 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 78 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 113 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 166 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 50 + + + + Activities Count + 活动计数 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 87 + + + + Historical Data + 历史数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 96 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 65 + + + + Sectors Count + 行业数 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 105 + + + + Countries Count + 国家数 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 114 + + + + Gather Recent Data + 收集最近的数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 144 + + + + Gather All Data + 收集所有数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 147 + + + + Gather Profile Data + 收集个人资料数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 150 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 45 + + + + Oops! Could not parse historical data. + 哎呀!无法解析历史数据。 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts + 223 + + + + Refresh + 刷新 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 22 + + + + Gather Historical Data + 收集历史数据 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 32 + + + + Import + 导入 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 91 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 154 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 189 + + + + Sector + 行业 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 159 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 210 + + + + Country + 国家 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 168 + + + apps/client/src/app/components/admin-users/admin-users.html + 77 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 220 + + + + Sectors + 行业 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 173 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 295 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 226 + + + apps/client/src/app/pages/public/public-page.html + 45 + + + + Countries + 国家 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 183 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 306 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 238 + + + + Benchmark + 基准 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 253 + + + + Symbol Mapping + 符号映射 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 259 + + + + Scraper Configuration + 刮削配置 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 270 + + + + Note + 笔记 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 317 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 78 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 323 + + + + Add Asset Profile + 添加资产概况 + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 7 + + + + Search + 搜索 + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 16 + + + + Add Manually + 手动添加 + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 19 + + + + Name, symbol or ISIN + 名称、符号或 ISIN + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 25 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 122 + + + + Please add a currency: + 请添加货币: + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 122 + + + + is an invalid currency! + 是无效的货币! + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 129 + + + + Do you really want to delete this coupon? + 您确实要删除此优惠券吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 140 + + + + Do you really want to delete this currency? + 您真的要删除该货币吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 153 + + + + Do you really want to delete this system message? + 您真的要删除这条系统消息吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 166 + + + + Do you really want to flush the cache? + 您真的要刷新缓存吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 183 + + + + Please set your system message: + 请设置您的系统消息: + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 214 + + + + Version + 版本 + + apps/client/src/app/components/admin-overview/admin-overview.html + 7 + + + + User Count + 用户数 + + apps/client/src/app/components/admin-overview/admin-overview.html + 13 + + + + Activity Count + 活动计数 + + apps/client/src/app/components/admin-overview/admin-overview.html + 23 + + + + per User + 每位用户 + + apps/client/src/app/components/admin-overview/admin-overview.html + 32 + + + + Exchange Rates + 汇率 + + apps/client/src/app/components/admin-overview/admin-overview.html + 37 + + + + Add Currency + 添加货币 + + apps/client/src/app/components/admin-overview/admin-overview.html + 104 + + + + User Signup + 用户注册 + + apps/client/src/app/components/admin-overview/admin-overview.html + 110 + + + + Read-only Mode + 只读模式 + + apps/client/src/app/components/admin-overview/admin-overview.html + 123 + + + + System Message + 系统信息 + + apps/client/src/app/components/admin-overview/admin-overview.html + 145 + + + + Set Message + 设置留言 + + apps/client/src/app/components/admin-overview/admin-overview.html + 165 + + + + Coupons + 优惠券 + + apps/client/src/app/components/admin-overview/admin-overview.html + 173 + + + + Add + 添加 + + apps/client/src/app/components/admin-overview/admin-overview.html + 231 + + + + Housekeeping + 家政 + + apps/client/src/app/components/admin-overview/admin-overview.html + 238 + + + + Flush Cache + 刷新缓存 + + apps/client/src/app/components/admin-overview/admin-overview.html + 242 + + + + Add Platform + 添加平台 + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 11 + + + + Url + 网址 + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 50 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 13 + + + + Accounts + 帐户 + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 64 + + + apps/client/src/app/components/admin-users/admin-users.html + 113 + + + apps/client/src/app/components/header/header.component.html + 54 + + + apps/client/src/app/components/header/header.component.html + 257 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 312 + + + apps/client/src/app/pages/accounts/accounts-page.html + 4 + + + libs/ui/src/lib/assistant/assistant.html + 107 + + + + Do you really want to delete this platform? + 您真的要删除这个平台吗? + + apps/client/src/app/components/admin-platform/admin-platform.component.ts + 79 + + + + Update platform + 更新平台 + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 2 + + + + Add platform + 添加平台 + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 3 + + + + Platforms + 平台 + + apps/client/src/app/components/admin-settings/admin-settings.component.html + 4 + + + + Tags + 标签 + + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 332 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 367 + + + libs/ui/src/lib/assistant/assistant.html + 127 + + + + Add Tag + 添加标签 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11 + + + + Do you really want to delete this tag? + 您真的要删除此标签吗? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 79 + + + + Update tag + 更新标签 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + 添加标签 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + Do you really want to delete this user? + 您真的要删除该用户吗? + + apps/client/src/app/components/admin-users/admin-users.component.ts + 113 + + + + User + 用户 + + apps/client/src/app/components/admin-users/admin-users.html + 29 + + + + Registration + 注册 + + apps/client/src/app/components/admin-users/admin-users.html + 96 + + + + Engagement per Day + 每天的参与度 + + apps/client/src/app/components/admin-users/admin-users.html + 158 + + + + Last Request + 最后请求 + + apps/client/src/app/components/admin-users/admin-users.html + 183 + + + + Impersonate User + 模拟用户 + + apps/client/src/app/components/admin-users/admin-users.html + 222 + + + + Delete User + 删除用户 + + apps/client/src/app/components/admin-users/admin-users.html + 232 + + + + Performance + 表现 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html + 6 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 59 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + + + + Compare with... + 与之比较... + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html + 19 + + + + Manage Benchmarks + 管理基准 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html + 38 + + + + Portfolio + 文件夹 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts + 110 + + + apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts + 48 + + + + Benchmark + 基准 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts + 119 + + + + Current Market Mood + 当前市场情绪 + + apps/client/src/app/components/fear-and-greed-index/fear-and-greed-index.component.html + 12 + + + + Overview + 概述 + + apps/client/src/app/components/header/header.component.html + 28 + + + apps/client/src/app/components/header/header.component.html + 239 + + + + Portfolio + 文件夹 + + apps/client/src/app/components/header/header.component.html + 41 + + + apps/client/src/app/components/header/header.component.html + 249 + + + + Admin Control + 管理控制 + + apps/client/src/app/components/header/header.component.html + 67 + + + apps/client/src/app/components/header/header.component.html + 273 + + + + Me + + + apps/client/src/app/components/header/header.component.html + 206 + + + + User + 用户 + + apps/client/src/app/components/header/header.component.html + 225 + + + + My Ghostfolio + 我的 Ghostfolio + + apps/client/src/app/components/header/header.component.html + 264 + + + + About Ghostfolio + 关于 Ghostfolio + + apps/client/src/app/components/header/header.component.html + 304 + + + apps/client/src/app/pages/about/overview/about-overview-page.html + 5 + + + + Sign in + 登入 + + apps/client/src/app/components/header/header.component.html + 394 + + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 71 + + + + Get started + 开始使用 + + apps/client/src/app/components/header/header.component.html + 406 + + + + Sign in + 登入 + + apps/client/src/app/components/header/header.component.ts + 226 + + + apps/client/src/app/pages/webauthn/webauthn-page-routing.module.ts + 7 + + + + Oops! Incorrect Security Token. + 哎呀!安全令牌不正确。 + + apps/client/src/app/components/header/header.component.ts + 240 + + + + Manage Activities + 管理活动 + + apps/client/src/app/components/home-holdings/home-holdings.html + 22 + + + apps/client/src/app/pages/portfolio/holdings/holdings-page.html + 32 + + + + Fear + 恐惧 + + apps/client/src/app/components/home-market/home-market.component.ts + 25 + + + libs/ui/src/lib/i18n.ts + 69 + + + + Greed + 贪婪 + + apps/client/src/app/components/home-market/home-market.component.ts + 26 + + + libs/ui/src/lib/i18n.ts + 70 + + + + Last Days + 最后的 + + apps/client/src/app/components/home-market/home-market.html + 6 + + + + Welcome to Ghostfolio + 欢迎来到Ghostfolio + + apps/client/src/app/components/home-overview/home-overview.html + 7 + + + + Ready to take control of your personal finances? + 准备好掌控您的个人财务了吗? + + apps/client/src/app/components/home-overview/home-overview.html + 8 + + + + Setup your accounts + 设置您的帐户 + + apps/client/src/app/components/home-overview/home-overview.html + 15 + + + + Get a comprehensive financial overview by adding your bank and brokerage accounts. + 通过添加您的银行和经纪账户来获取全面的财务概览。 + + apps/client/src/app/components/home-overview/home-overview.html + 17 + + + + Capture your activities + 记录你的活动 + + apps/client/src/app/components/home-overview/home-overview.html + 24 + + + + Record your investment activities to keep your portfolio up to date. + 记录您的投资活动以使您的投资组合保持最新状态。 + + apps/client/src/app/components/home-overview/home-overview.html + 26 + + + + Monitor and analyze your portfolio + 监控和分析您的投资组合 + + apps/client/src/app/components/home-overview/home-overview.html + 33 + + + + Track your progress in real-time with comprehensive analysis and insights. + 通过全面的分析和见解实时跟踪您的进度。 + + apps/client/src/app/components/home-overview/home-overview.html + 35 + + + + Setup accounts + 设置帐户 + + apps/client/src/app/components/home-overview/home-overview.html + 48 + + + + Add activity + 添加活动 + + apps/client/src/app/components/home-overview/home-overview.html + 56 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 8 + + + + This feature requires a subscription. + 此功能需要订阅。 + + apps/client/src/app/components/home-summary/home-summary.component.ts + 113 + + + apps/client/src/app/core/http-response.interceptor.ts + 68 + + + + Upgrade Plan + 升级计划 + + apps/client/src/app/components/home-summary/home-summary.component.ts + 115 + + + apps/client/src/app/core/http-response.interceptor.ts + 70 + + + + Summary + 概括 + + apps/client/src/app/components/home-summary/home-summary.html + 2 + + + + Total Amount + 总金额 + + apps/client/src/app/components/investment-chart/investment-chart.component.ts + 191 + + + + Savings Rate + 储蓄率 + + apps/client/src/app/components/investment-chart/investment-chart.component.ts + 263 + + + + Security Token + 安全令牌 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 11 + + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 10 + + + + or + + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 31 + + + apps/client/src/app/pages/landing/landing-page.html + 429 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 99 + + + apps/client/src/app/pages/register/register-page.html + 29 + + + apps/client/src/app/pages/webauthn/webauthn-page.html + 29 + + + + Sign in with Internet Identity + 使用互联网身份登录 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 42 + + + + Sign in with Google + 使用 Google 登录 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 52 + + + + Stay signed in + 保持登录 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 61 + + + + Time in Market + 上市时间 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 3 + + + + + + + + + + + + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 12 + + + + {VAR_PLURAL, plural, =1 {transaction} other {transactions}} + {VAR_PLURAL,复数,=1 {交易} 其他{交易}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy + + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 21 + + + + Sell + + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 33 + + + + Investment + 投资 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 48 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 134 + + + + Absolute Gross Performance + 绝对总业绩 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 60 + + + + Gross Performance + 总表现 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 77 + + + + Fees + 费用 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 100 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 156 + + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 161 + + + + Absolute Net Performance + 绝对净绩效 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 116 + + + + Net Performance + 净绩效 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 133 + + + + Total Assets + 总资产 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 159 + + + + Valuables + 贵重物品 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 172 + + + + Emergency Fund + 应急基金 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 184 + + + apps/client/src/app/pages/features/features-page.html + 89 + + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 122 + + + + Cash + 现金 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 205 + + + + Assets + 资产 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 218 + + + + Buying Power + 购买力 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 231 + + + + Excluded from Analysis + 从分析中排除 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 243 + + + + Liabilities + 负债 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 258 + + + apps/client/src/app/pages/features/features-page.html + 102 + + + + Net Worth + 净值 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 278 + + + + Annualized Performance + 年化业绩 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 290 + + + + Interest + 利息 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 312 + + + + Dividend + 股息 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 324 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 145 + + + apps/client/src/app/pages/features/features-page.html + 63 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 196 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 261 + + + + Please enter the amount of your emergency fund: + 请输入您的应急基金金额: + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts + 53 + + + + Change + 修改 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 48 + + + + Average Unit Price + 平均单价 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 70 + + + + Minimum Price + 最低价格 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 97 + + + + Maximum Price + 最高价格 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 113 + + + + Quantity + 数量 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 123 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 183 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 184 + + + + Report Data Glitch + 报告数据故障 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 350 + + + + Are you an ambitious investor who needs the full picture? + 您是一位雄心勃勃、需要全面了解的投资者吗? + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 12 + + + + Upgrade to Ghostfolio Premium today and gain access to exclusive features to enhance your investment experience: + 立即升级至 Ghostfolio Premium 并获得独家功能,以增强您的投资体验: + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 15 + + + + Portfolio Summary + 投资组合摘要 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 22 + + + apps/client/src/app/pages/pricing/pricing-page.html + 55 + + + apps/client/src/app/pages/pricing/pricing-page.html + 199 + + + + Portfolio Allocations + 投资组合分配 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 26 + + + apps/client/src/app/pages/features/features-page.html + 160 + + + apps/client/src/app/pages/pricing/pricing-page.html + 59 + + + apps/client/src/app/pages/pricing/pricing-page.html + 203 + + + + Performance Benchmarks + 性能基准 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 30 + + + apps/client/src/app/pages/pricing/pricing-page.html + 63 + + + apps/client/src/app/pages/pricing/pricing-page.html + 207 + + + + FIRE Calculator + 财务自由计算器 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 34 + + + apps/client/src/app/pages/pricing/pricing-page.html + 67 + + + apps/client/src/app/pages/pricing/pricing-page.html + 211 + + + + Professional Data Provider + 专业数据提供商 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 38 + + + apps/client/src/app/pages/pricing/pricing-page.html + 226 + + + + and more Features... + 以及更多功能... + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 42 + + + apps/client/src/app/pages/pricing/pricing-page.html + 83 + + + apps/client/src/app/pages/pricing/pricing-page.html + 231 + + + + Get the tools to effectively manage your finances and refine your personal investment strategy. + 获取有效管理财务和完善个人投资策略的工具。 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 45 + + + + Skip + 跳过 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 52 + + + + Upgrade Plan + 升级计划 + + apps/client/src/app/components/header/header.component.html + 177 + + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 59 + + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 20 + + + apps/client/src/app/pages/pricing/pricing-page.html + 268 + + + + Today + 今天 + + apps/client/src/app/components/toggle/toggle.component.ts + 22 + + + libs/ui/src/lib/assistant/assistant.component.ts + 99 + + + + YTD + 年初至今 + + apps/client/src/app/components/toggle/toggle.component.ts + 23 + + + libs/ui/src/lib/assistant/assistant.component.ts + 109 + + + + 1Y + 1年 + + apps/client/src/app/components/toggle/toggle.component.ts + 24 + + + libs/ui/src/lib/assistant/assistant.component.ts + 112 + + + + 5Y + 5年 + + apps/client/src/app/components/toggle/toggle.component.ts + 25 + + + libs/ui/src/lib/assistant/assistant.component.ts + 114 + + + + Max + 最大限度 + + apps/client/src/app/components/toggle/toggle.component.ts + 26 + + + libs/ui/src/lib/assistant/assistant.component.ts + 117 + + + + Grant access + 授予访问权限 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 7 + + + + Public + 公开 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 25 + + + + Granted Access + 授予访问权限 + + apps/client/src/app/components/user-account-access/user-account-access.html + 5 + + + + Please enter your coupon code: + 请输入您的优惠券代码: + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 111 + + + + Could not redeem coupon code + 无法兑换优惠券代码 + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 121 + + + + Coupon code has been redeemed + 优惠券代码已兑换 + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 133 + + + + Reload + 重新加载 + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 134 + + + + per year + 每年 + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 41 + + + apps/client/src/app/pages/pricing/pricing-page.html + 254 + + + + Try Premium + 尝试高级版 + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 50 + + + + Redeem Coupon + 兑换优惠券 + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 63 + + + + Auto + 自动 + + apps/client/src/app/components/user-account-settings/user-account-settings.component.ts + 33 + + + + Do you really want to remove this sign in method? + 您确实要删除此登录方法吗? + + apps/client/src/app/components/user-account-settings/user-account-settings.component.ts + 188 + + + + Settings + 设置 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 2 + + + + Presenter View + 演示者视图 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 7 + + + + Protection for sensitive information like absolute performances and quantity values + 保护绝对性能和数量值等敏感信息 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 8 + + + + Base Currency + 基础货币 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 27 + + + + Language + 语言 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 50 + + + + Locale + 语言环境 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 113 + + + + Date and number format + 日期和数字格式 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 115 + + + + Appearance + 外貌 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 138 + + + + Auto + 自动 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 152 + + + + Light + 明亮 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 153 + + + + Dark + 黑暗 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 154 + + + + Zen Mode + 极简模式 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 163 + + + apps/client/src/app/pages/features/features-page.html + 190 + + + + Distraction-free experience for turbulent times + 动荡时期的无干扰体验 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 164 + + + + Biometric Authentication + 生物识别认证 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 180 + + + + Sign in with fingerprint + 使用指纹登录 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 181 + + + + Experimental Features + 实验性功能 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 198 + + + + Sneak peek at upcoming functionality + 预览即将推出的功能 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 199 + + + + User ID + 用户身份 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 47 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 215 + + + + Export Data + 导出数据 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 223 + + + + This feature is currently unavailable. + 此功能目前无法使用。 + + apps/client/src/app/core/http-response.interceptor.ts + 60 + + + + Please try again later. + 请稍后再试。 + + apps/client/src/app/core/http-response.interceptor.ts + 62 + + + apps/client/src/app/core/http-response.interceptor.ts + 89 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 138 + + + + Oops! Something went wrong. + 哎呀!出了些问题。 + + apps/client/src/app/core/http-response.interceptor.ts + 87 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 136 + + + + Okay + 好的 + + apps/client/src/app/core/http-response.interceptor.ts + 90 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 139 + + + + About + 关于 + + apps/client/src/app/pages/about/about-page-routing.module.ts + 51 + + + apps/client/src/app/pages/about/about-page.component.ts + 44 + + + apps/client/src/app/pages/about/overview/about-overview-page-routing.module.ts + 13 + + + + Changelog + 更新日志 + + apps/client/src/app/pages/about/about-page.component.ts + 49 + + + apps/client/src/app/pages/about/changelog/changelog-page-routing.module.ts + 13 + + + + License + 许可 + + apps/client/src/app/pages/about/about-page.component.ts + 54 + + + apps/client/src/app/pages/about/license/license-page-routing.module.ts + 13 + + + + Privacy Policy + 隐私政策 + + apps/client/src/app/pages/about/about-page.component.ts + 62 + + + apps/client/src/app/pages/about/privacy-policy/privacy-policy-page-routing.module.ts + 13 + + + + Our + 我们的 + + apps/client/src/app/pages/about/oss-friends/oss-friends-page.html + 6 + + + + Discover other exciting Open Source Software projects + 发现其他令人兴奋的开源软件项目 + + apps/client/src/app/pages/about/oss-friends/oss-friends-page.html + 9 + + + + Visit + 访问 + + apps/client/src/app/pages/about/oss-friends/oss-friends-page.html + 28 + + + + Accounts + 账户 + + apps/client/src/app/pages/accounts/accounts-page-routing.module.ts + 13 + + + + Oops, cash balance transfer has failed. + 糟糕,现金余额转账失败。 + + apps/client/src/app/pages/accounts/accounts-page.component.ts + 306 + + + + Update account + 更新账户 + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 8 + + + + Add account + 新增帐户 + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 10 + + + + Account ID + 帐户ID + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 96 + + + + From + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 11 + + + + To + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 28 + + + + Transfer + 转移 + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 64 + + + + Admin Control + 管理控制 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 20 + + + + Market Data + 市场数据 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 30 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 37 + + + + Settings + 设置 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 35 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 32 + + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 18 + + + apps/client/src/app/pages/user-account/user-account-page.component.ts + 35 + + + + Users + 用户 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 40 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 47 + + + + Overview + 概述 + + apps/client/src/app/pages/admin/admin-page.component.ts + 27 + + + apps/client/src/app/pages/home/home-page.component.ts + 34 + + + apps/client/src/app/pages/zen/zen-page-routing.module.ts + 19 + + + apps/client/src/app/pages/zen/zen-page.component.ts + 34 + + + + Blog + 博客 + + apps/client/src/app/pages/blog/blog-page-routing.module.ts + 13 + + + + Discover the latest Ghostfolio updates and insights on personal finance + 了解最新的 Ghostfolio 更新和个人理财见解 + + apps/client/src/app/pages/blog/blog-page.html + 7 + + + + As you are already logged in, you cannot access the demo account. + 由于您已经登录,因此无法访问模拟帐户。 + + apps/client/src/app/pages/demo/demo-page.component.ts + 32 + + + + Frequently Asked Questions (FAQ) + 常见问题 (FAQ) + + apps/client/src/app/pages/faq/faq-page-routing.module.ts + 34 + + + apps/client/src/app/pages/faq/overview/faq-overview-page-routing.module.ts + 13 + + + + Frequently Asked Questions (FAQ) + 常见问题 (FAQ) + + apps/client/src/app/pages/faq/overview/faq-overview-page.html + 4 + + + apps/client/src/app/pages/faq/saas/saas-page.html + 4 + + + apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html + 4 + + + + Features + 功能 + + apps/client/src/app/pages/features/features-page-routing.module.ts + 13 + + + + Check out the numerous features of Ghostfolio to manage your wealth + 查看 Ghostfolio 的众多功能来管理您的财富 + + apps/client/src/app/pages/features/features-page.html + 6 + + + + Stocks + 股票 + + apps/client/src/app/pages/features/features-page.html + 15 + + + + ETFs + ETF + + apps/client/src/app/pages/features/features-page.html + 25 + + + + Bonds + 债券 + + apps/client/src/app/pages/features/features-page.html + 38 + + + + Cryptocurrencies + 加密货币 + + apps/client/src/app/pages/features/features-page.html + 51 + + + + Wealth Items + 财富项目 + + apps/client/src/app/pages/features/features-page.html + 76 + + + + Import and Export + 导入和导出 + + apps/client/src/app/pages/features/features-page.html + 115 + + + + Multi-Accounts + 多账户 + + apps/client/src/app/pages/features/features-page.html + 127 + + + + Portfolio Calculations + 投资组合计算 + + apps/client/src/app/pages/features/features-page.html + 141 + + + + Dark Mode + 深色模式 + + apps/client/src/app/pages/features/features-page.html + 177 + + + + Market Mood + 市场情绪 + + apps/client/src/app/pages/features/features-page.html + 205 + + + + Static Analysis + 静态分析 + + apps/client/src/app/pages/features/features-page.html + 224 + + + + Multi-Language + 多语言 + + apps/client/src/app/pages/features/features-page.html + 241 + + + + Open Source Software + 开源软件 + + apps/client/src/app/pages/features/features-page.html + 275 + + + + Get Started + 立即开始 + + apps/client/src/app/pages/features/features-page.html + 300 + + + apps/client/src/app/pages/public/public-page.html + 153 + + + + Holdings + 控股 + + apps/client/src/app/pages/home/home-page-routing.module.ts + 23 + + + apps/client/src/app/pages/home/home-page.component.ts + 39 + + + apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 39 + + + apps/client/src/app/pages/zen/zen-page.component.ts + 39 + + + + Summary + 概括 + + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 + + + apps/client/src/app/pages/home/home-page.component.ts + 44 + + + + Markets + 市场 + + apps/client/src/app/pages/home/home-page-routing.module.ts + 33 + + + apps/client/src/app/pages/home/home-page.component.ts + 49 + + + apps/client/src/app/pages/markets/markets-page-routing.module.ts + 13 + + + + Ghostfolio is a personal finance dashboard to keep track of your net worth including cash, stocks, ETFs and cryptocurrencies across multiple platforms. + Ghostfolio 是一个个人财务仪表板,用于跨多个平台跟踪您的净资产,包括现金、股票、ETF 和加密货币。 + + apps/client/src/app/pages/i18n/i18n-page.html + 4 + + + + app, asset, cryptocurrency, dashboard, etf, finance, management, performance, portfolio, software, stock, trading, wealth, web3 + 应用程序、资产、加密货币、仪表板、etf、财务、管理、绩效、投资组合、软件、股票、交易、财富、web3 + + apps/client/src/app/pages/i18n/i18n-page.html + 9 + + + + Open Source Wealth Management Software + 开源财富管理软件 + + apps/client/src/app/pages/i18n/i18n-page.html + 14 + + + + New + 新的 + + apps/client/src/app/pages/landing/landing-page.html + 7 + + + + Manage your wealth like a boss + 像老板一样管理您的财富 + + apps/client/src/app/pages/landing/landing-page.html + 11 + + + + Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. + Ghostfolio 是一个隐私优先、开源的个人财务仪表板。分解您的资产配置,了解您的净资产并做出可靠的、数据驱动的投资决策。 + + apps/client/src/app/pages/landing/landing-page.html + 15 + + + + Get Started + 开始使用 + + apps/client/src/app/pages/landing/landing-page.html + 47 + + + apps/client/src/app/pages/landing/landing-page.html + 425 + + + + or + + + apps/client/src/app/pages/landing/landing-page.html + 52 + + + + Live Demo + 现场演示 + + apps/client/src/app/pages/landing/landing-page.html + 55 + + + apps/client/src/app/pages/landing/landing-page.html + 430 + + + + Monthly Active Users + 每月活跃用户数 + + apps/client/src/app/pages/landing/landing-page.html + 75 + + + + Stars on GitHub + GitHub 上的星星 + + apps/client/src/app/pages/landing/landing-page.html + 93 + + + apps/client/src/app/pages/open/open-page.html + 103 + + + + Pulls on Docker Hub + 拉动 Docker Hub + + apps/client/src/app/pages/landing/landing-page.html + 111 + + + apps/client/src/app/pages/open/open-page.html + 117 + + + + As seen in + 如图所示 + + apps/client/src/app/pages/landing/landing-page.html + 119 + + + + Protect your assets. Refine your personal investment strategy. + 保护你的资产。完善你的个人投资策略 + + apps/client/src/app/pages/landing/landing-page.html + 221 + + + + Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. + Ghostfolio 使忙碌的人们能够在不被追踪的情况下跟踪股票、ETF 或加密货币。 + + apps/client/src/app/pages/landing/landing-page.html + 225 + + + + 360° View + 360° 视角 + + apps/client/src/app/pages/landing/landing-page.html + 236 + + + + Get the full picture of your personal finances across multiple platforms. + 跨多个平台全面了解您的个人财务状况。 + + apps/client/src/app/pages/landing/landing-page.html + 238 + + + + Web3 Ready + Web3 就绪 + + apps/client/src/app/pages/landing/landing-page.html + 247 + + + + Use Ghostfolio anonymously and own your financial data. + 匿名使用 Ghostfolio 并拥有您的财务数据。 + + apps/client/src/app/pages/landing/landing-page.html + 249 + + + + Open Source + 开源 + + apps/client/src/app/pages/landing/landing-page.html + 257 + + + + Benefit from continuous improvements through a strong community. + 通过强大的社区不断改进,从中受益。 + + apps/client/src/app/pages/landing/landing-page.html + 259 + + + + Why Ghostfolio? + 为什么使用Ghostfolio + + apps/client/src/app/pages/landing/landing-page.html + 268 + + + + Ghostfolio is for you if you are... + 如果您符合以下条件,那么 Ghostfolio 适合您... + + apps/client/src/app/pages/landing/landing-page.html + 269 + + + + trading stocks, ETFs or cryptocurrencies on multiple platforms + 在多个平台上交易股票、ETF 或加密货币 + + apps/client/src/app/pages/landing/landing-page.html + 276 + + + + pursuing a buy & hold strategy + 采取买入并持有策略 + + apps/client/src/app/pages/landing/landing-page.html + 282 + + + + interested in getting insights of your portfolio composition + 有兴趣深入了解您的投资组合构成 + + apps/client/src/app/pages/landing/landing-page.html + 287 + + + + valuing privacy and data ownership + 重视隐私和数据所有权 + + apps/client/src/app/pages/landing/landing-page.html + 292 + + + + into minimalism + 进入极简主义 + + apps/client/src/app/pages/landing/landing-page.html + 295 + + + + caring about diversifying your financial resources + 关心您的财务资源多元化 + + apps/client/src/app/pages/landing/landing-page.html + 299 + + + + interested in financial independence + 对财务独立感兴趣 + + apps/client/src/app/pages/landing/landing-page.html + 303 + + + + saying no to spreadsheets in + 对电子表格说不 + + apps/client/src/app/pages/landing/landing-page.html + 307 + + + + still reading this list + 仍在阅读此列表 + + apps/client/src/app/pages/landing/landing-page.html + 310 + + + + Learn more about Ghostfolio + 了解有关 Ghostfolio 的更多信息 + + apps/client/src/app/pages/landing/landing-page.html + 315 + + + + What our users are saying + 我们的什么用户正在说 + + apps/client/src/app/pages/landing/landing-page.html + 323 + + + + Members from around the globe are using Ghostfolio Premium + 来自世界各地的会员正在使用Ghostfolio 高级版 + + apps/client/src/app/pages/landing/landing-page.html + 355 + + + + How does Ghostfolio work? + 如何幽灵作品集工作? + + apps/client/src/app/pages/landing/landing-page.html + 367 + + + + Get started in only 3 steps + 只需 3 步即可开始 + + apps/client/src/app/pages/landing/landing-page.html + 370 + + + + Sign up anonymously* + 匿名注册* + + apps/client/src/app/pages/landing/landing-page.html + 376 + + + + * no e-mail address nor credit card required + * 无需电子邮件地址或信用卡 + + apps/client/src/app/pages/landing/landing-page.html + 378 + + + + Add any of your historical transactions + 添加您的任何历史交易 + + apps/client/src/app/pages/landing/landing-page.html + 389 + + + + Get valuable insights of your portfolio composition + 获取有关您的投资组合构成的宝贵见解 + + apps/client/src/app/pages/landing/landing-page.html + 401 + + + + Are you ready? + 准备好? + + apps/client/src/app/pages/landing/landing-page.html + 413 + + + + Join now or check out the example account + 立即加入或查看示例帐户 + + apps/client/src/app/pages/landing/landing-page.html + 414 + + + + At Ghostfolio, transparency is at the core of our values. We publish the source code as open source software (OSS) under the AGPL-3.0 license and we openly share aggregated key metrics of the platform’s operational status. + 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 + + apps/client/src/app/pages/open/open-page.html + 6 + + + + (Last 24 hours) + (最近 24 小时) + + apps/client/src/app/pages/open/open-page.html + 37 + + + + Active Users + 活跃用户 + + apps/client/src/app/pages/open/open-page.html + 40 + + + apps/client/src/app/pages/open/open-page.html + 62 + + + + (Last 30 days) + (最近 30 天) + + apps/client/src/app/pages/open/open-page.html + 48 + + + apps/client/src/app/pages/open/open-page.html + 59 + + + + New Users + 新用户 + + apps/client/src/app/pages/open/open-page.html + 51 + + + + Users in Slack community + Slack 社区的用户 + + apps/client/src/app/pages/open/open-page.html + 75 + + + + Contributors on GitHub + GitHub 上的贡献者 + + apps/client/src/app/pages/open/open-page.html + 89 + + + + (Last 90 days) + (过去 90 天) + + apps/client/src/app/pages/open/open-page.html + 127 + + + + Uptime + 正常运行时间 + + apps/client/src/app/pages/open/open-page.html + 132 + + + + Activities + 活动 + + apps/client/src/app/pages/portfolio/activities/activities-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 44 + + + + Do you really want to delete all your activities? + 您真的要删除所有活动吗? + + apps/client/src/app/pages/portfolio/activities/activities-page.component.ts + 168 + + + + Update activity + 更新活动 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 7 + + + + Stocks, ETFs, bonds, cryptocurrencies, commodities + 股票、ETF、债券、加密货币、大宗商品 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 22 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 62 + + + + One-time fee, annual account fees + 一次性费用、年度账户费用 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 30 + + + + Distribution of corporate earnings + 企业盈利分配 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 38 + + + + Revenue for lending out money + 放贷收入 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 46 + + + + Mortgages, personal loans, credit cards + 抵押贷款、个人贷款、信用卡 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 54 + + + + Luxury items, real estate, private companies + 奢侈品、房地产、私营公司 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 70 + + + + Account + 帐户 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 82 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 306 + + + + Update Cash Balance + 更新现金余额 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 110 + + + + Unit Price + 单价 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 203 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 267 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 208 + + + + Oops! Could not get the historical exchange rate from + 哎呀!无法从以下来源获取历史汇率 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 232 + + + + Fee + 费用 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 286 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 314 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 232 + + + + Oops! Could not get the historical exchange rate from + 哎呀!无法获取历史汇率 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 304 + + + + Import Activities + 导入活动 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 44 + + + + Import Dividends + 导入股息 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 86 + + + + Importing data... + 正在导入数据... + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 120 + + + + Import has been completed + 导入已完成 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 128 + + + + Validating data... + 验证数据... + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 233 + + + + Select Holding + 选择控股 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 20 + + + + Select File + 选择文件 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 23 + + + + Holding + 保持 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 33 + + + + Load Dividends + 加载股息 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 70 + + + + Choose or drop a file here + 在此处选择或放置文件 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 86 + + + + The following file formats are supported: + 支持以下文件格式: + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 92 + + + + Select Dividends + 选择股息 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 115 + + + + Select Activities + 选择活动 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 118 + + + + Back + 后退 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 145 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 181 + + + + Allocations + 分配 + + apps/client/src/app/pages/portfolio/allocations/allocations-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 49 + + + + Allocations + 分配 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 4 + + + + Proportion of Net Worth + 占净资产的比例 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 12 + + + + By Platform + 按平台 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 44 + + + + By Currency + 按货币 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 63 + + + + By Asset Class + 按资产类别 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 86 + + + + By Holding + 通过持有 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 109 + + + + By Sector + 按部门 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 132 + + + + By Continent + 按大陆 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 156 + + + + By Market + 按市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 179 + + + + Regions + 区域 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 203 + + + apps/client/src/app/pages/public/public-page.html + 76 + + + + Developed Markets + 发达市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 228 + + + apps/client/src/app/pages/public/public-page.html + 93 + + + + Emerging Markets + 新兴市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 237 + + + apps/client/src/app/pages/public/public-page.html + 102 + + + + Other Markets + 其他市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 246 + + + apps/client/src/app/pages/public/public-page.html + 111 + + + + No data available + 无可用数据 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 258 + + + apps/client/src/app/pages/public/public-page.html + 123 + + + + By Account + 按帐户 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 270 + + + + By ETF Provider + 按 ETF 提供商 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 290 + + + + By Country + 按国家/地区 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 313 + + + + Analysis + 分析 + + apps/client/src/app/pages/portfolio/analysis/analysis-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 34 + + + + Dividend + 股息 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 42 + + + libs/ui/src/lib/i18n.ts + 31 + + + + Deposit + 订金 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.ts + 332 + + + + Monthly + 每月 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 54 + + + + Yearly + 每年 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 55 + + + + Analysis + 分析 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 2 + + + + Top + 顶部 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 168 + + + + Bottom + 底部 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 216 + + + + Portfolio Evolution + 投资组合演变 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 268 + + + + Investment Timeline + 投资时间表 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 298 + + + + Current Streak + 当前连胜 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 319 + + + + Longest Streak + 最长连续纪录 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 328 + + + + Dividend Timeline + 股息时间表 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 356 + + + + FIRE + 财务独立 + + apps/client/src/app/pages/portfolio/fire/fire-page-routing.module.ts + 13 + + + + FIRE + 财务独立 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 4 + + + + Calculator + 计算器 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 7 + + + + 4% Rule + 4%规则 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 41 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray 使用静态分析来识别您的投资组合中的潜在问题和风险。 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Currency Cluster Risks + 货币集群风险 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 135 + + + + Account Cluster Risks + 账户集群风险 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 148 + + + + Holdings + 控股 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 77 + + + apps/client/src/app/pages/portfolio/holdings/holdings-page.html + 4 + + + apps/client/src/app/pages/public/public-page.html + 14 + + + libs/ui/src/lib/assistant/assistant.html + 46 + + + + Pricing + 价钱 + + apps/client/src/app/pages/pricing/pricing-page-routing.module.ts + 13 + + + + Pricing Plans + 定价计划 + + apps/client/src/app/pages/pricing/pricing-page.html + 4 + + + + Our official Ghostfolio Premium cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. Revenue is used to cover the costs of the hosting infrastructure and to fund ongoing development. + 我们的官方 Ghostfolio Premium 云产品是最简单的入门方法。由于它节省了时间,这对于大多数人来说将是最佳选择。收入用于支付托管基础设施的成本和资助持续开发。 + + apps/client/src/app/pages/pricing/pricing-page.html + 6 + + + + If you prefer to run Ghostfolio on your own infrastructure, please find the source code and further instructions on GitHub. + 如果你希望在自己的基础设施上运行 Ghostfolio,请查看源代码和进一步的说明GitHub + + apps/client/src/app/pages/pricing/pricing-page.html + 24 + + + + For tech-savvy investors who prefer to run Ghostfolio on their own infrastructure. + 适合喜欢在自己的基础设施上运行 Ghostfolio 的精通技术的投资者。 + + apps/client/src/app/pages/pricing/pricing-page.html + 36 + + + + Unlimited Transactions + 无限交易 + + apps/client/src/app/pages/pricing/pricing-page.html + 43 + + + apps/client/src/app/pages/pricing/pricing-page.html + 126 + + + apps/client/src/app/pages/pricing/pricing-page.html + 187 + + + + Unlimited Accounts + 无限账户 + + apps/client/src/app/pages/pricing/pricing-page.html + 47 + + + apps/client/src/app/pages/pricing/pricing-page.html + 130 + + + apps/client/src/app/pages/pricing/pricing-page.html + 191 + + + + Portfolio Performance + 投资组合表现 + + apps/client/src/app/pages/pricing/pricing-page.html + 51 + + + apps/client/src/app/pages/pricing/pricing-page.html + 134 + + + apps/client/src/app/pages/pricing/pricing-page.html + 195 + + + + Data Import and Export + 数据导入与导出 + + apps/client/src/app/pages/pricing/pricing-page.html + 71 + + + apps/client/src/app/pages/pricing/pricing-page.html + 138 + + + apps/client/src/app/pages/pricing/pricing-page.html + 215 + + + + Community Support + 社区支持 + + apps/client/src/app/pages/pricing/pricing-page.html + 88 + + + + Self-hosted, update manually. + 自托管,手动更新。 + + apps/client/src/app/pages/pricing/pricing-page.html + 92 + + + + Free + 自由的 + + apps/client/src/app/pages/pricing/pricing-page.html + 93 + + + apps/client/src/app/pages/pricing/pricing-page.html + 150 + + + + For new investors who are just getting started with trading. + 适合刚开始交易的新投资者。 + + apps/client/src/app/pages/pricing/pricing-page.html + 120 + + + + Fully managed Ghostfolio cloud offering. + 完全托管的 Ghostfolio 云产品。 + + apps/client/src/app/pages/pricing/pricing-page.html + 149 + + + apps/client/src/app/pages/pricing/pricing-page.html + 240 + + + + For ambitious investors who need the full picture of their financial assets. + 适合需要全面了解其金融资产的雄心勃勃的投资者。 + + apps/client/src/app/pages/pricing/pricing-page.html + 180 + + + + Email and Chat Support + 电子邮件和聊天支持 + + apps/client/src/app/pages/pricing/pricing-page.html + 236 + + + + Renew Plan + 更新计划 + + apps/client/src/app/components/header/header.component.html + 185 + + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 28 + + + apps/client/src/app/pages/pricing/pricing-page.html + 276 + + + + One-time payment, no auto-renewal. + 一次性付款,无自动续订。 + + apps/client/src/app/pages/pricing/pricing-page.html + 280 + + + + Get Started + 开始使用 + + apps/client/src/app/pages/pricing/pricing-page.html + 291 + + + + It’s free. + 免费。 + + apps/client/src/app/pages/pricing/pricing-page.html + 294 + + + + Hello, has shared a Portfolio with you! + 你好,分享了一个文件夹与你! + + apps/client/src/app/pages/public/public-page.html + 4 + + + + Currencies + 货币 + + apps/client/src/app/pages/public/public-page.html + 30 + + + + Continents + 大陆 + + apps/client/src/app/pages/public/public-page.html + 60 + + + + Ghostfolio empowers you to keep track of your wealth. + Ghostfolio 使您能够跟踪您的财富。 + + apps/client/src/app/pages/public/public-page.html + 148 + + + + Registration + 注册 + + apps/client/src/app/pages/register/register-page-routing.module.ts + 13 + + + + Continue with Internet Identity + 继续互联网身份 + + apps/client/src/app/pages/register/register-page.html + 41 + + + + Continue with Google + 继续使用谷歌 + + apps/client/src/app/pages/register/register-page.html + 51 + + + + Copy to clipboard + 复制到剪贴板 + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 26 + + + + I agree to have stored my Security Token from above in a secure place. If I lose it, I cannot get my account back. + 我同意存储我的保安编码器从上面看,在一个安全的地方。如果我丢失了它,我将无法找回我的帐户。 + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 32 + + + + Agree and continue + 同意并继续 + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 45 + + + + Personal Finance Tools + 个人理财工具 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts + 14 + + + + open-source-alternative-to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts + 23 + + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts + 13 + + + + Open Source Alternative to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts + 26 + + + + Discover Open Source Alternatives for Personal Finance Tools + 发现个人理财工具的开源替代品 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 4 + + + + This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management. + 此概述页面包含与开源替代方案相比的精选个人理财工具集合Ghostfolio。如果您重视透明度、数据隐私和社区协作,Ghostfolio 提供了一个绝佳的机会来控制您的财务管理。 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 8 + + + + Explore the links below to compare a variety of personal finance tools with Ghostfolio. + 浏览下面的链接,将各种个人理财工具与 Ghostfolio 进行比较。 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 16 + + + + Open Source Alternative to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 38 + + + + The Open Source Alternative to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. + 您是否正在寻找开源替代方案幽灵作品集是一个强大的投资组合管理工具,为个人提供一个全面的平台来跟踪、分析和优化他们的投资。无论您是经验丰富的投资者还是刚刚起步的投资者,Ghostfolio 都提供直观的用户界面和广泛的功能帮助您做出明智的决定并掌控您的财务未来。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. + Ghostfolio 是一款开源软件 (OSS),提供了一种经济高效的替代方案使其特别适合预算紧张的个人,例如追求财务独立,提前退休(FIRE) 。通过利用开发者社区和个人理财爱好者的集体努力,Ghostfolio 不断增强其功能、安全性和用户体验。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + + Let’s dive deeper into the detailed Ghostfolio vs comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. + 让我们更深入地了解 Ghostfolio 与下面的比较表可帮助您全面了解 Ghostfolio 相对于其他产品的定位。我们将探讨功能、数据隐私、定价等各个方面,让您根据个人需求做出明智的选择。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + + Ghostfolio vs comparison table + Ghostfolio vs比较表 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + + Founded + 成立 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + + Origin + 来源 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + + Region + 地区 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + + Available in + 可用于 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + + ✅ Yes + ✅ 是的 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + + ❌ No + ❌ 没有 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + + ❌ No + ❌ 没有 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + + Self-Hosting + 自托管 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + + Use anonymously + 匿名使用 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + + Free Plan + 免费计划 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + + Starting from + 从...开始 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + + year + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + + Notes + 笔记 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + + Please note that the information provided in the Ghostfolio vs comparison table is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. + 请注意,Ghostfolio 与 Ghostfolio 中提供的信息比较表基于我们的独立研究和分析。该网站不隶属于或比较中提到的任何其他产品。随着个人理财工具格局的不断发展,直接从相应的产品页面验证任何具体的细节或变化至关重要。数据需要刷新吗?帮助我们维护准确的数据GitHub + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + + Ready to take your investments to the next level? + 准备好带走你的投资下一级 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. + 使用 Ghostfolio 轻松跟踪、分析和可视化您的财富。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + + Get Started + 开始使用 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + + Personal Finance Tools + 个人理财工具 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + + Switzerland + 瑞士 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 530 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 580 + + + + Global + 全球的 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 341 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 462 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 581 + + + + United States + 美国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 93 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 149 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 159 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 201 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 220 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 242 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 294 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 316 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 327 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 352 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 354 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 364 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 429 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 439 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 449 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 518 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 541 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 569 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 591 + + + + France + 法国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 482 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 498 + + + + Poland + 波兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 131 + + + + Germany + 德国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 140 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 274 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 284 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 305 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 339 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 385 + + + + Belgium + 比利时 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 179 + + + + South Africa + 南非 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 251 + + + + Austria + 奥地利 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 262 + + + + Italy + 意大利 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 396 + + + + Netherlands + 荷兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 406 + + + + Thailand + 泰国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 418 + + + + New Zealand + 新西兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 460 + + + + Czech Republic + 捷克共和国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 471 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 508 + + + + Finland + 芬兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 490 + + + + Canada + 加拿大 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 561 + + + + Resources + 资源 + + apps/client/src/app/pages/resources/resources-page-routing.module.ts + 13 + + + + Guides + 指南 + + apps/client/src/app/pages/resources/resources-page.html + 22 + + + + Glossary + 词汇表 + + apps/client/src/app/pages/resources/resources-page.html + 92 + + + + Membership + 会员资格 + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 23 + + + apps/client/src/app/pages/user-account/user-account-page.component.ts + 40 + + + + Access + 使用权 + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 28 + + + apps/client/src/app/pages/user-account/user-account-page.component.ts + 46 + + + + My Ghostfolio + 我的 Ghostfolio + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 33 + + + + Oops, authentication has failed. + 糟糕,身份验证失败。 + + apps/client/src/app/pages/webauthn/webauthn-page.html + 19 + + + + Try again + 再试一次 + + apps/client/src/app/pages/webauthn/webauthn-page.html + 27 + + + + Go back to Home Page + 返回首页 + + apps/client/src/app/pages/webauthn/webauthn-page.html + 31 + + + + Do you really want to delete this account balance? + 您确实要删除该帐户余额吗? + + libs/ui/src/lib/account-balances/account-balances.component.ts + 58 + + + + Import Activities + 进口活动 + + libs/ui/src/lib/activities-table/activities-table.component.html + 9 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 369 + + + + Import Dividends + 导入股息 + + libs/ui/src/lib/activities-table/activities-table.component.html + 29 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 381 + + + + Export Activities + 出口活动 + + libs/ui/src/lib/activities-table/activities-table.component.html + 41 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 394 + + + + Export Drafts as ICS + 将汇票导出为 ICS + + libs/ui/src/lib/activities-table/activities-table.component.html + 54 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 407 + + + + Delete all Activities + 删除所有活动 + + libs/ui/src/lib/activities-table/activities-table.component.html + 65 + + + + Draft + 草稿 + + libs/ui/src/lib/activities-table/activities-table.component.html + 143 + + + + Clone + 克隆 + + libs/ui/src/lib/activities-table/activities-table.component.html + 434 + + + + Export Draft as ICS + 将汇票导出为 ICS + + libs/ui/src/lib/activities-table/activities-table.component.html + 444 + + + + Do you really want to delete this activity? + 您确实要删除此活动吗? + + libs/ui/src/lib/activities-table/activities-table.component.ts + 175 + + + + Find holding... + 查找持有... + + libs/ui/src/lib/assistant/assistant.component.ts + 126 + + + + No entries... + 没有条目... + + libs/ui/src/lib/assistant/assistant.html + 63 + + + libs/ui/src/lib/assistant/assistant.html + 84 + + + + Asset Profiles + 资产概况 + + libs/ui/src/lib/assistant/assistant.html + 67 + + + + Index + 指数 + + libs/ui/src/lib/benchmark/benchmark.component.html + 3 + + + + 50-Day Trend + 50 天趋势 + + libs/ui/src/lib/benchmark/benchmark.component.html + 15 + + + + 200-Day Trend + 200天趋势 + + libs/ui/src/lib/benchmark/benchmark.component.html + 40 + + + + Last All Time High + 上次历史最高纪录 + + libs/ui/src/lib/benchmark/benchmark.component.html + 65 + + + + Change from All Time High + 从历史最高点开始变化 + + libs/ui/src/lib/benchmark/benchmark.component.html + 81 + + + + from ATH + 来自 ATH + + libs/ui/src/lib/benchmark/benchmark.component.html + 83 + + + + Market data provided by + 市场数据提供者 + + libs/ui/src/lib/data-provider-credits/data-provider-credits.component.html + 2 + + + + Savings Rate per Month + 每月储蓄率 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 10 + + + + Annual Interest Rate + 年利率 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 21 + + + + Retirement Date + 退休日期 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 32 + + + + Projected Total Amount + 预计总额 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 60 + + + + Interest + 利息 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.ts + 342 + + + libs/ui/src/lib/i18n.ts + 33 + + + + Savings + 储蓄 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.ts + 352 + + + + Allocation + 分配 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 98 + + + + Show all + 显示所有 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 174 + + + + Account + 帐户 + + libs/ui/src/lib/i18n.ts + 4 + + + + Asia-Pacific + 亚太 + + libs/ui/src/lib/i18n.ts + 5 + + + + Asset Class + 资产类别 + + libs/ui/src/lib/i18n.ts + 6 + + + + Asset Sub Class + 资产子类别 + + libs/ui/src/lib/i18n.ts + 7 + + + + Core + 核心 + + libs/ui/src/lib/i18n.ts + 8 + + + + Switch to Ghostfolio Premium or Ghostfolio Open Source easily + 轻松切换到 Ghostfolio Premium 或 Ghostfolio Open Source + + libs/ui/src/lib/i18n.ts + 9 + + + + Switch to Ghostfolio Premium easily + 轻松切换到 Ghostfolio Premium + + libs/ui/src/lib/i18n.ts + 10 + + + + Switch to Ghostfolio Open Source or Ghostfolio Basic easily + 轻松切换到 Ghostfolio Open Source 或 Ghostfolio Basic + + libs/ui/src/lib/i18n.ts + 11 + + + + Emergency Fund + 应急基金 + + libs/ui/src/lib/i18n.ts + 12 + + + + Grant + 授予 + + libs/ui/src/lib/i18n.ts + 13 + + + + Higher Risk + 风险较高 + + libs/ui/src/lib/i18n.ts + 14 + + + + This activity already exists. + 这项活动已经存在。 + + libs/ui/src/lib/i18n.ts + 15 + + + + Japan + 日本 + + libs/ui/src/lib/i18n.ts + 16 + + + + Lower Risk + 降低风险 + + libs/ui/src/lib/i18n.ts + 17 + + + + Month + + + libs/ui/src/lib/i18n.ts + 18 + + + + Months + 几个月 + + libs/ui/src/lib/i18n.ts + 19 + + + + Other + 其他 + + libs/ui/src/lib/i18n.ts + 20 + + + libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts + 385 + + + + Preset + 预设 + + libs/ui/src/lib/i18n.ts + 21 + + + + Retirement Provision + 退休金 + + libs/ui/src/lib/i18n.ts + 22 + + + + Satellite + 卫星 + + libs/ui/src/lib/i18n.ts + 23 + + + + Symbol + 符号 + + libs/ui/src/lib/i18n.ts + 24 + + + + Tag + 标签 + + libs/ui/src/lib/i18n.ts + 25 + + + + Year + + + libs/ui/src/lib/i18n.ts + 26 + + + + Years + + + libs/ui/src/lib/i18n.ts + 27 + + + + Buy + + + libs/ui/src/lib/i18n.ts + 30 + + + + Fee + 费用 + + libs/ui/src/lib/i18n.ts + 32 + + + + Valuable + 有价值的 + + libs/ui/src/lib/i18n.ts + 34 + + + + Liability + 责任 + + libs/ui/src/lib/i18n.ts + 35 + + + + Sell + + + libs/ui/src/lib/i18n.ts + 36 + + + + Cash + 现金 + + libs/ui/src/lib/i18n.ts + 39 + + + + Commodity + 商品 + + libs/ui/src/lib/i18n.ts + 40 + + + + Equity + 公平 + + libs/ui/src/lib/i18n.ts + 41 + + + + Fixed Income + 固定收入 + + libs/ui/src/lib/i18n.ts + 42 + + + + Real Estate + 房地产 + + libs/ui/src/lib/i18n.ts + 43 + + + + Bond + 纽带 + + libs/ui/src/lib/i18n.ts + 46 + + + + Cryptocurrency + 加密货币 + + libs/ui/src/lib/i18n.ts + 47 + + + + ETF + 交易所交易基金 + + libs/ui/src/lib/i18n.ts + 48 + + + + Mutual Fund + 共同基金 + + libs/ui/src/lib/i18n.ts + 49 + + + + Precious Metal + 贵金属 + + libs/ui/src/lib/i18n.ts + 50 + + + + Private Equity + 私人产权 + + libs/ui/src/lib/i18n.ts + 51 + + + + Stock + 库存 + + libs/ui/src/lib/i18n.ts + 52 + + + + Africa + 非洲 + + libs/ui/src/lib/i18n.ts + 59 + + + + Asia + 亚洲 + + libs/ui/src/lib/i18n.ts + 60 + + + + Europe + 欧洲 + + libs/ui/src/lib/i18n.ts + 61 + + + + North America + 北美 + + libs/ui/src/lib/i18n.ts + 62 + + + + Oceania + 大洋洲 + + libs/ui/src/lib/i18n.ts + 63 + + + + South America + 南美洲 + + libs/ui/src/lib/i18n.ts + 64 + + + + Extreme Fear + 极度恐惧 + + libs/ui/src/lib/i18n.ts + 67 + + + + Extreme Greed + 极度贪婪 + + libs/ui/src/lib/i18n.ts + 68 + + + + Neutral + 中性的 + + libs/ui/src/lib/i18n.ts + 71 + + + + Membership + 会员资格 + + libs/ui/src/lib/membership-card/membership-card.component.html + 18 + + + + Valid until + 有效期至 + + libs/ui/src/lib/membership-card/membership-card.component.html + 23 + + + + Time to add your first activity. + 是时候添加您的第一个活动了。 + + libs/ui/src/lib/no-transactions-info/no-transactions-info.component.html + 12 + + + + No data available + 无可用数据 + + libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts + 387 + + + libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts + 400 + + + + If a translation is missing, kindly support us in extending it here. + 如果翻译缺失,请支持我们进行扩展这里 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 55 + + + + Date Range + 日期范围 + + libs/ui/src/lib/assistant/assistant.html + 93 + + + + The current market price is + 当前市场价格为 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts + 317 + + + + Test + 测试 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 288 + + + + Oops! Could not grant access. + 哎呀!无法授予访问权限。 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts + 80 + + + + Restricted view + 视野受限 + + apps/client/src/app/components/access-table/access-table.component.html + 25 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 36 + + + + Permission + 允许 + + apps/client/src/app/components/access-table/access-table.component.html + 17 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 33 + + + + Private + 私人的 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 24 + + + + Job Queue + 作业队列 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 25 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 42 + + + + Market data is delayed for + 市场数据延迟 + + apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts + 82 + + + + Absolute Currency Performance + 绝对货币表现 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 73 + + + + Absolute Net Performance + 绝对净性能 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 121 + + + + Absolute Asset Performance + 绝对资产绩效 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 29 + + + + Investment + 投资 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 46 + + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 60 + + + + Asset Performance + 资产绩效 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 51 + + + + Net Performance + 净绩效 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 140 + + + + Currency Performance + 货币表现 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 98 + + + + Year to date + 今年迄今为止 + + libs/ui/src/lib/assistant/assistant.component.ts + 109 + + + + Week to date + 本周至今 + + libs/ui/src/lib/assistant/assistant.component.ts + 101 + + + + Month to date + 本月至今 + + libs/ui/src/lib/assistant/assistant.component.ts + 105 + + + + MTD + 最大输运量 + + libs/ui/src/lib/assistant/assistant.component.ts + 105 + + + + WTD + 世界贸易组织 + + libs/ui/src/lib/assistant/assistant.component.ts + 101 + + + + Oops! A data provider is experiencing the hiccups. + 哎呀!数据提供商遇到了问题。 + + apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html + 8 + + + + View + 看法 + + apps/client/src/app/components/access-table/access-table.component.html + 22 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 39 + + + + Reset Filters + 重置过滤器 + + libs/ui/src/lib/assistant/assistant.html + 155 + + + + If you retire today, you would be able to withdraw per year or per month, based on your total assets of and a withdrawal rate of 4%. + 如果你今天退休,你可以领取每年或者每月,根据您的总资产提款率为4%。 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 68 + + + + year + + + libs/ui/src/lib/assistant/assistant.component.ts + 112 + + + + years + + + libs/ui/src/lib/assistant/assistant.component.ts + 114 + + + + Apply Filters + 应用过滤器 + + libs/ui/src/lib/assistant/assistant.html + 165 + + + + Asset Classes + 资产类别 + + libs/ui/src/lib/assistant/assistant.html + 138 + + + + self-hosting + 自托管 + + apps/client/src/app/pages/faq/faq-page.component.ts + 48 + + + + FAQ + 常见问题 + + apps/client/src/app/pages/faq/saas/saas-page-routing.module.ts + 13 + + + apps/client/src/app/pages/faq/self-hosting/self-hosting-page-routing.module.ts + 13 + + + + Self-Hosting + 自托管 + + apps/client/src/app/pages/faq/faq-page.component.ts + 47 + + + apps/client/src/app/pages/faq/self-hosting/self-hosting-page-routing.module.ts + 13 + + + + Data Gathering + 数据收集 + + apps/client/src/app/components/admin-overview/admin-overview.html + 134 + + + + General + 一般的 + + apps/client/src/app/pages/faq/faq-page.component.ts + 36 + + + + Cloud + + + apps/client/src/app/pages/faq/faq-page.component.ts + 41 + + + apps/client/src/app/pages/faq/saas/saas-page-routing.module.ts + 13 + + + + Oops! It looks like you’re making too many requests. Please slow down a bit. + 哎呀!看来您提出了太多要求。请慢一点。 + + apps/client/src/app/core/http-response.interceptor.ts + 105 + + + + My Account + 我的账户 + + apps/client/src/app/pages/i18n/i18n-page.html + 13 + + + + Closed + 关闭 + + apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + 31 + + + + Active + 积极的 + + apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + 30 + + + + Activity + 活动 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 176 + + From 084467ee9adce35f2099d4e8ea1119e55ff40cb7 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 31 Mar 2024 11:24:50 +0200 Subject: [PATCH 03/14] Feature/reverse order of specific years in date range selector of assistant (#3221) * Reverse order * Update changelog --- CHANGELOG.md | 6 +++++- libs/ui/src/lib/assistant/assistant.component.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39cefd95f..ce6ec2a7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Set up the language localization for Chinese (`zh`) +### Changed + +- Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) + ## 2.69.0 - 2024-03-30 ### Added - Added the date range support in the activities table on the portfolio activities page (experimental) -- Extended the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) +- Extended the date range support by specific years (`2021`, `2022`, `2023`, etc.) in the assistant (experimental) - Set up `Tini` to avoid zombie processes and perform signal forwarding in docker image ### Changed diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index bd8355125..310bede05 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -219,6 +219,7 @@ export class AssistantComponent implements OnChanges, OnDestroy, OnInit { return { label: format(date, 'yyyy'), value: format(date, 'yyyy') }; }) .slice(0, -1) + .reverse() ); } From 34997f91db6faac15821d6176a799c65360638f9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 31 Mar 2024 11:38:09 +0200 Subject: [PATCH 04/14] Feature/setup webpack bundle analyzer (#3222) * Set up Webpack Bundle Analyzer * Update changelog --- CHANGELOG.md | 1 + package.json | 4 ++- yarn.lock | 78 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce6ec2a7d..1ce4ef296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Set up the language localization for Chinese (`zh`) +- Set up _Webpack Bundle Analyzer_ ### Changed diff --git a/package.json b/package.json index aa9bf0fd0..05ffd3e49 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "affected:libs": "nx affected:libs", "affected:lint": "nx affected:lint", "affected:test": "nx affected:test", + "analyze:client": "nx run client:build:production --stats-json && webpack-bundle-analyzer -p 1234 dist/apps/client/en/stats.json", "angular": "node --max_old_space_size=32768 ./node_modules/@angular/cli/bin/ng", "build:production": "nx run api:copy-assets && nx run api:build:production && nx run client:copy-assets && nx run client:build:production && yarn replace-placeholders-in-build", "build:storybook": "nx run ui:build-storybook", @@ -197,7 +198,8 @@ "ts-jest": "29.1.0", "ts-node": "10.9.1", "tslib": "2.6.0", - "typescript": "5.3.3" + "typescript": "5.3.3", + "webpack-bundle-analyzer": "4.10.1" }, "engines": { "node": ">=18" diff --git a/yarn.lock b/yarn.lock index 03e4cca81..ee83c3606 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5352,6 +5352,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@polka/url@^1.0.0-next.24": + version "1.0.0-next.25" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.25.tgz#f077fdc0b5d0078d30893396ff4827a13f99e817" + integrity sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ== + "@prisma/client@5.11.0": version "5.11.0" resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.11.0.tgz#d8e55fab85163415b2245fb408b9106f83c8106d" @@ -8039,11 +8044,21 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn-walk@^8.0.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + acorn-walk@^8.0.2, acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== +acorn@^8.0.4: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + acorn@^8.1.0, acorn@^8.10.0, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: version "8.10.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" @@ -10474,6 +10489,11 @@ dayjs@^1.11.7: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -10849,7 +10869,7 @@ dotenv@^16.0.0, dotenv@~16.3.1: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== -duplexer@^0.1.1: +duplexer@^0.1.1, duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== @@ -12455,6 +12475,13 @@ gunzip-maybe@^1.4.2: pumpify "^1.3.3" through2 "^2.0.3" +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -12596,7 +12623,7 @@ html-entities@^2.1.0, html-entities@^2.3.2: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== -html-escaper@^2.0.0: +html-escaper@^2.0.0, html-escaper@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== @@ -13207,6 +13234,11 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" @@ -15122,7 +15154,7 @@ mri@^1.1.0, mri@^1.2.0: resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== -mrmime@2.0.0: +mrmime@2.0.0, mrmime@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.0.tgz#151082a6e06e59a9a39b46b3e14d5cfe92b3abb4" integrity sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw== @@ -15693,7 +15725,7 @@ open@^7.0.3: is-docker "^2.0.0" is-wsl "^2.1.1" -opener@^1.5.1: +opener@^1.5.1, opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== @@ -17649,6 +17681,15 @@ simple-update-notifier@^2.0.0: dependencies: semver "^7.5.3" +sirv@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0" + integrity sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ== + dependencies: + "@polka/url" "^1.0.0-next.24" + mrmime "^2.0.0" + totalist "^3.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -18377,6 +18418,11 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== + tough-cookie-file-store@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/tough-cookie-file-store/-/tough-cookie-file-store-2.0.3.tgz#788f7a6fe5cd8f61a1afb71b2f0b964ebf914b80" @@ -19080,6 +19126,25 @@ webidl-conversions@^7.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== +webpack-bundle-analyzer@4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz#84b7473b630a7b8c21c741f81d8fe4593208b454" + integrity sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ== + dependencies: + "@discoveryjs/json-ext" "0.5.7" + acorn "^8.0.4" + acorn-walk "^8.0.0" + commander "^7.2.0" + debounce "^1.2.1" + escape-string-regexp "^4.0.0" + gzip-size "^6.0.0" + html-escaper "^2.0.2" + is-plain-object "^5.0.0" + opener "^1.5.2" + picocolors "^1.0.0" + sirv "^2.0.3" + ws "^7.3.1" + webpack-dev-middleware@6.1.1, webpack-dev-middleware@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz#6bbc257ec83ae15522de7a62f995630efde7cc3d" @@ -19409,6 +19474,11 @@ ws@^6.1.0: dependencies: async-limiter "~1.0.0" +ws@^7.3.1: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + ws@^8.11.0, ws@^8.13.0, ws@^8.2.3: version "8.14.2" resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" From 0c684748025d26e0b22182ea71f98288d67ae668 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 31 Mar 2024 11:41:44 +0200 Subject: [PATCH 05/14] Extract locales (#3223) --- apps/client/src/locales/messages.de.xlf | 200 ++++++++------- apps/client/src/locales/messages.es.xlf | 200 ++++++++------- apps/client/src/locales/messages.fr.xlf | 200 ++++++++------- apps/client/src/locales/messages.it.xlf | 200 ++++++++------- apps/client/src/locales/messages.nl.xlf | 200 ++++++++------- apps/client/src/locales/messages.pl.xlf | 200 ++++++++------- apps/client/src/locales/messages.pt.xlf | 200 ++++++++------- apps/client/src/locales/messages.tr.xlf | 200 ++++++++------- apps/client/src/locales/messages.xlf | 200 ++++++++------- apps/client/src/locales/messages.zh.xlf | 318 ++++++++++++------------ 10 files changed, 1099 insertions(+), 1019 deletions(-) diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index bbe0d1edd..58b55bc01 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -22,7 +22,7 @@ Das Ausfallrisiko beim Börsenhandel kann erheblich sein. Es ist nicht ratsam, Geld zu investieren, welches du kurzfristig benötigst. apps/client/src/app/app.component.html - 179 + 184 @@ -94,7 +94,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -130,7 +130,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -270,7 +270,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -326,7 +330,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -474,7 +478,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -490,7 +494,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -518,7 +522,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -534,7 +538,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -554,7 +558,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -582,7 +586,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1492,11 +1496,11 @@ Sektoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1512,11 +1516,11 @@ Länder apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1592,7 +1596,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1604,7 +1608,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1616,7 +1620,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1628,7 +1632,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1640,7 +1644,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1876,7 +1880,7 @@ Möchtest du diese Anmeldemethode wirklich löschen? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1948,7 +1952,7 @@ Lokalität apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1956,7 +1960,7 @@ Datums- und Zahlenformat apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1964,7 +1968,7 @@ Zen Modus apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1976,7 +1980,7 @@ Einloggen mit Fingerabdruck apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1984,11 +1988,11 @@ Benutzer ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2056,11 +2060,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2496,7 +2500,7 @@ Kommentar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2516,11 +2520,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2572,7 +2576,7 @@ Portfolio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2880,11 +2884,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2900,7 +2904,7 @@ Sektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2912,7 +2916,7 @@ Land apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2972,7 +2976,7 @@ Monatlich apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3048,7 +3052,7 @@ Filtern nach... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3076,7 +3080,7 @@ Experimentelle Funktionen apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3092,7 +3096,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3124,7 +3128,7 @@ Aussehen apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3132,7 +3136,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3140,7 +3144,7 @@ Hell apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3148,7 +3152,7 @@ Dunkel apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3156,7 +3160,7 @@ Gesamtbetrag apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3172,7 +3176,7 @@ Sparrate apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3412,31 +3416,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3464,7 +3472,7 @@ Symbol Zuordnung apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3480,7 +3488,7 @@ Dividenden apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3516,7 +3524,7 @@ Importieren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3584,7 +3592,7 @@ Jährlich apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3664,7 +3672,7 @@ Unbeschwertes Erlebnis für turbulente Zeiten apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3672,7 +3680,7 @@ Vorschau auf kommende Funktionalität apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4100,7 +4108,7 @@ Möchtest du wirklich alle Aktivitäten löschen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4524,7 +4532,7 @@ Scraper Konfiguration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9868,7 +9876,7 @@ ETFs ohne Länder apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9876,7 +9884,7 @@ ETFs ohne Sektoren apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10008,7 +10016,7 @@ Biometrische Authentifizierung apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10092,7 +10100,7 @@ Daten exportieren apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10100,7 +10108,7 @@ Währungen apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10480,7 +10488,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10512,7 +10520,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10772,19 +10780,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11052,7 +11060,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11068,7 +11076,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11084,7 +11092,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11116,7 +11124,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11188,7 +11196,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11224,7 +11232,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13344,7 +13352,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13424,7 +13432,7 @@ Finde Position... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13451,8 +13459,8 @@ Do you really want to delete this asset profile? Möchtest du dieses Anlageprofil wirklich löschen? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13776,7 +13784,7 @@ Ups! Die historischen Daten konnten nicht geparsed werden. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14648,7 +14656,7 @@ Der aktuelle Marktpreis ist apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14656,7 +14664,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14732,11 +14740,11 @@ Einlage apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14792,7 +14800,7 @@ Seit Wochenbeginn libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14800,7 +14808,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14808,7 +14816,7 @@ Seit Monatsbeginn libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14816,7 +14824,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14824,7 +14832,7 @@ Seit Jahresbeginn libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14836,7 +14844,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14868,7 +14876,7 @@ Jahr libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14876,7 +14884,7 @@ Jahre libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 6535d4034..6f4bd17fc 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -23,7 +23,7 @@ El riesgo de pérdida en trading puede ser importante. No es aconsejable invertir dinero que puedas necesitar a corto plazo. apps/client/src/app/app.component.html - 179 + 184 @@ -95,7 +95,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -131,7 +131,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -271,7 +271,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -327,7 +331,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -475,7 +479,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -491,7 +495,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -519,7 +523,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -535,7 +539,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -555,7 +559,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -583,7 +587,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1490,11 +1494,11 @@ Sectores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1510,11 +1514,11 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1590,7 +1594,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1602,7 +1606,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1614,7 +1618,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1626,7 +1630,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1638,7 +1642,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1874,7 +1878,7 @@ ¿Estás seguro de eliminar este método de acceso? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1946,7 +1950,7 @@ Ubicación apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1954,7 +1958,7 @@ Formato de fecha y número apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1962,7 +1966,7 @@ Modo Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1974,7 +1978,7 @@ Accede con huella digital apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1982,11 +1986,11 @@ ID usuario apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2054,11 +2058,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2494,7 +2498,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2514,11 +2518,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2570,7 +2574,7 @@ Cartera apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2866,11 +2870,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2926,7 +2930,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2938,7 +2942,7 @@ País apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2998,7 +3002,7 @@ Mensual apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3046,7 +3050,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3074,7 +3078,7 @@ Funcionalidades experimentales apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3082,7 +3086,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3122,7 +3126,7 @@ Apariencia apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3130,7 +3134,7 @@ Automático apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3138,7 +3142,7 @@ Claro apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3146,7 +3150,7 @@ Oscuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3154,7 +3158,7 @@ Importe total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3170,7 +3174,7 @@ Tasa de ahorro apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3410,31 +3414,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3462,7 +3470,7 @@ Mapeo de símbolos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3470,7 +3478,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3514,7 +3522,7 @@ Import apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3582,7 +3590,7 @@ Yearly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3662,7 +3670,7 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3670,7 +3678,7 @@ Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4098,7 +4106,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4522,7 +4530,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9866,7 +9874,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9874,7 +9882,7 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10006,7 +10014,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10090,7 +10098,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10098,7 +10106,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10478,7 +10486,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10510,7 +10518,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10770,19 +10778,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11050,7 +11058,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11066,7 +11074,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11082,7 +11090,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11114,7 +11122,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11186,7 +11194,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11222,7 +11230,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13342,7 +13350,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13422,7 +13430,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13449,8 +13457,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13774,7 +13782,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14646,7 +14654,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14654,7 +14662,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14730,11 +14738,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14790,7 +14798,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14798,7 +14806,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14806,7 +14814,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14814,7 +14822,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14822,7 +14830,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14834,7 +14842,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14866,7 +14874,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14874,7 +14882,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 9faea802b..fd2fdae57 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -6,7 +6,7 @@ Le risque de perte en investissant peut être important. Il est déconseillé d'investir de l'argent dont vous pourriez avoir besoin à court terme. apps/client/src/app/app.component.html - 179 + 184 @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -142,7 +142,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -194,11 +194,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -326,7 +326,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -374,7 +378,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -530,7 +534,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -546,7 +550,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -574,7 +578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -590,7 +594,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -606,7 +610,7 @@ Filtrer par... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -618,11 +622,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -642,11 +646,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -666,7 +670,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -694,7 +698,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -754,7 +758,7 @@ Secteur apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -766,7 +770,7 @@ Pays apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -782,11 +786,11 @@ Secteurs apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -802,11 +806,11 @@ Pays apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -818,7 +822,7 @@ Équivalence de Symboles apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -826,7 +830,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1102,7 +1106,7 @@ Portefeuille apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -1114,7 +1118,7 @@ Référence apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -1602,7 +1606,7 @@ Montant Total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -1610,7 +1614,7 @@ Taux d'Épargne apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -1921,7 +1925,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1933,7 +1937,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1945,7 +1949,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1957,7 +1961,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1969,7 +1973,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -2137,7 +2141,7 @@ Voulez-vous vraiment supprimer cette méthode de connexion ? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -2221,31 +2225,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -2257,7 +2265,7 @@ Paramètres régionaux apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -2265,7 +2273,7 @@ Format de date et d'heure apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -2273,7 +2281,7 @@ Apparence apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -2281,7 +2289,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2289,7 +2297,7 @@ Clair apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -2297,7 +2305,7 @@ Sombre apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -2305,7 +2313,7 @@ Mode Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -2317,7 +2325,7 @@ Se connecter avec empreinte apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -2325,7 +2333,7 @@ Fonctionnalités expérimentales apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -2333,11 +2341,11 @@ ID d'utilisateur apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2745,7 +2753,7 @@ Importer apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2905,7 +2913,7 @@ Dividende apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -2925,7 +2933,7 @@ Mensuel apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3581,7 +3589,7 @@ Annuel apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3661,7 +3669,7 @@ Expérience sans distraction pour les périodes tumultueuses apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3669,7 +3677,7 @@ Avant-première de fonctionnalités futures apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4097,7 +4105,7 @@ Voulez-vous vraiment supprimer toutes vos activités ? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4521,7 +4529,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9865,7 +9873,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9873,7 +9881,7 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10005,7 +10013,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10089,7 +10097,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10097,7 +10105,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10477,7 +10485,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10509,7 +10517,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10769,19 +10777,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11049,7 +11057,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11065,7 +11073,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11081,7 +11089,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11113,7 +11121,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11185,7 +11193,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11221,7 +11229,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 581bdc55c..283dcd868 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -23,7 +23,7 @@ Il rischio di perdita nel trading può essere notevole. Non è consigliabile investire denaro di cui potresti avere bisogno a breve termine. apps/client/src/app/app.component.html - 179 + 184 @@ -95,7 +95,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -131,7 +131,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -271,7 +271,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -327,7 +331,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -475,7 +479,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -491,7 +495,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -519,7 +523,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -535,7 +539,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -555,7 +559,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -583,7 +587,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1490,11 +1494,11 @@ Settori apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1510,11 +1514,11 @@ Paesi apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1590,7 +1594,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1602,7 +1606,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1614,7 +1618,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1626,7 +1630,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1638,7 +1642,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1874,7 +1878,7 @@ Vuoi davvero rimuovere questo metodo di accesso? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1946,7 +1950,7 @@ Locale apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1954,7 +1958,7 @@ Formato data e numero apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1962,7 +1966,7 @@ Modalità Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1974,7 +1978,7 @@ Accesso con impronta digitale apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1982,11 +1986,11 @@ ID utente apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2054,11 +2058,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2494,7 +2498,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2514,11 +2518,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2570,7 +2574,7 @@ Portafoglio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2866,11 +2870,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2926,7 +2930,7 @@ Settore apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2938,7 +2942,7 @@ Paese apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2998,7 +3002,7 @@ Mensile apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3046,7 +3050,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3074,7 +3078,7 @@ Funzionalità sperimentali apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3082,7 +3086,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3122,7 +3126,7 @@ Aspetto apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3130,7 +3134,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3138,7 +3142,7 @@ Chiaro apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3146,7 +3150,7 @@ Scuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3154,7 +3158,7 @@ Importo totale apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3170,7 +3174,7 @@ Tasso di risparmio apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3410,31 +3414,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3462,7 +3470,7 @@ Mappatura dei simboli apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3470,7 +3478,7 @@ Dividendi apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3514,7 +3522,7 @@ Importa apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3582,7 +3590,7 @@ Annuale apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3662,7 +3670,7 @@ Esperienza priva di distrazioni per i periodi più turbolenti apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3670,7 +3678,7 @@ Un'anteprima delle funzionalità in arrivo apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4098,7 +4106,7 @@ Vuoi davvero eliminare tutte le tue attività? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4522,7 +4530,7 @@ Configurazione dello scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9866,7 +9874,7 @@ ETF senza paesi apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9874,7 +9882,7 @@ ETF senza settori apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10006,7 +10014,7 @@ Autenticazione biometrica apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10090,7 +10098,7 @@ Esporta dati apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10098,7 +10106,7 @@ Valute apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10478,7 +10486,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10510,7 +10518,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10770,19 +10778,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11050,7 +11058,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11066,7 +11074,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11082,7 +11090,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11114,7 +11122,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11186,7 +11194,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11222,7 +11230,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13342,7 +13350,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13422,7 +13430,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13449,8 +13457,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13774,7 +13782,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14646,7 +14654,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14654,7 +14662,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14730,11 +14738,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14790,7 +14798,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14798,7 +14806,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14806,7 +14814,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14814,7 +14822,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14822,7 +14830,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14834,7 +14842,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14866,7 +14874,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14874,7 +14882,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 39d0d9532..4a2874300 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -22,7 +22,7 @@ Het risico op verlies bij handelen kan aanzienlijk zijn. Het is niet aan te raden om geld te investeren dat je misschien op korte termijn nodig heeft. apps/client/src/app/app.component.html - 179 + 184 @@ -94,7 +94,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -130,7 +130,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -270,7 +270,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -326,7 +330,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -474,7 +478,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -490,7 +494,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -518,7 +522,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -534,7 +538,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -554,7 +558,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -582,7 +586,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1489,11 +1493,11 @@ Sectoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1509,11 +1513,11 @@ Landen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1589,7 +1593,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1601,7 +1605,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1613,7 +1617,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1625,7 +1629,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1637,7 +1641,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1873,7 +1877,7 @@ Wil je deze aanmeldingsmethode echt verwijderen? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1945,7 +1949,7 @@ Locatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1953,7 +1957,7 @@ Datum- en getalnotatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1961,7 +1965,7 @@ Zen-modus apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1973,7 +1977,7 @@ Aanmelden met vingerafdruk apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1981,11 +1985,11 @@ Gebruikers-ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2053,11 +2057,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2493,7 +2497,7 @@ Opmerking apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2513,11 +2517,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2569,7 +2573,7 @@ Portefeuille apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2865,11 +2869,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2925,7 +2929,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2937,7 +2941,7 @@ Land apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2997,7 +3001,7 @@ Maandelijks apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3045,7 +3049,7 @@ Filter op... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3073,7 +3077,7 @@ Experimentele functies apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3081,7 +3085,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3121,7 +3125,7 @@ Weergave apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3129,7 +3133,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3137,7 +3141,7 @@ Licht apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3145,7 +3149,7 @@ Donker apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3153,7 +3157,7 @@ Totaalbedrag apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3169,7 +3173,7 @@ Spaarrente apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3409,31 +3413,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3461,7 +3469,7 @@ Symbool toewijzen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3469,7 +3477,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3513,7 +3521,7 @@ Importeren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3581,7 +3589,7 @@ Jaarlijks apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3661,7 +3669,7 @@ Afleidingsvrije ervaring voor roerige tijden apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3669,7 +3677,7 @@ Voorproefje van nieuwe functionaliteit apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4097,7 +4105,7 @@ Wil je echt al je activiteiten verwijderen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4521,7 +4529,7 @@ Scraper instellingen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9865,7 +9873,7 @@ ETF's zonder Landen apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9873,7 +9881,7 @@ ETF's zonder Sectoren apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10005,7 +10013,7 @@ Biometrische authenticatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10089,7 +10097,7 @@ Exporteer Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10097,7 +10105,7 @@ Valuta apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10477,7 +10485,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10509,7 +10517,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10769,19 +10777,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11049,7 +11057,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11065,7 +11073,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11081,7 +11089,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11113,7 +11121,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11185,7 +11193,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11221,7 +11229,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index f59f2652a..5a1611384 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -10,19 +10,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -290,7 +290,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -322,7 +322,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -582,7 +582,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -598,7 +598,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -630,7 +630,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -702,7 +702,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -718,7 +718,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -754,7 +754,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1462,31 +1462,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1498,7 +1502,7 @@ The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term. apps/client/src/app/app.component.html - 179 + 184 @@ -1606,7 +1610,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1670,7 +1674,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1722,11 +1726,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1838,7 +1842,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1902,7 +1910,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2042,7 +2050,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2058,7 +2066,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2086,7 +2094,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2102,7 +2110,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2118,7 +2126,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -2126,7 +2134,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -2134,15 +2142,15 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -2150,7 +2158,7 @@ Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2162,11 +2170,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2186,11 +2194,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2210,7 +2218,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2238,7 +2246,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2290,7 +2298,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -2314,7 +2322,7 @@ Import apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2330,7 +2338,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2342,7 +2350,7 @@ Country apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2358,11 +2366,11 @@ Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2378,11 +2386,11 @@ Countries apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2394,7 +2402,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -2402,7 +2410,7 @@ Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -2410,7 +2418,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -2418,7 +2426,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2854,7 +2862,7 @@ Portfolio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2866,7 +2874,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3154,7 +3162,7 @@ Total Amount apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3162,7 +3170,7 @@ Savings Rate apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3676,7 +3684,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3688,7 +3696,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3700,7 +3708,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3712,7 +3720,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3724,7 +3732,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3824,7 +3832,7 @@ Do you really want to remove this sign in method? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -3872,7 +3880,7 @@ Locale apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -3880,7 +3888,7 @@ Date and number format apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -3888,7 +3896,7 @@ Appearance apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3896,7 +3904,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3904,7 +3912,7 @@ Light apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3912,7 +3920,7 @@ Dark apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3920,7 +3928,7 @@ Zen Mode apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -3932,7 +3940,7 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3940,7 +3948,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -3948,7 +3956,7 @@ Sign in with fingerprint apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -3956,7 +3964,7 @@ Experimental Features apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3964,7 +3972,7 @@ Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -3972,11 +3980,11 @@ User ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -3984,7 +3992,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -4940,7 +4948,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -5372,7 +5380,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -5392,7 +5400,7 @@ Monthly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -5400,7 +5408,7 @@ Yearly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -13216,7 +13224,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -14648,7 +14656,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14656,7 +14664,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14732,11 +14740,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14792,7 +14800,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14800,7 +14808,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14808,7 +14816,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14816,7 +14824,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14824,7 +14832,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14836,7 +14844,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14868,7 +14876,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14876,7 +14884,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 60d8a37cf..3970b11aa 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -6,7 +6,7 @@ O risco de perda em investimentos pode ser substancial. Não é aconselhável investir dinheiro que possa vir a precisar a curto prazo. apps/client/src/app/app.component.html - 179 + 184 @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -142,7 +142,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -194,11 +194,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -326,7 +326,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -374,7 +378,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -530,7 +534,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -546,7 +550,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -574,7 +578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -590,7 +594,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -606,7 +610,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -618,11 +622,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -642,11 +646,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -666,7 +670,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -694,7 +698,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -970,7 +974,7 @@ Portefólio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -982,7 +986,7 @@ Referência apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -1478,7 +1482,7 @@ Valor Total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -1486,7 +1490,7 @@ Taxa de Poupança apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -1785,7 +1789,7 @@ Setor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1797,7 +1801,7 @@ País apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -1813,11 +1817,11 @@ Setores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1833,11 +1837,11 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1897,7 +1901,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1909,7 +1913,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1921,7 +1925,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1933,7 +1937,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1945,7 +1949,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -2113,7 +2117,7 @@ Deseja realmente remover este método de início de sessão? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -2205,7 +2209,7 @@ Localidade apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -2213,7 +2217,7 @@ Formato de números e datas apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -2221,7 +2225,7 @@ Modo Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -2233,7 +2237,7 @@ Aparência apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -2241,7 +2245,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2249,7 +2253,7 @@ Claro apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -2257,7 +2261,7 @@ Escuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -2265,7 +2269,7 @@ Iniciar sessão com impressão digital apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -2273,7 +2277,7 @@ Funcionalidades Experimentais apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -2281,11 +2285,11 @@ ID do Utilizador apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2609,7 +2613,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2805,7 +2809,7 @@ Mensalmente apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3433,7 +3437,7 @@ Mapeamento de Símbolo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3453,31 +3457,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3521,7 +3529,7 @@ Importar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3537,7 +3545,7 @@ Dividendos apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3581,7 +3589,7 @@ Anualmente apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3661,7 +3669,7 @@ Experiência sem distrações para tempos turbulentos apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3669,7 +3677,7 @@ Acesso antecipado a funcionalidades futuras apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4097,7 +4105,7 @@ Deseja mesmo eliminar todas as suas atividades? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4521,7 +4529,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9865,7 +9873,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9873,7 +9881,7 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10005,7 +10013,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10089,7 +10097,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10097,7 +10105,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10477,7 +10485,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10509,7 +10517,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10769,19 +10777,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11049,7 +11057,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11065,7 +11073,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11081,7 +11089,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11113,7 +11121,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11185,7 +11193,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11221,7 +11229,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index ae9ae985c..2052e6667 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -10,19 +10,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -290,7 +290,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -322,7 +322,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -582,7 +582,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -598,7 +598,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -630,7 +630,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -702,7 +702,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -718,7 +718,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -754,7 +754,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1438,31 +1438,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1474,7 +1478,7 @@ Alım satımda kayıp riski büyük boyutta olabilir. Kısa vadede ihtiyaç duyabileceğiniz parayla yatırım yapmak tavsiye edilmez. apps/client/src/app/app.component.html - 179 + 184 @@ -1598,7 +1602,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1634,7 +1638,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1686,11 +1690,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1802,7 +1806,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1850,7 +1858,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2006,7 +2014,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2022,7 +2030,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2050,7 +2058,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2066,7 +2074,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2082,7 +2090,7 @@ Para Birimleri apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -2090,7 +2098,7 @@ Ülkesi Olmayan ETF'ler apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -2098,7 +2106,7 @@ Sektörü Olmayan ETF'ler apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -2106,7 +2114,7 @@ Filtrele... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2118,11 +2126,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2142,11 +2150,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2166,7 +2174,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2194,7 +2202,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2262,7 +2270,7 @@ Sektör apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2274,7 +2282,7 @@ Ülke apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2290,11 +2298,11 @@ Sektörler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2310,11 +2318,11 @@ Ülkeler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2326,7 +2334,7 @@ Sembol Eşleştirme apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -2334,7 +2342,7 @@ Veri Toplayıcı Yapılandırması apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -2342,7 +2350,7 @@ Not apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2714,7 +2722,7 @@ Portföy apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2726,7 +2734,7 @@ Karşılaştırma Ölçütü apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3006,7 +3014,7 @@ Toplam Tutar apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3014,7 +3022,7 @@ Tasarruf Oranı apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3517,7 +3525,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3529,7 +3537,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3541,7 +3549,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3553,7 +3561,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3565,7 +3573,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3941,7 +3949,7 @@ Zen Modu apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -4441,7 +4449,7 @@ Tüm işlemlerinizi silmeyi gerçekten istiyor musunuz? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4653,7 +4661,7 @@ İçe Aktar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -4849,7 +4857,7 @@ Temettü apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -4869,7 +4877,7 @@ Aylık apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -4877,7 +4885,7 @@ Yıllık apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -12353,7 +12361,7 @@ Bu giriş yöntemini kaldırmayı gerçekten istiyor musunuz? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -12437,7 +12445,7 @@ Yerel Ayarlar apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -12445,7 +12453,7 @@ Tarih ve Sayı Formatları apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -12453,7 +12461,7 @@ Görünüm apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -12461,7 +12469,7 @@ Otomatik apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -12469,7 +12477,7 @@ Açık apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -12477,7 +12485,7 @@ Koyu apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -12485,7 +12493,7 @@ Çalkantılı zamanlar için dikkat dağıtmayan bir deneyim apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -12493,7 +12501,7 @@ Biyometrik Kimlik Doğrulama apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -12501,7 +12509,7 @@ Parmak iziyle oturum aç apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -12509,7 +12517,7 @@ Deneysel Özellikler apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -12517,7 +12525,7 @@ Gelecek özelliklere göz atın apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -12525,11 +12533,11 @@ Kullanıcı Kimliği apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -12537,7 +12545,7 @@ Verileri Dışa Aktar apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index b5fca055a..1cb9af6dd 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -10,19 +10,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -289,7 +289,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -320,7 +320,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -579,7 +579,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -594,7 +594,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -625,7 +625,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -696,7 +696,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -711,7 +711,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -746,7 +746,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1440,31 +1440,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1475,7 +1479,7 @@ The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term. apps/client/src/app/app.component.html - 179 + 184 @@ -1574,7 +1578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1642,7 +1646,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1692,11 +1696,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1805,7 +1809,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1865,7 +1873,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1992,7 +2000,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2008,7 +2016,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2035,7 +2043,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2051,7 +2059,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2066,35 +2074,35 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2105,11 +2113,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2128,11 +2136,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2151,7 +2159,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2177,7 +2185,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2223,7 +2231,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -2244,7 +2252,7 @@ Import apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2259,7 +2267,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2270,7 +2278,7 @@ Country apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2285,11 +2293,11 @@ Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2304,11 +2312,11 @@ Countries apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2319,28 +2327,28 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2736,7 +2744,7 @@ Portfolio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2747,7 +2755,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3005,14 +3013,14 @@ Total Amount apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 Savings Rate apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3476,7 +3484,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3487,7 +3495,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3498,7 +3506,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3509,7 +3517,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3520,7 +3528,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3608,7 +3616,7 @@ Do you really want to remove this sign in method? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -3650,49 +3658,49 @@ Locale apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 Date and number format apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 Appearance apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 Light apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 Dark apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 Zen Mode apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -3703,53 +3711,53 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 Sign in with fingerprint apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 Experimental Features apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 User ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -4603,7 +4611,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4988,7 +4996,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -5006,14 +5014,14 @@ Monthly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 Yearly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -13533,7 +13541,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -14067,14 +14075,14 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14156,11 +14164,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14188,35 +14196,35 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14234,7 +14242,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14255,14 +14263,14 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 2887d5724..7ff1ce5bb 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -1,6 +1,6 @@ - + about @@ -11,19 +11,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -291,7 +291,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -323,7 +323,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -583,7 +583,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -599,7 +599,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -631,7 +631,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -703,7 +703,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -719,7 +719,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -755,7 +755,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1463,31 +1463,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1499,7 +1503,7 @@ 交易损失的风险可能很大。不建议将短期内可能需要的资金进行投资。 apps/client/src/app/app.component.html - 179 + 184 @@ -1607,7 +1611,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1679,7 +1683,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1731,11 +1735,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1847,7 +1851,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1911,7 +1919,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2003,8 +2011,8 @@ - Details for - 详细信息 + Details for + 详细信息 apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html 2 @@ -2051,7 +2059,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2067,7 +2075,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2095,7 +2103,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2111,7 +2119,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2127,7 +2135,7 @@ 货币 apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -2135,7 +2143,7 @@ 没有国家的 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -2143,15 +2151,15 @@ 无行业类别的 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 Do you really want to delete this asset profile? 您确实要删除此资产配置文件吗? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -2159,7 +2167,7 @@ 过滤... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2171,11 +2179,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2195,11 +2203,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2219,7 +2227,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2247,7 +2255,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2299,7 +2307,7 @@ 哎呀!无法解析历史数据。 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -2323,7 +2331,7 @@ 导入 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2339,7 +2347,7 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2351,7 +2359,7 @@ 国家 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2367,11 +2375,11 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2387,11 +2395,11 @@ 国家 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2403,7 +2411,7 @@ 基准 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -2411,7 +2419,7 @@ 符号映射 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -2419,7 +2427,7 @@ 刮削配置 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -2427,7 +2435,7 @@ 笔记 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2483,8 +2491,8 @@ - is an invalid currency! - 是无效的货币! + is an invalid currency! + 是无效的货币! apps/client/src/app/components/admin-overview/admin-overview.component.ts 129 @@ -2871,7 +2879,7 @@ 文件夹 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2883,7 +2891,7 @@ 基准 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3043,8 +3051,8 @@ - Last Days - 最后的 + Last Days + 最后的 apps/client/src/app/components/home-market/home-market.html 6 @@ -3171,7 +3179,7 @@ 总金额 apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3179,7 +3187,7 @@ 储蓄率 apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3252,12 +3260,12 @@ - - + + - - + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -3693,7 +3701,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3705,7 +3713,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3717,7 +3725,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3729,7 +3737,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3741,7 +3749,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3841,7 +3849,7 @@ 您确实要删除此登录方法吗? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -3889,7 +3897,7 @@ 语言环境 apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -3897,7 +3905,7 @@ 日期和数字格式 apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -3905,7 +3913,7 @@ 外貌 apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3913,7 +3921,7 @@ 自动 apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3921,7 +3929,7 @@ 明亮 apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3929,7 +3937,7 @@ 黑暗 apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3937,7 +3945,7 @@ 极简模式 apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -3949,7 +3957,7 @@ 动荡时期的无干扰体验 apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3957,7 +3965,7 @@ 生物识别认证 apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -3965,7 +3973,7 @@ 使用指纹登录 apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -3973,7 +3981,7 @@ 实验性功能 apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3981,7 +3989,7 @@ 预览即将推出的功能 apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -3989,11 +3997,11 @@ 用户身份 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -4001,7 +4009,7 @@ 导出数据 apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -4621,8 +4629,8 @@ - Protect your assets. Refine your personal investment strategy. - 保护你的资产。完善你的个人投资策略 + Protect your assets. Refine your personal investment strategy. + 保护你的资产。完善你的个人投资策略 apps/client/src/app/pages/landing/landing-page.html 221 @@ -4685,8 +4693,8 @@ - Why Ghostfolio? - 为什么使用Ghostfolio + Why Ghostfolio? + 为什么使用Ghostfolio apps/client/src/app/pages/landing/landing-page.html 268 @@ -4757,8 +4765,8 @@ - saying no to spreadsheets in - 对电子表格说不 + saying no to spreadsheets in + 对电子表格说不 apps/client/src/app/pages/landing/landing-page.html 307 @@ -4781,24 +4789,24 @@ - What our users are saying - 我们的什么用户正在说 + What our users are saying + 我们的什么用户正在说 apps/client/src/app/pages/landing/landing-page.html 323 - Members from around the globe are using Ghostfolio Premium - 来自世界各地的会员正在使用Ghostfolio 高级版 + Members from around the globe are using Ghostfolio Premium + 来自世界各地的会员正在使用Ghostfolio 高级版 apps/client/src/app/pages/landing/landing-page.html 355 - How does Ghostfolio work? - 如何幽灵作品集工作? + How does Ghostfolio work? + 如何幽灵作品集工作? apps/client/src/app/pages/landing/landing-page.html 367 @@ -4821,8 +4829,8 @@ - * no e-mail address nor credit card required - * 无需电子邮件地址或信用卡 + * no e-mail address nor credit card required + * 无需电子邮件地址或信用卡 apps/client/src/app/pages/landing/landing-page.html 378 @@ -4845,24 +4853,24 @@ - Are you ready? - 准备好? + Are you ready? + 准备好? apps/client/src/app/pages/landing/landing-page.html 413 - Join now or check out the example account - 立即加入或查看示例帐户 + Join now or check out the example account + 立即加入或查看示例帐户 apps/client/src/app/pages/landing/landing-page.html 414 - At Ghostfolio, transparency is at the core of our values. We publish the source code as open source software (OSS) under the AGPL-3.0 license and we openly share aggregated key metrics of the platform’s operational status. - 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 + At Ghostfolio, transparency is at the core of our values. We publish the source code as open source software (OSS) under the AGPL-3.0 license and we openly share aggregated key metrics of the platform’s operational status. + 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 apps/client/src/app/pages/open/open-page.html 6 @@ -4957,7 +4965,7 @@ 您真的要删除所有活动吗? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -5389,7 +5397,7 @@ 股息 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -5409,7 +5417,7 @@ 每月 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -5417,7 +5425,7 @@ 每年 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -5585,8 +5593,8 @@ - If you prefer to run Ghostfolio on your own infrastructure, please find the source code and further instructions on GitHub. - 如果你希望在自己的基础设施上运行 Ghostfolio,请查看源代码和进一步的说明GitHub + If you prefer to run Ghostfolio on your own infrastructure, please find the source code and further instructions on GitHub. + 如果你希望在自己的基础设施上运行 Ghostfolio,请查看源代码和进一步的说明GitHub apps/client/src/app/pages/pricing/pricing-page.html 24 @@ -5769,8 +5777,8 @@ - Hello, has shared a Portfolio with you! - 你好,分享了一个文件夹与你! + Hello, has shared a Portfolio with you! + 你好,分享了一个文件夹与你! apps/client/src/app/pages/public/public-page.html 4 @@ -5833,8 +5841,8 @@ - I agree to have stored my Security Token from above in a secure place. If I lose it, I cannot get my account back. - 我同意存储我的保安编码器从上面看,在一个安全的地方。如果我丢失了它,我将无法找回我的帐户。 + I agree to have stored my Security Token from above in a secure place. If I lose it, I cannot get my account back. + 我同意存储我的保安编码器从上面看,在一个安全的地方。如果我丢失了它,我将无法找回我的帐户。 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html 32 @@ -5869,8 +5877,8 @@ - Open Source Alternative to - 开源替代方案 + Open Source Alternative to + 开源替代方案 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts 26 @@ -5885,8 +5893,8 @@ - This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management. - 此概述页面包含与开源替代方案相比的精选个人理财工具集合Ghostfolio。如果您重视透明度、数据隐私和社区协作,Ghostfolio 提供了一个绝佳的机会来控制您的财务管理。 + This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management. + 此概述页面包含与开源替代方案相比的精选个人理财工具集合Ghostfolio。如果您重视透明度、数据隐私和社区协作,Ghostfolio 提供了一个绝佳的机会来控制您的财务管理。 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html 8 @@ -5901,8 +5909,8 @@ - Open Source Alternative to - 开源替代方案 + Open Source Alternative to + 开源替代方案 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html 38 @@ -6113,8 +6121,8 @@ - Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. - 您是否正在寻找开源替代方案幽灵作品集是一个强大的投资组合管理工具,为个人提供一个全面的平台来跟踪、分析和优化他们的投资。无论您是经验丰富的投资者还是刚刚起步的投资者,Ghostfolio 都提供直观的用户界面和广泛的功能帮助您做出明智的决定并掌控您的财务未来。 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. + 您是否正在寻找开源替代方案幽灵作品集是一个强大的投资组合管理工具,为个人提供一个全面的平台来跟踪、分析和优化他们的投资。无论您是经验丰富的投资者还是刚刚起步的投资者,Ghostfolio 都提供直观的用户界面和广泛的功能帮助您做出明智的决定并掌控您的财务未来。 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13 @@ -6317,8 +6325,8 @@ - Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. - Ghostfolio 是一款开源软件 (OSS),提供了一种经济高效的替代方案使其特别适合预算紧张的个人,例如追求财务独立,提前退休(FIRE) 。通过利用开发者社区和个人理财爱好者的集体努力,Ghostfolio 不断增强其功能、安全性和用户体验。 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. + Ghostfolio 是一款开源软件 (OSS),提供了一种经济高效的替代方案使其特别适合预算紧张的个人,例如追求财务独立,提前退休(FIRE) 。通过利用开发者社区和个人理财爱好者的集体努力,Ghostfolio 不断增强其功能、安全性和用户体验。 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 27 @@ -6521,8 +6529,8 @@ - Let’s dive deeper into the detailed Ghostfolio vs comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. - 让我们更深入地了解 Ghostfolio 与下面的比较表可帮助您全面了解 Ghostfolio 相对于其他产品的定位。我们将探讨功能、数据隐私、定价等各个方面,让您根据个人需求做出明智的选择。 + Let’s dive deeper into the detailed Ghostfolio vs comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. + 让我们更深入地了解 Ghostfolio 与下面的比较表可帮助您全面了解 Ghostfolio 相对于其他产品的定位。我们将探讨功能、数据隐私、定价等各个方面,让您根据个人需求做出明智的选择。 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 38 @@ -6725,8 +6733,8 @@ - Ghostfolio vs comparison table - Ghostfolio vs比较表 + Ghostfolio vs comparison table + Ghostfolio vs比较表 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 49 @@ -12581,8 +12589,8 @@ - Please note that the information provided in the Ghostfolio vs comparison table is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. - 请注意,Ghostfolio 与 Ghostfolio 中提供的信息比较表基于我们的独立研究和分析。该网站不隶属于或比较中提到的任何其他产品。随着个人理财工具格局的不断发展,直接从相应的产品页面验证任何具体的细节或变化至关重要。数据需要刷新吗?帮助我们维护准确的数据GitHub + Please note that the information provided in the Ghostfolio vs comparison table is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. + 请注意,Ghostfolio 与 Ghostfolio 中提供的信息比较表基于我们的独立研究和分析。该网站不隶属于或比较中提到的任何其他产品。随着个人理财工具格局的不断发展,直接从相应的产品页面验证任何具体的细节或变化至关重要。数据需要刷新吗?帮助我们维护准确的数据GitHub apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 210 @@ -12785,8 +12793,8 @@ - Ready to take your investments to the next level? - 准备好带走你的投资下一级 + Ready to take your investments to the next level? + 准备好带走你的投资下一级 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 223 @@ -14049,7 +14057,7 @@ 查找持有... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -14637,8 +14645,8 @@ - If a translation is missing, kindly support us in extending it here. - 如果翻译缺失,请支持我们进行扩展这里 + If a translation is missing, kindly support us in extending it here. + 如果翻译缺失,请支持我们进行扩展这里 apps/client/src/app/components/user-account-settings/user-account-settings.html 55 @@ -14657,7 +14665,7 @@ 当前市场价格为 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14665,7 +14673,7 @@ 测试 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14757,11 +14765,11 @@ 投资 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14793,7 +14801,7 @@ 今年迄今为止 libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14801,7 +14809,7 @@ 本周至今 libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14809,7 +14817,7 @@ 本月至今 libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14817,7 +14825,7 @@ 最大输运量 libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14825,7 +14833,7 @@ 世界贸易组织 libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14845,7 +14853,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14857,8 +14865,8 @@ - If you retire today, you would be able to withdraw per year or per month, based on your total assets of and a withdrawal rate of 4%. - 如果你今天退休,你可以领取每年或者每月,根据您的总资产提款率为4%。 + If you retire today, you would be able to withdraw per year or per month, based on your total assets of and a withdrawal rate of 4%. + 如果你今天退休,你可以领取每年或者每月,根据您的总资产提款率为4%。 apps/client/src/app/pages/portfolio/fire/fire-page.html 68 @@ -14869,7 +14877,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14877,7 +14885,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 From 8cd6c34ed83071cb93124a34b17cff1bc740294d Mon Sep 17 00:00:00 2001 From: Francisco Silva Date: Sun, 31 Mar 2024 20:07:58 +0200 Subject: [PATCH 06/14] Feature/introduce portfolio calculator factory (#3214) * Introduce portfolio calculator factory * Update changelog --- CHANGELOG.md | 1 + .../calculator/mwr/portfolio-calculator.ts | 37 + .../portfolio-calculator-test-utils.ts | 25 + .../portfolio-calculator.factory.ts | 51 ++ .../calculator/portfolio-calculator.ts | 788 ++++++++++++++++++ ...aln-buy-and-sell-in-two-activities.spec.ts | 107 ++- ...folio-calculator-baln-buy-and-sell.spec.ts | 81 +- .../twr/portfolio-calculator-baln-buy.spec.ts | 55 +- ...ator-btcusd-buy-and-sell-partially.spec.ts | 81 +- .../portfolio-calculator-googl-buy.spec.ts | 55 +- ...-calculator-msft-buy-with-dividend.spec.ts | 81 +- .../portfolio-calculator-no-orders.spec.ts | 20 +- ...ulator-novn-buy-and-sell-partially.spec.ts | 82 +- ...folio-calculator-novn-buy-and-sell.spec.ts | 81 +- .../twr/portfolio-calculator.spec.ts | 25 +- .../calculator/twr/portfolio-calculator.ts | 765 +---------------- .../interfaces/current-positions.interface.ts | 1 + ...e.ts => portfolio-order-item.interface.ts} | 0 .../api/src/app/portfolio/portfolio.module.ts | 2 + .../src/app/portfolio/portfolio.service.ts | 75 +- 20 files changed, 1361 insertions(+), 1052 deletions(-) create mode 100644 apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts create mode 100644 apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts create mode 100644 apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts create mode 100644 apps/api/src/app/portfolio/calculator/portfolio-calculator.ts rename apps/api/src/app/portfolio/interfaces/{portfolio-calculator.interface.ts => portfolio-order-item.interface.ts} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce4ef296..7a0b55060 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) +- Introduced a factory for the portfolio calculations to support different algorithms in future ## 2.69.0 - 2024-03-30 diff --git a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts new file mode 100644 index 000000000..ec744f624 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts @@ -0,0 +1,37 @@ +import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; +import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; +import { + SymbolMetrics, + TimelinePosition, + UniqueAsset +} from '@ghostfolio/common/interfaces'; + +export class MWRPortfolioCalculator extends PortfolioCalculator { + protected calculateOverallPerformance( + positions: TimelinePosition[] + ): CurrentPositions { + throw new Error('Method not implemented.'); + } + + protected getSymbolMetrics({ + dataSource, + end, + exchangeRates, + isChartMode = false, + marketSymbolMap, + start, + step = 1, + symbol + }: { + end: Date; + exchangeRates: { [dateString: string]: number }; + isChartMode?: boolean; + marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + }; + start: Date; + step?: number; + } & UniqueAsset): SymbolMetrics { + throw new Error('Method not implemented.'); + } +} diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts new file mode 100644 index 000000000..6d1939fcd --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts @@ -0,0 +1,25 @@ +export const activityDummyData = { + accountId: undefined, + accountUserId: undefined, + comment: undefined, + createdAt: new Date(), + feeInBaseCurrency: undefined, + id: undefined, + isDraft: false, + symbolProfileId: undefined, + updatedAt: new Date(), + userId: undefined, + value: undefined, + valueInBaseCurrency: undefined +}; + +export const symbolProfileDummyData = { + activitiesCount: undefined, + assetClass: undefined, + assetSubClass: undefined, + countries: [], + createdAt: undefined, + id: undefined, + sectors: [], + updatedAt: undefined +}; diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts new file mode 100644 index 000000000..cf1fe9324 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -0,0 +1,51 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; + +import { Injectable } from '@nestjs/common'; + +import { MWRPortfolioCalculator } from './mwr/portfolio-calculator'; +import { PortfolioCalculator } from './portfolio-calculator'; +import { TWRPortfolioCalculator } from './twr/portfolio-calculator'; + +export enum PerformanceCalculationType { + MWR = 'MWR', // Money-Weighted Rate of Return + TWR = 'TWR' // Time-Weighted Rate of Return +} + +@Injectable() +export class PortfolioCalculatorFactory { + public constructor( + private readonly currentRateService: CurrentRateService, + private readonly exchangeRateDataService: ExchangeRateDataService + ) {} + + public createCalculator({ + activities, + calculationType, + currency + }: { + activities: Activity[]; + calculationType: PerformanceCalculationType; + currency: string; + }): PortfolioCalculator { + switch (calculationType) { + case PerformanceCalculationType.MWR: + return new MWRPortfolioCalculator({ + activities, + currency, + currentRateService: this.currentRateService, + exchangeRateDataService: this.exchangeRateDataService + }); + case PerformanceCalculationType.TWR: + return new TWRPortfolioCalculator({ + activities, + currency, + currentRateService: this.currentRateService, + exchangeRateDataService: this.exchangeRateDataService + }); + default: + throw new Error('Invalid calculation type'); + } + } +} diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts new file mode 100644 index 000000000..c3edc86d9 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -0,0 +1,788 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; +import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; +import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; +import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; +import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; +import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; +import { + DataProviderInfo, + HistoricalDataItem, + InvestmentItem, + ResponseError, + SymbolMetrics, + TimelinePosition, + UniqueAsset +} from '@ghostfolio/common/interfaces'; +import { GroupBy } from '@ghostfolio/common/types'; + +import { Big } from 'big.js'; +import { + eachDayOfInterval, + endOfDay, + format, + isBefore, + isSameDay, + max, + subDays +} from 'date-fns'; +import { isNumber, last, uniq } from 'lodash'; + +export abstract class PortfolioCalculator { + protected static readonly ENABLE_LOGGING = false; + + protected orders: PortfolioOrder[]; + + private currency: string; + private currentRateService: CurrentRateService; + private dataProviderInfos: DataProviderInfo[]; + private exchangeRateDataService: ExchangeRateDataService; + private transactionPoints: TransactionPoint[]; + + public constructor({ + activities, + currency, + currentRateService, + exchangeRateDataService + }: { + activities: Activity[]; + currency: string; + currentRateService: CurrentRateService; + exchangeRateDataService: ExchangeRateDataService; + }) { + this.currency = currency; + this.currentRateService = currentRateService; + this.exchangeRateDataService = exchangeRateDataService; + this.orders = activities.map( + ({ date, fee, quantity, SymbolProfile, type, unitPrice }) => { + return { + SymbolProfile, + type, + date: format(date, DATE_FORMAT), + fee: new Big(fee), + quantity: new Big(quantity), + unitPrice: new Big(unitPrice) + }; + } + ); + + this.orders.sort((a, b) => { + return a.date?.localeCompare(b.date); + }); + + this.computeTransactionPoints(); + } + + protected abstract calculateOverallPerformance( + positions: TimelinePosition[] + ): CurrentPositions; + + public getAnnualizedPerformancePercent({ + daysInMarket, + netPerformancePercent + }: { + daysInMarket: number; + netPerformancePercent: 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) + ).minus(1); + } + + return new Big(0); + } + + public async getChartData({ + end = new Date(Date.now()), + start, + step = 1 + }: { + end?: Date; + start: Date; + step?: number; + }): Promise { + const symbols: { [symbol: string]: boolean } = {}; + + const transactionPointsBeforeEndDate = + this.transactionPoints?.filter((transactionPoint) => { + return isBefore(parseDate(transactionPoint.date), end); + }) ?? []; + + const currencies: { [symbol: string]: string } = {}; + const dataGatheringItems: IDataGatheringItem[] = []; + const firstIndex = transactionPointsBeforeEndDate.length; + + let dates = eachDayOfInterval({ start, end }, { step }).map((date) => { + return resetHours(date); + }); + + const includesEndDate = isSameDay(last(dates), end); + + if (!includesEndDate) { + dates.push(resetHours(end)); + } + + if (transactionPointsBeforeEndDate.length > 0) { + for (const { + currency, + dataSource, + symbol + } of transactionPointsBeforeEndDate[firstIndex - 1].items) { + dataGatheringItems.push({ + dataSource, + symbol + }); + currencies[symbol] = currency; + symbols[symbol] = true; + } + } + + const { dataProviderInfos, values: marketSymbols } = + await this.currentRateService.getValues({ + dataGatheringItems, + dateQuery: { + in: dates + } + }); + + this.dataProviderInfos = dataProviderInfos; + + const marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + } = {}; + + let exchangeRatesByCurrency = + await this.exchangeRateDataService.getExchangeRatesByCurrency({ + currencies: uniq(Object.values(currencies)), + endDate: endOfDay(end), + startDate: this.getStartDate(), + targetCurrency: this.currency + }); + + for (const marketSymbol of marketSymbols) { + const dateString = format(marketSymbol.date, DATE_FORMAT); + if (!marketSymbolMap[dateString]) { + marketSymbolMap[dateString] = {}; + } + if (marketSymbol.marketPrice) { + marketSymbolMap[dateString][marketSymbol.symbol] = new Big( + marketSymbol.marketPrice + ); + } + } + + const accumulatedValuesByDate: { + [date: string]: { + investmentValueWithCurrencyEffect: Big; + totalCurrentValue: Big; + totalCurrentValueWithCurrencyEffect: Big; + totalInvestmentValue: Big; + totalInvestmentValueWithCurrencyEffect: Big; + totalNetPerformanceValue: Big; + totalNetPerformanceValueWithCurrencyEffect: Big; + totalTimeWeightedInvestmentValue: Big; + totalTimeWeightedInvestmentValueWithCurrencyEffect: Big; + }; + } = {}; + + const valuesBySymbol: { + [symbol: string]: { + currentValues: { [date: string]: Big }; + currentValuesWithCurrencyEffect: { [date: string]: Big }; + investmentValuesAccumulated: { [date: string]: Big }; + investmentValuesAccumulatedWithCurrencyEffect: { [date: string]: Big }; + investmentValuesWithCurrencyEffect: { [date: string]: Big }; + netPerformanceValues: { [date: string]: Big }; + netPerformanceValuesWithCurrencyEffect: { [date: string]: Big }; + timeWeightedInvestmentValues: { [date: string]: Big }; + timeWeightedInvestmentValuesWithCurrencyEffect: { [date: string]: Big }; + }; + } = {}; + + for (const symbol of Object.keys(symbols)) { + const { + currentValues, + currentValuesWithCurrencyEffect, + investmentValuesAccumulated, + investmentValuesAccumulatedWithCurrencyEffect, + investmentValuesWithCurrencyEffect, + netPerformanceValues, + netPerformanceValuesWithCurrencyEffect, + timeWeightedInvestmentValues, + timeWeightedInvestmentValuesWithCurrencyEffect + } = this.getSymbolMetrics({ + end, + marketSymbolMap, + start, + step, + symbol, + dataSource: null, + exchangeRates: + exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`], + isChartMode: true + }); + + valuesBySymbol[symbol] = { + currentValues, + currentValuesWithCurrencyEffect, + investmentValuesAccumulated, + investmentValuesAccumulatedWithCurrencyEffect, + investmentValuesWithCurrencyEffect, + netPerformanceValues, + netPerformanceValuesWithCurrencyEffect, + timeWeightedInvestmentValues, + timeWeightedInvestmentValuesWithCurrencyEffect + }; + } + + for (const currentDate of dates) { + const dateString = format(currentDate, DATE_FORMAT); + + for (const symbol of Object.keys(valuesBySymbol)) { + const symbolValues = valuesBySymbol[symbol]; + + const currentValue = + symbolValues.currentValues?.[dateString] ?? new Big(0); + + const currentValueWithCurrencyEffect = + symbolValues.currentValuesWithCurrencyEffect?.[dateString] ?? + new Big(0); + + const investmentValueAccumulated = + symbolValues.investmentValuesAccumulated?.[dateString] ?? new Big(0); + + const investmentValueAccumulatedWithCurrencyEffect = + symbolValues.investmentValuesAccumulatedWithCurrencyEffect?.[ + dateString + ] ?? new Big(0); + + const investmentValueWithCurrencyEffect = + symbolValues.investmentValuesWithCurrencyEffect?.[dateString] ?? + new Big(0); + + const netPerformanceValue = + symbolValues.netPerformanceValues?.[dateString] ?? new Big(0); + + const netPerformanceValueWithCurrencyEffect = + symbolValues.netPerformanceValuesWithCurrencyEffect?.[dateString] ?? + new Big(0); + + const timeWeightedInvestmentValue = + symbolValues.timeWeightedInvestmentValues?.[dateString] ?? new Big(0); + + const timeWeightedInvestmentValueWithCurrencyEffect = + symbolValues.timeWeightedInvestmentValuesWithCurrencyEffect?.[ + dateString + ] ?? new Big(0); + + accumulatedValuesByDate[dateString] = { + investmentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.investmentValueWithCurrencyEffect ?? new Big(0) + ).add(investmentValueWithCurrencyEffect), + totalCurrentValue: ( + accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) + ).add(currentValue), + totalCurrentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalCurrentValueWithCurrencyEffect ?? new Big(0) + ).add(currentValueWithCurrencyEffect), + totalInvestmentValue: ( + accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? + new Big(0) + ).add(investmentValueAccumulated), + totalInvestmentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) + ).add(investmentValueAccumulatedWithCurrencyEffect), + totalNetPerformanceValue: ( + accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? + new Big(0) + ).add(netPerformanceValue), + totalNetPerformanceValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalNetPerformanceValueWithCurrencyEffect ?? new Big(0) + ).add(netPerformanceValueWithCurrencyEffect), + totalTimeWeightedInvestmentValue: ( + accumulatedValuesByDate[dateString] + ?.totalTimeWeightedInvestmentValue ?? new Big(0) + ).add(timeWeightedInvestmentValue), + totalTimeWeightedInvestmentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalTimeWeightedInvestmentValueWithCurrencyEffect ?? new Big(0) + ).add(timeWeightedInvestmentValueWithCurrencyEffect) + }; + } + } + + return Object.entries(accumulatedValuesByDate).map(([date, values]) => { + const { + investmentValueWithCurrencyEffect, + totalCurrentValue, + totalCurrentValueWithCurrencyEffect, + totalInvestmentValue, + totalInvestmentValueWithCurrencyEffect, + totalNetPerformanceValue, + totalNetPerformanceValueWithCurrencyEffect, + totalTimeWeightedInvestmentValue, + totalTimeWeightedInvestmentValueWithCurrencyEffect + } = values; + + const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0) + ? 0 + : totalNetPerformanceValue + .div(totalTimeWeightedInvestmentValue) + .mul(100) + .toNumber(); + + const netPerformanceInPercentageWithCurrencyEffect = + totalTimeWeightedInvestmentValueWithCurrencyEffect.eq(0) + ? 0 + : totalNetPerformanceValueWithCurrencyEffect + .div(totalTimeWeightedInvestmentValueWithCurrencyEffect) + .mul(100) + .toNumber(); + + return { + date, + netPerformanceInPercentage, + netPerformanceInPercentageWithCurrencyEffect, + investmentValueWithCurrencyEffect: + investmentValueWithCurrencyEffect.toNumber(), + netPerformance: totalNetPerformanceValue.toNumber(), + netPerformanceWithCurrencyEffect: + totalNetPerformanceValueWithCurrencyEffect.toNumber(), + totalInvestment: totalInvestmentValue.toNumber(), + totalInvestmentValueWithCurrencyEffect: + totalInvestmentValueWithCurrencyEffect.toNumber(), + value: totalCurrentValue.toNumber(), + valueWithCurrencyEffect: totalCurrentValueWithCurrencyEffect.toNumber() + }; + }); + } + + public async getCurrentPositions( + start: Date, + end?: Date + ): Promise { + const lastTransactionPoint = last(this.transactionPoints); + + let endDate = end; + + if (!endDate) { + endDate = new Date(Date.now()); + + if (lastTransactionPoint) { + endDate = max([endDate, parseDate(lastTransactionPoint.date)]); + } + } + + const transactionPoints = this.transactionPoints?.filter(({ date }) => { + return isBefore(parseDate(date), endDate); + }); + + if (!transactionPoints.length) { + return { + currentValueInBaseCurrency: new Big(0), + grossPerformance: new Big(0), + grossPerformancePercentage: new Big(0), + grossPerformancePercentageWithCurrencyEffect: new Big(0), + grossPerformanceWithCurrencyEffect: new Big(0), + hasErrors: false, + netPerformance: new Big(0), + netPerformancePercentage: new Big(0), + netPerformancePercentageWithCurrencyEffect: new Big(0), + netPerformanceWithCurrencyEffect: new Big(0), + positions: [], + totalInvestment: new Big(0), + totalInvestmentWithCurrencyEffect: new Big(0) + }; + } + + const currencies: { [symbol: string]: string } = {}; + const dataGatheringItems: IDataGatheringItem[] = []; + let dates: Date[] = []; + let firstIndex = transactionPoints.length; + let firstTransactionPoint: TransactionPoint = null; + + dates.push(resetHours(start)); + + for (const { currency, dataSource, symbol } of transactionPoints[ + firstIndex - 1 + ].items) { + dataGatheringItems.push({ + dataSource, + symbol + }); + + currencies[symbol] = currency; + } + + for (let i = 0; i < transactionPoints.length; i++) { + if ( + !isBefore(parseDate(transactionPoints[i].date), start) && + firstTransactionPoint === null + ) { + firstTransactionPoint = transactionPoints[i]; + firstIndex = i; + } + + if (firstTransactionPoint !== null) { + dates.push(resetHours(parseDate(transactionPoints[i].date))); + } + } + + dates.push(resetHours(endDate)); + + // Add dates of last week for fallback + dates.push(subDays(resetHours(new Date()), 7)); + dates.push(subDays(resetHours(new Date()), 6)); + dates.push(subDays(resetHours(new Date()), 5)); + dates.push(subDays(resetHours(new Date()), 4)); + dates.push(subDays(resetHours(new Date()), 3)); + dates.push(subDays(resetHours(new Date()), 2)); + dates.push(subDays(resetHours(new Date()), 1)); + dates.push(resetHours(new Date())); + + dates = uniq( + dates.map((date) => { + return date.getTime(); + }) + ) + .map((timestamp) => { + return new Date(timestamp); + }) + .sort((a, b) => { + return a.getTime() - b.getTime(); + }); + + let exchangeRatesByCurrency = + await this.exchangeRateDataService.getExchangeRatesByCurrency({ + currencies: uniq(Object.values(currencies)), + endDate: endOfDay(endDate), + startDate: this.getStartDate(), + targetCurrency: this.currency + }); + + const { + dataProviderInfos, + errors: currentRateErrors, + values: marketSymbols + } = await this.currentRateService.getValues({ + dataGatheringItems, + dateQuery: { + in: dates + } + }); + + this.dataProviderInfos = dataProviderInfos; + + const marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + } = {}; + + for (const marketSymbol of marketSymbols) { + const date = format(marketSymbol.date, DATE_FORMAT); + + if (!marketSymbolMap[date]) { + marketSymbolMap[date] = {}; + } + + if (marketSymbol.marketPrice) { + marketSymbolMap[date][marketSymbol.symbol] = new Big( + marketSymbol.marketPrice + ); + } + } + + const endDateString = format(endDate, DATE_FORMAT); + + if (firstIndex > 0) { + firstIndex--; + } + + const positions: TimelinePosition[] = []; + let hasAnySymbolMetricsErrors = false; + + const errors: ResponseError['errors'] = []; + + for (const item of lastTransactionPoint.items) { + const marketPriceInBaseCurrency = ( + marketSymbolMap[endDateString]?.[item.symbol] ?? item.averagePrice + ).mul( + exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[ + endDateString + ] + ); + + const { + grossPerformance, + grossPerformancePercentage, + grossPerformancePercentageWithCurrencyEffect, + grossPerformanceWithCurrencyEffect, + hasErrors, + netPerformance, + netPerformancePercentage, + netPerformancePercentageWithCurrencyEffect, + netPerformanceWithCurrencyEffect, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, + totalDividend, + totalDividendInBaseCurrency, + totalInvestment, + totalInvestmentWithCurrencyEffect + } = this.getSymbolMetrics({ + marketSymbolMap, + start, + dataSource: item.dataSource, + end: endDate, + exchangeRates: + exchangeRatesByCurrency[`${item.currency}${this.currency}`], + symbol: item.symbol + }); + + hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; + + positions.push({ + dividend: totalDividend, + dividendInBaseCurrency: totalDividendInBaseCurrency, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, + averagePrice: item.averagePrice, + currency: item.currency, + dataSource: item.dataSource, + fee: item.fee, + firstBuyDate: item.firstBuyDate, + grossPerformance: !hasErrors ? grossPerformance ?? null : null, + grossPerformancePercentage: !hasErrors + ? grossPerformancePercentage ?? null + : null, + grossPerformancePercentageWithCurrencyEffect: !hasErrors + ? grossPerformancePercentageWithCurrencyEffect ?? null + : null, + grossPerformanceWithCurrencyEffect: !hasErrors + ? grossPerformanceWithCurrencyEffect ?? null + : null, + investment: totalInvestment, + investmentWithCurrencyEffect: totalInvestmentWithCurrencyEffect, + marketPrice: + marketSymbolMap[endDateString]?.[item.symbol]?.toNumber() ?? null, + marketPriceInBaseCurrency: + marketPriceInBaseCurrency?.toNumber() ?? null, + netPerformance: !hasErrors ? netPerformance ?? null : null, + netPerformancePercentage: !hasErrors + ? netPerformancePercentage ?? null + : null, + netPerformancePercentageWithCurrencyEffect: !hasErrors + ? netPerformancePercentageWithCurrencyEffect ?? null + : null, + netPerformanceWithCurrencyEffect: !hasErrors + ? netPerformanceWithCurrencyEffect ?? null + : null, + quantity: item.quantity, + symbol: item.symbol, + tags: item.tags, + transactionCount: item.transactionCount, + valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( + item.quantity + ) + }); + + if ( + (hasErrors || + currentRateErrors.find(({ dataSource, symbol }) => { + return dataSource === item.dataSource && symbol === item.symbol; + })) && + item.investment.gt(0) + ) { + errors.push({ dataSource: item.dataSource, symbol: item.symbol }); + } + } + + const overall = this.calculateOverallPerformance(positions); + + return { + ...overall, + errors, + positions, + hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors + }; + } + + public getDataProviderInfos() { + return this.dataProviderInfos; + } + + public getInvestments(): { date: string; investment: Big }[] { + if (this.transactionPoints.length === 0) { + return []; + } + + return this.transactionPoints.map((transactionPoint) => { + return { + date: transactionPoint.date, + investment: transactionPoint.items.reduce( + (investment, transactionPointSymbol) => + investment.plus(transactionPointSymbol.investment), + new Big(0) + ) + }; + }); + } + + public getInvestmentsByGroup({ + data, + groupBy + }: { + data: HistoricalDataItem[]; + groupBy: GroupBy; + }): InvestmentItem[] { + const groupedData: { [dateGroup: string]: Big } = {}; + + for (const { date, investmentValueWithCurrencyEffect } of data) { + const dateGroup = + groupBy === 'month' ? date.substring(0, 7) : date.substring(0, 4); + groupedData[dateGroup] = (groupedData[dateGroup] ?? new Big(0)).plus( + investmentValueWithCurrencyEffect + ); + } + + return Object.keys(groupedData).map((dateGroup) => ({ + date: groupBy === 'month' ? `${dateGroup}-01` : `${dateGroup}-01-01`, + investment: groupedData[dateGroup].toNumber() + })); + } + + public getStartDate() { + return this.transactionPoints.length > 0 + ? parseDate(this.transactionPoints[0].date) + : new Date(); + } + + protected abstract getSymbolMetrics({ + dataSource, + end, + exchangeRates, + isChartMode, + marketSymbolMap, + start, + step, + symbol + }: { + end: Date; + exchangeRates: { [dateString: string]: number }; + isChartMode?: boolean; + marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + }; + start: Date; + step?: number; + } & UniqueAsset): SymbolMetrics; + + public getTransactionPoints() { + return this.transactionPoints; + } + + private computeTransactionPoints() { + this.transactionPoints = []; + const symbols: { [symbol: string]: TransactionPointSymbol } = {}; + + let lastDate: string = null; + let lastTransactionPoint: TransactionPoint = null; + + for (const { + fee, + date, + quantity, + SymbolProfile, + tags, + type, + unitPrice + } of this.orders) { + let currentTransactionPointItem: TransactionPointSymbol; + const oldAccumulatedSymbol = symbols[SymbolProfile.symbol]; + + const factor = getFactor(type); + + if (oldAccumulatedSymbol) { + let investment = oldAccumulatedSymbol.investment; + + const newQuantity = quantity + .mul(factor) + .plus(oldAccumulatedSymbol.quantity); + + if (type === 'BUY') { + investment = oldAccumulatedSymbol.investment.plus( + quantity.mul(unitPrice) + ); + } else if (type === 'SELL') { + investment = oldAccumulatedSymbol.investment.minus( + quantity.mul(oldAccumulatedSymbol.averagePrice) + ); + } + + currentTransactionPointItem = { + investment, + tags, + averagePrice: newQuantity.gt(0) + ? investment.div(newQuantity) + : new Big(0), + currency: SymbolProfile.currency, + dataSource: SymbolProfile.dataSource, + dividend: new Big(0), + fee: fee.plus(oldAccumulatedSymbol.fee), + firstBuyDate: oldAccumulatedSymbol.firstBuyDate, + quantity: newQuantity, + symbol: SymbolProfile.symbol, + transactionCount: oldAccumulatedSymbol.transactionCount + 1 + }; + } else { + currentTransactionPointItem = { + fee, + tags, + averagePrice: unitPrice, + currency: SymbolProfile.currency, + dataSource: SymbolProfile.dataSource, + dividend: new Big(0), + firstBuyDate: date, + investment: unitPrice.mul(quantity).mul(factor), + quantity: quantity.mul(factor), + symbol: SymbolProfile.symbol, + transactionCount: 1 + }; + } + + symbols[SymbolProfile.symbol] = currentTransactionPointItem; + + const items = lastTransactionPoint?.items ?? []; + + const newItems = items.filter(({ symbol }) => { + return symbol !== SymbolProfile.symbol; + }); + + newItems.push(currentTransactionPointItem); + + newItems.sort((a, b) => { + return a.symbol?.localeCompare(b.symbol); + }); + + if (lastDate !== date || lastTransactionPoint === null) { + lastTransactionPoint = { + date, + items: newItems + }; + + this.transactionPoints.push(lastTransactionPoint); + } else { + lastTransactionPoint.items = newItems; + } + + lastDate = date; + } + } +} diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index e08de8e22..ee71a1fb3 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,54 +37,66 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BALN.SW buy and sell in two activities', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-11-22'), - fee: 1.55, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'BUY', - unitPrice: 142.9 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-11-22'), + fee: 1.55, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' }, - { - date: new Date('2021-11-30'), - fee: 1.65, - quantity: 1, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'SELL', - unitPrice: 136.6 + type: 'BUY', + unitPrice: 142.9 + }, + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 1.65, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' }, - { - date: new Date('2021-11-30'), - fee: 0, - quantity: 1, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'SELL', - unitPrice: 136.6 - } - ], + type: 'SELL', + unitPrice: 136.6 + }, + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' + }, + type: 'SELL', + unitPrice: 136.6 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index 411c5e4db..69078be7c 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,41 +37,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BALN.SW buy and sell', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-11-22'), - fee: 1.55, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'BUY', - unitPrice: 142.9 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-11-22'), + fee: 1.55, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' }, - { - date: new Date('2021-11-30'), - fee: 1.65, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'SELL', - unitPrice: 136.6 - } - ], + type: 'BUY', + unitPrice: 142.9 + }, + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 1.65, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' + }, + type: 'SELL', + unitPrice: 136.6 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index 32f582647..b52aac68d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,28 +37,36 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BALN.SW buy', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-11-30'), - fee: 1.55, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'BUY', - unitPrice: 136.6 - } - ], + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 1.55, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' + }, + type: 'BUY', + unitPrice: 136.6 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index f5687f810..420ba48f1 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -7,8 +15,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -33,6 +39,7 @@ jest.mock( describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -43,41 +50,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BTCUSD buy and sell partially', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2015-01-01'), - fee: 0, - quantity: 2, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Bitcoin USD', - symbol: 'BTCUSD' - }, - type: 'BUY', - unitPrice: 320.43 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2015-01-01'), + fee: 0, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Bitcoin USD', + symbol: 'BTCUSD' }, - { - date: new Date('2017-12-31'), - fee: 0, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Bitcoin USD', - symbol: 'BTCUSD' - }, - type: 'SELL', - unitPrice: 14156.4 - } - ], + type: 'BUY', + unitPrice: 320.43 + }, + { + ...activityDummyData, + date: new Date('2017-12-31'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Bitcoin USD', + symbol: 'BTCUSD' + }, + type: 'SELL', + unitPrice: 14156.4 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index 743733733..5f33d771b 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -7,8 +15,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -33,6 +39,7 @@ jest.mock( describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -43,28 +50,36 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with GOOGL buy', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2023-01-03'), - fee: 1, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Alphabet Inc.', - symbol: 'GOOGL' - }, - type: 'BUY', - unitPrice: 89.12 - } - ], + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2023-01-03'), + fee: 1, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Alphabet Inc.', + symbol: 'GOOGL' + }, + type: 'BUY', + unitPrice: 89.12 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index afd5e9ff2..a2c106784 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -7,8 +15,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -33,6 +39,7 @@ jest.mock( describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -43,41 +50,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with MSFT buy', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-09-16'), - fee: 19, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Microsoft Inc.', - symbol: 'MSFT' - }, - type: 'BUY', - unitPrice: 298.58 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-09-16'), + fee: 19, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Microsoft Inc.', + symbol: 'MSFT' }, - { - date: new Date('2021-11-16'), - fee: 0, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Microsoft Inc.', - symbol: 'MSFT' - }, - type: 'DIVIDEND', - unitPrice: 0.62 - } - ], + type: 'BUY', + unitPrice: 298.58 + }, + { + ...activityDummyData, + date: new Date('2021-11-16'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Microsoft Inc.', + symbol: 'MSFT' + }, + type: 'DIVIDEND', + unitPrice: 0.62 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'USD' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index 39a563b85..905747519 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -1,3 +1,7 @@ +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +10,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; import { subDays } from 'date-fns'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +22,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,14 +33,18 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it('with no orders', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, + const portfolioCalculator = factory.createCalculator({ activities: [], + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); @@ -73,7 +80,8 @@ describe('PortfolioCalculator', () => { netPerformancePercentageWithCurrencyEffect: new Big(0), netPerformanceWithCurrencyEffect: new Big(0), positions: [], - totalInvestment: new Big(0) + totalInvestment: new Big(0), + totalInvestmentWithCurrencyEffect: new Big(0) }); expect(investments).toEqual([]); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index d7e7c6eab..21e0bb499 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,44 +37,53 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with NOVN.SW buy and sell partially', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2022-03-07'), - fee: 1.3, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'BUY', - unitPrice: 75.8 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2022-03-07'), + fee: 1.3, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' }, - { - date: new Date('2022-04-08'), - fee: 2.95, - quantity: 1, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'SELL', - unitPrice: 85.73 - } - ], + type: 'BUY', + unitPrice: 75.8 + }, + { + ...activityDummyData, + date: new Date('2022-04-08'), + fee: 2.95, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' + }, + type: 'SELL', + unitPrice: 85.73 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); - const spy = jest .spyOn(Date, 'now') .mockImplementation(() => parseDate('2022-04-11').getTime()); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 68eecea22..28920ece7 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,41 +37,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with NOVN.SW buy and sell', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2022-03-07'), - fee: 0, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'BUY', - unitPrice: 75.8 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2022-03-07'), + fee: 0, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' }, - { - date: new Date('2022-04-08'), - fee: 0, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'SELL', - unitPrice: 85.73 - } - ], + type: 'BUY', + unitPrice: 75.8 + }, + { + ...activityDummyData, + date: new Date('2022-04-08'), + fee: 0, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' + }, + type: 'SELL', + unitPrice: 85.73 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts index de011d813..b68f4358d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts @@ -1,13 +1,16 @@ +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -18,17 +21,21 @@ describe('PortfolioCalculator', () => { null, null ); - }); - describe('annualized performance percentage', () => { - const portfolioCalculator = new PortfolioCalculator({ - activities: [], + factory = new PortfolioCalculatorFactory( currentRateService, - exchangeRateDataService, - currency: 'USD' - }); + exchangeRateDataService + ); + }); + describe('annualized performance percentage', () => { it('Get annualized performance', async () => { + const portfolioCalculator = factory.createCalculator({ + activities: [], + calculationType: PerformanceCalculationType.TWR, + currency: 'CHF' + }); + expect( portfolioCalculator .getAnnualizedPerformancePercent({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 6ea93a670..0fee9c5c7 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -1,24 +1,13 @@ -import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; -import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; -import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator.interface'; -import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; -import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; -import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; +import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order-item.interface'; import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; -import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; -import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; +import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { - DataProviderInfo, - HistoricalDataItem, - InvestmentItem, - ResponseError, SymbolMetrics, TimelinePosition, UniqueAsset } from '@ghostfolio/common/interfaces'; -import { GroupBy } from '@ghostfolio/common/types'; import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; @@ -26,638 +15,15 @@ import { addDays, addMilliseconds, differenceInDays, - eachDayOfInterval, - endOfDay, format, - isBefore, - isSameDay, - max, - subDays + isBefore } from 'date-fns'; -import { cloneDeep, first, isNumber, last, sortBy, uniq } from 'lodash'; - -export class PortfolioCalculator { - private static readonly ENABLE_LOGGING = false; - - private currency: string; - private currentRateService: CurrentRateService; - private dataProviderInfos: DataProviderInfo[]; - private exchangeRateDataService: ExchangeRateDataService; - private orders: PortfolioOrder[]; - private transactionPoints: TransactionPoint[]; - - public constructor({ - activities, - currency, - currentRateService, - exchangeRateDataService - }: { - activities: Activity[]; - currency: string; - currentRateService: CurrentRateService; - exchangeRateDataService: ExchangeRateDataService; - }) { - this.currency = currency; - this.currentRateService = currentRateService; - this.exchangeRateDataService = exchangeRateDataService; - this.orders = activities.map( - ({ date, fee, quantity, SymbolProfile, type, unitPrice }) => { - return { - SymbolProfile, - type, - date: format(date, DATE_FORMAT), - fee: new Big(fee), - quantity: new Big(quantity), - unitPrice: new Big(unitPrice) - }; - } - ); - - this.orders.sort((a, b) => { - return a.date?.localeCompare(b.date); - }); - - this.computeTransactionPoints(); - } - - public getAnnualizedPerformancePercent({ - daysInMarket, - netPerformancePercent - }: { - daysInMarket: number; - netPerformancePercent: 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) - ).minus(1); - } - - return new Big(0); - } - - public async getChartData({ - end = new Date(Date.now()), - start, - step = 1 - }: { - end?: Date; - start: Date; - step?: number; - }): Promise { - const symbols: { [symbol: string]: boolean } = {}; - - const transactionPointsBeforeEndDate = - this.transactionPoints?.filter((transactionPoint) => { - return isBefore(parseDate(transactionPoint.date), end); - }) ?? []; - - const currencies: { [symbol: string]: string } = {}; - const dataGatheringItems: IDataGatheringItem[] = []; - const firstIndex = transactionPointsBeforeEndDate.length; - - let dates = eachDayOfInterval({ start, end }, { step }).map((date) => { - return resetHours(date); - }); - - const includesEndDate = isSameDay(last(dates), end); - - if (!includesEndDate) { - dates.push(resetHours(end)); - } - - if (transactionPointsBeforeEndDate.length > 0) { - for (const { - currency, - dataSource, - symbol - } of transactionPointsBeforeEndDate[firstIndex - 1].items) { - dataGatheringItems.push({ - dataSource, - symbol - }); - currencies[symbol] = currency; - symbols[symbol] = true; - } - } - - const { dataProviderInfos, values: marketSymbols } = - await this.currentRateService.getValues({ - dataGatheringItems, - dateQuery: { - in: dates - } - }); - - this.dataProviderInfos = dataProviderInfos; - - const marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - } = {}; - - let exchangeRatesByCurrency = - await this.exchangeRateDataService.getExchangeRatesByCurrency({ - currencies: uniq(Object.values(currencies)), - endDate: endOfDay(end), - startDate: this.getStartDate(), - targetCurrency: this.currency - }); - - for (const marketSymbol of marketSymbols) { - const dateString = format(marketSymbol.date, DATE_FORMAT); - if (!marketSymbolMap[dateString]) { - marketSymbolMap[dateString] = {}; - } - if (marketSymbol.marketPrice) { - marketSymbolMap[dateString][marketSymbol.symbol] = new Big( - marketSymbol.marketPrice - ); - } - } - - const accumulatedValuesByDate: { - [date: string]: { - investmentValueWithCurrencyEffect: Big; - totalCurrentValue: Big; - totalCurrentValueWithCurrencyEffect: Big; - totalInvestmentValue: Big; - totalInvestmentValueWithCurrencyEffect: Big; - totalNetPerformanceValue: Big; - totalNetPerformanceValueWithCurrencyEffect: Big; - totalTimeWeightedInvestmentValue: Big; - totalTimeWeightedInvestmentValueWithCurrencyEffect: Big; - }; - } = {}; - - const valuesBySymbol: { - [symbol: string]: { - currentValues: { [date: string]: Big }; - currentValuesWithCurrencyEffect: { [date: string]: Big }; - investmentValuesAccumulated: { [date: string]: Big }; - investmentValuesAccumulatedWithCurrencyEffect: { [date: string]: Big }; - investmentValuesWithCurrencyEffect: { [date: string]: Big }; - netPerformanceValues: { [date: string]: Big }; - netPerformanceValuesWithCurrencyEffect: { [date: string]: Big }; - timeWeightedInvestmentValues: { [date: string]: Big }; - timeWeightedInvestmentValuesWithCurrencyEffect: { [date: string]: Big }; - }; - } = {}; - - for (const symbol of Object.keys(symbols)) { - const { - currentValues, - currentValuesWithCurrencyEffect, - investmentValuesAccumulated, - investmentValuesAccumulatedWithCurrencyEffect, - investmentValuesWithCurrencyEffect, - netPerformanceValues, - netPerformanceValuesWithCurrencyEffect, - timeWeightedInvestmentValues, - timeWeightedInvestmentValuesWithCurrencyEffect - } = this.getSymbolMetrics({ - end, - marketSymbolMap, - start, - step, - symbol, - dataSource: null, - exchangeRates: - exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`], - isChartMode: true - }); - - valuesBySymbol[symbol] = { - currentValues, - currentValuesWithCurrencyEffect, - investmentValuesAccumulated, - investmentValuesAccumulatedWithCurrencyEffect, - investmentValuesWithCurrencyEffect, - netPerformanceValues, - netPerformanceValuesWithCurrencyEffect, - timeWeightedInvestmentValues, - timeWeightedInvestmentValuesWithCurrencyEffect - }; - } - - for (const currentDate of dates) { - const dateString = format(currentDate, DATE_FORMAT); - - for (const symbol of Object.keys(valuesBySymbol)) { - const symbolValues = valuesBySymbol[symbol]; - - const currentValue = - symbolValues.currentValues?.[dateString] ?? new Big(0); - - const currentValueWithCurrencyEffect = - symbolValues.currentValuesWithCurrencyEffect?.[dateString] ?? - new Big(0); - - const investmentValueAccumulated = - symbolValues.investmentValuesAccumulated?.[dateString] ?? new Big(0); - - const investmentValueAccumulatedWithCurrencyEffect = - symbolValues.investmentValuesAccumulatedWithCurrencyEffect?.[ - dateString - ] ?? new Big(0); - - const investmentValueWithCurrencyEffect = - symbolValues.investmentValuesWithCurrencyEffect?.[dateString] ?? - new Big(0); - - const netPerformanceValue = - symbolValues.netPerformanceValues?.[dateString] ?? new Big(0); - - const netPerformanceValueWithCurrencyEffect = - symbolValues.netPerformanceValuesWithCurrencyEffect?.[dateString] ?? - new Big(0); - - const timeWeightedInvestmentValue = - symbolValues.timeWeightedInvestmentValues?.[dateString] ?? new Big(0); - - const timeWeightedInvestmentValueWithCurrencyEffect = - symbolValues.timeWeightedInvestmentValuesWithCurrencyEffect?.[ - dateString - ] ?? new Big(0); - - accumulatedValuesByDate[dateString] = { - investmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.investmentValueWithCurrencyEffect ?? new Big(0) - ).add(investmentValueWithCurrencyEffect), - totalCurrentValue: ( - accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) - ).add(currentValue), - totalCurrentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalCurrentValueWithCurrencyEffect ?? new Big(0) - ).add(currentValueWithCurrencyEffect), - totalInvestmentValue: ( - accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? - new Big(0) - ).add(investmentValueAccumulated), - totalInvestmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) - ).add(investmentValueAccumulatedWithCurrencyEffect), - totalNetPerformanceValue: ( - accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? - new Big(0) - ).add(netPerformanceValue), - totalNetPerformanceValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalNetPerformanceValueWithCurrencyEffect ?? new Big(0) - ).add(netPerformanceValueWithCurrencyEffect), - totalTimeWeightedInvestmentValue: ( - accumulatedValuesByDate[dateString] - ?.totalTimeWeightedInvestmentValue ?? new Big(0) - ).add(timeWeightedInvestmentValue), - totalTimeWeightedInvestmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalTimeWeightedInvestmentValueWithCurrencyEffect ?? new Big(0) - ).add(timeWeightedInvestmentValueWithCurrencyEffect) - }; - } - } - - return Object.entries(accumulatedValuesByDate).map(([date, values]) => { - const { - investmentValueWithCurrencyEffect, - totalCurrentValue, - totalCurrentValueWithCurrencyEffect, - totalInvestmentValue, - totalInvestmentValueWithCurrencyEffect, - totalNetPerformanceValue, - totalNetPerformanceValueWithCurrencyEffect, - totalTimeWeightedInvestmentValue, - totalTimeWeightedInvestmentValueWithCurrencyEffect - } = values; - - const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0) - ? 0 - : totalNetPerformanceValue - .div(totalTimeWeightedInvestmentValue) - .mul(100) - .toNumber(); - - const netPerformanceInPercentageWithCurrencyEffect = - totalTimeWeightedInvestmentValueWithCurrencyEffect.eq(0) - ? 0 - : totalNetPerformanceValueWithCurrencyEffect - .div(totalTimeWeightedInvestmentValueWithCurrencyEffect) - .mul(100) - .toNumber(); - - return { - date, - netPerformanceInPercentage, - netPerformanceInPercentageWithCurrencyEffect, - investmentValueWithCurrencyEffect: - investmentValueWithCurrencyEffect.toNumber(), - netPerformance: totalNetPerformanceValue.toNumber(), - netPerformanceWithCurrencyEffect: - totalNetPerformanceValueWithCurrencyEffect.toNumber(), - totalInvestment: totalInvestmentValue.toNumber(), - totalInvestmentValueWithCurrencyEffect: - totalInvestmentValueWithCurrencyEffect.toNumber(), - value: totalCurrentValue.toNumber(), - valueWithCurrencyEffect: totalCurrentValueWithCurrencyEffect.toNumber() - }; - }); - } - - public async getCurrentPositions( - start: Date, - end?: Date - ): Promise { - const lastTransactionPoint = last(this.transactionPoints); - - let endDate = end; - - if (!endDate) { - endDate = new Date(Date.now()); - - if (lastTransactionPoint) { - endDate = max([endDate, parseDate(lastTransactionPoint.date)]); - } - } - - const transactionPoints = this.transactionPoints?.filter(({ date }) => { - return isBefore(parseDate(date), endDate); - }); - - if (!transactionPoints.length) { - return { - currentValueInBaseCurrency: new Big(0), - grossPerformance: new Big(0), - grossPerformancePercentage: new Big(0), - grossPerformancePercentageWithCurrencyEffect: new Big(0), - grossPerformanceWithCurrencyEffect: new Big(0), - hasErrors: false, - netPerformance: new Big(0), - netPerformancePercentage: new Big(0), - netPerformancePercentageWithCurrencyEffect: new Big(0), - netPerformanceWithCurrencyEffect: new Big(0), - positions: [], - totalInvestment: new Big(0) - }; - } - - const currencies: { [symbol: string]: string } = {}; - const dataGatheringItems: IDataGatheringItem[] = []; - let dates: Date[] = []; - let firstIndex = transactionPoints.length; - let firstTransactionPoint: TransactionPoint = null; +import { cloneDeep, first, last, sortBy } from 'lodash'; - dates.push(resetHours(start)); - - for (const { currency, dataSource, symbol } of transactionPoints[ - firstIndex - 1 - ].items) { - dataGatheringItems.push({ - dataSource, - symbol - }); - - currencies[symbol] = currency; - } - - for (let i = 0; i < transactionPoints.length; i++) { - if ( - !isBefore(parseDate(transactionPoints[i].date), start) && - firstTransactionPoint === null - ) { - firstTransactionPoint = transactionPoints[i]; - firstIndex = i; - } - - if (firstTransactionPoint !== null) { - dates.push(resetHours(parseDate(transactionPoints[i].date))); - } - } - - dates.push(resetHours(endDate)); - - // Add dates of last week for fallback - dates.push(subDays(resetHours(new Date()), 7)); - dates.push(subDays(resetHours(new Date()), 6)); - dates.push(subDays(resetHours(new Date()), 5)); - dates.push(subDays(resetHours(new Date()), 4)); - dates.push(subDays(resetHours(new Date()), 3)); - dates.push(subDays(resetHours(new Date()), 2)); - dates.push(subDays(resetHours(new Date()), 1)); - dates.push(resetHours(new Date())); - - dates = uniq( - dates.map((date) => { - return date.getTime(); - }) - ) - .map((timestamp) => { - return new Date(timestamp); - }) - .sort((a, b) => { - return a.getTime() - b.getTime(); - }); - - let exchangeRatesByCurrency = - await this.exchangeRateDataService.getExchangeRatesByCurrency({ - currencies: uniq(Object.values(currencies)), - endDate: endOfDay(endDate), - startDate: this.getStartDate(), - targetCurrency: this.currency - }); - - const { - dataProviderInfos, - errors: currentRateErrors, - values: marketSymbols - } = await this.currentRateService.getValues({ - dataGatheringItems, - dateQuery: { - in: dates - } - }); - - this.dataProviderInfos = dataProviderInfos; - - const marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - } = {}; - - for (const marketSymbol of marketSymbols) { - const date = format(marketSymbol.date, DATE_FORMAT); - - if (!marketSymbolMap[date]) { - marketSymbolMap[date] = {}; - } - - if (marketSymbol.marketPrice) { - marketSymbolMap[date][marketSymbol.symbol] = new Big( - marketSymbol.marketPrice - ); - } - } - - const endDateString = format(endDate, DATE_FORMAT); - - if (firstIndex > 0) { - firstIndex--; - } - - const positions: TimelinePosition[] = []; - let hasAnySymbolMetricsErrors = false; - - const errors: ResponseError['errors'] = []; - - for (const item of lastTransactionPoint.items) { - const marketPriceInBaseCurrency = ( - marketSymbolMap[endDateString]?.[item.symbol] ?? item.averagePrice - ).mul( - exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[ - endDateString - ] - ); - - const { - grossPerformance, - grossPerformancePercentage, - grossPerformancePercentageWithCurrencyEffect, - grossPerformanceWithCurrencyEffect, - hasErrors, - netPerformance, - netPerformancePercentage, - netPerformancePercentageWithCurrencyEffect, - netPerformanceWithCurrencyEffect, - timeWeightedInvestment, - timeWeightedInvestmentWithCurrencyEffect, - totalDividend, - totalDividendInBaseCurrency, - totalInvestment, - totalInvestmentWithCurrencyEffect - } = this.getSymbolMetrics({ - marketSymbolMap, - start, - dataSource: item.dataSource, - end: endDate, - exchangeRates: - exchangeRatesByCurrency[`${item.currency}${this.currency}`], - symbol: item.symbol - }); - - hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; - - positions.push({ - dividend: totalDividend, - dividendInBaseCurrency: totalDividendInBaseCurrency, - timeWeightedInvestment, - timeWeightedInvestmentWithCurrencyEffect, - averagePrice: item.averagePrice, - currency: item.currency, - dataSource: item.dataSource, - fee: item.fee, - firstBuyDate: item.firstBuyDate, - grossPerformance: !hasErrors ? grossPerformance ?? null : null, - grossPerformancePercentage: !hasErrors - ? grossPerformancePercentage ?? null - : null, - grossPerformancePercentageWithCurrencyEffect: !hasErrors - ? grossPerformancePercentageWithCurrencyEffect ?? null - : null, - grossPerformanceWithCurrencyEffect: !hasErrors - ? grossPerformanceWithCurrencyEffect ?? null - : null, - investment: totalInvestment, - investmentWithCurrencyEffect: totalInvestmentWithCurrencyEffect, - marketPrice: - marketSymbolMap[endDateString]?.[item.symbol]?.toNumber() ?? null, - marketPriceInBaseCurrency: - marketPriceInBaseCurrency?.toNumber() ?? null, - netPerformance: !hasErrors ? netPerformance ?? null : null, - netPerformancePercentage: !hasErrors - ? netPerformancePercentage ?? null - : null, - netPerformancePercentageWithCurrencyEffect: !hasErrors - ? netPerformancePercentageWithCurrencyEffect ?? null - : null, - netPerformanceWithCurrencyEffect: !hasErrors - ? netPerformanceWithCurrencyEffect ?? null - : null, - quantity: item.quantity, - symbol: item.symbol, - tags: item.tags, - transactionCount: item.transactionCount, - valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( - item.quantity - ) - }); - - if ( - (hasErrors || - currentRateErrors.find(({ dataSource, symbol }) => { - return dataSource === item.dataSource && symbol === item.symbol; - })) && - item.investment.gt(0) - ) { - errors.push({ dataSource: item.dataSource, symbol: item.symbol }); - } - } - - const overall = this.calculateOverallPerformance(positions); - - return { - ...overall, - errors, - positions, - hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors - }; - } - - public getDataProviderInfos() { - return this.dataProviderInfos; - } - - public getInvestments(): { date: string; investment: Big }[] { - if (this.transactionPoints.length === 0) { - return []; - } - - return this.transactionPoints.map((transactionPoint) => { - return { - date: transactionPoint.date, - investment: transactionPoint.items.reduce( - (investment, transactionPointSymbol) => - investment.plus(transactionPointSymbol.investment), - new Big(0) - ) - }; - }); - } - - public getInvestmentsByGroup({ - data, - groupBy - }: { - data: HistoricalDataItem[]; - groupBy: GroupBy; - }): InvestmentItem[] { - const groupedData: { [dateGroup: string]: Big } = {}; - - for (const { date, investmentValueWithCurrencyEffect } of data) { - const dateGroup = - groupBy === 'month' ? date.substring(0, 7) : date.substring(0, 4); - groupedData[dateGroup] = (groupedData[dateGroup] ?? new Big(0)).plus( - investmentValueWithCurrencyEffect - ); - } - - return Object.keys(groupedData).map((dateGroup) => ({ - date: groupBy === 'month' ? `${dateGroup}-01` : `${dateGroup}-01-01`, - investment: groupedData[dateGroup].toNumber() - })); - } - - private calculateOverallPerformance(positions: TimelinePosition[]) { +export class TWRPortfolioCalculator extends PortfolioCalculator { + protected calculateOverallPerformance( + positions: TimelinePosition[] + ): CurrentPositions { let currentValueInBaseCurrency = new Big(0); let grossPerformance = new Big(0); let grossPerformanceWithCurrencyEffect = new Big(0); @@ -754,119 +120,12 @@ export class PortfolioCalculator { ? new Big(0) : grossPerformanceWithCurrencyEffect.div( totalTimeWeightedInvestmentWithCurrencyEffect - ) + ), + positions }; } - public getStartDate() { - return this.transactionPoints.length > 0 - ? parseDate(this.transactionPoints[0].date) - : new Date(); - } - - public getTransactionPoints() { - return this.transactionPoints; - } - - private computeTransactionPoints() { - this.transactionPoints = []; - const symbols: { [symbol: string]: TransactionPointSymbol } = {}; - - let lastDate: string = null; - let lastTransactionPoint: TransactionPoint = null; - - for (const { - fee, - date, - quantity, - SymbolProfile, - tags, - type, - unitPrice - } of this.orders) { - let currentTransactionPointItem: TransactionPointSymbol; - const oldAccumulatedSymbol = symbols[SymbolProfile.symbol]; - - const factor = getFactor(type); - - if (oldAccumulatedSymbol) { - let investment = oldAccumulatedSymbol.investment; - - const newQuantity = quantity - .mul(factor) - .plus(oldAccumulatedSymbol.quantity); - - if (type === 'BUY') { - investment = oldAccumulatedSymbol.investment.plus( - quantity.mul(unitPrice) - ); - } else if (type === 'SELL') { - investment = oldAccumulatedSymbol.investment.minus( - quantity.mul(oldAccumulatedSymbol.averagePrice) - ); - } - - currentTransactionPointItem = { - investment, - tags, - averagePrice: newQuantity.gt(0) - ? investment.div(newQuantity) - : new Big(0), - currency: SymbolProfile.currency, - dataSource: SymbolProfile.dataSource, - dividend: new Big(0), - fee: fee.plus(oldAccumulatedSymbol.fee), - firstBuyDate: oldAccumulatedSymbol.firstBuyDate, - quantity: newQuantity, - symbol: SymbolProfile.symbol, - transactionCount: oldAccumulatedSymbol.transactionCount + 1 - }; - } else { - currentTransactionPointItem = { - fee, - tags, - averagePrice: unitPrice, - currency: SymbolProfile.currency, - dataSource: SymbolProfile.dataSource, - dividend: new Big(0), - firstBuyDate: date, - investment: unitPrice.mul(quantity).mul(factor), - quantity: quantity.mul(factor), - symbol: SymbolProfile.symbol, - transactionCount: 1 - }; - } - - symbols[SymbolProfile.symbol] = currentTransactionPointItem; - - const items = lastTransactionPoint?.items ?? []; - - const newItems = items.filter(({ symbol }) => { - return symbol !== SymbolProfile.symbol; - }); - - newItems.push(currentTransactionPointItem); - - newItems.sort((a, b) => { - return a.symbol?.localeCompare(b.symbol); - }); - - if (lastDate !== date || lastTransactionPoint === null) { - lastTransactionPoint = { - date, - items: newItems - }; - - this.transactionPoints.push(lastTransactionPoint); - } else { - lastTransactionPoint.items = newItems; - } - - lastDate = date; - } - } - - private getSymbolMetrics({ + protected getSymbolMetrics({ dataSource, end, exchangeRates, diff --git a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts b/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts index cf759b7ac..308cc4037 100644 --- a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts @@ -16,4 +16,5 @@ export interface CurrentPositions extends ResponseError { netPerformancePercentageWithCurrencyEffect: Big; positions: TimelinePosition[]; totalInvestment: Big; + totalInvestmentWithCurrencyEffect: Big; } diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts similarity index 100% rename from apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts rename to apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts diff --git a/apps/api/src/app/portfolio/portfolio.module.ts b/apps/api/src/app/portfolio/portfolio.module.ts index 4b5034979..6b06bf02d 100644 --- a/apps/api/src/app/portfolio/portfolio.module.ts +++ b/apps/api/src/app/portfolio/portfolio.module.ts @@ -15,6 +15,7 @@ import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/sym import { Module } from '@nestjs/common'; +import { PortfolioCalculatorFactory } from './calculator/portfolio-calculator.factory'; import { CurrentRateService } from './current-rate.service'; import { PortfolioController } from './portfolio.controller'; import { PortfolioService } from './portfolio.service'; @@ -41,6 +42,7 @@ import { RulesService } from './rules.service'; AccountBalanceService, AccountService, CurrentRateService, + PortfolioCalculatorFactory, PortfolioService, RulesService ] diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 8384427c3..566ad4049 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -3,7 +3,6 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface'; import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { OrderService } from '@ghostfolio/api/app/order/order.service'; -import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { UserService } from '@ghostfolio/api/app/user/user.service'; import { getFactor, @@ -81,7 +80,11 @@ import { } from 'date-fns'; import { isEmpty, last, uniq, uniqBy } from 'lodash'; -import { PortfolioCalculator } from './calculator/twr/portfolio-calculator'; +import { PortfolioCalculator } from './calculator/portfolio-calculator'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from './calculator/portfolio-calculator.factory'; import { HistoricalDataContainer, PortfolioPositionDetail @@ -98,7 +101,7 @@ export class PortfolioService { public constructor( private readonly accountBalanceService: AccountBalanceService, private readonly accountService: AccountService, - private readonly currentRateService: CurrentRateService, + private readonly calculatorFactory: PortfolioCalculatorFactory, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly impersonationService: ImpersonationService, @@ -265,11 +268,10 @@ export class PortfolioService { }; } - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: this.request.user.Settings.settings.baseCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: this.request.user.Settings.settings.baseCurrency }); const { items } = await this.getChart({ @@ -354,11 +356,10 @@ export class PortfolioService { withExcludedAccounts }); - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency }); const { startDate } = getInterval( @@ -720,15 +721,14 @@ export class PortfolioService { tags = uniqBy(tags, 'id'); - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities: orders.filter((order) => { tags = tags.concat(order.tags); return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); }), - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency }); const portfolioStart = portfolioCalculator.getStartDate(); @@ -963,11 +963,10 @@ export class PortfolioService { }; } - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: this.request.user.Settings.settings.baseCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: this.request.user.Settings.settings.baseCurrency }); const currentPositions = await portfolioCalculator.getCurrentPositions( @@ -1152,11 +1151,10 @@ export class PortfolioService { }; } - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency }); const { @@ -1270,11 +1268,10 @@ export class PortfolioService { types: ['BUY', 'SELL'] }); - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: this.request.user.Settings.settings.baseCurrency }); const currentPositions = await portfolioCalculator.getCurrentPositions( @@ -1772,12 +1769,12 @@ export class PortfolioService { const daysInMarket = differenceInDays(new Date(), firstOrderDate); - const annualizedPerformancePercent = new PortfolioCalculator({ - activities: [], - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService - }) + const annualizedPerformancePercent = this.calculatorFactory + .createCalculator({ + activities: [], + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency + }) .getAnnualizedPerformancePercent({ daysInMarket, netPerformancePercent: new Big( @@ -1787,12 +1784,12 @@ export class PortfolioService { ?.toNumber(); const annualizedPerformancePercentWithCurrencyEffect = - new PortfolioCalculator({ - activities: [], - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService - }) + this.calculatorFactory + .createCalculator({ + activities: [], + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency + }) .getAnnualizedPerformancePercent({ daysInMarket, netPerformancePercent: new Big( From 1b81409b35117321cceed0177b7f30786ff2b095 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 1 Apr 2024 09:02:10 +0200 Subject: [PATCH 07/14] Add OpenAlternative logo (#3225) --- .../src/app/pages/landing/landing-page.html | 6 +++--- .../src/app/pages/landing/landing-page.scss | 9 +++------ .../src/assets/images/logo-openalternative.svg | 11 +++++++++++ .../src/assets/images/logo-openstartup.png | Bin 57189 -> 0 bytes 4 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 apps/client/src/assets/images/logo-openalternative.svg delete mode 100644 apps/client/src/assets/images/logo-openstartup.png diff --git a/apps/client/src/app/pages/landing/landing-page.html b/apps/client/src/app/pages/landing/landing-page.html index e48b5e6ed..579b35702 100644 --- a/apps/client/src/app/pages/landing/landing-page.html +++ b/apps/client/src/app/pages/landing/landing-page.html @@ -152,10 +152,10 @@
diff --git a/apps/client/src/app/pages/landing/landing-page.scss b/apps/client/src/app/pages/landing/landing-page.scss index 6d5578ffb..6a8dd8ec5 100644 --- a/apps/client/src/app/pages/landing/landing-page.scss +++ b/apps/client/src/app/pages/landing/landing-page.scss @@ -57,12 +57,8 @@ mask-image: url('/assets/images/logo-hacker-news.svg'); } - &.logo-openstartup { - background-image: url('/assets/images/logo-openstartup.png'); - background-position: center; - background-repeat: no-repeat; - background-size: contain; - filter: grayscale(1); + &.logo-openalternative { + mask-image: url('/assets/images/logo-openalternative.svg'); } &.logo-privacy-tools { @@ -133,6 +129,7 @@ &.logo-alternative-to, &.logo-dev-community, &.logo-hacker-news, + &.logo-openalternative, &.logo-privacy-tools, &.logo-reddit, &.logo-sackgeld, diff --git a/apps/client/src/assets/images/logo-openalternative.svg b/apps/client/src/assets/images/logo-openalternative.svg new file mode 100644 index 000000000..b8488e9ac --- /dev/null +++ b/apps/client/src/assets/images/logo-openalternative.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/client/src/assets/images/logo-openstartup.png b/apps/client/src/assets/images/logo-openstartup.png deleted file mode 100644 index 1eaa2c43017fddd6cdfb32408bea9040870423c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57189 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 Date: Mon, 1 Apr 2024 09:22:35 +0200 Subject: [PATCH 08/14] Bugfix/fix duplicated tags in position detail dialog (#3224) * Fix duplicated tags * Update changelog --- CHANGELOG.md | 4 ++++ apps/api/src/app/portfolio/portfolio.service.ts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a0b55060..7da7e2f93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) - Introduced a factory for the portfolio calculations to support different algorithms in future +### Fixed + +- Fixed the duplicated tags in the position detail dialog + ## 2.69.0 - 2024-03-30 ### Added diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 566ad4049..0bdafec48 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -719,8 +719,6 @@ export class PortfolioService { { dataSource: aDataSource, symbol: aSymbol } ]); - tags = uniqBy(tags, 'id'); - const portfolioCalculator = this.calculatorFactory.createCalculator({ activities: orders.filter((order) => { tags = tags.concat(order.tags); @@ -731,6 +729,8 @@ export class PortfolioService { currency: userCurrency }); + tags = uniqBy(tags, 'id'); + const portfolioStart = portfolioCalculator.getStartDate(); const transactionPoints = portfolioCalculator.getTransactionPoints(); From d7b579e3e86bf9bf7973b60322c821a69bd15559 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:42:15 +0200 Subject: [PATCH 09/14] Feature/refactor getAnnualizedPerformancePercent to portfolio calculator (#3226) * Move getAnnualizedPerformancePercent() to portfolio calculator --- .../calculator/portfolio-calculator.ts | 19 +---- .../twr/portfolio-calculator.spec.ts | 68 +--------------- .../app/portfolio/portfolio.service.spec.ts | 78 +++++++++++++++++++ .../src/app/portfolio/portfolio.service.ts | 56 ++++++------- 4 files changed, 111 insertions(+), 110 deletions(-) create mode 100644 apps/api/src/app/portfolio/portfolio.service.spec.ts diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index c3edc86d9..48fcaf343 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -29,7 +29,7 @@ import { max, subDays } from 'date-fns'; -import { isNumber, last, uniq } from 'lodash'; +import { last, uniq } from 'lodash'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -80,23 +80,6 @@ export abstract class PortfolioCalculator { positions: TimelinePosition[] ): CurrentPositions; - public getAnnualizedPerformancePercent({ - daysInMarket, - netPerformancePercent - }: { - daysInMarket: number; - netPerformancePercent: 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) - ).minus(1); - } - - return new Big(0); - } - public async getChartData({ end = new Date(Date.now()), start, diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts index b68f4358d..365593846 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts @@ -1,12 +1,7 @@ -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { Big } from 'big.js'; - describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; @@ -28,64 +23,5 @@ describe('PortfolioCalculator', () => { ); }); - describe('annualized performance percentage', () => { - it('Get annualized performance', async () => { - const portfolioCalculator = factory.createCalculator({ - activities: [], - calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' - }); - - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: NaN, // differenceInDays of date-fns returns NaN for the same day - netPerformancePercent: new Big(0) - }) - .toNumber() - ).toEqual(0); - - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 0, - netPerformancePercent: new Big(0) - }) - .toNumber() - ).toEqual(0); - - /** - * Source: https://www.readyratios.com/reference/analysis/annualized_rate.html - */ - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 65, // < 1 year - netPerformancePercent: new Big(0.1025) - }) - .toNumber() - ).toBeCloseTo(0.729705); - - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 365, // 1 year - netPerformancePercent: new Big(0.05) - }) - .toNumber() - ).toBeCloseTo(0.05); - - /** - * Source: https://www.investopedia.com/terms/a/annualized-total-return.asp#annualized-return-formula-and-calculation - */ - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 575, // > 1 year - netPerformancePercent: new Big(0.2374) - }) - .toNumber() - ).toBeCloseTo(0.145); - }); - }); + test.skip('Skip empty test', () => 1); }); diff --git a/apps/api/src/app/portfolio/portfolio.service.spec.ts b/apps/api/src/app/portfolio/portfolio.service.spec.ts new file mode 100644 index 000000000..7654b7df3 --- /dev/null +++ b/apps/api/src/app/portfolio/portfolio.service.spec.ts @@ -0,0 +1,78 @@ +import { Big } from 'big.js'; + +import { PortfolioService } from './portfolio.service'; + +describe('PortfolioService', () => { + let portfolioService: PortfolioService; + + beforeAll(async () => { + portfolioService = new PortfolioService( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + }); + + describe('annualized performance percentage', () => { + it('Get annualized performance', async () => { + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: NaN, // differenceInDays of date-fns returns NaN for the same day + netPerformancePercent: new Big(0) + }) + .toNumber() + ).toEqual(0); + + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 0, + netPerformancePercent: new Big(0) + }) + .toNumber() + ).toEqual(0); + + /** + * Source: https://www.readyratios.com/reference/analysis/annualized_rate.html + */ + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 65, // < 1 year + netPerformancePercent: new Big(0.1025) + }) + .toNumber() + ).toBeCloseTo(0.729705); + + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 365, // 1 year + netPerformancePercent: new Big(0.05) + }) + .toNumber() + ).toBeCloseTo(0.05); + + /** + * Source: https://www.investopedia.com/terms/a/annualized-total-return.asp#annualized-return-formula-and-calculation + */ + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 575, // > 1 year + netPerformancePercent: new Big(0.2374) + }) + .toNumber() + ).toBeCloseTo(0.145); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 0bdafec48..17a1ea4a0 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -78,7 +78,7 @@ import { parseISO, set } from 'date-fns'; -import { isEmpty, last, uniq, uniqBy } from 'lodash'; +import { isEmpty, isNumber, last, uniq, uniqBy } from 'lodash'; import { PortfolioCalculator } from './calculator/portfolio-calculator'; import { @@ -217,6 +217,24 @@ export class PortfolioService { }; } + public getAnnualizedPerformancePercent({ + daysInMarket, + netPerformancePercent + }: { + daysInMarket: number; + netPerformancePercent: 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) + ).minus(1); + } + + return new Big(0); + } + public async getDividends({ activities, groupBy @@ -1769,34 +1787,20 @@ export class PortfolioService { const daysInMarket = differenceInDays(new Date(), firstOrderDate); - const annualizedPerformancePercent = this.calculatorFactory - .createCalculator({ - activities: [], - calculationType: PerformanceCalculationType.TWR, - currency: userCurrency - }) - .getAnnualizedPerformancePercent({ + const annualizedPerformancePercent = this.getAnnualizedPerformancePercent({ + daysInMarket, + netPerformancePercent: new Big( + performanceInformation.performance.currentNetPerformancePercent + ) + })?.toNumber(); + + const annualizedPerformancePercentWithCurrencyEffect = + this.getAnnualizedPerformancePercent({ daysInMarket, netPerformancePercent: new Big( - performanceInformation.performance.currentNetPerformancePercent + performanceInformation.performance.currentNetPerformancePercentWithCurrencyEffect ) - }) - ?.toNumber(); - - const annualizedPerformancePercentWithCurrencyEffect = - this.calculatorFactory - .createCalculator({ - activities: [], - calculationType: PerformanceCalculationType.TWR, - currency: userCurrency - }) - .getAnnualizedPerformancePercent({ - daysInMarket, - netPerformancePercent: new Big( - performanceInformation.performance.currentNetPerformancePercentWithCurrencyEffect - ) - }) - ?.toNumber(); + })?.toNumber(); return { ...performanceInformation.performance, From efdc9b387fa89310e135a315654a7ec8fabb0d2b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 1 Apr 2024 13:24:00 +0200 Subject: [PATCH 10/14] Eliminate ghostfolio-style.scss (#3228) --- apps/client/src/app/app.component.scss | 2 -- .../app/components/access-table/access-table.component.scss | 2 -- .../components/accounts-table/accounts-table.component.scss | 2 -- apps/client/src/app/components/admin-jobs/admin-jobs.scss | 2 -- .../admin-market-data-detail.component.scss | 2 -- .../app/components/admin-market-data/admin-market-data.scss | 2 -- .../src/app/components/admin-overview/admin-overview.scss | 2 -- .../components/admin-platform/admin-platform.component.scss | 2 -- .../components/admin-settings/admin-settings.component.scss | 2 -- .../src/app/components/admin-tag/admin-tag.component.scss | 2 -- apps/client/src/app/components/admin-users/admin-users.scss | 2 -- apps/client/src/app/components/header/header.component.scss | 2 -- .../src/app/components/home-holdings/home-holdings.scss | 2 -- apps/client/src/app/components/home-market/home-market.scss | 2 -- .../src/app/components/home-overview/home-overview.scss | 2 -- .../src/app/components/home-summary/home-summary.scss | 2 -- .../src/app/components/positions/positions.component.scss | 6 ++---- apps/client/src/app/pages/about/about-page.scss | 2 -- apps/client/src/app/pages/admin/admin-page.scss | 2 -- apps/client/src/app/pages/home/home-page.scss | 2 -- apps/client/src/app/pages/landing/landing-page.scss | 2 -- apps/client/src/app/pages/portfolio/portfolio-page.scss | 2 -- .../src/app/pages/user-account/user-account-page.scss | 2 -- apps/client/src/app/pages/zen/zen-page.scss | 2 -- apps/client/src/styles/ghostfolio-style.scss | 4 ---- apps/client/src/styles/theme.scss | 3 +++ .../lib/account-balances/account-balances.component.scss | 2 -- .../lib/activities-filter/activities-filter.component.scss | 2 -- .../lib/activities-table/activities-table.component.scss | 2 -- .../ui/src/lib/holdings-table/holdings-table.component.scss | 2 -- 30 files changed, 5 insertions(+), 62 deletions(-) delete mode 100644 apps/client/src/styles/ghostfolio-style.scss diff --git a/apps/client/src/app/app.component.scss b/apps/client/src/app/app.component.scss index 21d33e3c9..a23e94fbb 100644 --- a/apps/client/src/app/app.component.scss +++ b/apps/client/src/app/app.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; min-height: 100svh; diff --git a/apps/client/src/app/components/access-table/access-table.component.scss b/apps/client/src/app/components/access-table/access-table.component.scss index f506edfc6..22a5d6732 100644 --- a/apps/client/src/app/components/access-table/access-table.component.scss +++ b/apps/client/src/app/components/access-table/access-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.scss b/apps/client/src/app/components/accounts-table/accounts-table.component.scss index 39e455dca..e934483db 100644 --- a/apps/client/src/app/components/accounts-table/accounts-table.component.scss +++ b/apps/client/src/app/components/accounts-table/accounts-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.scss b/apps/client/src/app/components/admin-jobs/admin-jobs.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.scss +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss index 8121fc119..a03533589 100644 --- a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss +++ b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; font-size: 0.9rem; diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.scss b/apps/client/src/app/components/admin-market-data/admin-market-data.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.scss +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-overview/admin-overview.scss b/apps/client/src/app/components/admin-overview/admin-overview.scss index 25209ac97..a4ae1edd2 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.scss +++ b/apps/client/src/app/components/admin-overview/admin-overview.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.scss b/apps/client/src/app/components/admin-platform/admin-platform.component.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.scss +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.scss b/apps/client/src/app/components/admin-settings/admin-settings.component.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.scss +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.scss b/apps/client/src/app/components/admin-tag/admin-tag.component.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.scss +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-users/admin-users.scss b/apps/client/src/app/components/admin-users/admin-users.scss index f06a9d825..e4990bf59 100644 --- a/apps/client/src/app/components/admin-users/admin-users.scss +++ b/apps/client/src/app/components/admin-users/admin-users.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/header/header.component.scss b/apps/client/src/app/components/header/header.component.scss index 0c6557ddd..04d634d3b 100644 --- a/apps/client/src/app/components/header/header.component.scss +++ b/apps/client/src/app/components/header/header.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; z-index: 999; diff --git a/apps/client/src/app/components/home-holdings/home-holdings.scss b/apps/client/src/app/components/home-holdings/home-holdings.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.scss +++ b/apps/client/src/app/components/home-holdings/home-holdings.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/home-market/home-market.scss b/apps/client/src/app/components/home-market/home-market.scss index f9e5e6275..5b523160d 100644 --- a/apps/client/src/app/components/home-market/home-market.scss +++ b/apps/client/src/app/components/home-market/home-market.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/home-overview/home-overview.scss b/apps/client/src/app/components/home-overview/home-overview.scss index 9f8a1ce49..3a692b28d 100644 --- a/apps/client/src/app/components/home-overview/home-overview.scss +++ b/apps/client/src/app/components/home-overview/home-overview.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; height: 100%; diff --git a/apps/client/src/app/components/home-summary/home-summary.scss b/apps/client/src/app/components/home-summary/home-summary.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/home-summary/home-summary.scss +++ b/apps/client/src/app/components/home-summary/home-summary.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/positions/positions.component.scss b/apps/client/src/app/components/positions/positions.component.scss index 90eff65ea..d3e8995a1 100644 --- a/apps/client/src/app/components/positions/positions.component.scss +++ b/apps/client/src/app/components/positions/positions.component.scss @@ -1,11 +1,9 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; gf-position { &:nth-child(even) { - background-color: rgba(0, 0, 0, $alpha-hover); + background-color: rgba(0, 0, 0, var(--gf-theme-alpha-hover)); } } } @@ -13,7 +11,7 @@ :host-context(.is-dark-theme) { gf-position { &:nth-child(even) { - background-color: rgba(255, 255, 255, $alpha-hover); + background-color: rgba(255, 255, 255, var(--gf-theme-alpha-hover)); } } } diff --git a/apps/client/src/app/pages/about/about-page.scss b/apps/client/src/app/pages/about/about-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/about/about-page.scss +++ b/apps/client/src/app/pages/about/about-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/admin/admin-page.scss b/apps/client/src/app/pages/admin/admin-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/admin/admin-page.scss +++ b/apps/client/src/app/pages/admin/admin-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/home/home-page.scss b/apps/client/src/app/pages/home/home-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/home/home-page.scss +++ b/apps/client/src/app/pages/home/home-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/landing/landing-page.scss b/apps/client/src/app/pages/landing/landing-page.scss index 6a8dd8ec5..0b8736819 100644 --- a/apps/client/src/app/pages/landing/landing-page.scss +++ b/apps/client/src/app/pages/landing/landing-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/pages/portfolio/portfolio-page.scss b/apps/client/src/app/pages/portfolio/portfolio-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page.scss +++ b/apps/client/src/app/pages/portfolio/portfolio-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/user-account/user-account-page.scss b/apps/client/src/app/pages/user-account/user-account-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.scss +++ b/apps/client/src/app/pages/user-account/user-account-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/zen/zen-page.scss b/apps/client/src/app/pages/zen/zen-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/zen/zen-page.scss +++ b/apps/client/src/app/pages/zen/zen-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/styles/ghostfolio-style.scss b/apps/client/src/styles/ghostfolio-style.scss deleted file mode 100644 index 103f4cf14..000000000 --- a/apps/client/src/styles/ghostfolio-style.scss +++ /dev/null @@ -1,4 +0,0 @@ -$mat-css-dark-theme-selector: '.is-dark-theme'; - -$alpha-disabled-text: 0.38; -$alpha-hover: 0.04; diff --git a/apps/client/src/styles/theme.scss b/apps/client/src/styles/theme.scss index 8114402d5..cc9b164e6 100644 --- a/apps/client/src/styles/theme.scss +++ b/apps/client/src/styles/theme.scss @@ -3,6 +3,8 @@ $dark-primary-text: rgba(black, 0.87); $light-primary-text: white; +$mat-css-dark-theme-selector: '.is-dark-theme'; + $gf-primary: ( 50: var(--gf-theme-primary-50), 100: var(--gf-theme-primary-100), @@ -106,6 +108,7 @@ $gf-theme-dark: mat.define-dark-theme( } :root { + --gf-theme-alpha-hover: 0.04; --gf-theme-primary-500: #36cfcc; --gf-theme-primary-500-rgb: 0, 187, 255; --gf-theme-secondary-500: #3686cf; diff --git a/libs/ui/src/lib/account-balances/account-balances.component.scss b/libs/ui/src/lib/account-balances/account-balances.component.scss index b5b58f67e..5d4e87f30 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.scss +++ b/libs/ui/src/lib/account-balances/account-balances.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/libs/ui/src/lib/activities-filter/activities-filter.component.scss b/libs/ui/src/lib/activities-filter/activities-filter.component.scss index 7d0649bfc..07964fdfa 100644 --- a/libs/ui/src/lib/activities-filter/activities-filter.component.scss +++ b/libs/ui/src/lib/activities-filter/activities-filter.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.scss b/libs/ui/src/lib/activities-table/activities-table.component.scss index 003303f95..bb5e11691 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.scss +++ b/libs/ui/src/lib/activities-table/activities-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.scss b/libs/ui/src/lib/holdings-table/holdings-table.component.scss index a33b78aff..8e321bcf1 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.scss +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; From 6f3cce1c5f2cb5bb59d2051f912db8e7d5bc95bb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:17:16 +0200 Subject: [PATCH 11/14] Feature/disable option to update cash balance if date is not today (#3229) * Disable option to update cash balance if date is not today * Update changelog --- CHANGELOG.md | 1 + .../create-or-update-activity-dialog.component.ts | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da7e2f93..0e0559738 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Disabled the option to update the cash balance of an account if date is not today - Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) - Introduced a factory for the portfolio calculations to support different algorithms in future diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index b628aba46..4fb8e9d81 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -275,6 +275,17 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { } ); + this.activityForm.controls['date'].valueChanges.subscribe(() => { + if (isToday(this.activityForm.controls['date'].value)) { + this.activityForm.controls['updateAccountBalance'].enable(); + } else { + this.activityForm.controls['updateAccountBalance'].disable(); + this.activityForm.controls['updateAccountBalance'].setValue(false); + } + + this.changeDetectorRef.markForCheck(); + }); + this.activityForm.controls['searchSymbol'].valueChanges.subscribe(() => { if (this.activityForm.controls['searchSymbol'].invalid) { this.data.activity.SymbolProfile = null; From ca7717f9c56a70dc5f6fb2ab1ddaa8f1707d36d5 Mon Sep 17 00:00:00 2001 From: Bastien Jeannelle <48835068+Sonlis@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:26:14 +0300 Subject: [PATCH 12/14] Bugfix/Enable tini in docker compose files instead of adding it to the Dockerfile (#3232) * Enable tini in docker compose files instead of adding it to the Dockerfile * Update changelog --- CHANGELOG.md | 2 ++ Dockerfile | 7 ------- docker/docker-compose.build.yml | 1 + docker/docker-compose.yml | 1 + 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e0559738..c0446ee8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Set up the language localization for Chinese (`zh`) +- Added `init: true` to the `docker-compose` files (`docker-compose.yml` and `docker-compose.build.yml`) to avoid zombie processes - Set up _Webpack Bundle Analyzer_ ### Changed @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the duplicated tags in the position detail dialog +- Removed `Tini` from the docker image ## 2.69.0 - 2024-03-30 diff --git a/Dockerfile b/Dockerfile index aa578e235..f9396d0e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,13 +56,6 @@ RUN apt update && apt install -y \ openssl \ && rm -rf /var/lib/apt/lists/* -# Add tini, which is an init process that handles signaling within the container -# and with the host. See https://github.com/krallin/tini -ENV TINI_VERSION v0.19.0 -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini -RUN chmod +x /tini -ENTRYPOINT ["/tini", "--"] - COPY --from=builder /ghostfolio/dist/apps /ghostfolio/apps COPY ./docker/entrypoint.sh /ghostfolio/entrypoint.sh WORKDIR /ghostfolio/apps/api diff --git a/docker/docker-compose.build.yml b/docker/docker-compose.build.yml index 2ac90b7c1..7ad52be7d 100644 --- a/docker/docker-compose.build.yml +++ b/docker/docker-compose.build.yml @@ -2,6 +2,7 @@ version: '3.9' services: ghostfolio: build: ../ + init: true env_file: - ../.env environment: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 007a46883..d2dbb8112 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,6 +2,7 @@ version: '3.9' services: ghostfolio: image: ghostfolio/ghostfolio:latest + init: true env_file: - ../.env environment: From 26b9660e110f67bbdb49975eadf4e5fdf94d56d6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:29:47 +0200 Subject: [PATCH 13/14] Release 2.70.0 (#3234) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0446ee8f..2c36c692d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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). -## Unreleased +## 2.70.0 - 2024-04-02 ### Added diff --git a/package.json b/package.json index 05ffd3e49..5db51af5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.69.0", + "version": "2.70.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 371c999fbc8a94ac6ee2b610da148d011bec457f Mon Sep 17 00:00:00 2001 From: Arshad Jamal Date: Wed, 3 Apr 2024 23:17:53 +0530 Subject: [PATCH 14/14] Feature/Add dividend yield to position detail dialog (#2636) * Add dividend yield to position detail dialog * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 6 +++ .../portfolio-position-detail.interface.ts | 2 + .../src/app/portfolio/portfolio.service.ts | 24 ++++++++++++ .../position-detail-dialog.component.ts | 4 ++ .../position-detail-dialog.html | 39 +++++++++++++------ 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c36c692d..a6513785b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ 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). +## Unreleased + +### Added + +- Added the dividend yield to the position detail dialog (experimental) + ## 2.70.0 - 2024-04-02 ### Added diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts index 2925ca9bc..c058a0249 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts @@ -12,6 +12,8 @@ export interface PortfolioPositionDetail { averagePrice: number; dataProviderInfo: DataProviderInfo; dividendInBaseCurrency: number; + dividendYieldPercent: number; + dividendYieldPercentWithCurrencyEffect: number; feeInBaseCurrency: number; firstBuyDate: string; grossPerformance: number; diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 17a1ea4a0..3b8a42d89 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -710,6 +710,8 @@ export class PortfolioService { averagePrice: undefined, dataProviderInfo: undefined, dividendInBaseCurrency: undefined, + dividendYieldPercent: undefined, + dividendYieldPercentWithCurrencyEffect: undefined, feeInBaseCurrency: undefined, firstBuyDate: undefined, grossPerformance: undefined, @@ -769,6 +771,8 @@ export class PortfolioService { firstBuyDate, marketPrice, quantity, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, transactionCount } = position; @@ -781,6 +785,21 @@ export class PortfolioService { return Account; }); + const dividendYieldPercent = this.getAnnualizedPerformancePercent({ + daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), + netPerformancePercent: dividendInBaseCurrency.div( + timeWeightedInvestment + ) + }); + + const dividendYieldPercentWithCurrencyEffect = + this.getAnnualizedPerformancePercent({ + daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), + netPerformancePercent: dividendInBaseCurrency.div( + timeWeightedInvestmentWithCurrencyEffect + ) + }); + const historicalData = await this.dataProviderService.getHistorical( [{ dataSource, symbol: aSymbol }], 'day', @@ -854,6 +873,9 @@ export class PortfolioService { averagePrice: averagePrice.toNumber(), dataProviderInfo: portfolioCalculator.getDataProviderInfos()?.[0], dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), + dividendYieldPercent: dividendYieldPercent.toNumber(), + dividendYieldPercentWithCurrencyEffect: + dividendYieldPercentWithCurrencyEffect.toNumber(), feeInBaseCurrency: this.exchangeRateDataService.toCurrency( fee.toNumber(), SymbolProfile.currency, @@ -930,6 +952,8 @@ export class PortfolioService { averagePrice: 0, dataProviderInfo: undefined, dividendInBaseCurrency: 0, + dividendYieldPercent: 0, + dividendYieldPercentWithCurrencyEffect: 0, feeInBaseCurrency: 0, firstBuyDate: undefined, grossPerformance: undefined, diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts index 6ada2eeb1..bb37b9ed5 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts @@ -48,6 +48,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit { public dataProviderInfo: DataProviderInfo; public dataSource: MatTableDataSource; public dividendInBaseCurrency: number; + public dividendYieldPercentWithCurrencyEffect: number; public feeInBaseCurrency: number; public firstBuyDate: string; public historicalDataItems: LineChartItem[]; @@ -95,6 +96,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit { averagePrice, dataProviderInfo, dividendInBaseCurrency, + dividendYieldPercentWithCurrencyEffect, feeInBaseCurrency, firstBuyDate, historicalData, @@ -119,6 +121,8 @@ export class PositionDetailDialog implements OnDestroy, OnInit { this.dataProviderInfo = dataProviderInfo; this.dataSource = new MatTableDataSource(orders.reverse()); this.dividendInBaseCurrency = dividendInBaseCurrency; + this.dividendYieldPercentWithCurrencyEffect = + dividendYieldPercentWithCurrencyEffect; this.feeInBaseCurrency = feeInBaseCurrency; this.firstBuyDate = firstBuyDate; this.historicalDataItems = historicalData.map( diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html index 3a8694c83..3680f5701 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -134,17 +134,29 @@ >Investment
-
- Dividend -
+ @if (dividendInBaseCurrency && user?.settings?.isExperimentalFeatures) { +
+ Dividend +
+
+ Dividend Yield +
+ }
+ @if (user?.settings?.isExperimentalFeatures) { +
+ }
Asset Class