Bugfix/improve allocations by currency with cash balances (#508)

* Improve allocations by currency in combination with cash balances

* Update changelog
pull/511/head
Thomas Kaul 3 years ago committed by GitHub
parent 050c0a4da7
commit 49f46e1a1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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/), 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). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Fixed
- Improved the allocations by currency in combination with cash balances
## 1.85.0 - 01.12.2021 ## 1.85.0 - 01.12.2021
### Fixed ### Fixed

@ -347,13 +347,17 @@ export class PortfolioService {
}; };
} }
// TODO: Add a cash position for each currency const cashPositions = await this.getCashPositions({
holdings[ghostfolioCashSymbol] = await this.getCashPosition({
cashDetails, cashDetails,
userCurrency,
investment: totalInvestment, investment: totalInvestment,
value: totalValue value: totalValue
}); });
for (const symbol of Object.keys(cashPositions)) {
holdings[symbol] = cashPositions[symbol];
}
const accounts = await this.getValueOfAccounts( const accounts = await this.getValueOfAccounts(
orders, orders,
portfolioItemsNow, portfolioItemsNow,
@ -872,38 +876,73 @@ export class PortfolioService {
}; };
} }
private async getCashPosition({ private async getCashPositions({
cashDetails, cashDetails,
investment, investment,
userCurrency,
value value
}: { }: {
cashDetails: CashDetails; cashDetails: CashDetails;
investment: Big; investment: Big;
value: Big; value: Big;
userCurrency: string;
}) { }) {
const cashValue = new Big(cashDetails.balance); const cashPositions = {};
return { for (const account of cashDetails.accounts) {
allocationCurrent: cashValue.div(value).toNumber(), const convertedBalance = this.exchangeRateDataService.toCurrency(
allocationInvestment: cashValue.div(investment).toNumber(), account.balance,
assetClass: AssetClass.CASH, account.currency,
assetSubClass: AssetClass.CASH, userCurrency
countries: [], );
currency: 'CHF',
grossPerformance: 0, if (convertedBalance === 0) {
grossPerformancePercent: 0, continue;
investment: cashValue.toNumber(), }
marketPrice: 0,
marketState: MarketState.open, if (cashPositions[account.currency]) {
name: 'Cash', cashPositions[account.currency].investment += convertedBalance;
netPerformance: 0, cashPositions[account.currency].value += convertedBalance;
netPerformancePercent: 0, } else {
quantity: 0, cashPositions[account.currency] = {
sectors: [], allocationCurrent: 0,
symbol: ghostfolioCashSymbol, allocationInvestment: 0,
transactionCount: 0, assetClass: AssetClass.CASH,
value: cashValue.toNumber() assetSubClass: AssetClass.CASH,
}; countries: [],
currency: account.currency,
grossPerformance: 0,
grossPerformancePercent: 0,
investment: convertedBalance,
marketPrice: 0,
marketState: MarketState.open,
name: account.currency,
netPerformance: 0,
netPerformancePercent: 0,
quantity: 0,
sectors: [],
symbol: account.currency,
transactionCount: 0,
value: convertedBalance
};
}
}
for (const symbol of Object.keys(cashPositions)) {
// Calculate allocations for each currency
cashPositions[symbol].allocationCurrent = new Big(
cashPositions[symbol].value
)
.div(value)
.toNumber();
cashPositions[symbol].allocationInvestment = new Big(
cashPositions[symbol].investment
)
.div(investment)
.toNumber();
}
return cashPositions;
} }
private getStartDate(aDateRange: DateRange, portfolioStart: Date) { private getStartDate(aDateRange: DateRange, portfolioStart: Date) {
@ -997,6 +1036,8 @@ export class PortfolioService {
userCurrency userCurrency
); );
accounts[account.name] = { accounts[account.name] = {
balance: convertedBalance,
currency: account.currency,
current: convertedBalance, current: convertedBalance,
original: convertedBalance original: convertedBalance
}; };
@ -1018,6 +1059,8 @@ export class PortfolioService {
originalValueOfSymbol; originalValueOfSymbol;
} else { } else {
accounts[order.Account?.name || UNKNOWN_KEY] = { accounts[order.Account?.name || UNKNOWN_KEY] = {
balance: 0,
currency: order.Account?.currency,
current: currentValueOfSymbol, current: currentValueOfSymbol,
original: originalValueOfSymbol original: originalValueOfSymbol
}; };

@ -2,7 +2,12 @@ import { PortfolioPosition } from '@ghostfolio/common/interfaces';
export interface PortfolioDetails { export interface PortfolioDetails {
accounts: { accounts: {
[name: string]: { current: number; original: number }; [name: string]: {
balance: number;
currency: string;
current: number;
original: number;
};
}; };
holdings: { [symbol: string]: PortfolioPosition }; holdings: { [symbol: string]: PortfolioPosition };
} }

Loading…
Cancel
Save