Feature/set up caching in portfolio calculator (#3335)
* Set up caching * Update changelogpull/3338/head
parent
cd07802400
commit
4f41bac328
@ -1,24 +0,0 @@
|
||||
import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces';
|
||||
|
||||
import { Big } from 'big.js';
|
||||
|
||||
export interface PortfolioSnapshot extends ResponseError {
|
||||
currentValueInBaseCurrency: Big;
|
||||
grossPerformance: Big;
|
||||
grossPerformanceWithCurrencyEffect: Big;
|
||||
grossPerformancePercentage: Big;
|
||||
grossPerformancePercentageWithCurrencyEffect: Big;
|
||||
netAnnualizedPerformance?: Big;
|
||||
netAnnualizedPerformanceWithCurrencyEffect?: Big;
|
||||
netPerformance: Big;
|
||||
netPerformanceWithCurrencyEffect: Big;
|
||||
netPerformancePercentage: Big;
|
||||
netPerformancePercentageWithCurrencyEffect: Big;
|
||||
positions: TimelinePosition[];
|
||||
totalFeesWithCurrencyEffect: Big;
|
||||
totalInterestWithCurrencyEffect: Big;
|
||||
totalInvestment: Big;
|
||||
totalInvestmentWithCurrencyEffect: Big;
|
||||
totalLiabilitiesWithCurrencyEffect: Big;
|
||||
totalValuablesWithCurrencyEffect: Big;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import { RedisCacheService } from './redis-cache.service';
|
||||
|
||||
export const RedisCacheServiceMock = {
|
||||
get: (key: string): Promise<string> => {
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
getPortfolioSnapshotKey: (userId: string): string => {
|
||||
return `portfolio-snapshot-${userId}`;
|
||||
},
|
||||
set: (key: string, value: string, ttlInSeconds?: number): Promise<string> => {
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
};
|
@ -1,8 +1,11 @@
|
||||
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
|
||||
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { PortfolioChangedListener } from './portfolio-changed.listener';
|
||||
|
||||
@Module({
|
||||
imports: [RedisCacheModule],
|
||||
providers: [PortfolioChangedListener]
|
||||
})
|
||||
export class EventsModule {}
|
||||
|
@ -0,0 +1,9 @@
|
||||
import { Big } from 'big.js';
|
||||
|
||||
export function transformToBig({ value }: { value: string }): Big {
|
||||
if (value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Big(value);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
import { DataSource, Tag } from '@prisma/client';
|
||||
import { Big } from 'big.js';
|
||||
|
||||
export interface TimelinePosition {
|
||||
averagePrice: Big;
|
||||
currency: string;
|
||||
dataSource: DataSource;
|
||||
dividend: Big;
|
||||
dividendInBaseCurrency: Big;
|
||||
fee: Big;
|
||||
firstBuyDate: string;
|
||||
grossPerformance: Big;
|
||||
grossPerformancePercentage: Big;
|
||||
grossPerformancePercentageWithCurrencyEffect: Big;
|
||||
grossPerformanceWithCurrencyEffect: Big;
|
||||
investment: Big;
|
||||
investmentWithCurrencyEffect: Big;
|
||||
marketPrice: number;
|
||||
marketPriceInBaseCurrency: number;
|
||||
netPerformance: Big;
|
||||
netPerformancePercentage: Big;
|
||||
netPerformancePercentageWithCurrencyEffect: Big;
|
||||
netPerformanceWithCurrencyEffect: Big;
|
||||
quantity: Big;
|
||||
symbol: string;
|
||||
tags?: Tag[];
|
||||
timeWeightedInvestment: Big;
|
||||
timeWeightedInvestmentWithCurrencyEffect: Big;
|
||||
transactionCount: number;
|
||||
valueInBaseCurrency: Big;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
import { PortfolioSnapshot } from './portfolio-snapshot';
|
||||
import { TimelinePosition } from './timeline-position';
|
||||
|
||||
export { PortfolioSnapshot, TimelinePosition };
|
@ -0,0 +1,82 @@
|
||||
import { transformToBig } from '@ghostfolio/common/class-transformer';
|
||||
import { UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||
import { TimelinePosition } from '@ghostfolio/common/models';
|
||||
|
||||
import { Big } from 'big.js';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
|
||||
export class PortfolioSnapshot {
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
currentValueInBaseCurrency: Big;
|
||||
errors?: UniqueAsset[];
|
||||
|
||||
@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;
|
||||
|
||||
@Type(() => TimelinePosition)
|
||||
positions: TimelinePosition[];
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalFeesWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalInterestWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalInvestment: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalInvestmentWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalLiabilitiesWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
totalValuablesWithCurrencyEffect: Big;
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
import { transformToBig } from '@ghostfolio/common/class-transformer';
|
||||
|
||||
import { DataSource, Tag } from '@prisma/client';
|
||||
import { Big } from 'big.js';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
|
||||
export class TimelinePosition {
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
averagePrice: Big;
|
||||
|
||||
currency: string;
|
||||
dataSource: DataSource;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
dividend: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
dividendInBaseCurrency: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
fee: Big;
|
||||
|
||||
firstBuyDate: string;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformance: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformancePercentage: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformancePercentageWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
grossPerformanceWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
investment: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
investmentWithCurrencyEffect: Big;
|
||||
|
||||
marketPrice: number;
|
||||
marketPriceInBaseCurrency: number;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformance: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformancePercentage: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformancePercentageWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
netPerformanceWithCurrencyEffect: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
quantity: Big;
|
||||
|
||||
symbol: string;
|
||||
tags?: Tag[];
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
timeWeightedInvestment: Big;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
timeWeightedInvestmentWithCurrencyEffect: Big;
|
||||
|
||||
transactionCount: number;
|
||||
|
||||
@Transform(transformToBig, { toClassOnly: true })
|
||||
@Type(() => Big)
|
||||
valueInBaseCurrency: Big;
|
||||
}
|
Loading…
Reference in new issue