Bugfix/improve allocations by currency with cash balances (#508)
* Improve allocations by currency in combination with cash balances * Update changelog
This commit is contained in:
parent
050c0a4da7
commit
49f46e1a1e
@ -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
|
||||
|
||||
### Fixed
|
||||
|
||||
- Improved the allocations by currency in combination with cash balances
|
||||
|
||||
## 1.85.0 - 01.12.2021
|
||||
|
||||
### Fixed
|
||||
|
@ -347,13 +347,17 @@ export class PortfolioService {
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Add a cash position for each currency
|
||||
holdings[ghostfolioCashSymbol] = await this.getCashPosition({
|
||||
const cashPositions = await this.getCashPositions({
|
||||
cashDetails,
|
||||
userCurrency,
|
||||
investment: totalInvestment,
|
||||
value: totalValue
|
||||
});
|
||||
|
||||
for (const symbol of Object.keys(cashPositions)) {
|
||||
holdings[symbol] = cashPositions[symbol];
|
||||
}
|
||||
|
||||
const accounts = await this.getValueOfAccounts(
|
||||
orders,
|
||||
portfolioItemsNow,
|
||||
@ -872,39 +876,74 @@ export class PortfolioService {
|
||||
};
|
||||
}
|
||||
|
||||
private async getCashPosition({
|
||||
private async getCashPositions({
|
||||
cashDetails,
|
||||
investment,
|
||||
userCurrency,
|
||||
value
|
||||
}: {
|
||||
cashDetails: CashDetails;
|
||||
investment: Big;
|
||||
value: Big;
|
||||
userCurrency: string;
|
||||
}) {
|
||||
const cashValue = new Big(cashDetails.balance);
|
||||
const cashPositions = {};
|
||||
|
||||
return {
|
||||
allocationCurrent: cashValue.div(value).toNumber(),
|
||||
allocationInvestment: cashValue.div(investment).toNumber(),
|
||||
for (const account of cashDetails.accounts) {
|
||||
const convertedBalance = this.exchangeRateDataService.toCurrency(
|
||||
account.balance,
|
||||
account.currency,
|
||||
userCurrency
|
||||
);
|
||||
|
||||
if (convertedBalance === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cashPositions[account.currency]) {
|
||||
cashPositions[account.currency].investment += convertedBalance;
|
||||
cashPositions[account.currency].value += convertedBalance;
|
||||
} else {
|
||||
cashPositions[account.currency] = {
|
||||
allocationCurrent: 0,
|
||||
allocationInvestment: 0,
|
||||
assetClass: AssetClass.CASH,
|
||||
assetSubClass: AssetClass.CASH,
|
||||
countries: [],
|
||||
currency: 'CHF',
|
||||
currency: account.currency,
|
||||
grossPerformance: 0,
|
||||
grossPerformancePercent: 0,
|
||||
investment: cashValue.toNumber(),
|
||||
investment: convertedBalance,
|
||||
marketPrice: 0,
|
||||
marketState: MarketState.open,
|
||||
name: 'Cash',
|
||||
name: account.currency,
|
||||
netPerformance: 0,
|
||||
netPerformancePercent: 0,
|
||||
quantity: 0,
|
||||
sectors: [],
|
||||
symbol: ghostfolioCashSymbol,
|
||||
symbol: account.currency,
|
||||
transactionCount: 0,
|
||||
value: cashValue.toNumber()
|
||||
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) {
|
||||
switch (aDateRange) {
|
||||
@ -997,6 +1036,8 @@ export class PortfolioService {
|
||||
userCurrency
|
||||
);
|
||||
accounts[account.name] = {
|
||||
balance: convertedBalance,
|
||||
currency: account.currency,
|
||||
current: convertedBalance,
|
||||
original: convertedBalance
|
||||
};
|
||||
@ -1018,6 +1059,8 @@ export class PortfolioService {
|
||||
originalValueOfSymbol;
|
||||
} else {
|
||||
accounts[order.Account?.name || UNKNOWN_KEY] = {
|
||||
balance: 0,
|
||||
currency: order.Account?.currency,
|
||||
current: currentValueOfSymbol,
|
||||
original: originalValueOfSymbol
|
||||
};
|
||||
|
@ -2,7 +2,12 @@ import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||
|
||||
export interface PortfolioDetails {
|
||||
accounts: {
|
||||
[name: string]: { current: number; original: number };
|
||||
[name: string]: {
|
||||
balance: number;
|
||||
currency: string;
|
||||
current: number;
|
||||
original: number;
|
||||
};
|
||||
};
|
||||
holdings: { [symbol: string]: PortfolioPosition };
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user