Browse Source

Fixes

pull/5027/head
Daniel Devaud 1 year ago
parent
commit
0245e836e0
  1. 14
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts
  2. 6
      apps/api/src/app/portfolio/portfolio.controller.ts
  3. 102
      apps/api/src/app/portfolio/portfolio.service.ts

14
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts

@ -216,6 +216,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
return { return {
currentValues: {}, currentValues: {},
currentValuesWithCurrencyEffect: {}, currentValuesWithCurrencyEffect: {},
unitPrices: {},
feesWithCurrencyEffect: new Big(0), feesWithCurrencyEffect: new Big(0),
grossPerformance: new Big(0), grossPerformance: new Big(0),
grossPerformancePercentage: new Big(0), grossPerformancePercentage: new Big(0),
@ -232,6 +233,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
netPerformancePercentageWithCurrencyEffect: new Big(0), netPerformancePercentageWithCurrencyEffect: new Big(0),
netPerformanceValues: {}, netPerformanceValues: {},
netPerformanceValuesWithCurrencyEffect: {}, netPerformanceValuesWithCurrencyEffect: {},
netPerformanceValuesPercentage: {},
netPerformanceWithCurrencyEffect: new Big(0), netPerformanceWithCurrencyEffect: new Big(0),
timeWeightedInvestment: new Big(0), timeWeightedInvestment: new Big(0),
timeWeightedInvestmentValues: {}, timeWeightedInvestmentValues: {},
@ -265,6 +267,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
return { return {
currentValues: {}, currentValues: {},
currentValuesWithCurrencyEffect: {}, currentValuesWithCurrencyEffect: {},
unitPrices: {},
feesWithCurrencyEffect: new Big(0), feesWithCurrencyEffect: new Big(0),
grossPerformance: new Big(0), grossPerformance: new Big(0),
grossPerformancePercentage: new Big(0), grossPerformancePercentage: new Big(0),
@ -281,6 +284,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
netPerformancePercentageWithCurrencyEffect: new Big(0), netPerformancePercentageWithCurrencyEffect: new Big(0),
netPerformanceValues: {}, netPerformanceValues: {},
netPerformanceValuesWithCurrencyEffect: {}, netPerformanceValuesWithCurrencyEffect: {},
netPerformanceValuesPercentage: {},
netPerformanceWithCurrencyEffect: new Big(0), netPerformanceWithCurrencyEffect: new Big(0),
timeWeightedInvestment: new Big(0), timeWeightedInvestment: new Big(0),
timeWeightedInvestmentValues: {}, timeWeightedInvestmentValues: {},
@ -858,9 +862,18 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
); );
} }
let unitPrices = Object.keys(marketSymbolMap)
.map((date) => {
return { [date]: marketSymbolMap[date][symbol] };
})
.reduce((map, u) => {
return { ...u, ...map };
}, {});
return { return {
currentValues, currentValues,
currentValuesWithCurrencyEffect, currentValuesWithCurrencyEffect,
unitPrices,
feesWithCurrencyEffect, feesWithCurrencyEffect,
grossPerformancePercentage, grossPerformancePercentage,
grossPerformancePercentageWithCurrencyEffect, grossPerformancePercentageWithCurrencyEffect,
@ -873,6 +886,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
netPerformancePercentageWithCurrencyEffect, netPerformancePercentageWithCurrencyEffect,
netPerformanceValues, netPerformanceValues,
netPerformanceValuesWithCurrencyEffect, netPerformanceValuesWithCurrencyEffect,
netPerformanceValuesPercentage: {},
timeWeightedInvestmentValues, timeWeightedInvestmentValues,
timeWeightedInvestmentValuesWithCurrencyEffect, timeWeightedInvestmentValuesWithCurrencyEffect,
totalDividend, totalDividend,

6
apps/api/src/app/portfolio/portfolio.controller.ts

@ -79,7 +79,7 @@ export class PortfolioController {
@Query('assetClasses') filterByAssetClasses?: string, @Query('assetClasses') filterByAssetClasses?: string,
@Query('range') dateRange: DateRange = 'max', @Query('range') dateRange: DateRange = 'max',
@Query('tags') filterByTags?: string, @Query('tags') filterByTags?: string,
@Query('isAllocation') isAllocation: boolean = false @Query('isAllocation') isAllocation: boolean = false,
@Query('withMarkets') withMarketsParam = 'false' @Query('withMarkets') withMarketsParam = 'false'
): Promise<PortfolioDetails & { hasError: boolean }> { ): Promise<PortfolioDetails & { hasError: boolean }> {
const withMarkets = withMarketsParam === 'true'; const withMarkets = withMarketsParam === 'true';
@ -428,10 +428,7 @@ export class PortfolioController {
@Query('withExcludedAccounts') withExcludedAccounts = false, @Query('withExcludedAccounts') withExcludedAccounts = false,
@Query('timeWeightedPerformance') calculateTimeWeightedPerformance = false, @Query('timeWeightedPerformance') calculateTimeWeightedPerformance = false,
@Query('withItems') withItems = false @Query('withItems') withItems = false
@Query('withExcludedAccounts') withExcludedAccountsParam = 'false'
): Promise<PortfolioPerformanceResponse> { ): Promise<PortfolioPerformanceResponse> {
const withExcludedAccounts = withExcludedAccountsParam === 'true';
const hasReadRestrictedAccessPermission = const hasReadRestrictedAccessPermission =
this.userService.hasReadRestrictedAccessPermission({ this.userService.hasReadRestrictedAccessPermission({
impersonationId, impersonationId,
@ -449,7 +446,6 @@ export class PortfolioController {
filters, filters,
impersonationId, impersonationId,
withExcludedAccounts, withExcludedAccounts,
withItems,
userId: this.request.user.id, userId: this.request.user.id,
calculateTimeWeightedPerformance calculateTimeWeightedPerformance
}); });

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

@ -511,7 +511,6 @@ export class PortfolioService {
valueInBaseCurrency: valueInBaseCurrency.toNumber() valueInBaseCurrency: valueInBaseCurrency.toNumber()
}; };
} }
}
if (filters?.length === 0 || isFilteredByAccount || isFilteredByCash) { if (filters?.length === 0 || isFilteredByAccount || isFilteredByCash) {
const cashPositions = await this.getCashPositions({ const cashPositions = await this.getCashPositions({
@ -524,7 +523,6 @@ export class PortfolioService {
holdings[symbol] = cashPositions[symbol]; holdings[symbol] = cashPositions[symbol];
} }
} }
}
const { accounts, platforms } = await this.getValueOfAccountsAndPlatforms({ const { accounts, platforms } = await this.getValueOfAccountsAndPlatforms({
activities, activities,
@ -698,6 +696,7 @@ export class PortfolioService {
accounts: [], accounts: [],
averagePrice: undefined, averagePrice: undefined,
dataProviderInfo: undefined, dataProviderInfo: undefined,
stakeRewards: undefined,
dividendInBaseCurrency: undefined, dividendInBaseCurrency: undefined,
dividendYieldPercent: undefined, dividendYieldPercent: undefined,
dividendYieldPercentWithCurrencyEffect: undefined, dividendYieldPercentWithCurrencyEffect: undefined,
@ -885,6 +884,7 @@ export class PortfolioService {
transactionCount, transactionCount,
averagePrice: averagePrice.toNumber(), averagePrice: averagePrice.toNumber(),
dataProviderInfo: portfolioCalculator.getDataProviderInfos()?.[0], dataProviderInfo: portfolioCalculator.getDataProviderInfos()?.[0],
stakeRewards: stakeRewards.toNumber(),
dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), dividendInBaseCurrency: dividendInBaseCurrency.toNumber(),
dividendYieldPercent: dividendYieldPercent.toNumber(), dividendYieldPercent: dividendYieldPercent.toNumber(),
dividendYieldPercentWithCurrencyEffect: dividendYieldPercentWithCurrencyEffect:
@ -963,6 +963,7 @@ export class PortfolioService {
accounts: [], accounts: [],
averagePrice: 0, averagePrice: 0,
dataProviderInfo: undefined, dataProviderInfo: undefined,
stakeRewards: 0,
dividendInBaseCurrency: 0, dividendInBaseCurrency: 0,
dividendYieldPercent: 0, dividendYieldPercent: 0,
dividendYieldPercentWithCurrencyEffect: 0, dividendYieldPercentWithCurrencyEffect: 0,
@ -1135,13 +1136,15 @@ export class PortfolioService {
filters, filters,
impersonationId, impersonationId,
userId, userId,
withExcludedAccounts = false withExcludedAccounts = false,
calculateTimeWeightedPerformance = false
}: { }: {
dateRange?: DateRange; dateRange?: DateRange;
filters?: Filter[]; filters?: Filter[];
impersonationId: string; impersonationId: string;
userId: string; userId: string;
withExcludedAccounts?: boolean; withExcludedAccounts?: boolean;
calculateTimeWeightedPerformance?: boolean;
}): Promise<PortfolioPerformanceResponse> { }): Promise<PortfolioPerformanceResponse> {
userId = await this.getUserId(impersonationId, userId); userId = await this.getUserId(impersonationId, userId);
const user = await this.userService.user({ id: userId }); const user = await this.userService.user({ id: userId });
@ -1676,42 +1679,6 @@ export class PortfolioService {
return { currentStreak, longestStreak }; return { currentStreak, longestStreak };
} }
@LogPerformance
private async getNetWorth(
impersonationId: string,
userId: string,
userCurrency: string
) {
userId = await this.getUserId(impersonationId, userId);
const { orders, portfolioOrders, transactionPoints } =
await this.getTransactionPoints({
userId,
withExcludedAccounts: true
});
const portfolioCalculator = new PortfolioCalculator({
currency: userCurrency,
currentRateService: this.currentRateService,
exchangeRateDataService: this.exchangeRateDataService,
orders: portfolioOrders
});
const portfolioStart = parseDate(
transactionPoints[0]?.date ?? format(new Date(), DATE_FORMAT)
);
portfolioCalculator.setTransactionPoints(transactionPoints);
const { currentValue } = await portfolioCalculator.getCurrentPositions(
portfolioStart,
new Date(Date.now()),
false
);
return currentValue;
}
@LogPerformance @LogPerformance
private async getSummary({ private async getSummary({
balanceInBaseCurrency, balanceInBaseCurrency,
@ -1761,63 +1728,22 @@ export class PortfolioService {
withExcludedAccounts: true withExcludedAccounts: true
}); });
const excludedActivities: Activity[] = []; const excludedActivities: Activity[] = [];
let dividend = 0; const nonExcludedActivities: Activity[] = [];
let fees = 0;
let items = 0;
let interest = 0;
let liabilities = 0; for (const activity of activities) {
if (activity.Account?.isExcluded) {
excludedActivities.push(activity);
} else {
nonExcludedActivities.push(activity);
}
}
let totalBuy = 0;
let totalSell = 0;
let activitiesUsed: Activity[] = [];
let ordersCount = 0;
let excludedAccountsAndActivities = 0; let excludedAccountsAndActivities = 0;
const firstOrderDate = activities[0]?.date;
performanceInformation = await this.getPerformance({ performanceInformation = await this.getPerformance({
impersonationId, impersonationId,
userId userId
}); });
for (let order of activities) {
if (order.Account?.isExcluded ?? false) {
excludedActivities.push(order);
} else {
activitiesUsed.push(order);
fees += this.exchangeRateDataService.toCurrency(
order.fee,
order.SymbolProfile.currency,
userCurrency
);
let amount = this.exchangeRateDataService.toCurrency(
new Big(order.quantity).mul(order.unitPrice).toNumber(),
order.SymbolProfile.currency,
userCurrency
);
switch (order.type) {
case 'DIVIDEND':
dividend += amount;
break;
case 'ITEM':
items += amount;
break;
case 'SELL':
totalSell += amount;
ordersCount++;
break;
case 'BUY':
totalBuy += amount;
ordersCount++;
break;
case 'LIABILITY':
liabilities += amount;
break;
case 'INTEREST':
interest += amount;
break;
}
}
}
const dividendInBaseCurrency = const dividendInBaseCurrency =
await portfolioCalculator.getDividendInBaseCurrency(); await portfolioCalculator.getDividendInBaseCurrency();

Loading…
Cancel
Save