Browse Source

Convert benchmark performance to base currency

pull/2790/head
Reto Kaul 2 years ago
parent
commit
24f9bfb1d0
  1. 10
      apps/api/src/app/benchmark/benchmark.controller.ts
  2. 2
      apps/api/src/app/benchmark/benchmark.module.ts
  3. 87
      apps/api/src/app/benchmark/benchmark.service.ts

10
apps/api/src/app/benchmark/benchmark.controller.ts

@ -25,10 +25,15 @@ import { DataSource } from '@prisma/client';
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { BenchmarkService } from './benchmark.service';
import { REQUEST } from '@nestjs/core';
import { RequestWithUser } from '@ghostfolio/common/types';
@Controller('benchmark')
export class BenchmarkController {
public constructor(private readonly benchmarkService: BenchmarkService) {}
public constructor(
private readonly benchmarkService: BenchmarkService,
@Inject(REQUEST) private readonly request: RequestWithUser
) {}
@HasPermission(permissions.accessAdminControl)
@Post()
@ -107,7 +112,8 @@ export class BenchmarkController {
return this.benchmarkService.getMarketDataBySymbol({
dataSource,
startDate,
symbol
symbol,
baseCurrency: this.request.user.Settings.settings.baseCurrency
});
}
}

2
apps/api/src/app/benchmark/benchmark.module.ts

@ -2,6 +2,7 @@ import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.mo
import { SymbolModule } from '@ghostfolio/api/app/symbol/symbol.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
import { MarketDataModule } from '@ghostfolio/api/services/market-data/market-data.module';
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
import { PropertyModule } from '@ghostfolio/api/services/property/property.module';
@ -17,6 +18,7 @@ import { BenchmarkService } from './benchmark.service';
imports: [
ConfigurationModule,
DataProviderModule,
ExchangeRateDataModule,
MarketDataModule,
PrismaModule,
PropertyModule,

87
apps/api/src/app/benchmark/benchmark.service.ts

@ -1,6 +1,7 @@
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
@ -25,7 +26,7 @@ import { Injectable } from '@nestjs/common';
import { SymbolProfile } from '@prisma/client';
import Big from 'big.js';
import { format, subDays } from 'date-fns';
import { uniqBy } from 'lodash';
import { isNumber, uniqBy } from 'lodash';
import ms from 'ms';
@Injectable()
@ -34,6 +35,7 @@ export class BenchmarkService {
public constructor(
private readonly dataProviderService: DataProviderService,
private readonly exchangeRateDataService: ExchangeRateDataService,
private readonly marketDataService: MarketDataService,
private readonly prismaService: PrismaService,
private readonly propertyService: PropertyService,
@ -201,10 +203,14 @@ export class BenchmarkService {
}
public async getMarketDataBySymbol({
baseCurrency,
dataSource,
startDate,
symbol
}: { startDate: Date } & UniqueAsset): Promise<BenchmarkMarketDataDetails> {
}: {
baseCurrency: string;
startDate: Date;
} & UniqueAsset): Promise<BenchmarkMarketDataDetails> {
const [currentSymbolItem, marketDataItems] = await Promise.all([
this.symbolService.get({
dataGatheringItem: {
@ -226,44 +232,75 @@ export class BenchmarkService {
})
]);
const exchangeRateAtStartDate =
await this.exchangeRateDataService.toCurrencyAtDate(
1,
currentSymbolItem.currency,
baseCurrency,
startDate
);
const step = Math.round(
marketDataItems.length / Math.min(marketDataItems.length, MAX_CHART_ITEMS)
);
const marketPriceAtStartDate = marketDataItems?.[0]?.marketPrice ?? 0;
const response = {
marketData: [
...marketDataItems
.filter((marketDataItem, index) => {
return index % step === 0;
})
.map((marketDataItem) => {
return {
date: format(marketDataItem.date, DATE_FORMAT),
value:
marketPriceAtStartDate === 0
? 0
: this.calculateChangeInPercentage(
marketPriceAtStartDate,
marketDataItem.marketPrice
) * 100
};
})
]
};
const marketData: { date: string; value: number }[] = [];
let i = 0;
for (let marketDataItem of marketDataItems) {
if (i % step != 0) {
continue;
}
const exchangeRate = await this.exchangeRateDataService.toCurrencyAtDate(
1,
currentSymbolItem.currency,
baseCurrency,
marketDataItem.date
);
const exchangeRateFactor = isNumber(exchangeRate)
? exchangeRate / exchangeRateAtStartDate
: 1;
marketData.push({
date: format(marketDataItem.date, DATE_FORMAT),
value:
marketPriceAtStartDate === 0
? 0
: this.calculateChangeInPercentage(
marketPriceAtStartDate,
marketDataItem.marketPrice * exchangeRateFactor
) * 100
});
}
if (currentSymbolItem?.marketPrice) {
response.marketData.push({
const exchangeRate = await this.exchangeRateDataService.toCurrencyAtDate(
1,
currentSymbolItem.currency,
baseCurrency,
new Date()
);
const exchangeRateFactor = isNumber(exchangeRate)
? exchangeRate / exchangeRateAtStartDate
: 1;
marketData.push({
date: format(new Date(), DATE_FORMAT),
value:
this.calculateChangeInPercentage(
marketPriceAtStartDate,
currentSymbolItem.marketPrice
currentSymbolItem.marketPrice * exchangeRateFactor
) * 100
});
}
return response;
return {
marketData
};
}
public async addBenchmark({

Loading…
Cancel
Save