Attila Cseh 2 days ago
committed by GitHub
parent
commit
0d39a9f896
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 23
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  3. 32
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts
  4. 1
      apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts
  5. 9
      libs/common/src/lib/config.ts

1
CHANGELOG.md

@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the language localization for Italian (`it`)
- Improved the language localization for Portuguese (`pt`)
- Improved the language localization for Spanish (`es`)
- Improved the holdings dialog not to include non-investment activities
### Fixed

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

@ -13,6 +13,7 @@ import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfac
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service';
import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper';
import {
INVESTMENT_ACTIVITY_TYPES,
PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME,
PORTFOLIO_SNAPSHOT_PROCESS_JOB_OPTIONS,
PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE_PRIORITY_HIGH,
@ -287,7 +288,9 @@ export abstract class PortfolioCalculator {
firstIndex--;
}
const positions: TimelinePosition[] = [];
const positions: (TimelinePosition & {
isInvestmentAssetProfilePosition: boolean;
})[] = [];
let hasAnySymbolMetricsErrors = false;
const errors: ResponseError['errors'] = [];
@ -411,6 +414,7 @@ export abstract class PortfolioCalculator {
: null,
investment: totalInvestment,
investmentWithCurrencyEffect: totalInvestmentWithCurrencyEffect,
isInvestmentAssetProfilePosition: item.isInvestmentAssetProfileItem,
marketPrice:
marketSymbolMap[endDateString]?.[item.symbol]?.toNumber() ?? null,
marketPriceInBaseCurrency:
@ -605,14 +609,23 @@ export abstract class PortfolioCalculator {
const overall = this.calculateOverallPerformance(positions);
const investmentPositions = positions
.filter(({ isInvestmentAssetProfilePosition }) => {
return isInvestmentAssetProfilePosition;
})
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.map(({ isInvestmentAssetProfilePosition, ...rest }) => {
return rest;
});
return {
...overall,
errors,
historicalData,
positions,
totalInterestWithCurrencyEffect,
totalLiabilitiesWithCurrencyEffect,
hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors
hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors,
positions: investmentPositions
};
}
@ -935,6 +948,8 @@ export abstract class PortfolioCalculator {
dividend: new Big(0),
fee: oldAccumulatedSymbol.fee.plus(fee),
firstBuyDate: oldAccumulatedSymbol.firstBuyDate,
isInvestmentAssetProfileItem:
oldAccumulatedSymbol.isInvestmentAssetProfileItem,
quantity: newQuantity,
tags: oldAccumulatedSymbol.tags.concat(tags),
transactionCount: oldAccumulatedSymbol.transactionCount + 1
@ -951,6 +966,8 @@ export abstract class PortfolioCalculator {
dividend: new Big(0),
firstBuyDate: date,
investment: unitPrice.mul(quantity).mul(factor),
isInvestmentAssetProfileItem:
INVESTMENT_ACTIVITY_TYPES.includes(type),
quantity: quantity.mul(factor),
transactionCount: 1
};

32
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator-fee.spec.ts

@ -116,37 +116,7 @@ describe('PortfolioCalculator', () => {
currentValueInBaseCurrency: new Big('0'),
errors: [],
hasErrors: true,
positions: [
{
averagePrice: new Big('0'),
currency: 'USD',
dataSource: 'MANUAL',
dividend: new Big('0'),
dividendInBaseCurrency: new Big('0'),
fee: new Big('49'),
feeInBaseCurrency: new Big('49'),
firstBuyDate: '2021-09-01',
grossPerformance: null,
grossPerformancePercentage: null,
grossPerformancePercentageWithCurrencyEffect: null,
grossPerformanceWithCurrencyEffect: null,
investment: new Big('0'),
investmentWithCurrencyEffect: new Big('0'),
marketPrice: null,
marketPriceInBaseCurrency: 0,
netPerformance: null,
netPerformancePercentage: null,
netPerformancePercentageWithCurrencyEffectMap: null,
netPerformanceWithCurrencyEffectMap: null,
quantity: new Big('0'),
symbol: '2c463fb3-af07-486e-adb0-8301b3d72141',
tags: [],
timeWeightedInvestment: new Big('0'),
timeWeightedInvestmentWithCurrencyEffect: new Big('0'),
transactionCount: 1,
valueInBaseCurrency: new Big('0')
}
],
positions: [],
totalFeesWithCurrencyEffect: new Big('49'),
totalInterestWithCurrencyEffect: new Big('0'),
totalInvestment: new Big('0'),

1
apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts

@ -9,6 +9,7 @@ export interface TransactionPointSymbol {
fee: Big;
firstBuyDate: string;
investment: Big;
isInvestmentAssetProfileItem: boolean;
quantity: Big;
skipErrors: boolean;
symbol: string;

9
libs/common/src/lib/config.ts

@ -1,4 +1,4 @@
import { AssetClass, AssetSubClass, DataSource } from '@prisma/client';
import { AssetClass, AssetSubClass, DataSource, Type } from '@prisma/client';
import { JobOptions, JobStatus } from 'bull';
import ms from 'ms';
@ -118,6 +118,13 @@ export const GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_OPTIONS: JobOptions = {
removeOnComplete: true
};
export const INVESTMENT_ACTIVITY_TYPES = [
Type.BUY,
Type.DIVIDEND,
Type.ITEM,
Type.SELL
] as Type[];
export const PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME = 'PORTFOLIO';
export const PORTFOLIO_SNAPSHOT_PROCESS_JOB_OPTIONS: JobOptions = {
removeOnComplete: true

Loading…
Cancel
Save