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 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,39 +876,74 @@ 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,
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, assetClass: AssetClass.CASH,
assetSubClass: AssetClass.CASH, assetSubClass: AssetClass.CASH,
countries: [], countries: [],
currency: 'CHF', currency: account.currency,
grossPerformance: 0, grossPerformance: 0,
grossPerformancePercent: 0, grossPerformancePercent: 0,
investment: cashValue.toNumber(), investment: convertedBalance,
marketPrice: 0, marketPrice: 0,
marketState: MarketState.open, marketState: MarketState.open,
name: 'Cash', name: account.currency,
netPerformance: 0, netPerformance: 0,
netPerformancePercent: 0, netPerformancePercent: 0,
quantity: 0, quantity: 0,
sectors: [], sectors: [],
symbol: ghostfolioCashSymbol, symbol: account.currency,
transactionCount: 0, 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) { private getStartDate(aDateRange: DateRange, portfolioStart: Date) {
switch (aDateRange) { switch (aDateRange) {
@ -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
}; };

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

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