Browse Source

Improve allocations by currency in combination with cash balances

pull/508/head
Thomas 4 years ago
parent
commit
e733c563e7
  1. 67
      apps/api/src/app/portfolio/portfolio.service.ts
  2. 7
      libs/common/src/lib/interfaces/portfolio-details.interface.ts

67
apps/api/src/app/portfolio/portfolio.service.ts

@ -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
};

7
libs/common/src/lib/interfaces/portfolio-details.interface.ts

@ -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…
Cancel
Save