Browse Source

Refactor PortfolioSnapshotProcessor

pull/3725/head
Thomas Kaul 12 months ago
parent
commit
0b1cadabd9
  1. 13
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  2. 9
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts
  3. 1
      apps/api/src/services/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts
  4. 11
      apps/api/src/services/portfolio-snapshot/portfolio-snapshot.module.ts
  5. 42
      apps/api/src/services/portfolio-snapshot/portfolio-snapshot.processor.ts

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

@ -160,7 +160,7 @@ export abstract class PortfolioCalculator {
): PortfolioSnapshot;
@LogPerformance
private async computeSnapshot(): Promise<PortfolioSnapshot> {
public async computeSnapshot(): Promise<PortfolioSnapshot> {
const lastTransactionPoint = last(this.transactionPoints);
const transactionPoints = this.transactionPoints?.filter(({ date }) => {
@ -1018,6 +1018,7 @@ export abstract class PortfolioCalculator {
let cachedPortfolioSnapshot: PortfolioSnapshot;
let isCachedPortfolioSnapshotExpired = false;
const jobId = this.userId;
try {
const cachedPortfolioSnapshotValue = await this.redisCacheService.get(
@ -1056,12 +1057,13 @@ export abstract class PortfolioCalculator {
this.portfolioSnapshotService.addJobToQueue({
data: {
filters: this.filters,
userCurrency: this.currency,
userId: this.userId
},
name: PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME,
opts: {
...PORTFOLIO_SNAPSHOT_PROCESS_JOB_OPTIONS
// jobId
...PORTFOLIO_SNAPSHOT_PROCESS_JOB_OPTIONS,
jobId
// priority
}
});
@ -1072,12 +1074,13 @@ export abstract class PortfolioCalculator {
const job = await this.portfolioSnapshotService.addJobToQueue({
data: {
filters: this.filters,
userCurrency: this.currency,
userId: this.userId
},
name: PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME,
opts: {
...PORTFOLIO_SNAPSHOT_PROCESS_JOB_OPTIONS
// jobId
...PORTFOLIO_SNAPSHOT_PROCESS_JOB_OPTIONS,
jobId
// priority
}
});

9
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts

@ -14,7 +14,6 @@ import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.s
import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { PortfolioSnapshotProcessor } from '@ghostfolio/api/services/portfolio-snapshot/portfolio-snapshot.processor';
import { PortfolioSnapshotService } from '@ghostfolio/api/services/portfolio-snapshot/portfolio-snapshot.service';
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/portfolio-snapshot/portfolio-snapshot.service.mock';
import { parseDate } from '@ghostfolio/common/helper';
@ -129,13 +128,7 @@ describe('PortfolioCalculator', () => {
userId: userDummyData.id
});
const portfolioSnapshotProcessor = new PortfolioSnapshotProcessor(
null,
null
);
const portfolioSnapshot =
await portfolioSnapshotProcessor.computeSnapshot();
const portfolioSnapshot = await portfolioCalculator.computeSnapshot();
const investments = portfolioCalculator.getInvestments();

1
apps/api/src/services/portfolio-snapshot/interfaces/portfolio-snapshot-queue-job.interface.ts

@ -2,5 +2,6 @@ import { Filter } from '@ghostfolio/common/interfaces';
export interface IPortfolioSnapshotQueueJob {
filters: Filter[];
userCurrency: string;
userId: string;
}

11
apps/api/src/services/portfolio-snapshot/portfolio-snapshot.module.ts

@ -1,3 +1,6 @@
import { OrderModule } from '@ghostfolio/api/app/order/order.module';
import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory';
import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service';
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
@ -27,12 +30,18 @@ import { PortfolioSnapshotProcessor } from './portfolio-snapshot.processor';
DataProviderModule,
ExchangeRateDataModule,
MarketDataModule,
OrderModule,
PrismaModule,
PropertyModule,
RedisCacheModule,
SymbolProfileModule
],
providers: [PortfolioSnapshotProcessor, PortfolioSnapshotService],
providers: [
CurrentRateService,
PortfolioCalculatorFactory,
PortfolioSnapshotProcessor,
PortfolioSnapshotService
],
exports: [BullModule, PortfolioSnapshotService]
})
export class PortfolioSnapshotQueueModule {}

42
apps/api/src/services/portfolio-snapshot/portfolio-snapshot.processor.ts

@ -1,3 +1,8 @@
import { OrderService } from '@ghostfolio/api/app/order/order.service';
import {
PerformanceCalculationType,
PortfolioCalculatorFactory
} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory';
import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface';
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
@ -6,11 +11,9 @@ import {
PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME,
PORTFOLIO_SNAPSHOT_QUEUE
} from '@ghostfolio/common/config';
import { PortfolioSnapshot } from '@ghostfolio/common/models';
import { Process, Processor } from '@nestjs/bull';
import { Injectable, Logger } from '@nestjs/common';
import * as Big from 'big.js';
import { Job } from 'bull';
import { addMilliseconds } from 'date-fns';
@ -20,7 +23,9 @@ import { IPortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queu
@Processor(PORTFOLIO_SNAPSHOT_QUEUE)
export class PortfolioSnapshotProcessor {
public constructor(
private readonly calculatorFactory: PortfolioCalculatorFactory,
private readonly configurationService: ConfigurationService,
private readonly orderService: OrderService,
private readonly redisCacheService: RedisCacheService
) {}
@ -34,7 +39,22 @@ export class PortfolioSnapshotProcessor {
`PortfolioSnapshotProcessor (${PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME})`
);
const snapshot = await this.computeSnapshot();
const { activities } =
await this.orderService.getOrdersForPortfolioCalculator({
filters: job.data.filters,
userCurrency: job.data.userCurrency,
userId: job.data.userId
});
const portfolioCalculator = this.calculatorFactory.createCalculator({
activities,
calculationType: PerformanceCalculationType.TWR,
currency: job.data.userCurrency,
filters: job.data.filters,
userId: job.data.userId
});
const snapshot = await portfolioCalculator.computeSnapshot();
Logger.log(
`Portfolio snapshot calculation of user ${job.data.userId} has been completed`,
@ -68,20 +88,4 @@ export class PortfolioSnapshotProcessor {
throw new Error(error);
}
}
// TODO
public async computeSnapshot(): Promise<PortfolioSnapshot> {
return {
currentValueInBaseCurrency: new Big(0),
hasErrors: false,
historicalData: [],
positions: [],
totalFeesWithCurrencyEffect: new Big(0),
totalInterestWithCurrencyEffect: new Big(0),
totalInvestment: new Big(0),
totalInvestmentWithCurrencyEffect: new Big(0),
totalLiabilitiesWithCurrencyEffect: new Big(0),
totalValuablesWithCurrencyEffect: new Big(0)
};
}
}

Loading…
Cancel
Save