@ -46,7 +46,6 @@ import {
@Injectable ( )
@Injectable ( )
export class FinancialModelingPrepService implements DataProviderInterface {
export class FinancialModelingPrepService implements DataProviderInterface {
private apiKey : string ;
private apiKey : string ;
private readonly URL = this . getUrl ( { version : 3 } ) ;
public constructor (
public constructor (
private readonly configurationService : ConfigurationService ,
private readonly configurationService : ConfigurationService ,
@ -81,7 +80,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
) ;
) ;
} else if ( this . cryptocurrencyService . isCryptocurrency ( symbol ) ) {
} else if ( this . cryptocurrencyService . isCryptocurrency ( symbol ) ) {
const [ quote ] = await fetch (
const [ quote ] = await fetch (
` ${ this . URL } /quote/ ${ symbol } ? apikey=${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/quote?symbol= ${ symbol } & apikey=${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
@ -95,7 +94,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
response . name = quote . name ;
response . name = quote . name ;
} else {
} else {
const [ assetProfile ] = await fetch (
const [ assetProfile ] = await fetch (
` ${ this . URL } /profile/ ${ symbol } ? apikey=${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/profile?symbol= ${ symbol } & apikey=${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
@ -109,7 +108,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
if ( assetSubClass === AssetSubClass . ETF ) {
if ( assetSubClass === AssetSubClass . ETF ) {
const etfCountryWeightings = await fetch (
const etfCountryWeightings = await fetch (
` ${ this . URL } /etf-country-weightings/ ${ symbol } ? apikey=${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/etf/country-weightings?symbol= ${ symbol } & apikey=${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
@ -133,45 +132,38 @@ export class FinancialModelingPrepService implements DataProviderInterface {
}
}
) ;
) ;
const [ etfInformation ] = await fetch (
const etfHoldings = await fetch (
` ${ this . getUrl ( { version : 4 } )}/etf-info ?symbol= ${ symbol } &apikey= ${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/etf/holdings ?symbol=${ symbol } &apikey= ${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
) . then ( ( res ) = > res . json ( ) ) ;
) . then ( ( res ) = > res . json ( ) ) ;
if ( etfInformation . website ) {
const sortedTopHoldings = etfHoldings
response . url = etfInformation . website ;
. sort ( ( a , b ) = > {
}
return b . weightPercentage - a . weightPercentage ;
} )
. slice ( 0 , 10 ) ;
const [ portfolioDate ] = await fetch (
response . holdings = sortedTopHoldings . map (
` ${ this . getUrl ( { version : 4 } )}/etf-holdings/portfolio-date?symbol= ${ symbol } &apikey= ${ this . apiKey } ` ,
( { name , weightPercentage } ) = > {
{
return { name , weight : weightPercentage / 100 } ;
signal : AbortSignal.timeout ( requestTimeout )
}
}
) . then ( ( res ) = > res . json ( ) ) ;
) ;
if ( portfolioDate ) {
const [ etfInformation ] = await fetch (
const etfHoldings = await fetch (
` ${ this . getUrl ( { version : 'stable' } )}/etf/info?symbol= ${ symbol } &apikey= ${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 4 } )}/etf-holdings?date= ${ portfolioDate . date } &symbol= ${ symbol } &apikey= ${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
) . then ( ( res ) = > res . json ( ) ) ;
) . then ( ( res ) = > res . json ( ) ) ;
const sortedTopHoldings = etfHoldings
if ( etfInformation . website ) {
. sort ( ( a , b ) = > {
response . url = etfInformation . website ;
return b . pctVal - a . pctVal ;
} )
. slice ( 0 , 10 ) ;
response . holdings = sortedTopHoldings . map ( ( { name , pctVal } ) = > {
return { name , weight : pctVal / 100 } ;
} ) ;
}
}
const etfSectorWeightings = await fetch (
const etfSectorWeightings = await fetch (
` ${ this . URL } /etf-sector-weightings/ ${ symbol } ? apikey=${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/etf/sector-weightings?symbol= ${ symbol } &apikey= ${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
@ -181,7 +173,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
( { sector , weightPercentage } ) = > {
( { sector , weightPercentage } ) = > {
return {
return {
name : sector ,
name : sector ,
weight : parseFloat ( weightPercentage . slice ( 0 , - 1 ) ) / 100
weight : weightPercentage / 100
} ;
} ;
}
}
) ;
) ;
@ -246,14 +238,14 @@ export class FinancialModelingPrepService implements DataProviderInterface {
[ date : string ] : IDataProviderHistoricalResponse ;
[ date : string ] : IDataProviderHistoricalResponse ;
} = { } ;
} = { } ;
const { historical = [ ] } = await fetch (
const dividends = await fetch (
` ${ this . URL } /historical-price-full/stock_dividend/ ${ symbol } ? apikey=${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/dividends?symbol= ${ symbol } & apikey=${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
) . then ( ( res ) = > res . json ( ) ) ;
) . then ( ( res ) = > res . json ( ) ) ;
historical
dividends
. filter ( ( { date } ) = > {
. filter ( ( { date } ) = > {
return (
return (
( isSameDay ( parseISO ( date ) , from ) ||
( isSameDay ( parseISO ( date ) , from ) ||
@ -307,21 +299,21 @@ export class FinancialModelingPrepService implements DataProviderInterface {
? addYears ( currentFrom , MAX_YEARS_PER_REQUEST )
? addYears ( currentFrom , MAX_YEARS_PER_REQUEST )
: to ;
: to ;
const { historical = [ ] } = await fetch (
const historical = await fetch (
` ${ this . URL } /historical-price-full/ ${ symbol } ? apikey=${ this . apiKey } &from= ${ format ( currentFrom , DATE_FORMAT ) } &to= ${ format ( currentTo , DATE_FORMAT ) } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/historical-price-eod/full?symbol= ${ symbol } & apikey=${ this . apiKey } &from= ${ format ( currentFrom , DATE_FORMAT ) } &to= ${ format ( currentTo , DATE_FORMAT ) } ` ,
{
{
signal : AbortSignal.timeout ( requestTimeout )
signal : AbortSignal.timeout ( requestTimeout )
}
}
) . then ( ( res ) = > res . json ( ) ) ;
) . then ( ( res ) = > res . json ( ) ) ;
for ( const { adjC lose, date } of historical ) {
for ( const { c lose, date } of historical ) {
if (
if (
( isSameDay ( parseDate ( date ) , currentFrom ) ||
( isSameDay ( parseDate ( date ) , currentFrom ) ||
isAfter ( parseDate ( date ) , currentFrom ) ) &&
isAfter ( parseDate ( date ) , currentFrom ) ) &&
isBefore ( parseDate ( date ) , currentTo )
isBefore ( parseDate ( date ) , currentTo )
) {
) {
result [ symbol ] [ date ] = {
result [ symbol ] [ date ] = {
marketPrice : adjC lose
marketPrice : c lose
} ;
} ;
}
}
}
}
@ -454,7 +446,7 @@ export class FinancialModelingPrepService implements DataProviderInterface {
} ) ;
} ) ;
} else {
} else {
const result = await fetch (
const result = await fetch (
` ${ this . URL } /search ?query=${ query } &apikey= ${ this . apiKey } ` ,
` ${ this . getUrl ( { version : 'stable' } )}/search-symbol ?query=${ query } &apikey= ${ this . apiKey } ` ,
{
{
signal : AbortSignal.timeout (
signal : AbortSignal.timeout (
this . configurationService . get ( 'REQUEST_TIMEOUT' )
this . configurationService . get ( 'REQUEST_TIMEOUT' )