Browse Source

Task/rename NetPerformancePercentages to PerformancePercentages (#7927)

Rename NetPerformancePercentages to PerformancePercentages
pull/7930/head
Thomas Kaul 1 week ago
committed by GitHub
parent
commit
d91e3084fd
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts
  2. 31
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  3. 212
      apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts
  4. 14
      apps/api/src/app/portfolio/calculator/roi/portfolio-calculator.ts
  5. 14
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts
  6. 2
      apps/api/src/app/portfolio/types/performance-percentages.type.ts

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

@ -1,24 +1,24 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { NetPerformancePercentages } from '@ghostfolio/api/app/portfolio/types/net-performance-percentages.type'; import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { PortfolioSnapshot } from '@ghostfolio/common/models'; import { PortfolioSnapshot } from '@ghostfolio/common/models';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export class MwrPortfolioCalculator extends PortfolioCalculator { export class MwrPortfolioCalculator extends PortfolioCalculator {
protected calculateNetPerformancePercentages(): { protected calculateOverallPerformance(): PortfolioSnapshot {
[date: string]: NetPerformancePercentages;
} {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }
protected calculateNetPerformancePercentagesForDateRange(): { protected calculatePerformancePercentages(): {
[date: string]: NetPerformancePercentages; [date: string]: PerformancePercentages;
} { } {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }
protected calculateOverallPerformance(): PortfolioSnapshot { protected calculatePerformancePercentagesForDateRange(): {
[date: string]: PerformancePercentages;
} {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }

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

@ -10,7 +10,7 @@ import { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/i
import { PortfolioCalculatorActivity } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity.interface'; import { PortfolioCalculatorActivity } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity.interface';
import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface'; import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface';
import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface'; import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface';
import { NetPerformancePercentages } from '@ghostfolio/api/app/portfolio/types/net-performance-percentages.type'; import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { getFactor } from '@ghostfolio/api/helper/portfolio.helper';
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor'; import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
@ -218,21 +218,21 @@ export abstract class PortfolioCalculator {
this.snapshotPromise.catch(() => undefined); this.snapshotPromise.catch(() => undefined);
} }
protected abstract calculateNetPerformancePercentages({ protected abstract calculateOverallPerformance(
positions: PortfolioCalculatorHolding[]
): PortfolioSnapshot;
protected abstract calculatePerformancePercentages({
accumulatedValuesByDate accumulatedValuesByDate
}: { }: {
accumulatedValuesByDate: { [date: string]: AccumulatedValues }; accumulatedValuesByDate: { [date: string]: AccumulatedValues };
}): { [date: string]: NetPerformancePercentages }; }): { [date: string]: PerformancePercentages };
protected abstract calculateNetPerformancePercentagesForDateRange({ protected abstract calculatePerformancePercentagesForDateRange({
historicalDataItems historicalDataItems
}: { }: {
historicalDataItems: HistoricalDataItem[]; historicalDataItems: HistoricalDataItem[];
}): { [date: string]: NetPerformancePercentages }; }): { [date: string]: PerformancePercentages };
protected abstract calculateOverallPerformance(
positions: PortfolioCalculatorHolding[]
): PortfolioSnapshot;
@LogPerformance @LogPerformance
public async computeSnapshot(): Promise<PortfolioSnapshot> { public async computeSnapshot(): Promise<PortfolioSnapshot> {
@ -644,8 +644,9 @@ export abstract class PortfolioCalculator {
} }
} }
const netPerformancePercentagesByDate = const performancePercentagesByDate = this.calculatePerformancePercentages({
this.calculateNetPerformancePercentages({ accumulatedValuesByDate }); accumulatedValuesByDate
});
const historicalData: HistoricalDataItem[] = Object.entries( const historicalData: HistoricalDataItem[] = Object.entries(
accumulatedValuesByDate accumulatedValuesByDate
@ -663,7 +664,7 @@ export abstract class PortfolioCalculator {
} = values; } = values;
return { return {
...netPerformancePercentagesByDate[date], ...performancePercentagesByDate[date],
date, date,
investmentValueWithCurrencyEffect: investmentValueWithCurrencyEffect:
investmentValueWithCurrencyEffect.toNumber(), investmentValueWithCurrencyEffect.toNumber(),
@ -1369,15 +1370,15 @@ export abstract class PortfolioCalculator {
} }
} }
const netPerformancePercentagesByDate = const performancePercentagesByDate =
this.calculateNetPerformancePercentagesForDateRange({ this.calculatePerformancePercentagesForDateRange({
historicalDataItems: historicalDataItemsOfDateRange historicalDataItems: historicalDataItemsOfDateRange
}); });
const chart = historicalDataItemsOfDateRange.map((historicalDataItem) => { const chart = historicalDataItemsOfDateRange.map((historicalDataItem) => {
return { return {
...historicalDataItem, ...historicalDataItem,
...netPerformancePercentagesByDate[historicalDataItem.date] ...performancePercentagesByDate[historicalDataItem.date]
}; };
}); });

212
apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts

@ -3,7 +3,7 @@ import { AccumulatedValues } from '@ghostfolio/api/app/portfolio/interfaces/accu
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity-item.interface'; import { PortfolioCalculatorActivityItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-activity-item.interface';
import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface'; import { PortfolioCalculatorHolding } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator-holding.interface';
import { NetPerformancePercentages } from '@ghostfolio/api/app/portfolio/types/net-performance-percentages.type'; import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { import {
getAnnualizedPerformancePercent, getAnnualizedPerformancePercent,
getIntervalFromDateRange getIntervalFromDateRange
@ -32,111 +32,6 @@ import {
import { sum } from 'lodash'; import { sum } from 'lodash';
export class RoaiPortfolioCalculator extends PortfolioCalculator { export class RoaiPortfolioCalculator extends PortfolioCalculator {
protected calculateNetPerformancePercentages({
accumulatedValuesByDate
}: {
accumulatedValuesByDate: { [date: string]: AccumulatedValues };
}): { [date: string]: NetPerformancePercentages } {
const netPerformancePercentagesByDate: {
[date: string]: NetPerformancePercentages;
} = {};
for (const [
date,
{
totalAverageInvestmentValue,
totalAverageInvestmentValueWithCurrencyEffect,
totalNetPerformanceValue,
totalNetPerformanceValueWithCurrencyEffect
}
] of Object.entries(accumulatedValuesByDate)) {
netPerformancePercentagesByDate[date] = {
netPerformanceInPercentage: totalAverageInvestmentValue.eq(0)
? 0
: totalNetPerformanceValue
.div(totalAverageInvestmentValue)
.toNumber(),
netPerformanceInPercentageWithCurrencyEffect:
totalAverageInvestmentValueWithCurrencyEffect.eq(0)
? 0
: totalNetPerformanceValueWithCurrencyEffect
.div(totalAverageInvestmentValueWithCurrencyEffect)
.toNumber()
};
}
return netPerformancePercentagesByDate;
}
protected calculateNetPerformancePercentagesForDateRange({
historicalDataItems
}: {
historicalDataItems: HistoricalDataItem[];
}): { [date: string]: NetPerformancePercentages } {
const averageInvestmentValues: number[] = [];
const averageInvestmentValuesWithCurrencyEffect: number[] = [];
let grossPerformanceAtStartDate: number;
let grossPerformanceWithCurrencyEffectAtStartDate: number;
const netPerformancePercentagesByDate: {
[date: string]: NetPerformancePercentages;
} = {};
for (const [index, historicalDataItem] of historicalDataItems.entries()) {
// Take the values at the start date from the first day of the date
// range
if (index === 0) {
grossPerformanceAtStartDate =
historicalDataItem.value - historicalDataItem.totalInvestment;
grossPerformanceWithCurrencyEffectAtStartDate =
historicalDataItem.valueWithCurrencyEffect -
historicalDataItem.totalInvestmentValueWithCurrencyEffect;
}
// Add the gross performance at the start date of the range to the
// investment of each day. Thus the range starts with the value of its
// first day, and subsequent buy and sell activities stay included.
if (historicalDataItem.totalInvestment > 0) {
averageInvestmentValues.push(
historicalDataItem.totalInvestment + grossPerformanceAtStartDate
);
}
if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) {
averageInvestmentValuesWithCurrencyEffect.push(
historicalDataItem.totalInvestmentValueWithCurrencyEffect +
grossPerformanceWithCurrencyEffectAtStartDate
);
}
const averageInvestmentValue =
averageInvestmentValues.length > 0
? sum(averageInvestmentValues) / averageInvestmentValues.length
: 0;
const averageInvestmentValueWithCurrencyEffect =
averageInvestmentValuesWithCurrencyEffect.length > 0
? sum(averageInvestmentValuesWithCurrencyEffect) /
averageInvestmentValuesWithCurrencyEffect.length
: 0;
netPerformancePercentagesByDate[historicalDataItem.date] = {
netPerformanceInPercentage:
averageInvestmentValue > 0
? historicalDataItem.netPerformance / averageInvestmentValue
: 0,
netPerformanceInPercentageWithCurrencyEffect:
averageInvestmentValueWithCurrencyEffect > 0
? historicalDataItem.netPerformanceWithCurrencyEffect /
averageInvestmentValueWithCurrencyEffect
: 0
};
}
return netPerformancePercentagesByDate;
}
protected calculateOverallPerformance( protected calculateOverallPerformance(
positions: PortfolioCalculatorHolding[] positions: PortfolioCalculatorHolding[]
): PortfolioSnapshot { ): PortfolioSnapshot {
@ -269,6 +164,111 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator {
}; };
} }
protected calculatePerformancePercentages({
accumulatedValuesByDate
}: {
accumulatedValuesByDate: { [date: string]: AccumulatedValues };
}): { [date: string]: PerformancePercentages } {
const performancePercentagesByDate: {
[date: string]: PerformancePercentages;
} = {};
for (const [
date,
{
totalAverageInvestmentValue,
totalAverageInvestmentValueWithCurrencyEffect,
totalNetPerformanceValue,
totalNetPerformanceValueWithCurrencyEffect
}
] of Object.entries(accumulatedValuesByDate)) {
performancePercentagesByDate[date] = {
netPerformanceInPercentage: totalAverageInvestmentValue.eq(0)
? 0
: totalNetPerformanceValue
.div(totalAverageInvestmentValue)
.toNumber(),
netPerformanceInPercentageWithCurrencyEffect:
totalAverageInvestmentValueWithCurrencyEffect.eq(0)
? 0
: totalNetPerformanceValueWithCurrencyEffect
.div(totalAverageInvestmentValueWithCurrencyEffect)
.toNumber()
};
}
return performancePercentagesByDate;
}
protected calculatePerformancePercentagesForDateRange({
historicalDataItems
}: {
historicalDataItems: HistoricalDataItem[];
}): { [date: string]: PerformancePercentages } {
const averageInvestmentValues: number[] = [];
const averageInvestmentValuesWithCurrencyEffect: number[] = [];
let grossPerformanceAtStartDate: number;
let grossPerformanceWithCurrencyEffectAtStartDate: number;
const performancePercentagesByDate: {
[date: string]: PerformancePercentages;
} = {};
for (const [index, historicalDataItem] of historicalDataItems.entries()) {
// Take the values at the start date from the first day of the date
// range
if (index === 0) {
grossPerformanceAtStartDate =
historicalDataItem.value - historicalDataItem.totalInvestment;
grossPerformanceWithCurrencyEffectAtStartDate =
historicalDataItem.valueWithCurrencyEffect -
historicalDataItem.totalInvestmentValueWithCurrencyEffect;
}
// Add the gross performance at the start date of the range to the
// investment of each day. Thus the range starts with the value of its
// first day, and subsequent buy and sell activities stay included.
if (historicalDataItem.totalInvestment > 0) {
averageInvestmentValues.push(
historicalDataItem.totalInvestment + grossPerformanceAtStartDate
);
}
if (historicalDataItem.totalInvestmentValueWithCurrencyEffect > 0) {
averageInvestmentValuesWithCurrencyEffect.push(
historicalDataItem.totalInvestmentValueWithCurrencyEffect +
grossPerformanceWithCurrencyEffectAtStartDate
);
}
const averageInvestmentValue =
averageInvestmentValues.length > 0
? sum(averageInvestmentValues) / averageInvestmentValues.length
: 0;
const averageInvestmentValueWithCurrencyEffect =
averageInvestmentValuesWithCurrencyEffect.length > 0
? sum(averageInvestmentValuesWithCurrencyEffect) /
averageInvestmentValuesWithCurrencyEffect.length
: 0;
performancePercentagesByDate[historicalDataItem.date] = {
netPerformanceInPercentage:
averageInvestmentValue > 0
? historicalDataItem.netPerformance / averageInvestmentValue
: 0,
netPerformanceInPercentageWithCurrencyEffect:
averageInvestmentValueWithCurrencyEffect > 0
? historicalDataItem.netPerformanceWithCurrencyEffect /
averageInvestmentValueWithCurrencyEffect
: 0
};
}
return performancePercentagesByDate;
}
protected getHoldingPerformance({ protected getHoldingPerformance({
chartDates, chartDates,
dataSource, dataSource,

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

@ -1,24 +1,24 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { NetPerformancePercentages } from '@ghostfolio/api/app/portfolio/types/net-performance-percentages.type'; import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { PortfolioSnapshot } from '@ghostfolio/common/models'; import { PortfolioSnapshot } from '@ghostfolio/common/models';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export class RoiPortfolioCalculator extends PortfolioCalculator { export class RoiPortfolioCalculator extends PortfolioCalculator {
protected calculateNetPerformancePercentages(): { protected calculateOverallPerformance(): PortfolioSnapshot {
[date: string]: NetPerformancePercentages;
} {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }
protected calculateNetPerformancePercentagesForDateRange(): { protected calculatePerformancePercentages(): {
[date: string]: NetPerformancePercentages; [date: string]: PerformancePercentages;
} { } {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }
protected calculateOverallPerformance(): PortfolioSnapshot { protected calculatePerformancePercentagesForDateRange(): {
[date: string]: PerformancePercentages;
} {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }

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

@ -1,24 +1,24 @@
import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator';
import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface'; import { HoldingPerformance } from '@ghostfolio/api/app/portfolio/interfaces/holding-performance.interface';
import { NetPerformancePercentages } from '@ghostfolio/api/app/portfolio/types/net-performance-percentages.type'; import { PerformancePercentages } from '@ghostfolio/api/app/portfolio/types/performance-percentages.type';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import { PortfolioSnapshot } from '@ghostfolio/common/models'; import { PortfolioSnapshot } from '@ghostfolio/common/models';
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type'; import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type';
export class TwrPortfolioCalculator extends PortfolioCalculator { export class TwrPortfolioCalculator extends PortfolioCalculator {
protected calculateNetPerformancePercentages(): { protected calculateOverallPerformance(): PortfolioSnapshot {
[date: string]: NetPerformancePercentages;
} {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }
protected calculateNetPerformancePercentagesForDateRange(): { protected calculatePerformancePercentages(): {
[date: string]: NetPerformancePercentages; [date: string]: PerformancePercentages;
} { } {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }
protected calculateOverallPerformance(): PortfolioSnapshot { protected calculatePerformancePercentagesForDateRange(): {
[date: string]: PerformancePercentages;
} {
throw new Error('Method not implemented.'); throw new Error('Method not implemented.');
} }

2
apps/api/src/app/portfolio/types/net-performance-percentages.type.ts → apps/api/src/app/portfolio/types/performance-percentages.type.ts

@ -1,6 +1,6 @@
import { HistoricalDataItem } from '@ghostfolio/common/interfaces'; import { HistoricalDataItem } from '@ghostfolio/common/interfaces';
export type NetPerformancePercentages = Required< export type PerformancePercentages = Required<
Pick< Pick<
HistoricalDataItem, HistoricalDataItem,
| 'netPerformanceInPercentage' | 'netPerformanceInPercentage'
Loading…
Cancel
Save