mirror of https://github.com/ghostfolio/ghostfolio
				
				
			
							committed by
							
								 GitHub
								GitHub
							
						
					
				
				 36 changed files with 687 additions and 145 deletions
			
			
		| @ -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