Browse Source

feat(api): create getCashSymbolProfiles method

pull/5650/head
KenTandrian 1 week ago
parent
commit
543a44a1a7
  1. 1
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  2. 50
      apps/api/src/app/portfolio/portfolio.service.ts
  3. 4
      libs/common/src/lib/models/timeline-position.ts

1
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -405,7 +405,6 @@ export abstract class PortfolioCalculator {
feeInBaseCurrency,
timeWeightedInvestment,
timeWeightedInvestmentWithCurrencyEffect,
assetSubClass: item.assetSubClass,
dividend: totalDividend,
dividendInBaseCurrency: totalDividendInBaseCurrency,
averagePrice: item.averagePrice,

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

@ -553,6 +553,9 @@ export class PortfolioService {
assetProfileIdentifiers
);
const cashSymbolProfiles = this.getCashSymbolProfiles(cashDetails);
symbolProfiles.push(...cashSymbolProfiles);
const symbolProfileMap: { [symbol: string]: EnhancedSymbolProfile } = {};
for (const symbolProfile of symbolProfiles) {
symbolProfileMap[symbolProfile.symbol] = symbolProfile;
@ -564,7 +567,6 @@ export class PortfolioService {
}
for (const {
assetSubClass,
currency,
dividend,
firstBuyDate,
@ -608,7 +610,6 @@ export class PortfolioService {
}
holdings[symbol] = {
assetSubClass,
currency,
markets,
marketsAdvanced,
@ -619,9 +620,10 @@ export class PortfolioService {
allocationInPercentage: filteredValueInBaseCurrency.eq(0)
? 0
: valueInBaseCurrency.div(filteredValueInBaseCurrency).toNumber(),
assetClass: assetProfile?.assetClass,
countries: assetProfile?.countries,
dataSource: assetProfile?.dataSource,
assetClass: assetProfile.assetClass,
assetSubClass: assetProfile.assetSubClass,
countries: assetProfile.countries,
dataSource: assetProfile.dataSource,
dateOfFirstActivity: parseDate(firstBuyDate),
dividend: dividend?.toNumber() ?? 0,
grossPerformance: grossPerformance?.toNumber() ?? 0,
@ -631,7 +633,7 @@ export class PortfolioService {
grossPerformanceWithCurrencyEffect:
grossPerformanceWithCurrencyEffect?.toNumber() ?? 0,
holdings:
assetProfile?.holdings.map(({ allocationInPercentage, name }) => {
assetProfile.holdings.map(({ allocationInPercentage, name }) => {
return {
allocationInPercentage,
name,
@ -641,8 +643,7 @@ export class PortfolioService {
};
}) ?? [],
investment: investment.toNumber(),
name:
assetSubClass === AssetSubClass.CASH ? currency : assetProfile?.name,
name: assetProfile.name,
netPerformance: netPerformance?.toNumber() ?? 0,
netPerformancePercent: netPerformancePercentage?.toNumber() ?? 0,
netPerformancePercentWithCurrencyEffect:
@ -652,8 +653,8 @@ export class PortfolioService {
netPerformanceWithCurrencyEffect:
netPerformanceWithCurrencyEffectMap?.[dateRange]?.toNumber() ?? 0,
quantity: quantity.toNumber(),
sectors: assetProfile?.sectors,
url: assetProfile?.url,
sectors: assetProfile.sectors,
url: assetProfile.url,
valueInBaseCurrency: valueInBaseCurrency.toNumber()
};
}
@ -1533,6 +1534,35 @@ export class PortfolioService {
return cashPositions;
}
private getCashSymbolProfiles(cashDetails: CashDetails) {
const cashSymbols = [
...new Set(cashDetails.accounts.map(({ currency }) => currency))
];
return cashSymbols.map<EnhancedSymbolProfile>((currency) => {
const account = cashDetails.accounts.find(
({ currency: accountCurrency }) => accountCurrency === currency
);
return {
currency,
activitiesCount: 0,
assetClass: AssetClass.LIQUIDITY,
assetSubClass: AssetSubClass.CASH,
countries: [],
createdAt: account.createdAt,
dataSource: DataSource.MANUAL,
holdings: [],
id: currency,
isActive: true,
name: currency,
sectors: [],
symbol: currency,
updatedAt: account.updatedAt
};
});
}
private getDividendsByGroup({
dividends,
groupBy

4
libs/common/src/lib/models/timeline-position.ts

@ -4,13 +4,11 @@ import {
} from '@ghostfolio/common/class-transformer';
import { DateRange } from '@ghostfolio/common/types';
import { AssetSubClass, DataSource, Tag } from '@prisma/client';
import { DataSource, Tag } from '@prisma/client';
import { Big } from 'big.js';
import { Transform, Type } from 'class-transformer';
export class TimelinePosition {
assetSubClass: AssetSubClass;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
averagePrice: Big;

Loading…
Cancel
Save