Improve typings (#2889)
This commit is contained in:
parent
c918deeb1c
commit
0ee632470e
@ -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) {
|
||||||
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',
|
granularity = 'day',
|
||||||
from: Date,
|
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
|
||||||
to: Date,
|
symbol,
|
||||||
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT')
|
to
|
||||||
): Promise<{
|
}: GetHistoricalParams): 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…
x
Reference in New Issue
Block a user