Feature/add emergency fund setup to static portfolio analysis rules (#2400)

* Add new static portfolio analysis rule: Emergency fund setup

* Update changelog
pull/2396/head^2
Thomas Kaul 8 months ago committed by GitHub
parent 5b69dee246
commit 5fa0540936
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Added a new static portfolio analysis rule: Emergency fund setup
### Changed
- Set up the _Inter_ font family

@ -10,6 +10,7 @@ import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rule
import { AccountClusterRiskSingleAccount } from '@ghostfolio/api/models/rules/account-cluster-risk/single-account';
import { CurrencyClusterRiskBaseCurrencyCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/base-currency-current-investment';
import { CurrencyClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/current-investment';
import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup';
import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
@ -1214,12 +1215,6 @@ export class PortfolioService {
userId
});
if (isEmpty(orders)) {
return {
rules: {}
};
}
const portfolioCalculator = new PortfolioCalculator({
currency: userCurrency,
currentRateService: this.currentRateService,
@ -1228,7 +1223,9 @@ export class PortfolioService {
portfolioCalculator.setTransactionPoints(transactionPoints);
const portfolioStart = parseDate(transactionPoints[0].date);
const portfolioStart = parseDate(
transactionPoints[0]?.date ?? format(new Date(), DATE_FORMAT)
);
const currentPositions =
await portfolioCalculator.getCurrentPositions(portfolioStart);
@ -1249,33 +1246,48 @@ export class PortfolioService {
userId
});
const userSettings = <UserSettings>this.request.user.Settings.settings;
return {
rules: {
accountClusterRisk: await this.rulesService.evaluate(
[
new AccountClusterRiskCurrentInvestment(
this.exchangeRateDataService,
accounts
accountClusterRisk: isEmpty(orders)
? undefined
: await this.rulesService.evaluate(
[
new AccountClusterRiskCurrentInvestment(
this.exchangeRateDataService,
accounts
),
new AccountClusterRiskSingleAccount(
this.exchangeRateDataService,
accounts
)
],
userSettings
),
new AccountClusterRiskSingleAccount(
this.exchangeRateDataService,
accounts
)
],
<UserSettings>this.request.user.Settings.settings
),
currencyClusterRisk: await this.rulesService.evaluate(
[
new CurrencyClusterRiskBaseCurrencyCurrentInvestment(
this.exchangeRateDataService,
positions
currencyClusterRisk: isEmpty(orders)
? undefined
: await this.rulesService.evaluate(
[
new CurrencyClusterRiskBaseCurrencyCurrentInvestment(
this.exchangeRateDataService,
positions
),
new CurrencyClusterRiskCurrentInvestment(
this.exchangeRateDataService,
positions
)
],
userSettings
),
new CurrencyClusterRiskCurrentInvestment(
emergencyFund: await this.rulesService.evaluate(
[
new EmergencyFundSetup(
this.exchangeRateDataService,
positions
userSettings.emergencyFund
)
],
<UserSettings>this.request.user.Settings.settings
userSettings
),
fees: await this.rulesService.evaluate(
[
@ -1285,7 +1297,7 @@ export class PortfolioService {
this.getFees({ userCurrency, activities: orders }).toNumber()
)
],
<UserSettings>this.request.user.Settings.settings
userSettings
)
}
};

@ -1,4 +1,5 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import {
PortfolioDetails,
@ -6,16 +7,18 @@ import {
UserSettings
} from '@ghostfolio/common/interfaces';
import { Rule } from '../../rule';
export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
private accounts: PortfolioDetails['accounts'];
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private accounts: PortfolioDetails['accounts']
accounts: PortfolioDetails['accounts']
) {
super(exchangeRateDataService, {
name: 'Investment'
});
this.accounts = accounts;
}
public evaluate(ruleSettings: Settings) {

@ -1,17 +1,20 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { PortfolioDetails, UserSettings } from '@ghostfolio/common/interfaces';
import { Rule } from '../../rule';
export class AccountClusterRiskSingleAccount extends Rule<RuleSettings> {
private accounts: PortfolioDetails['accounts'];
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private accounts: PortfolioDetails['accounts']
accounts: PortfolioDetails['accounts']
) {
super(exchangeRateDataService, {
name: 'Single Account'
});
this.accounts = accounts;
}
public evaluate() {

@ -1,17 +1,20 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces';
import { Rule } from '../../rule';
export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule<Settings> {
private positions: TimelinePosition[];
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: TimelinePosition[]
positions: TimelinePosition[]
) {
super(exchangeRateDataService, {
name: 'Investment: Base Currency'
});
this.positions = positions;
}
public evaluate(ruleSettings: Settings) {

@ -1,17 +1,20 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces';
import { Rule } from '../../rule';
export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> {
private positions: TimelinePosition[];
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: TimelinePosition[]
positions: TimelinePosition[]
) {
super(exchangeRateDataService, {
name: 'Investment'
});
this.positions = positions;
}
public evaluate(ruleSettings: Settings) {

@ -0,0 +1,46 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { UserSettings } from '@ghostfolio/common/interfaces';
export class EmergencyFundSetup extends Rule<Settings> {
private emergencyFund: number;
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
emergencyFund: number
) {
super(exchangeRateDataService, {
name: 'Emergency Fund: Set up'
});
this.emergencyFund = emergencyFund;
}
public evaluate(ruleSettings: Settings) {
if (this.emergencyFund > ruleSettings.threshold) {
return {
evaluation: 'An emergency fund has been set up',
value: true
};
}
return {
evaluation: 'No emergency fund has been set up',
value: false
};
}
public getSettings(aUserSettings: UserSettings): Settings {
return {
baseCurrency: aUserSettings.baseCurrency,
isActive: true,
threshold: 0
};
}
}
interface Settings extends RuleSettings {
baseCurrency: string;
threshold: number;
}

@ -1,22 +1,29 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { UserSettings } from '@ghostfolio/common/interfaces';
import { Rule } from '../../rule';
export class FeeRatioInitialInvestment extends Rule<Settings> {
private fees: number;
private totalInvestment: number;
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private totalInvestment: number,
private fees: number
totalInvestment: number,
fees: number
) {
super(exchangeRateDataService, {
name: 'Investment'
name: 'Fee Ratio'
});
this.fees = fees;
this.totalInvestment = totalInvestment;
}
public evaluate(ruleSettings: Settings) {
const feeRatio = this.fees / this.totalInvestment;
const feeRatio = this.totalInvestment
? this.fees / this.totalInvestment
: 0;
if (feeRatio > ruleSettings.threshold) {
return {

@ -18,6 +18,7 @@ export class FirePageComponent implements OnDestroy, OnInit {
public accountClusterRiskRules: PortfolioReportRule[];
public currencyClusterRiskRules: PortfolioReportRule[];
public deviceType: string;
public emergencyFundRules: PortfolioReportRule[];
public feeRules: PortfolioReportRule[];
public fireWealth: Big;
public hasImpersonationId: boolean;
@ -67,6 +68,8 @@ export class FirePageComponent implements OnDestroy, OnInit {
portfolioReport.rules['accountClusterRisk'] || null;
this.currencyClusterRiskRules =
portfolioReport.rules['currencyClusterRisk'] || null;
this.emergencyFundRules =
portfolioReport.rules['emergencyFund'] || null;
this.feeRules = portfolioReport.rules['fees'] || null;
this.changeDetectorRef.markForCheck();

@ -96,8 +96,10 @@
<div class="col">
<h2 class="h3 mb-3 text-center">X-ray</h2>
<p class="mb-4">
Ghostfolio X-ray uses static analysis to identify potential issues and
risks in your portfolio.
<span i18n
>Ghostfolio X-ray uses static analysis to identify potential issues
and risks in your portfolio.</span
>
<span class="d-none"
>It will be highly configurable in the future: activate / deactivate
rules and customize the thresholds to match your personal investment
@ -106,7 +108,20 @@
</p>
<div class="mb-4">
<h4 class="align-items-center d-flex m-0">
<span>Currency Cluster Risks</span
<span i18n>Emergency Fund</span
><gf-premium-indicator
*ngIf="user?.subscription?.type === 'Basic'"
class="ml-1"
></gf-premium-indicator>
</h4>
<gf-rules
[hasPermissionToCreateOrder]="hasPermissionToCreateOrder"
[rules]="emergencyFundRules"
></gf-rules>
</div>
<div class="mb-4">
<h4 class="align-items-center d-flex m-0">
<span i18n>Currency Cluster Risks</span
><gf-premium-indicator
*ngIf="user?.subscription?.type === 'Basic'"
class="ml-1"
@ -119,7 +134,7 @@
</div>
<div class="mb-4">
<h4 class="align-items-center d-flex m-0">
<span>Account Cluster Risks</span
<span i18n>Account Cluster Risks</span
><gf-premium-indicator
*ngIf="user?.subscription?.type === 'Basic'"
class="ml-1"
@ -132,7 +147,7 @@
</div>
<div>
<h4 class="align-items-center d-flex m-0">
<span>Fees</span
<span i18n>Fees</span
><gf-premium-indicator
*ngIf="user?.subscription?.type === 'Basic'"
class="ml-1"

@ -1274,6 +1274,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
@ -1590,6 +1594,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -3734,6 +3742,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
<source>Portfolio Allocations</source>
@ -8130,6 +8142,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -9927,6 +9943,30 @@
<context context-type="linenumber">312</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<target state="translated">Ghostfolio X-ray nutzt statische Analysen, um potenzielle Probleme und Risiken in deinem Portfolio zu identifizieren.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<target state="translated">Währungsklumpenrisiken</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<target state="translated">Kontoklumpenrisiken</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1272,6 +1272,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
@ -1588,6 +1592,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -3732,6 +3740,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
<source>Portfolio Allocations</source>
@ -8128,6 +8140,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -9925,6 +9941,30 @@
<context context-type="linenumber">312</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<target state="new">Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<target state="new">Currency Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<target state="new">Account Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1603,6 +1603,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
@ -2339,6 +2343,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -3731,6 +3739,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
<source>Portfolio Allocations</source>
@ -8127,6 +8139,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -9924,6 +9940,30 @@
<context context-type="linenumber">312</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<target state="new">Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<target state="new">Currency Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<target state="new">Account Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1272,6 +1272,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
@ -1588,6 +1592,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -3732,6 +3740,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
<source>Portfolio Allocations</source>
@ -8128,6 +8140,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -9925,6 +9941,30 @@
<context context-type="linenumber">312</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<target state="new">Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<target state="new">Currency Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<target state="new">Account Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1271,6 +1271,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
@ -1587,6 +1591,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -3731,6 +3739,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
<source>Portfolio Allocations</source>
@ -8127,6 +8139,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -9924,6 +9940,30 @@
<context context-type="linenumber">312</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<target state="new">Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<target state="new">Currency Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<target state="new">Account Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -1499,6 +1499,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="8cce9d03787606e0052d19c2ae7e7fa5ff785e94" datatype="html">
<source>Buying Power</source>
@ -2263,6 +2267,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -3731,6 +3739,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="a6f322a22d0ae0b95dd9c70d43ba2c92de7ed49b" datatype="html">
<source>Portfolio Allocations</source>
@ -8127,6 +8139,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -9924,6 +9940,30 @@
<context context-type="linenumber">312</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<target state="new">Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<target state="new">Currency Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<target state="new">Account Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -64,6 +64,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -804,6 +808,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -2671,6 +2679,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="311828ec96f91f6f530219b07d5531a8aa507d64" datatype="html">
<source>Cash</source>
@ -2823,6 +2835,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="bf3df1f4eb29a071630eed167406c06f974480b2" datatype="html">
<source>First Buy Date</source>
@ -9924,6 +9940,30 @@
<context context-type="linenumber">312</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<target state="new">Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<target state="new">Currency Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<target state="new">Account Cluster Risks</target>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

@ -64,6 +64,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts</context>
<context context-type="linenumber">14</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts</context>
<context context-type="linenumber">13</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/landing/landing-page.component.ts</context>
<context context-type="linenumber">25</context>
@ -791,6 +795,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html</context>
<context context-type="linenumber">273</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html</context>
<context context-type="linenumber">181</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/blog/blog-page.html</context>
<context context-type="linenumber">5</context>
@ -2504,6 +2512,10 @@
<context context-type="sourcefile">apps/client/src/app/pages/features/features-page.html</context>
<context context-type="linenumber">89</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">150</context>
</context-group>
</trans-unit>
<trans-unit id="311828ec96f91f6f530219b07d5531a8aa507d64" datatype="html">
<source>Cash</source>
@ -2641,6 +2653,10 @@
<context context-type="sourcefile">apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">137</context>
</context-group>
</trans-unit>
<trans-unit id="bf3df1f4eb29a071630eed167406c06f974480b2" datatype="html">
<source>First Buy Date</source>
@ -9370,6 +9386,27 @@
<context context-type="linenumber">11,13</context>
</context-group>
</trans-unit>
<trans-unit id="288b1a62b35a6fab0130723db4cfa06e433922eb" datatype="html">
<source>Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio.</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">100,101</context>
</context-group>
</trans-unit>
<trans-unit id="50760c2140335b2324deaee120f40d9aa64b3238" datatype="html">
<source>Currency Cluster Risks</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">111</context>
</context-group>
</trans-unit>
<trans-unit id="c7b797e5df289241021db16010efb6ac3c6cfb86" datatype="html">
<source>Account Cluster Risks</source>
<context-group purpose="location">
<context context-type="sourcefile">apps/client/src/app/pages/portfolio/fire/fire-page.html</context>
<context context-type="linenumber">124</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>

Loading…
Cancel
Save