Browse Source

Set up Ghostfolio data provider

pull/4016/head
Thomas Kaul 9 months ago
parent
commit
e1b2c60add
  1. 8
      apps/api/src/app/endpoints/data-providers/ghostfolio/get-historical.dto.ts
  2. 1
      apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts
  3. 27
      apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts
  4. 52
      apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts

8
apps/api/src/app/endpoints/data-providers/ghostfolio/get-historical.dto.ts

@ -1,9 +1,15 @@
import { IsISO8601 } from 'class-validator';
import { Granularity } from '@ghostfolio/common/types';
import { IsIn, IsISO8601, IsOptional } from 'class-validator';
export class GetHistoricalDto {
@IsISO8601()
from: string;
@IsIn(['day', 'month'] as Granularity[])
@IsOptional()
granularity: Granularity;
@IsISO8601()
to: string;
}

1
apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.controller.ts

@ -56,6 +56,7 @@ export class GhostfolioController {
const historicalData = await this.ghostfolioService.getHistorical({
symbol,
from: parseDate(query.from),
granularity: query.granularity,
to: parseDate(query.to)
});

27
apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts

@ -1,5 +1,10 @@
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import {
GetHistoricalParams,
GetQuotesParams,
GetSearchParams
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
@ -31,15 +36,11 @@ export class GhostfolioService {
public async getHistorical({
from,
granularity,
requestTimeout,
to,
symbol
}: {
from: Date;
requestTimeout?: number;
symbol: string;
to: Date;
}) {
}: GetHistoricalParams) {
const result: HistoricalResponse = { historicalData: {} };
try {
@ -52,6 +53,7 @@ export class GhostfolioService {
dataProviderService
.getHistorical({
from,
granularity,
requestTimeout,
symbol,
to
@ -83,13 +85,7 @@ export class GhostfolioService {
);
}
public async getQuotes({
requestTimeout,
symbols
}: {
requestTimeout?: number;
symbols: string[];
}) {
public async getQuotes({ requestTimeout, symbols }: GetQuotesParams) {
const promises: Promise<any>[] = [];
const results: QuotesResponse = { quotes: {} };
@ -180,10 +176,7 @@ export class GhostfolioService {
public async lookup({
includeIndices = false,
query
}: {
includeIndices?: boolean;
query: string;
}): Promise<LookupResponse> {
}: GetSearchParams): Promise<LookupResponse> {
const results: LookupResponse = { items: [] };
if (!query) {

52
apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts

@ -13,14 +13,17 @@ import {
} from '@ghostfolio/api/services/interfaces/interfaces';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { PROPERTY_API_KEY_GHOSTFOLIO } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import {
DataProviderInfo,
HistoricalResponse,
LookupResponse,
QuotesResponse
} from '@ghostfolio/common/interfaces';
import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client';
import { format } from 'date-fns';
import got from 'got';
@Injectable()
@ -52,9 +55,16 @@ export class GhostfolioService implements DataProviderInterface {
}: {
symbol: string;
}): Promise<Partial<SymbolProfile>> {
const { items } = await this.search({ query: symbol });
const searchResult = items?.[0];
return {
symbol,
dataSource: this.getName()
assetClass: searchResult?.assetClass,
assetSubClass: searchResult?.assetSubClass,
currency: searchResult?.currency,
dataSource: this.getName(),
name: searchResult?.name
};
}
@ -70,11 +80,45 @@ export class GhostfolioService implements DataProviderInterface {
return {};
}
public async getHistorical({}: GetHistoricalParams): Promise<{
public async getHistorical({
from,
granularity = 'day',
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'),
symbol,
to
}: GetHistoricalParams): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> {
// TODO
return {};
try {
const abortController = new AbortController();
setTimeout(() => {
abortController.abort();
}, requestTimeout);
const { historicalData } = await got(
`${this.URL}/v1/data-providers/ghostfolio/historical/${symbol}?from=${format(from, DATE_FORMAT)}&granularity=${granularity}&to=${format(
to,
DATE_FORMAT
)}`,
{
headers: this.getRequestHeaders(),
// @ts-ignore
signal: abortController.signal
}
).json<HistoricalResponse>();
return {
[symbol]: historicalData
};
} catch (error) {
throw new Error(
`Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
from,
DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
);
}
}
public getMaxNumberOfSymbolsPerRequest() {

Loading…
Cancel
Save