ghostfolio/apps/api/src/app/portfolio/current-rate.service.ts

100 lines
3.0 KiB
TypeScript
Raw Normal View History

import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
import { resetHours } from '@ghostfolio/common/helper';
2021-07-03 16:37:33 +02:00
import { Injectable } from '@nestjs/common';
2021-07-27 21:54:17 +02:00
import { isBefore, isToday } from 'date-fns';
2021-07-28 15:15:31 +02:00
import { flatten } from 'lodash';
import { GetValueObject } from './interfaces/get-value-object.interface';
import { GetValuesParams } from './interfaces/get-values-params.interface';
2021-07-03 16:37:33 +02:00
@Injectable()
export class CurrentRateService {
public constructor(
2021-07-08 22:42:19 +02:00
private readonly dataProviderService: DataProviderService,
private readonly exchangeRateDataService: ExchangeRateDataService,
2021-07-03 16:37:33 +02:00
private readonly marketDataService: MarketDataService
) {}
public async getValues({
2021-07-20 20:42:56 +02:00
currencies,
dataGatheringItems,
dateQuery,
userCurrency
}: GetValuesParams): Promise<GetValueObject[]> {
2021-07-27 21:54:17 +02:00
const includeToday =
(!dateQuery.lt || isBefore(new Date(), dateQuery.lt)) &&
(!dateQuery.gte || isBefore(dateQuery.gte, new Date())) &&
(!dateQuery.in || this.containsToday(dateQuery.in));
const promises: Promise<
{
date: Date;
marketPrice: number;
2021-07-28 15:27:53 +02:00
symbol: string;
2021-07-27 21:54:17 +02:00
}[]
>[] = [];
if (includeToday) {
const today = resetHours(new Date());
promises.push(
this.dataProviderService
.getQuotes(dataGatheringItems)
.then((dataResultProvider) => {
const result = [];
for (const dataGatheringItem of dataGatheringItems) {
result.push({
date: today,
marketPrice: this.exchangeRateDataService.toCurrency(
dataResultProvider?.[dataGatheringItem.symbol]?.marketPrice ??
0,
dataResultProvider?.[dataGatheringItem.symbol]?.currency,
userCurrency
),
symbol: dataGatheringItem.symbol
});
}
return result;
})
2021-07-27 21:54:17 +02:00
);
}
const symbols = dataGatheringItems.map((dataGatheringItem) => {
return dataGatheringItem.symbol;
});
2021-07-27 21:54:17 +02:00
promises.push(
2021-07-27 22:59:24 +02:00
this.marketDataService
.getRange({
dateQuery,
symbols
})
.then((data) => {
return data.map((marketDataItem) => {
return {
date: marketDataItem.date,
marketPrice: this.exchangeRateDataService.toCurrency(
marketDataItem.marketPrice,
currencies[marketDataItem.symbol],
userCurrency
2021-07-28 15:27:53 +02:00
),
symbol: marketDataItem.symbol
2021-07-27 22:59:24 +02:00
};
});
})
2021-07-27 21:54:17 +02:00
);
2021-07-27 22:59:24 +02:00
return flatten(await Promise.all(promises));
}
2021-07-27 21:54:17 +02:00
private containsToday(dates: Date[]): boolean {
for (const date of dates) {
if (isToday(date)) {
return true;
}
}
return false;
}
}