Feature/add financial modeling prep as data source type (#1960)
* Add Financial Modeling Prep as new data source type * Update changelog
This commit is contained in:
parent
8e000baef2
commit
ad46fb6d61
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added `FINANCIAL_MODELING_PREP` as a new data source type
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Improved the market price on the first buy date in the chart of the position detail dialog
|
- Improved the market price on the first buy date in the chart of the position detail dialog
|
||||||
|
@ -29,6 +29,7 @@ export class ConfigurationService {
|
|||||||
ENABLE_FEATURE_SUBSCRIPTION: bool({ default: false }),
|
ENABLE_FEATURE_SUBSCRIPTION: bool({ default: false }),
|
||||||
ENABLE_FEATURE_SYSTEM_MESSAGE: bool({ default: false }),
|
ENABLE_FEATURE_SYSTEM_MESSAGE: bool({ default: false }),
|
||||||
EOD_HISTORICAL_DATA_API_KEY: str({ default: '' }),
|
EOD_HISTORICAL_DATA_API_KEY: str({ default: '' }),
|
||||||
|
FINANCIAL_MODELING_PREP_API_KEY: str({ default: '' }),
|
||||||
GOOGLE_CLIENT_ID: str({ default: 'dummyClientId' }),
|
GOOGLE_CLIENT_ID: str({ default: 'dummyClientId' }),
|
||||||
GOOGLE_SECRET: str({ default: 'dummySecret' }),
|
GOOGLE_SECRET: str({ default: 'dummySecret' }),
|
||||||
GOOGLE_SHEETS_ACCOUNT: str({ default: '' }),
|
GOOGLE_SHEETS_ACCOUNT: str({ default: '' }),
|
||||||
|
@ -3,6 +3,7 @@ import { CryptocurrencyModule } from '@ghostfolio/api/services/cryptocurrency/cr
|
|||||||
import { AlphaVantageService } from '@ghostfolio/api/services/data-provider/alpha-vantage/alpha-vantage.service';
|
import { AlphaVantageService } from '@ghostfolio/api/services/data-provider/alpha-vantage/alpha-vantage.service';
|
||||||
import { CoinGeckoService } from '@ghostfolio/api/services/data-provider/coingecko/coingecko.service';
|
import { CoinGeckoService } from '@ghostfolio/api/services/data-provider/coingecko/coingecko.service';
|
||||||
import { EodHistoricalDataService } from '@ghostfolio/api/services/data-provider/eod-historical-data/eod-historical-data.service';
|
import { EodHistoricalDataService } from '@ghostfolio/api/services/data-provider/eod-historical-data/eod-historical-data.service';
|
||||||
|
import { FinancialModelingPrepService } from '@ghostfolio/api/services/data-provider/financial-modeling-prep/financial-modeling-prep.service';
|
||||||
import { GoogleSheetsService } from '@ghostfolio/api/services/data-provider/google-sheets/google-sheets.service';
|
import { GoogleSheetsService } from '@ghostfolio/api/services/data-provider/google-sheets/google-sheets.service';
|
||||||
import { ManualService } from '@ghostfolio/api/services/data-provider/manual/manual.service';
|
import { ManualService } from '@ghostfolio/api/services/data-provider/manual/manual.service';
|
||||||
import { RapidApiService } from '@ghostfolio/api/services/data-provider/rapid-api/rapid-api.service';
|
import { RapidApiService } from '@ghostfolio/api/services/data-provider/rapid-api/rapid-api.service';
|
||||||
@ -32,6 +33,7 @@ import { DataProviderService } from './data-provider.service';
|
|||||||
CoinGeckoService,
|
CoinGeckoService,
|
||||||
DataProviderService,
|
DataProviderService,
|
||||||
EodHistoricalDataService,
|
EodHistoricalDataService,
|
||||||
|
FinancialModelingPrepService,
|
||||||
GoogleSheetsService,
|
GoogleSheetsService,
|
||||||
ManualService,
|
ManualService,
|
||||||
RapidApiService,
|
RapidApiService,
|
||||||
@ -41,6 +43,7 @@ import { DataProviderService } from './data-provider.service';
|
|||||||
AlphaVantageService,
|
AlphaVantageService,
|
||||||
CoinGeckoService,
|
CoinGeckoService,
|
||||||
EodHistoricalDataService,
|
EodHistoricalDataService,
|
||||||
|
FinancialModelingPrepService,
|
||||||
GoogleSheetsService,
|
GoogleSheetsService,
|
||||||
ManualService,
|
ManualService,
|
||||||
RapidApiService,
|
RapidApiService,
|
||||||
@ -51,6 +54,7 @@ import { DataProviderService } from './data-provider.service';
|
|||||||
alphaVantageService,
|
alphaVantageService,
|
||||||
coinGeckoService,
|
coinGeckoService,
|
||||||
eodHistoricalDataService,
|
eodHistoricalDataService,
|
||||||
|
financialModelingPrepService,
|
||||||
googleSheetsService,
|
googleSheetsService,
|
||||||
manualService,
|
manualService,
|
||||||
rapidApiService,
|
rapidApiService,
|
||||||
@ -59,6 +63,7 @@ import { DataProviderService } from './data-provider.service';
|
|||||||
alphaVantageService,
|
alphaVantageService,
|
||||||
coinGeckoService,
|
coinGeckoService,
|
||||||
eodHistoricalDataService,
|
eodHistoricalDataService,
|
||||||
|
financialModelingPrepService,
|
||||||
googleSheetsService,
|
googleSheetsService,
|
||||||
manualService,
|
manualService,
|
||||||
rapidApiService,
|
rapidApiService,
|
||||||
|
@ -399,7 +399,10 @@ export class DataProviderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private isPremiumDataSource(aDataSource: DataSource) {
|
private isPremiumDataSource(aDataSource: DataSource) {
|
||||||
const premiumDataSources: DataSource[] = [DataSource.EOD_HISTORICAL_DATA];
|
const premiumDataSources: DataSource[] = [
|
||||||
|
DataSource.EOD_HISTORICAL_DATA,
|
||||||
|
DataSource.FINANCIAL_MODELING_PREP
|
||||||
|
];
|
||||||
return premiumDataSources.includes(aDataSource);
|
return premiumDataSources.includes(aDataSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
|
||||||
|
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||||
|
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
||||||
|
import {
|
||||||
|
IDataProviderHistoricalResponse,
|
||||||
|
IDataProviderResponse
|
||||||
|
} from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
|
import { DataProviderInfo } from '@ghostfolio/common/interfaces';
|
||||||
|
import { Granularity } from '@ghostfolio/common/types';
|
||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
import { DataSource, SymbolProfile } from '@prisma/client';
|
||||||
|
import bent from 'bent';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class FinancialModelingPrepService implements DataProviderInterface {
|
||||||
|
private apiKey: string;
|
||||||
|
private baseCurrency: string;
|
||||||
|
private readonly URL = 'https://financialmodelingprep.com/api/v3';
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
private readonly configurationService: ConfigurationService
|
||||||
|
) {
|
||||||
|
this.apiKey = this.configurationService.get(
|
||||||
|
'FINANCIAL_MODELING_PREP_API_KEY'
|
||||||
|
);
|
||||||
|
this.baseCurrency = this.configurationService.get('BASE_CURRENCY');
|
||||||
|
}
|
||||||
|
|
||||||
|
public canHandle(symbol: string) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getAssetProfile(
|
||||||
|
aSymbol: string
|
||||||
|
): Promise<Partial<SymbolProfile>> {
|
||||||
|
return {
|
||||||
|
dataSource: this.getName(),
|
||||||
|
symbol: aSymbol
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getDividends({
|
||||||
|
from,
|
||||||
|
granularity = 'day',
|
||||||
|
symbol,
|
||||||
|
to
|
||||||
|
}: {
|
||||||
|
from: Date;
|
||||||
|
granularity: Granularity;
|
||||||
|
symbol: string;
|
||||||
|
to: Date;
|
||||||
|
}) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getHistorical(
|
||||||
|
aSymbol: string,
|
||||||
|
aGranularity: Granularity = 'day',
|
||||||
|
from: Date,
|
||||||
|
to: Date
|
||||||
|
): Promise<{
|
||||||
|
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
|
||||||
|
}> {
|
||||||
|
return {
|
||||||
|
[aSymbol]: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public getName(): DataSource {
|
||||||
|
return DataSource.FINANCIAL_MODELING_PREP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getQuotes(
|
||||||
|
aSymbols: string[]
|
||||||
|
): Promise<{ [symbol: string]: IDataProviderResponse }> {
|
||||||
|
const results: { [symbol: string]: IDataProviderResponse } = {};
|
||||||
|
|
||||||
|
if (aSymbols.length <= 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const get = bent(
|
||||||
|
`${this.URL}/quote/${aSymbols.join(',')}?apikey=${this.apiKey}`,
|
||||||
|
'GET',
|
||||||
|
'json',
|
||||||
|
200
|
||||||
|
);
|
||||||
|
const response = await get();
|
||||||
|
|
||||||
|
for (const { price, symbol } of response) {
|
||||||
|
results[symbol] = {
|
||||||
|
currency: this.baseCurrency,
|
||||||
|
dataProviderInfo: this.getDataProviderInfo(),
|
||||||
|
dataSource: DataSource.FINANCIAL_MODELING_PREP,
|
||||||
|
marketPrice: price,
|
||||||
|
marketState: 'delayed'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
Logger.error(error, 'FinancialModelingPrepService');
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTestSymbol() {
|
||||||
|
return 'AAPL';
|
||||||
|
}
|
||||||
|
|
||||||
|
public async search(aQuery: string): Promise<{ items: LookupItem[] }> {
|
||||||
|
return { items: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDataProviderInfo(): DataProviderInfo {
|
||||||
|
return {
|
||||||
|
name: 'Financial Modeling Prep',
|
||||||
|
url: 'https://financialmodelingprep.com/developer/docs'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ export interface Environment extends CleanedEnvAccessors {
|
|||||||
ENABLE_FEATURE_SUBSCRIPTION: boolean;
|
ENABLE_FEATURE_SUBSCRIPTION: boolean;
|
||||||
ENABLE_FEATURE_SYSTEM_MESSAGE: boolean;
|
ENABLE_FEATURE_SYSTEM_MESSAGE: boolean;
|
||||||
EOD_HISTORICAL_DATA_API_KEY: string;
|
EOD_HISTORICAL_DATA_API_KEY: string;
|
||||||
|
FINANCIAL_MODELING_PREP_API_KEY: string;
|
||||||
GOOGLE_CLIENT_ID: string;
|
GOOGLE_CLIENT_ID: string;
|
||||||
GOOGLE_SECRET: string;
|
GOOGLE_SECRET: string;
|
||||||
GOOGLE_SHEETS_ACCOUNT: string;
|
GOOGLE_SHEETS_ACCOUNT: string;
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterEnum
|
||||||
|
ALTER TYPE "DataSource" ADD VALUE 'FINANCIAL_MODELING_PREP';
|
@ -209,6 +209,7 @@ enum DataSource {
|
|||||||
ALPHA_VANTAGE
|
ALPHA_VANTAGE
|
||||||
COINGECKO
|
COINGECKO
|
||||||
EOD_HISTORICAL_DATA
|
EOD_HISTORICAL_DATA
|
||||||
|
FINANCIAL_MODELING_PREP
|
||||||
GOOGLE_SHEETS
|
GOOGLE_SHEETS
|
||||||
MANUAL
|
MANUAL
|
||||||
RAPID_API
|
RAPID_API
|
||||||
|
Loading…
x
Reference in New Issue
Block a user