| 
						
						
							
								
							
						
						
					 | 
					@ -11,6 +11,7 @@ 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 { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; | 
					 | 
					 | 
					import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { | 
					 | 
					 | 
					import { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  DataProviderInfo, | 
					 | 
					 | 
					  DataProviderInfo, | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -27,7 +28,14 @@ import { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} from '@prisma/client'; | 
					 | 
					 | 
					} from '@prisma/client'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { isISIN } from 'class-validator'; | 
					 | 
					 | 
					import { isISIN } from 'class-validator'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { countries } from 'countries-list'; | 
					 | 
					 | 
					import { countries } from 'countries-list'; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					import { format, isAfter, isBefore, isSameDay } from 'date-fns'; | 
					 | 
					 | 
					import { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  addDays, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  format, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  isAfter, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  isBefore, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  isSameDay, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  parseISO | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					} from 'date-fns'; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					@Injectable() | 
					 | 
					 | 
					@Injectable() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					export class FinancialModelingPrepService implements DataProviderInterface { | 
					 | 
					 | 
					export class FinancialModelingPrepService implements DataProviderInterface { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -58,7 +66,10 @@ export class FinancialModelingPrepService implements DataProviderInterface { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }; | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    try { | 
					 | 
					 | 
					    try { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      if (this.cryptocurrencyService.isCryptocurrency(symbol)) { | 
					 | 
					 | 
					      if ( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        symbol.endsWith(DEFAULT_CURRENCY) && | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        this.cryptocurrencyService.isCryptocurrency(symbol) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        const [quote] = await fetch( | 
					 | 
					 | 
					        const [quote] = await fetch( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          `${this.URL}/quote/${symbol}?apikey=${this.apiKey}`, | 
					 | 
					 | 
					          `${this.URL}/quote/${symbol}?apikey=${this.apiKey}`, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -208,8 +219,54 @@ export class FinancialModelingPrepService implements DataProviderInterface { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }; | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  public async getDividends({}: GetDividendsParams) { | 
					 | 
					 | 
					  public async getDividends({ | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    return {}; | 
					 | 
					 | 
					    from, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    symbol, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    to | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  }: GetDividendsParams) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (isSameDay(from, to)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      to = addDays(to, 1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    try { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      const response: { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        [date: string]: IDataProviderHistoricalResponse; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      } = {}; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      const { historical } = await fetch( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        `${this.URL}/historical-price-full/stock_dividend/${symbol}?apikey=${this.apiKey}`, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          signal: AbortSignal.timeout(requestTimeout) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ).then((res) => res.json()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      historical | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .filter(({ date }) => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          return ( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            (isSameDay(parseISO(date), from) || | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              isAfter(parseISO(date), from)) && | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            isBefore(parseISO(date), to) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        }) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        .forEach(({ adjDividend, date }) => { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          response[date] = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            marketPrice: adjDividend | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      return response; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } catch (error) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      Logger.error( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        `Could not get dividends for ${symbol} (${this.getName()}) from ${format( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          from, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          DATE_FORMAT | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`,
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        'FinancialModelingPrepService' | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      return {}; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  public async getHistorical({ | 
					 | 
					 | 
					  public async getHistorical({ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -234,14 +291,14 @@ export class FinancialModelingPrepService implements DataProviderInterface { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        [symbol]: {} | 
					 | 
					 | 
					        [symbol]: {} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      }; | 
					 | 
					 | 
					      }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      for (const { close, date } of historical) { | 
					 | 
					 | 
					      for (const { adjClose, date } of historical) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        if ( | 
					 | 
					 | 
					        if ( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          (isSameDay(parseDate(date), from) || | 
					 | 
					 | 
					          (isSameDay(parseDate(date), from) || | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            isAfter(parseDate(date), from)) && | 
					 | 
					 | 
					            isAfter(parseDate(date), from)) && | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          isBefore(parseDate(date), to) | 
					 | 
					 | 
					          isBefore(parseDate(date), to) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        ) { | 
					 | 
					 | 
					        ) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          result[symbol][date] = { | 
					 | 
					 | 
					          result[symbol][date] = { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            marketPrice: close | 
					 | 
					 | 
					            marketPrice: adjClose | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					          }; | 
					 | 
					 | 
					          }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } | 
					 | 
					 | 
					      } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -375,7 +432,7 @@ export class FinancialModelingPrepService implements DataProviderInterface { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    return `https://financialmodelingprep.com/api/v${version}`; | 
					 | 
					 | 
					    return `https://financialmodelingprep.com/api/v${version}`; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  public parseAssetClass(profile: any): { | 
					 | 
					 | 
					  private parseAssetClass(profile: any): { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    assetClass: AssetClass; | 
					 | 
					 | 
					    assetClass: AssetClass; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    assetSubClass: AssetSubClass; | 
					 | 
					 | 
					    assetSubClass: AssetSubClass; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } { | 
					 | 
					 | 
					  } { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					
  |