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/),
|
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…
x
Reference in New Issue
Block a user