Improve typings (#2889)

pull/2892/head
Thomas Kaul 9 months ago committed by GitHub
parent c918deeb1c
commit 0ee632470e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,12 +1,17 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces'; } from '@ghostfolio/api/services/interfaces/interfaces';
import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import * as Alphavantage from 'alphavantage'; import * as Alphavantage from 'alphavantage';
@ -39,31 +44,17 @@ export class AlphaVantageService implements DataProviderInterface {
}; };
} }
public async getDividends({ public async getDividends({}: GetDividendsParams) {
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {}; return {};
} }
public async getHistorical( public async getHistorical({
aSymbol: string, from,
aGranularity: Granularity = 'day', symbol,
from: Date, to
to: Date, }: GetHistoricalParams): Promise<{
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT')
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
const symbol = aSymbol;
try { try {
const historicalData: { const historicalData: {
[symbol: string]: IAlphaVantageHistoricalResponse[]; [symbol: string]: IAlphaVantageHistoricalResponse[];
@ -94,7 +85,7 @@ export class AlphaVantageService implements DataProviderInterface {
return response; return response;
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -106,13 +97,9 @@ export class AlphaVantageService implements DataProviderInterface {
return DataSource.ALPHA_VANTAGE; return DataSource.ALPHA_VANTAGE;
} }
public async getQuotes({ public async getQuotes({}: GetQuotesParams): Promise<{
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), [symbol: string]: IDataProviderResponse;
symbols }> {
}: {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
return {}; return {};
} }
@ -121,12 +108,8 @@ export class AlphaVantageService implements DataProviderInterface {
} }
public async search({ public async search({
includeIndices = false,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
const result = await this.alphaVantage.data.search(query); const result = await this.alphaVantage.data.search(query);
return { return {

@ -1,6 +1,12 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
@ -8,7 +14,6 @@ import {
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper';
import { DataProviderInfo } from '@ghostfolio/common/interfaces'; import { DataProviderInfo } from '@ghostfolio/common/interfaces';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { import {
AssetClass, AssetClass,
@ -86,27 +91,16 @@ export class CoinGeckoService implements DataProviderInterface {
return response; return response;
} }
public async getDividends({ public async getDividends({}: GetDividendsParams) {
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {}; return {};
} }
public async getHistorical( public async getHistorical({
aSymbol: string, from,
aGranularity: Granularity = 'day', requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
from: Date, symbol,
to: Date, to
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT') }: GetHistoricalParams): Promise<{
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
try { try {
@ -119,7 +113,7 @@ export class CoinGeckoService implements DataProviderInterface {
const { prices } = await got( const { prices } = await got(
`${ `${
this.apiUrl this.apiUrl
}/coins/${aSymbol}/market_chart/range?vs_currency=${DEFAULT_CURRENCY.toLowerCase()}&from=${getUnixTime( }/coins/${symbol}/market_chart/range?vs_currency=${DEFAULT_CURRENCY.toLowerCase()}&from=${getUnixTime(
from from
)}&to=${getUnixTime(to)}`, )}&to=${getUnixTime(to)}`,
{ {
@ -132,11 +126,11 @@ export class CoinGeckoService implements DataProviderInterface {
const result: { const result: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
} = { } = {
[aSymbol]: {} [symbol]: {}
}; };
for (const [timestamp, marketPrice] of prices) { for (const [timestamp, marketPrice] of prices) {
result[aSymbol][format(fromUnixTime(timestamp / 1000), DATE_FORMAT)] = { result[symbol][format(fromUnixTime(timestamp / 1000), DATE_FORMAT)] = {
marketPrice marketPrice
}; };
} }
@ -144,7 +138,7 @@ export class CoinGeckoService implements DataProviderInterface {
return result; return result;
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -163,10 +157,7 @@ export class CoinGeckoService implements DataProviderInterface {
public async getQuotes({ public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {}; const response: { [symbol: string]: IDataProviderResponse } = {};
if (symbols.length <= 0) { if (symbols.length <= 0) {
@ -220,12 +211,8 @@ export class CoinGeckoService implements DataProviderInterface {
} }
public async search({ public async search({
includeIndices = false,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
let items: LookupItem[] = []; let items: LookupItem[] = [];
try { try {

@ -218,7 +218,12 @@ export class DataProviderService {
if (dataProvider.canHandle(symbol)) { if (dataProvider.canHandle(symbol)) {
promises.push( promises.push(
dataProvider dataProvider
.getHistorical(symbol, undefined, from, to, ms('30 seconds')) .getHistorical({
from,
symbol,
to,
requestTimeout: ms('30 seconds')
})
.then((data) => ({ data: data?.[symbol], symbol })) .then((data) => ({ data: data?.[symbol], symbol }))
); );
} }

@ -1,13 +1,18 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces'; } from '@ghostfolio/api/services/interfaces/interfaces';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT, isCurrency } from '@ghostfolio/common/helper'; import { DATE_FORMAT, isCurrency } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { import {
AssetClass, AssetClass,
@ -50,30 +55,20 @@ export class EodHistoricalDataService implements DataProviderInterface {
}; };
} }
public async getDividends({ public async getDividends({}: GetDividendsParams) {
return {};
}
public async getHistorical({
from, from,
granularity = 'day', granularity = 'day',
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbol, symbol,
to to
}: { }: GetHistoricalParams): Promise<{
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {};
}
public async getHistorical(
aSymbol: string,
aGranularity: Granularity = 'day',
from: Date,
to: Date,
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT')
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
const symbol = this.convertToEodSymbol(aSymbol); symbol = this.convertToEodSymbol(symbol);
try { try {
const abortController = new AbortController(); const abortController = new AbortController();
@ -88,7 +83,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
}&fmt=json&from=${format(from, DATE_FORMAT)}&to=${format( }&fmt=json&from=${format(from, DATE_FORMAT)}&to=${format(
to, to,
DATE_FORMAT DATE_FORMAT
)}&period=${aGranularity}`, )}&period=${granularity}`,
{ {
// @ts-ignore // @ts-ignore
signal: abortController.signal signal: abortController.signal
@ -99,7 +94,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
(result, historicalItem, index, array) => { (result, historicalItem, index, array) => {
result[this.convertFromEodSymbol(symbol)][historicalItem.date] = { result[this.convertFromEodSymbol(symbol)][historicalItem.date] = {
marketPrice: this.getConvertedValue({ marketPrice: this.getConvertedValue({
symbol: aSymbol, symbol: symbol,
value: historicalItem.close value: historicalItem.close
}) })
}; };
@ -110,7 +105,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
); );
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -131,10 +126,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
public async getQuotes({ public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
let response: { [symbol: string]: IDataProviderResponse } = {}; let response: { [symbol: string]: IDataProviderResponse } = {};
if (symbols.length <= 0) { if (symbols.length <= 0) {
@ -267,12 +259,8 @@ export class EodHistoricalDataService implements DataProviderInterface {
} }
public async search({ public async search({
includeIndices = false,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
const searchResult = await this.getSearchResult(query); const searchResult = await this.getSearchResult(query);
return { return {

@ -1,6 +1,12 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
@ -8,7 +14,6 @@ import {
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
import { DataProviderInfo } from '@ghostfolio/common/interfaces'; import { DataProviderInfo } from '@ghostfolio/common/interfaces';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import { format, isAfter, isBefore, isSameDay } from 'date-fns'; import { format, isAfter, isBefore, isSameDay } from 'date-fns';
@ -40,27 +45,16 @@ export class FinancialModelingPrepService implements DataProviderInterface {
}; };
} }
public async getDividends({ public async getDividends({}: GetDividendsParams) {
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {}; return {};
} }
public async getHistorical( public async getHistorical({
aSymbol: string, from,
aGranularity: Granularity = 'day', requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
from: Date, symbol,
to: Date, to
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT') }: GetHistoricalParams): Promise<{
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
try { try {
@ -71,7 +65,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
}, requestTimeout); }, requestTimeout);
const { historical } = await got( const { historical } = await got(
`${this.URL}/historical-price-full/${aSymbol}?apikey=${this.apiKey}`, `${this.URL}/historical-price-full/${symbol}?apikey=${this.apiKey}`,
{ {
// @ts-ignore // @ts-ignore
signal: abortController.signal signal: abortController.signal
@ -81,7 +75,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
const result: { const result: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
} = { } = {
[aSymbol]: {} [symbol]: {}
}; };
for (const { close, date } of historical) { for (const { close, date } of historical) {
@ -90,7 +84,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
isAfter(parseDate(date), from)) && isAfter(parseDate(date), from)) &&
isBefore(parseDate(date), to) isBefore(parseDate(date), to)
) { ) {
result[aSymbol][date] = { result[symbol][date] = {
marketPrice: close marketPrice: close
}; };
} }
@ -99,7 +93,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
return result; return result;
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -114,10 +108,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
public async getQuotes({ public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {}; const response: { [symbol: string]: IDataProviderResponse } = {};
if (symbols.length <= 0) { if (symbols.length <= 0) {
@ -168,12 +159,8 @@ export class FinancialModelingPrepService implements DataProviderInterface {
} }
public async search({ public async search({
includeIndices = false,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
let items: LookupItem[] = []; let items: LookupItem[] = [];
try { try {

@ -1,6 +1,12 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
@ -8,7 +14,6 @@ import {
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import { format } from 'date-fns'; import { format } from 'date-fns';
@ -35,32 +40,18 @@ export class GoogleSheetsService implements DataProviderInterface {
}; };
} }
public async getDividends({ public async getDividends({}: GetDividendsParams) {
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {}; return {};
} }
public async getHistorical( public async getHistorical({
aSymbol: string, from,
aGranularity: Granularity = 'day', symbol,
from: Date, to
to: Date, }: GetHistoricalParams): Promise<{
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT')
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
try { try {
const symbol = aSymbol;
const sheet = await this.getSheet({ const sheet = await this.getSheet({
symbol, symbol,
sheetId: this.configurationService.get('GOOGLE_SHEETS_ID') sheetId: this.configurationService.get('GOOGLE_SHEETS_ID')
@ -88,7 +79,7 @@ export class GoogleSheetsService implements DataProviderInterface {
}; };
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -101,12 +92,8 @@ export class GoogleSheetsService implements DataProviderInterface {
} }
public async getQuotes({ public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {}; const response: { [symbol: string]: IDataProviderResponse } = {};
if (symbols.length <= 0) { if (symbols.length <= 0) {
@ -159,12 +146,8 @@ export class GoogleSheetsService implements DataProviderInterface {
} }
public async search({ public async search({
includeIndices = false,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
const items = await this.prismaService.symbolProfile.findMany({ const items = await this.prismaService.symbolProfile.findMany({
select: { select: {
assetClass: true, assetClass: true,

@ -11,25 +11,17 @@ export interface DataProviderInterface {
getAssetProfile(aSymbol: string): Promise<Partial<SymbolProfile>>; getAssetProfile(aSymbol: string): Promise<Partial<SymbolProfile>>;
getDividends({ getDividends({ from, granularity, symbol, to }: GetDividendsParams): Promise<{
[date: string]: IDataProviderHistoricalResponse;
}>;
getHistorical({
from, from,
granularity, granularity,
requestTimeout,
symbol, symbol,
to to
}: { }: GetHistoricalParams): Promise<{
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}): Promise<{ [date: string]: IDataProviderHistoricalResponse }>;
getHistorical(
aSymbol: string,
aGranularity: Granularity,
from: Date,
to: Date,
requestTimeout?: number
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}>; // TODO: Return only one symbol }>; // TODO: Return only one symbol
@ -40,18 +32,37 @@ export interface DataProviderInterface {
getQuotes({ getQuotes({
requestTimeout, requestTimeout,
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }>;
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }>;
getTestSymbol(): string; getTestSymbol(): string;
search({ search({
includeIndices, includeIndices,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }>;
includeIndices?: boolean; }
query: string;
}): Promise<{ items: LookupItem[] }>; export interface GetDividendsParams {
from: Date;
granularity?: Granularity;
symbol: string;
to: Date;
}
export interface GetHistoricalParams {
from: Date;
granularity?: Granularity;
requestTimeout?: number;
symbol: string;
to: Date;
}
export interface GetQuotesParams {
requestTimeout?: number;
symbols: string[];
}
export interface GetSearchParams {
includeIndices?: boolean;
query: string;
} }

@ -1,6 +1,12 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
@ -13,7 +19,6 @@ import {
getYesterday getYesterday
} from '@ghostfolio/common/helper'; } from '@ghostfolio/common/helper';
import { ScraperConfiguration } from '@ghostfolio/common/interfaces'; import { ScraperConfiguration } from '@ghostfolio/common/interfaces';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
@ -43,32 +48,18 @@ export class ManualService implements DataProviderInterface {
}; };
} }
public async getDividends({ public async getDividends({}: GetDividendsParams) {
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {}; return {};
} }
public async getHistorical( public async getHistorical({
aSymbol: string, from,
aGranularity: Granularity = 'day', symbol,
from: Date, to
to: Date, }: GetHistoricalParams): Promise<{
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT')
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
try { try {
const symbol = aSymbol;
const [symbolProfile] = await this.symbolProfileService.getSymbolProfiles( const [symbolProfile] = await this.symbolProfileService.getSymbolProfiles(
[{ symbol, dataSource: this.getName() }] [{ symbol, dataSource: this.getName() }]
); );
@ -111,7 +102,7 @@ export class ManualService implements DataProviderInterface {
}; };
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -124,12 +115,8 @@ export class ManualService implements DataProviderInterface {
} }
public async getQuotes({ public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {}; const response: { [symbol: string]: IDataProviderResponse } = {};
if (symbols.length <= 0) { if (symbols.length <= 0) {
@ -180,12 +167,8 @@ export class ManualService implements DataProviderInterface {
} }
public async search({ public async search({
includeIndices = false,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
let items = await this.prismaService.symbolProfile.findMany({ let items = await this.prismaService.symbolProfile.findMany({
select: { select: {
assetClass: true, assetClass: true,

@ -1,13 +1,18 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces'; } from '@ghostfolio/api/services/interfaces/interfaces';
import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config'; import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config';
import { DATE_FORMAT, getYesterday } from '@ghostfolio/common/helper'; import { DATE_FORMAT, getYesterday } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import { format } from 'date-fns'; import { format } from 'date-fns';
@ -32,32 +37,18 @@ export class RapidApiService implements DataProviderInterface {
}; };
} }
public async getDividends({ public async getDividends({}: GetDividendsParams) {
from,
granularity = 'day',
symbol,
to
}: {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
return {}; return {};
} }
public async getHistorical( public async getHistorical({
aSymbol: string, from,
aGranularity: Granularity = 'day', symbol,
from: Date, to
to: Date, }: GetHistoricalParams): Promise<{
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT')
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
try { try {
const symbol = aSymbol;
if (symbol === ghostfolioFearAndGreedIndexSymbol) { if (symbol === ghostfolioFearAndGreedIndexSymbol) {
const fgi = await this.getFearAndGreedIndex(); const fgi = await this.getFearAndGreedIndex();
@ -71,7 +62,7 @@ export class RapidApiService implements DataProviderInterface {
} }
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -86,12 +77,8 @@ export class RapidApiService implements DataProviderInterface {
} }
public async getQuotes({ public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
if (symbols.length <= 0) { if (symbols.length <= 0) {
return {}; return {};
} }
@ -122,13 +109,7 @@ export class RapidApiService implements DataProviderInterface {
return undefined; return undefined;
} }
public async search({ public async search({}: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices = false,
query
}: {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
return { items: [] }; return { items: [] };
} }

@ -1,15 +1,19 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service'; import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service'; import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; import {
DataProviderInterface,
GetDividendsParams,
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { import {
IDataProviderHistoricalResponse, IDataProviderHistoricalResponse,
IDataProviderResponse IDataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces'; } from '@ghostfolio/api/services/interfaces/interfaces';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import Big from 'big.js'; import Big from 'big.js';
@ -20,7 +24,6 @@ import { Quote } from 'yahoo-finance2/dist/esm/src/modules/quote';
@Injectable() @Injectable()
export class YahooFinanceService implements DataProviderInterface { export class YahooFinanceService implements DataProviderInterface {
public constructor( public constructor(
private readonly configurationService: ConfigurationService,
private readonly cryptocurrencyService: CryptocurrencyService, private readonly cryptocurrencyService: CryptocurrencyService,
private readonly yahooFinanceDataEnhancerService: YahooFinanceDataEnhancerService private readonly yahooFinanceDataEnhancerService: YahooFinanceDataEnhancerService
) {} ) {}
@ -50,12 +53,7 @@ export class YahooFinanceService implements DataProviderInterface {
granularity = 'day', granularity = 'day',
symbol, symbol,
to to
}: { }: GetDividendsParams) {
from: Date;
granularity: Granularity;
symbol: string;
to: Date;
}) {
if (isSameDay(from, to)) { if (isSameDay(from, to)) {
to = addDays(to, 1); to = addDays(to, 1);
} }
@ -100,13 +98,11 @@ export class YahooFinanceService implements DataProviderInterface {
} }
} }
public async getHistorical( public async getHistorical({
aSymbol: string, from,
aGranularity: Granularity = 'day', symbol,
from: Date, to
to: Date, }: GetHistoricalParams): Promise<{
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT')
): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
if (isSameDay(from, to)) { if (isSameDay(from, to)) {
@ -116,7 +112,7 @@ export class YahooFinanceService implements DataProviderInterface {
try { try {
const historicalResult = await yahooFinance.historical( const historicalResult = await yahooFinance.historical(
this.yahooFinanceDataEnhancerService.convertToYahooFinanceSymbol( this.yahooFinanceDataEnhancerService.convertToYahooFinanceSymbol(
aSymbol symbol
), ),
{ {
interval: '1d', interval: '1d',
@ -129,12 +125,12 @@ export class YahooFinanceService implements DataProviderInterface {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
} = {}; } = {};
response[aSymbol] = {}; response[symbol] = {};
for (const historicalItem of historicalResult) { for (const historicalItem of historicalResult) {
response[aSymbol][format(historicalItem.date, DATE_FORMAT)] = { response[symbol][format(historicalItem.date, DATE_FORMAT)] = {
marketPrice: this.getConvertedValue({ marketPrice: this.getConvertedValue({
symbol: aSymbol, symbol: symbol,
value: historicalItem.close value: historicalItem.close
}) })
}; };
@ -143,7 +139,7 @@ export class YahooFinanceService implements DataProviderInterface {
return response; return response;
} catch (error) { } catch (error) {
throw new Error( throw new Error(
`Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from, from,
DATE_FORMAT DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
@ -160,12 +156,8 @@ export class YahooFinanceService implements DataProviderInterface {
} }
public async getQuotes({ public async getQuotes({
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbols symbols
}: { }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> {
requestTimeout?: number;
symbols: string[];
}): Promise<{ [symbol: string]: IDataProviderResponse }> {
const response: { [symbol: string]: IDataProviderResponse } = {}; const response: { [symbol: string]: IDataProviderResponse } = {};
if (symbols.length <= 0) { if (symbols.length <= 0) {
@ -280,10 +272,7 @@ export class YahooFinanceService implements DataProviderInterface {
public async search({ public async search({
includeIndices = false, includeIndices = false,
query query
}: { }: GetSearchParams): Promise<{ items: LookupItem[] }> {
includeIndices?: boolean;
query: string;
}): Promise<{ items: LookupItem[] }> {
const items: LookupItem[] = []; const items: LookupItem[] = [];
try { try {

Loading…
Cancel
Save