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

125 lines
3.4 KiB
TypeScript
Raw Normal View History

2021-07-28 15:15:31 +02:00
import { GetValueObject } from '@ghostfolio/api/app/core/get-value.object';
import { GetValueParams } from '@ghostfolio/api/app/core/get-value.params';
import { GetValuesParams } from '@ghostfolio/api/app/core/get-values.params';
2021-07-08 22:42:19 +02:00
import { DataProviderService } from '@ghostfolio/api/services/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-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';
2021-07-27 21:07:28 +02:00
import { MarketDataService } from './market-data.service';
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
) {}
2021-07-03 16:37:33 +02:00
public async getValue({
currency,
date,
symbol,
userCurrency
}: GetValueParams): Promise<GetValueObject> {
2021-07-08 22:42:19 +02:00
if (isToday(date)) {
const dataProviderResult = await this.dataProviderService.get([symbol]);
return {
date: resetHours(date),
2021-07-20 21:07:17 +02:00
marketPrice: dataProviderResult?.[symbol]?.marketPrice ?? 0,
symbol: symbol
};
2021-07-08 22:42:19 +02:00
}
2021-07-03 16:37:33 +02:00
const marketData = await this.marketDataService.get({
date,
symbol
});
2021-07-03 16:37:33 +02:00
if (marketData) {
return {
date: marketData.date,
2021-07-20 21:07:17 +02:00
symbol: marketData.symbol,
marketPrice: this.exchangeRateDataService.toCurrency(
marketData.marketPrice,
currency,
userCurrency
)
};
2021-07-03 16:37:33 +02:00
}
throw new Error(`Value not found for ${symbol} at ${resetHours(date)}`);
}
public async getValues({
2021-07-20 20:42:56 +02:00
currencies,
dateQuery,
2021-07-20 20:42:56 +02:00
symbols,
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;
symbol: string;
marketPrice: number;
}[]
>[] = [];
if (includeToday) {
const today = resetHours(new Date());
promises.push(
this.dataProviderService.get(symbols).then((dataResultProvider) => {
const result = [];
for (const symbol of symbols) {
result.push({
date: today,
symbol: symbol,
marketPrice: dataResultProvider?.[symbol]?.marketPrice ?? 0
});
}
return result;
})
);
}
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,
symbol: marketDataItem.symbol,
marketPrice: this.exchangeRateDataService.toCurrency(
marketDataItem.marketPrice,
currencies[marketDataItem.symbol],
userCurrency
)
};
});
})
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;
}
}