Feature/rework portfolio calculator (#3393)

* Rework portfolio calculation

* Update changelog

---------

Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
This commit is contained in:
gizmodus
2024-08-24 16:59:50 +02:00
committed by GitHub
parent 84d23764db
commit f360a12823
39 changed files with 1037 additions and 1191 deletions

View File

@@ -36,48 +36,36 @@ export function getIntervalFromDateRange(
aDateRange: DateRange,
portfolioStart = new Date(0)
) {
let endDate = endOfDay(new Date(Date.now()));
let endDate = endOfDay(new Date());
let startDate = portfolioStart;
switch (aDateRange) {
case '1d':
startDate = max([
startDate,
subDays(resetHours(new Date(Date.now())), 1)
]);
startDate = max([startDate, subDays(resetHours(new Date()), 1)]);
break;
case 'mtd':
startDate = max([
startDate,
subDays(startOfMonth(resetHours(new Date(Date.now()))), 1)
subDays(startOfMonth(resetHours(new Date())), 1)
]);
break;
case 'wtd':
startDate = max([
startDate,
subDays(
startOfWeek(resetHours(new Date(Date.now())), { weekStartsOn: 1 }),
1
)
subDays(startOfWeek(resetHours(new Date()), { weekStartsOn: 1 }), 1)
]);
break;
case 'ytd':
startDate = max([
startDate,
subDays(startOfYear(resetHours(new Date(Date.now()))), 1)
subDays(startOfYear(resetHours(new Date())), 1)
]);
break;
case '1y':
startDate = max([
startDate,
subYears(resetHours(new Date(Date.now())), 1)
]);
startDate = max([startDate, subYears(resetHours(new Date()), 1)]);
break;
case '5y':
startDate = max([
startDate,
subYears(resetHours(new Date(Date.now())), 5)
]);
startDate = max([startDate, subYears(resetHours(new Date()), 5)]);
break;
case 'max':
break;

View File

@@ -1,5 +1,21 @@
import { Big } from 'big.js';
export function transformToMapOfBig({
value
}: {
value: { [key: string]: string };
}): {
[key: string]: Big;
} {
const mapOfBig: { [key: string]: Big } = {};
for (const key in value) {
mapOfBig[key] = new Big(value[key]);
}
return mapOfBig;
}
export function transformToBig({ value }: { value: string }): Big {
if (value === null) {
return null;

View File

@@ -2,10 +2,6 @@ export interface PortfolioPerformance {
annualizedPerformancePercent?: number;
currentNetWorth?: number;
currentValueInBaseCurrency: number;
grossPerformance: number;
grossPerformancePercentage: number;
grossPerformancePercentageWithCurrencyEffect: number;
grossPerformanceWithCurrencyEffect: number;
netPerformance: number;
netPerformancePercentage: number;
netPerformancePercentageWithCurrencyEffect: number;

View File

@@ -1,6 +1,7 @@
import { Market, MarketAdvanced } from '@ghostfolio/common/types';
import { AssetClass, AssetSubClass, DataSource, Tag } from '@prisma/client';
import { Market, MarketAdvanced, MarketState } from '../types';
import { Country } from './country.interface';
import { Holding } from './holding.interface';
import { Sector } from './sector.interface';
@@ -28,7 +29,6 @@ export interface PortfolioPosition {
marketPrice: number;
markets?: { [key in Market]: number };
marketsAdvanced?: { [key in MarketAdvanced]: number };
marketState: MarketState;
name: string;
netPerformance: number;
netPerformancePercent: number;

View File

@@ -17,6 +17,8 @@ export interface PortfolioSummary extends PortfolioPerformance {
filteredValueInPercentage?: number;
fireWealth: number;
firstOrderDate: Date;
grossPerformance: number;
grossPerformanceWithCurrencyEffect: number;
interest: number;
items: number;
liabilities: number;

View File

@@ -1,3 +1,5 @@
import { DateRange } from '@ghostfolio/common/types';
import { Big } from 'big.js';
export interface SymbolMetrics {
@@ -26,12 +28,12 @@ export interface SymbolMetrics {
};
netPerformance: Big;
netPerformancePercentage: Big;
netPerformancePercentageWithCurrencyEffect: Big;
netPerformancePercentageWithCurrencyEffectMap: { [key: DateRange]: Big };
netPerformanceValues: {
[date: string]: Big;
};
netPerformanceValuesWithCurrencyEffect: { [date: string]: Big };
netPerformanceWithCurrencyEffect: Big;
netPerformanceWithCurrencyEffectMap: { [key: DateRange]: Big };
timeWeightedInvestment: Big;
timeWeightedInvestmentValues: {
[date: string]: Big;

View File

@@ -1,5 +1,8 @@
import { transformToBig } from '@ghostfolio/common/class-transformer';
import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces';
import {
AssetProfileIdentifier,
HistoricalDataItem
} from '@ghostfolio/common/interfaces';
import { TimelinePosition } from '@ghostfolio/common/models';
import { Big } from 'big.js';
@@ -9,49 +12,12 @@ export class PortfolioSnapshot {
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
currentValueInBaseCurrency: Big;
errors?: AssetProfileIdentifier[];
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
grossPerformance: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
grossPerformanceWithCurrencyEffect: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
grossPerformancePercentage: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
grossPerformancePercentageWithCurrencyEffect: Big;
hasErrors: boolean;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netAnnualizedPerformance?: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netAnnualizedPerformanceWithCurrencyEffect?: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netPerformance: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netPerformanceWithCurrencyEffect: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netPerformancePercentage: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netPerformancePercentageWithCurrencyEffect: Big;
historicalData: HistoricalDataItem[];
@Type(() => TimelinePosition)
positions: TimelinePosition[];

View File

@@ -1,4 +1,8 @@
import { transformToBig } from '@ghostfolio/common/class-transformer';
import {
transformToBig,
transformToMapOfBig
} from '@ghostfolio/common/class-transformer';
import { DateRange } from '@ghostfolio/common/types';
import { DataSource, Tag } from '@prisma/client';
import { Big } from 'big.js';
@@ -65,13 +69,11 @@ export class TimelinePosition {
@Type(() => Big)
netPerformancePercentage: Big;
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netPerformancePercentageWithCurrencyEffect: Big;
@Transform(transformToMapOfBig, { toClassOnly: true })
netPerformancePercentageWithCurrencyEffectMap: { [key: DateRange]: Big };
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)
netPerformanceWithCurrencyEffect: Big;
@Transform(transformToMapOfBig, { toClassOnly: true })
netPerformanceWithCurrencyEffectMap: { [key: DateRange]: Big };
@Transform(transformToBig, { toClassOnly: true })
@Type(() => Big)