SPB Git

spb/vquant Public MIT

VibeQuant — AI-powered institutional-grade financial intelligence platform.

TypeScript 84.3% Python 11.7% JavaScript 1.6% CSS 1.5% HTML 0.7%
91.3 KB · 2,574 lines typescript
Raw Blame History
1/*2 * =============================================================================3 *  VibeQuant (vquant) — AI-Powered Financial Intelligence Platform4 * -----------------------------------------------------------------------------5 *  File:      server/services/fmpService.ts6 *7 *  Author:    Simon-Pierre Boucher8 *  Contact:   contact@spboucher.ai9 *  Website:   https://www.spboucher.ai10 *  Demo:      https://www.vquant.ai11 *  License:   MIT (see LICENSE)12 *13 *  Copyright © 2026 Simon-Pierre Boucher. All rights reserved.14 * =============================================================================15 */1617import axios from 'axios';1819const FMP_API_KEY = process.env.FMP_API_KEY;20const FMP_BASE_URL = 'https://financialmodelingprep.com/stable';21const FMP_V4_URL = 'https://financialmodelingprep.com/stable';2223interface FMPResponse<T> {24  data: T;25  error?: string;26}2728export interface CompanyProfile {29  symbol: string;30  companyName: string;31  currency: string;32  cik: string;33  isin: string;34  cusip: string;35  exchange: string;36  exchangeShortName: string;37  industry: string;38  website: string;39  description: string;40  ceo: string;41  sector: string;42  country: string;43  fullTimeEmployees: string;44  phone: string;45  address: string;46  city: string;47  state: string;48  zip: string;49  dcfDiff: number;50  dcf: number;51  image: string;52  ipoDate: string;53  defaultImage: boolean;54  isEtf: boolean;55  isActivelyTrading: boolean;56  isAdr: boolean;57  isFund: boolean;58  price: number;59  beta: number;60  volAvg: number;61  mktCap: number;62  lastDiv: number;63  range: string;64  changes: number;65}6667export interface IncomeStatement {68  date: string;69  symbol: string;70  reportedCurrency: string;71  cik: string;72  fillingDate: string;73  acceptedDate: string;74  calendarYear: string;75  period: string;76  revenue: number;77  costOfRevenue: number;78  grossProfit: number;79  grossProfitRatio: number;80  researchAndDevelopmentExpenses: number;81  generalAndAdministrativeExpenses: number;82  sellingAndMarketingExpenses: number;83  sellingGeneralAndAdministrativeExpenses: number;84  otherExpenses: number;85  operatingExpenses: number;86  costAndExpenses: number;87  interestIncome: number;88  interestExpense: number;89  depreciationAndAmortization: number;90  ebitda: number;91  ebitdaratio: number;92  operatingIncome: number;93  operatingIncomeRatio: number;94  totalOtherIncomeExpensesNet: number;95  incomeBeforeTax: number;96  incomeBeforeTaxRatio: number;97  incomeTaxExpense: number;98  netIncome: number;99  netIncomeRatio: number;100  eps: number;101  epsdiluted: number;102  weightedAverageShsOut: number;103  weightedAverageShsOutDil: number;104  link: string;105  finalLink: string;106}107108export interface BalanceSheet {109  date: string;110  symbol: string;111  reportedCurrency: string;112  cik: string;113  fillingDate: string;114  acceptedDate: string;115  calendarYear: string;116  period: string;117  cashAndCashEquivalents: number;118  shortTermInvestments: number;119  cashAndShortTermInvestments: number;120  netReceivables: number;121  inventory: number;122  otherCurrentAssets: number;123  totalCurrentAssets: number;124  propertyPlantEquipmentNet: number;125  goodwill: number;126  intangibleAssets: number;127  goodwillAndIntangibleAssets: number;128  longTermInvestments: number;129  taxAssets: number;130  otherNonCurrentAssets: number;131  totalNonCurrentAssets: number;132  otherAssets: number;133  totalAssets: number;134  accountPayables: number;135  shortTermDebt: number;136  taxPayables: number;137  deferredRevenue: number;138  otherCurrentLiabilities: number;139  totalCurrentLiabilities: number;140  longTermDebt: number;141  deferredRevenueNonCurrent: number;142  deferredTaxLiabilitiesNonCurrent: number;143  otherNonCurrentLiabilities: number;144  totalNonCurrentLiabilities: number;145  otherLiabilities: number;146  capitalLeaseObligations: number;147  totalLiabilities: number;148  preferredStock: number;149  commonStock: number;150  retainedEarnings: number;151  accumulatedOtherComprehensiveIncomeLoss: number;152  othertotalStockholdersEquity: number;153  totalStockholdersEquity: number;154  totalEquity: number;155  totalLiabilitiesAndStockholdersEquity: number;156  minorityInterest: number;157  totalLiabilitiesAndTotalEquity: number;158  totalInvestments: number;159  totalDebt: number;160  netDebt: number;161  link: string;162  finalLink: string;163}164165export interface CashFlowStatement {166  date: string;167  symbol: string;168  reportedCurrency: string;169  cik: string;170  fillingDate: string;171  acceptedDate: string;172  calendarYear: string;173  period: string;174  netIncome: number;175  depreciationAndAmortization: number;176  deferredIncomeTax: number;177  stockBasedCompensation: number;178  changeInWorkingCapital: number;179  accountsReceivables: number;180  inventory: number;181  accountsPayables: number;182  otherWorkingCapital: number;183  otherNonCashItems: number;184  netCashProvidedByOperatingActivities: number;185  investmentsInPropertyPlantAndEquipment: number;186  acquisitionsNet: number;187  purchasesOfInvestments: number;188  salesMaturitiesOfInvestments: number;189  otherInvestingActivites: number;190  netCashUsedForInvestingActivites: number;191  debtRepayment: number;192  commonStockIssued: number;193  commonStockRepurchased: number;194  dividendsPaid: number;195  otherFinancingActivites: number;196  netCashUsedProvidedByFinancingActivities: number;197  effectOfForexChangesOnCash: number;198  netChangeInCash: number;199  cashAtEndOfPeriod: number;200  cashAtBeginningOfPeriod: number;201  operatingCashFlow: number;202  capitalExpenditure: number;203  freeCashFlow: number;204  link: string;205  finalLink: string;206}207208export interface KeyMetrics {209  symbol: string;210  date: string;211  calendarYear: string;212  period: string;213  revenuePerShare: number;214  netIncomePerShare: number;215  operatingCashFlowPerShare: number;216  freeCashFlowPerShare: number;217  cashPerShare: number;218  bookValuePerShare: number;219  tangibleBookValuePerShare: number;220  shareholdersEquityPerShare: number;221  interestDebtPerShare: number;222  marketCap: number;223  enterpriseValue: number;224  peRatio: number;225  priceToSalesRatio: number;226  pocfratio: number;227  pfcfRatio: number;228  pbRatio: number;229  ptbRatio: number;230  evToSales: number;231  enterpriseValueOverEBITDA: number;232  evToOperatingCashFlow: number;233  evToFreeCashFlow: number;234  earningsYield: number;235  freeCashFlowYield: number;236  debtToEquity: number;237  debtToAssets: number;238  netDebtToEBITDA: number;239  currentRatio: number;240  interestCoverage: number;241  incomeQuality: number;242  dividendYield: number;243  payoutRatio: number;244  salesGeneralAndAdministrativeToRevenue: number;245  researchAndDdevelopementToRevenue: number;246  intangiblesToTotalAssets: number;247  capexToOperatingCashFlow: number;248  capexToRevenue: number;249  capexToDepreciation: number;250  stockBasedCompensationToRevenue: number;251  grahamNumber: number;252  roic: number;253  returnOnTangibleAssets: number;254  grahamNetNet: number;255  workingCapital: number;256  tangibleAssetValue: number;257  netCurrentAssetValue: number;258  investedCapital: number;259  averageReceivables: number;260  averagePayables: number;261  averageInventory: number;262  daysSalesOutstanding: number;263  daysPayablesOutstanding: number;264  daysOfInventoryOnHand: number;265  receivablesTurnover: number;266  payablesTurnover: number;267  inventoryTurnover: number;268  roe: number;269  capexPerShare: number;270}271272export interface FinancialRatios {273  symbol: string;274  date: string;275  calendarYear: string;276  period: string;277  currentRatio: number;278  quickRatio: number;279  cashRatio: number;280  daysOfSalesOutstanding: number;281  daysOfInventoryOutstanding: number;282  operatingCycle: number;283  daysOfPayablesOutstanding: number;284  cashConversionCycle: number;285  grossProfitMargin: number;286  operatingProfitMargin: number;287  pretaxProfitMargin: number;288  netProfitMargin: number;289  effectiveTaxRate: number;290  returnOnAssets: number;291  returnOnEquity: number;292  returnOnCapitalEmployed: number;293  netIncomePerEBT: number;294  ebtPerEbit: number;295  ebitPerRevenue: number;296  debtRatio: number;297  debtEquityRatio: number;298  longTermDebtToCapitalization: number;299  totalDebtToCapitalization: number;300  interestCoverage: number;301  cashFlowToDebtRatio: number;302  companyEquityMultiplier: number;303  receivablesTurnover: number;304  payablesTurnover: number;305  inventoryTurnover: number;306  fixedAssetTurnover: number;307  assetTurnover: number;308  operatingCashFlowPerShare: number;309  freeCashFlowPerShare: number;310  cashPerShare: number;311  payoutRatio: number;312  operatingCashFlowSalesRatio: number;313  freeCashFlowOperatingCashFlowRatio: number;314  cashFlowCoverageRatios: number;315  shortTermCoverageRatios: number;316  capitalExpenditureCoverageRatio: number;317  dividendPaidAndCapexCoverageRatio: number;318  dividendPayoutRatio: number;319  priceBookValueRatio: number;320  priceToBookRatio: number;321  priceToSalesRatio: number;322  priceEarningsRatio: number;323  priceToFreeCashFlowsRatio: number;324  priceToOperatingCashFlowsRatio: number;325  priceCashFlowRatio: number;326  priceEarningsToGrowthRatio: number;327  priceSalesRatio: number;328  dividendYield: number;329  enterpriseValueMultiple: number;330  priceFairValue: number;331}332333export interface StockQuote {334  symbol: string;335  name: string;336  price: number;337  changesPercentage: number;338  change: number;339  dayLow: number;340  dayHigh: number;341  yearHigh: number;342  yearLow: number;343  marketCap: number;344  priceAvg50: number;345  priceAvg200: number;346  exchange: string;347  volume: number;348  avgVolume: number;349  open: number;350  previousClose: number;351  eps: number;352  pe: number;353  earningsAnnouncement: string;354  sharesOutstanding: number;355  timestamp: number;356}357358export interface HistoricalPrice {359  date: string;360  open: number;361  high: number;362  low: number;363  close: number;364  adjClose: number;365  volume: number;366  unadjustedVolume: number;367  change: number;368  changePercent: number;369  vwap: number;370  label: string;371  changeOverTime: number;372}373374export interface FinancialNews {375  symbol: string;376  publishedDate: string;377  title: string;378  image: string;379  site: string;380  text: string;381  url: string;382}383384async function fmpRequest<T>(endpoint: string, params: Record<string, any> = {}): Promise<T> {385  if (!FMP_API_KEY) {386    throw new Error('FMP_API_KEY not configured');387  }388389  try {390    const response = await axios.get(`${FMP_BASE_URL}${endpoint}`, {391      params: {392        ...params,393        apikey: FMP_API_KEY,394      },395      timeout: 15000,396    });397398    return response.data;399  } catch (error) {400    console.error(`FMP API error for ${endpoint}:`, error);401    throw new Error(`Failed to fetch from FMP: ${(error as Error).message}`);402  }403}404405async function fmpV4Request<T>(endpoint: string, params: Record<string, any> = {}): Promise<T> {406  if (!FMP_API_KEY) {407    throw new Error('FMP_API_KEY not configured');408  }409410  try {411    const response = await axios.get(`${FMP_V4_URL}${endpoint}`, {412      params: {413        ...params,414        apikey: FMP_API_KEY,415      },416      timeout: 15000,417    });418419    return response.data;420  } catch (error) {421    console.error(`FMP API error for ${endpoint}:`, error);422    throw new Error(`Failed to fetch from FMP: ${(error as Error).message}`);423  }424}425426export async function getCompanyProfile(symbol: string): Promise<CompanyProfile[]> {427  return fmpRequest<CompanyProfile[]>('/profile', { symbol });428}429430export async function getIncomeStatement(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<IncomeStatement[]> {431  return fmpRequest<IncomeStatement[]>('/income-statement', { symbol, period, limit });432}433434export async function getBalanceSheet(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<BalanceSheet[]> {435  return fmpRequest<BalanceSheet[]>('/balance-sheet-statement', { symbol, period, limit });436}437438export async function getCashFlowStatement(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<CashFlowStatement[]> {439  return fmpRequest<CashFlowStatement[]>('/cash-flow-statement', { symbol, period, limit });440}441442export async function getKeyMetrics(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<KeyMetrics[]> {443  return fmpRequest<KeyMetrics[]>('/key-metrics', { symbol, period, limit });444}445446export async function getFinancialRatios(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<FinancialRatios[]> {447  return fmpRequest<FinancialRatios[]>('/ratios', { symbol, period, limit });448}449450export async function getStockQuote(symbol: string): Promise<StockQuote[]> {451  return fmpRequest<StockQuote[]>('/quote', { symbol });452}453454export async function getHistoricalPrice(symbol: string, from?: string, to?: string): Promise<{ symbol: string; historical: HistoricalPrice[] }> {455  const params: Record<string, any> = {};456  if (from) params.from = from;457  // If 'to' is not provided, default to today's date to ensure current data458  if (to) {459    params.to = to;460  } else {461    params.to = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format462  }463  params.symbol = symbol;464  const data = await fmpRequest<HistoricalPrice[]>('/historical-price-eod/full', params);465466  // Stable API returns flat array; wrap to match legacy { symbol, historical } format467  let historical = Array.isArray(data) ? data : (data as any).historical || [];468469  // Limit to 504 most recent data points (2 years) for Monte Carlo simulations470  // This provides enough data for robust statistical analysis while staying within reasonable context limits471  // The tool result truncation in routes.ts will further limit if needed472  if (historical.length > 504) {473    historical = historical.slice(0, 504);474  }475476  return { symbol, historical };477}478479export async function getFinancialNews(symbol?: string, limit: number = 5): Promise<FinancialNews[]> {480  // Limit to 5 articles to avoid context overflow481  const actualLimit = Math.min(limit, 5);482  if (symbol) {483    return fmpRequest<FinancialNews[]>('/news/stock', { symbols: symbol, limit: actualLimit });484  }485  return fmpRequest<FinancialNews[]>('/news/stock', { limit: actualLimit });486}487488export async function searchCompanies(query: string, limit: number = 10): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string; exchangeShortName: string }>> {489  return fmpRequest('/search-symbol', { query, limit });490}491492export async function getStockPeers(symbol: string): Promise<string[]> {493  return fmpRequest<string[]>('/stock-peers', { symbol });494}495496export interface TechnicalIndicator {497  date: string;498  [key: string]: number | string;499}500501export interface EconomicCalendar {502  event: string;503  date: string;504  country: string;505  actual: number | null;506  previous: number | null;507  change: number | null;508  changePercentage: number | null;509  estimate: number | null;510  impact: string;511}512513export interface TreasuryRate {514  date: string;515  month1: number;516  month2: number;517  month3: number;518  month6: number;519  year1: number;520  year2: number;521  year3: number;522  year5: number;523  year7: number;524  year10: number;525  year20: number;526  year30: number;527}528529export interface EconomicIndicator {530  date: string;531  value: number;532}533534export interface InsiderTrade {535  symbol: string;536  filingDate: string;537  transactionDate: string;538  reportingName: string;539  typeOfOwner: string;540  acquistionOrDisposition: string;541  formType: string;542  securitiesOwned: number;543  securitiesTransacted: number;544  price: number;545  securityName: string;546  link: string;547}548549export interface InsiderTradeStatistics {550  symbol: string;551  cik: string;552  name: string;553  trades: number;554  buyTransactions: number;555  sellTransactions: number;556  totalBought: number;557  totalSold: number;558  avgBuyPrice: number;559  avgSellPrice: number;560}561562export interface EarningsCalendar {563  date: string;564  symbol: string;565  eps: number | null;566  epsEstimated: number | null;567  time: string;568  revenue: number | null;569  revenueEstimated: number | null;570  fiscalDateEnding: string;571  updatedFromDate: string;572}573574export interface EarningsSurprise {575  date: string;576  symbol: string;577  actualEarningResult: number;578  estimatedEarning: number;579}580581export interface AnalystEstimate {582  date: string;583  symbol: string;584  estimatedRevenueLow: number;585  estimatedRevenueHigh: number;586  estimatedRevenueAvg: number;587  estimatedEbitdaLow: number;588  estimatedEbitdaHigh: number;589  estimatedEbitdaAvg: number;590  estimatedEbitLow: number;591  estimatedEbitHigh: number;592  estimatedEbitAvg: number;593  estimatedNetIncomeLow: number;594  estimatedNetIncomeHigh: number;595  estimatedNetIncomeAvg: number;596  estimatedSgaExpenseLow: number;597  estimatedSgaExpenseHigh: number;598  estimatedSgaExpenseAvg: number;599  estimatedEpsAvg: number;600  estimatedEpsHigh: number;601  estimatedEpsLow: number;602  numberAnalystEstimatedRevenue: number;603  numberAnalystsEstimatedEps: number;604}605606export interface ForexQuote {607  ticker: string;608  bid: number;609  ask: number;610  open: number;611  low: number;612  high: number;613  changes: number;614  date: string;615}616617export interface CommodityQuote {618  symbol: string;619  name: string;620  price: number;621  changesPercentage: number;622  change: number;623  dayLow: number;624  dayHigh: number;625  yearHigh: number;626  yearLow: number;627  marketCap: number | null;628  priceAvg50: number;629  priceAvg200: number;630  volume: number;631  avgVolume: number;632  exchange: string;633  open: number;634  previousClose: number;635  timestamp: number;636}637638export interface COTReport {639  date: string;640  symbol: string;641  name: string;642  exchange: string;643  currentLongMarketSituation: number;644  currentShortMarketSituation: number;645  marketSituation: string;646  netPosition: number;647  percentOfOI_Long: number;648  percentOfOI_Short: number;649}650651export interface PressRelease {652  symbol: string;653  date: string;654  title: string;655  text: string;656}657658export interface Dividend {659  date: string;660  label: string;661  adjDividend: number;662  dividend: number;663  recordDate: string;664  paymentDate: string;665  declarationDate: string;666}667668export interface StockSplit {669  date: string;670  label: string;671  symbol: string;672  numerator: number;673  denominator: number;674}675676export interface IPOCalendar {677  date: string;678  company: string;679  symbol: string;680  exchange: string;681  actions: string;682  shares: number | null;683  priceRange: string;684  marketCap: number | null;685}686687export async function getRSI(symbol: string, period: number = 14, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {688  const result = await fmpRequest<TechnicalIndicator[]>('/technical-indicators/rsi', { symbol, timeframe: timePeriod, periodLength: period });689  return result.slice(0, 10);690}691692export async function getMACD(symbol: string, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {693  // MACD not available in FMP stable API — compute from historical prices694  const { historical } = await getHistoricalPrice(symbol);695  if (!historical || historical.length < 35) return [];696  const closes = historical.map(h => h.close).reverse(); // oldest first697  const ema12 = computeEMA(closes, 12);698  const ema26 = computeEMA(closes, 26);699  const macdLine: number[] = [];700  for (let i = 0; i < ema26.length; i++) {701    macdLine.push(ema12[i + (ema12.length - ema26.length)] - ema26[i]);702  }703  const signal = computeEMA(macdLine, 9);704  const results: TechnicalIndicator[] = [];705  const offset = macdLine.length - signal.length;706  const dates = historical.slice().reverse();707  const dateOffset = dates.length - signal.length - (closes.length - ema12.length) - (ema12.length - ema26.length);708  for (let i = signal.length - 1; i >= Math.max(0, signal.length - 10); i--) {709    const idx = dates.length - (signal.length - i);710    const d = dates[idx];711    if (!d) continue;712    results.push({713      date: d.date,714      open: d.open,715      high: d.high,716      low: d.low,717      close: d.close,718      volume: d.volume,719      macd: macdLine[i + offset],720      macdSignal: signal[i],721      macdHistogram: macdLine[i + offset] - signal[i],722    } as any);723  }724  return results;725}726727export async function getEMA(symbol: string, period: number = 50, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {728  const result = await fmpRequest<TechnicalIndicator[]>('/technical-indicators/ema', { symbol, timeframe: timePeriod, periodLength: period });729  return result.slice(0, 10);730}731732export async function getSMA(symbol: string, period: number = 50, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {733  const result = await fmpRequest<TechnicalIndicator[]>('/technical-indicators/sma', { symbol, timeframe: timePeriod, periodLength: period });734  return result.slice(0, 10);735}736737export async function getADX(symbol: string, period: number = 14, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {738  const result = await fmpRequest<TechnicalIndicator[]>('/technical-indicators/adx', { symbol, timeframe: timePeriod, periodLength: period });739  return result.slice(0, 10);740}741742export async function getWilliamsR(symbol: string, period: number = 14, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {743  const result = await fmpRequest<TechnicalIndicator[]>('/technical-indicators/williams', { symbol, timeframe: timePeriod, periodLength: period });744  return result.slice(0, 10);745}746747export async function getCCI(symbol: string, period: number = 20, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {748  // CCI not available in FMP stable API — compute from historical prices749  const { historical } = await getHistoricalPrice(symbol);750  if (!historical || historical.length < period + 10) return [];751  const data = historical.slice().reverse(); // oldest first752  const results: TechnicalIndicator[] = [];753  for (let i = data.length - 1; i >= Math.max(period - 1, data.length - 10); i--) {754    const window = data.slice(i - period + 1, i + 1);755    const tps = window.map(d => (d.high + d.low + d.close) / 3);756    const meanTP = tps.reduce((a, b) => a + b, 0) / tps.length;757    const meanDev = tps.reduce((a, tp) => a + Math.abs(tp - meanTP), 0) / tps.length;758    const cci = meanDev === 0 ? 0 : (tps[tps.length - 1] - meanTP) / (0.015 * meanDev);759    const d = data[i];760    results.push({761      date: d.date,762      open: d.open,763      high: d.high,764      low: d.low,765      close: d.close,766      volume: d.volume,767      cci,768    } as any);769  }770  return results;771}772773export async function getStochasticOscillator(symbol: string, period: number = 14, timePeriod: string = '1day'): Promise<TechnicalIndicator[]> {774  // Stochastic not available in FMP stable API — compute from historical prices775  const { historical } = await getHistoricalPrice(symbol);776  if (!historical || historical.length < period + 10) return [];777  const data = historical.slice().reverse(); // oldest first778  // Compute %K values779  const kValues: number[] = [];780  for (let i = period - 1; i < data.length; i++) {781    const window = data.slice(i - period + 1, i + 1);782    const lowestLow = Math.min(...window.map(d => d.low));783    const highestHigh = Math.max(...window.map(d => d.high));784    const range = highestHigh - lowestLow;785    const k = range === 0 ? 50 : ((data[i].close - lowestLow) / range) * 100;786    kValues.push(k);787  }788  // %D = 3-period SMA of %K789  const results: TechnicalIndicator[] = [];790  for (let i = kValues.length - 1; i >= Math.max(2, kValues.length - 10); i--) {791    const d3 = (kValues[i] + kValues[i - 1] + kValues[i - 2]) / 3;792    const dataIdx = i + (period - 1);793    const d = data[dataIdx];794    results.push({795      date: d.date,796      open: d.open,797      high: d.high,798      low: d.low,799      close: d.close,800      volume: d.volume,801      stochK: kValues[i],802      stochD: d3,803    } as any);804  }805  return results;806}807808// Helper: compute EMA from an array of values (oldest first)809function computeEMA(values: number[], period: number): number[] {810  if (values.length < period) return [];811  const k = 2 / (period + 1);812  let ema = values.slice(0, period).reduce((a, b) => a + b, 0) / period;813  const result = [ema];814  for (let i = period; i < values.length; i++) {815    ema = values[i] * k + ema * (1 - k);816    result.push(ema);817  }818  return result;819}820821export async function getEconomicCalendar(from?: string, to?: string): Promise<EconomicCalendar[]> {822  // If no dates specified, get last 30 days + next 30 days823  if (!from && !to) {824    const now = new Date();825    const past30Days = new Date(now);826    past30Days.setDate(past30Days.getDate() - 30);827    const future30Days = new Date(now);828    future30Days.setDate(future30Days.getDate() + 30);829    830    from = past30Days.toISOString().split('T')[0];831    to = future30Days.toISOString().split('T')[0];832  }833  834  const params: Record<string, any> = {};835  if (from) params.from = from;836  if (to) params.to = to;837  const result = await fmpRequest<EconomicCalendar[]>('/economic-calendar', params);838  839  // Filter to high/medium impact events and limit to avoid context overflow840  const filtered = result.filter(event => event.impact === 'High' || event.impact === 'Medium');841842  // Sort by date (most recent first) and limit to 15 total events843  return filtered844    .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())845    .slice(0, 15);846}847848export async function getTreasuryRates(from?: string, to?: string): Promise<TreasuryRate[]> {849  const params: Record<string, any> = {};850  if (from) params.from = from;851  if (to) params.to = to;852  const result = await fmpRequest<TreasuryRate[]>('/treasury', params);853  // Limit to most recent 15 days to avoid context overflow854  return result.slice(0, 15);855}856857export async function getEconomicIndicator(indicator: string, from?: string, to?: string): Promise<EconomicIndicator[]> {858  const params: Record<string, any> = {};859  if (from) params.from = from;860  if (to) params.to = to;861  const result = await fmpRequest<EconomicIndicator[]>('/economic-indicators', { name: indicator, ...params });862  // Limit to most recent 15 data points to avoid context overflow863  return result.slice(0, 15);864}865866export async function getInsiderTrading(symbol?: string, limit: number = 20): Promise<InsiderTrade[]> {867  // Limit to 20 trades to avoid context overflow868  const actualLimit = Math.min(limit, 20);869  const params: Record<string, any> = { limit: actualLimit };870  if (symbol) params.symbol = symbol;871  return fmpRequest<InsiderTrade[]>('/insider-trading/search', params);872}873874export async function getInsiderTradeStatistics(symbol: string): Promise<InsiderTradeStatistics[]> {875  return fmpRequest<InsiderTradeStatistics[]>('/insider-trade-statistics', { symbol });876}877878export async function getEarningsCalendar(from?: string, to?: string): Promise<EarningsCalendar[]> {879  // If no dates specified, get last 30 days + next 30 days880  if (!from && !to) {881    const now = new Date();882    const past30Days = new Date(now);883    past30Days.setDate(past30Days.getDate() - 30);884    const future30Days = new Date(now);885    future30Days.setDate(future30Days.getDate() + 30);886    887    from = past30Days.toISOString().split('T')[0];888    to = future30Days.toISOString().split('T')[0];889  }890  891  const params: Record<string, any> = {};892  if (from) params.from = from;893  if (to) params.to = to;894  const result = await fmpRequest<EarningsCalendar[]>('/earnings-calendar', params);895  896  // Sort by date (most recent first) and limit to avoid context overflow897  return result898    .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())899    .slice(0, 15);900}901902export async function getEarningsSurprises(symbol: string): Promise<EarningsSurprise[]> {903  return fmpRequest<EarningsSurprise[]>('/earnings-surprises', { symbol });904}905906export async function getAnalystEstimates(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<AnalystEstimate[]> {907  return fmpRequest<AnalystEstimate[]>('/analyst-estimates', { symbol, period, limit });908}909910export async function getForexQuote(pair: string): Promise<ForexQuote[]> {911  return fmpRequest<ForexQuote[]>('/fx', { symbol: pair });912}913914export async function getForexList(): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string }>> {915  return fmpRequest('/forex-currency-pairs');916}917918export async function getCommodityQuotes(): Promise<CommodityQuote[]> {919  return fmpRequest<CommodityQuote[]>('/batch-commodity-quote');920}921922export async function getCOTReport(symbol: string): Promise<COTReport[]> {923  return fmpRequest<COTReport[]>('/commitment-of-traders-report', { symbol });924}925926export async function getCOTAnalysis(symbol: string): Promise<COTReport[]> {927  return fmpRequest<COTReport[]>('/commitment-of-traders-report-analysis', { symbol });928}929930export async function getPressReleases(symbol: string, limit: number = 20): Promise<PressRelease[]> {931  return fmpRequest<PressRelease[]>('/press-releases', { symbol, limit });932}933934export async function getDividendHistory(symbol: string): Promise<Dividend[]> {935  const data = await fmpRequest<Dividend[]>('/dividends', { symbol });936  // Stable API returns flat array937  const dividends = Array.isArray(data) ? data : (data as any).historical || [];938  // Limit to last 10 dividends to avoid context overflow939  return dividends.slice(0, 10);940}941942export async function getStockSplitHistory(symbol: string): Promise<StockSplit[]> {943  const data = await fmpRequest<StockSplit[]>('/splits', { symbol });944  // Stable API returns flat array945  const splits = Array.isArray(data) ? data : (data as any).historical || [];946  return splits;947}948949export async function getIPOCalendar(from?: string, to?: string): Promise<IPOCalendar[]> {950  // If no dates specified, get last 30 days + next 90 days (IPOs are announced in advance)951  if (!from && !to) {952    const now = new Date();953    const past30Days = new Date(now);954    past30Days.setDate(past30Days.getDate() - 30);955    const future90Days = new Date(now);956    future90Days.setDate(future90Days.getDate() + 90);957958    from = past30Days.toISOString().split('T')[0];959    to = future90Days.toISOString().split('T')[0];960  }961962  const params: Record<string, any> = {};963  if (from) params.from = from;964  if (to) params.to = to;965  const result = await fmpRequest<IPOCalendar[]>('/ipo-calendar', params);966967  // Sort by date (most recent first) and limit to avoid context overflow968  return result969    .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())970    .slice(0, 20);971}972973// Intraday Price Data974export interface IntradayPrice {975  date: string;976  open: number;977  high: number;978  low: number;979  close: number;980  volume: number;981}982983export interface IntradayPriceResponse {984  symbol: string;985  interval: string;986  data: IntradayPrice[];987}988989export async function getIntradayPrice(symbol: string, interval: string = '15min'): Promise<IntradayPriceResponse> {990  const result = await fmpRequest<IntradayPrice[]>(`/historical-chart/${interval}`, { symbol });991  // Limit to last 15 data points to avoid context overflow992  const limitedData = result.slice(0, 15);993994  return {995    symbol,996    interval,997    data: limitedData998  };999}10001001// Price Target Data1002export interface PriceTarget {1003  symbol: string;1004  publishedDate: string;1005  newsURL: string;1006  newsTitle: string;1007  analystName: string;1008  analystCompany: string;1009  priceTarget: number;1010  adjPriceTarget: number;1011  priceWhenPosted: number;1012  newsPublisher: string;1013  newsBaseURL: string;1014}10151016export async function getPriceTarget(symbol: string): Promise<PriceTarget[]> {1017  return fmpRequest<PriceTarget[]>('/price-target', { symbol });1018}10191020export interface PriceTargetSummary {1021  symbol: string;1022  lastMonth: number;1023  lastMonthAvgPriceTarget: number;1024  lastQuarter: number;1025  lastQuarterAvgPriceTarget: number;1026  lastYear: number;1027  lastYearAvgPriceTarget: number;1028  allTime: number;1029  allTimeAvgPriceTarget: number;1030  publishers: string[];1031}10321033export async function getPriceTargetSummary(symbol: string): Promise<PriceTargetSummary> {1034  return fmpRequest<PriceTargetSummary>('/price-target-summary', { symbol });1035}10361037// Upgrades and Downgrades1038export interface UpgradeDowngrade {1039  symbol: string;1040  publishedDate: string;1041  newsURL: string;1042  newsTitle: string;1043  newsPublisher: string;1044  newsBaseURL: string;1045  action: string;1046  analystName: string;1047  analystCompany: string;1048  priceWhenPosted: number;1049  priceTarget: number;1050  newGrade: string;1051  previousGrade: string;1052  gradingCompany: string;1053}10541055export async function getUpgradesDowngrades(symbol: string): Promise<UpgradeDowngrade[]> {1056  return fmpRequest<UpgradeDowngrade[]>('/grades', { symbol });1057}10581059// Institutional Holders1060export interface InstitutionalHolder {1061  holder: string;1062  shares: number;1063  dateReported: string;1064  change: number;1065  symbol: string;1066}10671068export async function getInstitutionalHolders(symbol: string): Promise<InstitutionalHolder[]> {1069  return fmpRequest<InstitutionalHolder[]>('/institutional-ownership/latest', { symbol });1070}10711072// ESG Score1073export interface ESGScore {1074  symbol: string;1075  companyName: string;1076  formattedDate: string;1077  environmentalScore: number;1078  socialScore: number;1079  governanceScore: number;1080  ESGScore: number;1081}10821083export async function getESGScore(symbol: string): Promise<ESGScore[]> {1084  return fmpRequest<ESGScore[]>('/esg-environmental-social-governance-data', { symbol });1085}10861087// Social Sentiment1088export interface SocialSentiment {1089  date: string;1090  symbol: string;1091  stocktwitsPosts: number;1092  twitterPosts: number;1093  stocktwitsComments: number;1094  twitterComments: number;1095  stocktwitsLikes: number;1096  twitterLikes: number;1097  stocktwitsImpressions: number;1098  twitterImpressions: number;1099  stocktwitsSentiment: number;1100  twitterSentiment: number;1101}11021103export async function getSocialSentiment(symbol: string, limit: number = 10): Promise<SocialSentiment[]> {1104  // Limit to 10 records to avoid context overflow1105  const actualLimit = Math.min(limit, 10);1106  const result = await fmpRequest<SocialSentiment[]>('/social-sentiments/trending', { type: 'bullish', source: 'stocktwits' });1107  return result.slice(0, actualLimit);1108}11091110// Congressional Trading1111export interface CongressionalTrade {1112  transactionDate: string;1113  transactionType: string;1114  ticker: string;1115  assetDescription: string;1116  assetType: string;1117  type: string;1118  amount: string;1119  representative: string;1120  representativeLink: string;1121  transactionLink: string;1122  disclosureDate: string;1123}11241125export async function getCongressionalTrading(symbol?: string): Promise<CongressionalTrade[]> {1126  const params: Record<string, any> = {};1127  if (symbol) params.symbol = symbol;1128  return fmpRequest<CongressionalTrade[]>('/senate-trading', params);1129}11301131export async function getSenateTrading(symbol?: string): Promise<CongressionalTrade[]> {1132  const params: Record<string, any> = {};1133  if (symbol) params.symbol = symbol;1134  return fmpRequest<CongressionalTrade[]>('/senate-disclosure', params);1135}11361137// Search by CIK, CUSIP, ISIN1138export interface CompanySearchResult {1139  symbol: string;1140  name: string;1141  currency: string;1142  stockExchange: string;1143  exchangeShortName: string;1144}11451146export async function searchByCIK(cik: string): Promise<CompanySearchResult[]> {1147  return fmpRequest<CompanySearchResult[]>('/search-cik', { cik });1148}11491150export async function searchByCUSIP(cusip: string): Promise<CompanySearchResult[]> {1151  return fmpRequest<CompanySearchResult[]>('/search-cusip', { cusip });1152}11531154export async function searchByISIN(isin: string): Promise<CompanySearchResult[]> {1155  return fmpRequest<CompanySearchResult[]>('/search-isin', { isin });1156}11571158// Stock Screener1159export interface ScreenerResult {1160  symbol: string;1161  companyName: string;1162  marketCap: number;1163  sector: string;1164  industry: string;1165  beta: number;1166  price: number;1167  lastAnnualDividend: number;1168  volume: number;1169  exchange: string;1170  exchangeShortName: string;1171  country: string;1172  isEtf: boolean;1173  isActivelyTrading: boolean;1174}11751176export async function getStockScreener(filters: {1177  marketCapMoreThan?: number;1178  marketCapLowerThan?: number;1179  betaMoreThan?: number;1180  betaLowerThan?: number;1181  volumeMoreThan?: number;1182  sector?: string;1183  industry?: string;1184  exchange?: string;1185  limit?: number;1186}): Promise<ScreenerResult[]> {1187  return fmpRequest<ScreenerResult[]>('/stock-screener', filters);1188}11891190// Market Hours1191export interface MarketHours {1192  stockExchangeName: string;1193  stockMarketHours: {1194    openingHour: string;1195    closingHour: string;1196  };1197  stockMarketHolidays: string[];1198  isTheStockMarketOpen: boolean;1199  isTheEuronextMarketOpen: boolean;1200  isTheForexMarketOpen: boolean;1201  isTheCryptoMarketOpen: boolean;1202}12031204export async function getMarketHours(): Promise<MarketHours> {1205  return fmpRequest<MarketHours>('/all-exchange-market-hours');1206}12071208// Market Movers1209export interface MarketMover {1210  symbol: string;1211  name: string;1212  change: number;1213  price: number;1214  changesPercentage: number;1215}12161217export async function getGainers(): Promise<MarketMover[]> {1218  return fmpRequest<MarketMover[]>('/biggest-gainers');1219}12201221export async function getLosers(): Promise<MarketMover[]> {1222  return fmpRequest<MarketMover[]>('/biggest-losers');1223}12241225export async function getActives(): Promise<MarketMover[]> {1226  return fmpRequest<MarketMover[]>('/most-actives');1227}12281229// ETF Holdings1230export interface ETFHolding {1231  asset: string;1232  name: string;1233  sharesNumber: number;1234  weightPercentage: number;1235  marketValue: number;1236}12371238export async function getETFHoldings(symbol: string): Promise<ETFHolding[]> {1239  return fmpRequest<ETFHolding[]>('/etf-holder', { symbol });1240}12411242// ETF Sector Weightings1243export interface ETFSectorWeighting {1244  sector: string;1245  weightPercentage: string;1246}12471248export async function getETFSectorWeightings(symbol: string): Promise<ETFSectorWeighting[]> {1249  return fmpRequest<ETFSectorWeighting[]>('/etf-sector-weightings', { symbol });1250}12511252// ETF Country Weightings1253export interface ETFCountryWeighting {1254  country: string;1255  weightPercentage: string;1256}12571258export async function getETFCountryWeightings(symbol: string): Promise<ETFCountryWeighting[]> {1259  return fmpRequest<ETFCountryWeighting[]>('/etf-country-weightings', { symbol });1260}12611262// Financial Growth1263export interface FinancialGrowth {1264  date: string;1265  symbol: string;1266  period: string;1267  calendarYear: string;1268  revenueGrowth: number;1269  grossProfitGrowth: number;1270  ebitgrowth: number;1271  operatingIncomeGrowth: number;1272  netIncomeGrowth: number;1273  epsgrowth: number;1274  epsdilutedGrowth: number;1275  weightedAverageSharesGrowth: number;1276  weightedAverageSharesDilutedGrowth: number;1277  dividendsperShareGrowth: number;1278  operatingCashFlowGrowth: number;1279  freeCashFlowGrowth: number;1280  tenYRevenueGrowthPerShare: number;1281  fiveYRevenueGrowthPerShare: number;1282  threeYRevenueGrowthPerShare: number;1283  tenYOperatingCFGrowthPerShare: number;1284  fiveYOperatingCFGrowthPerShare: number;1285  threeYOperatingCFGrowthPerShare: number;1286  tenYNetIncomeGrowthPerShare: number;1287  fiveYNetIncomeGrowthPerShare: number;1288  threeYNetIncomeGrowthPerShare: number;1289  tenYShareholdersEquityGrowthPerShare: number;1290  fiveYShareholdersEquityGrowthPerShare: number;1291  threeYShareholdersEquityGrowthPerShare: number;1292  tenYDividendperShareGrowthPerShare: number;1293  fiveYDividendperShareGrowthPerShare: number;1294  threeYDividendperShareGrowthPerShare: number;1295  receivablesGrowth: number;1296  inventoryGrowth: number;1297  assetGrowth: number;1298  bookValueperShareGrowth: number;1299  debtGrowth: number;1300  rdexpenseGrowth: number;1301  sgaexpensesGrowth: number;1302}13031304export async function getFinancialGrowth(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<FinancialGrowth[]> {1305  return fmpRequest<FinancialGrowth[]>('/financial-growth', { symbol, period, limit });1306}13071308// Company Outlook1309export interface CompanyOutlook {1310  profile: CompanyProfile;1311  metrics: any;1312  ratios: any[];1313  insiderTrades: any[];1314  keyExecutives: any[];1315  splitHistory: any[];1316  stockDividend: any[];1317  stockNews: any[];1318  rating: any[];1319  financialsAnnual: any;1320  financialsQuarter: any;1321}13221323export async function getCompanyOutlook(symbol: string): Promise<CompanyOutlook> {1324  return fmpRequest<CompanyOutlook>('/company-outlook', { symbol });1325}13261327// Stock News Sentiment1328export interface StockNewsSentiment {1329  symbol: string;1330  publishedDate: string;1331  title: string;1332  image: string;1333  site: string;1334  text: string;1335  url: string;1336  sentiment: string;1337  sentimentScore: number;1338}13391340export async function getStockNewsSentiment(symbol: string, limit: number = 5): Promise<StockNewsSentiment[]> {1341  // Limit to 5 articles to avoid context overflow1342  const actualLimit = Math.min(limit, 5);1343  return fmpRequest<StockNewsSentiment[]>('/stock-news-sentiment-rss-feed', { tickers: symbol, limit: actualLimit });1344}13451346// Crypto Quote1347export interface CryptoQuote {1348  symbol: string;1349  name: string;1350  price: number;1351  changesPercentage: number;1352  change: number;1353  dayLow: number;1354  dayHigh: number;1355  yearHigh: number;1356  yearLow: number;1357  marketCap: number;1358  priceAvg50: number;1359  priceAvg200: number;1360  volume: number;1361  avgVolume: number;1362  exchange: string;1363  open: number;1364  previousClose: number;1365  timestamp: number;1366}13671368export async function getCryptoQuote(symbol: string): Promise<CryptoQuote[]> {1369  return fmpRequest<CryptoQuote[]>('/quote', { symbol });1370}13711372export async function getCryptoList(): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string }>> {1373  return fmpRequest('/available-cryptocurrencies');1374}13751376// Forex Historical1377export interface ForexHistorical {1378  date: string;1379  open: number;1380  high: number;1381  low: number;1382  close: number;1383  adjClose: number;1384  volume: number;1385}13861387export async function getForexHistorical(pair: string, from?: string, to?: string): Promise<{ symbol: string; historical: ForexHistorical[] }> {1388  const params: Record<string, any> = {};1389  if (from) params.from = from;1390  if (to) params.to = to;1391  params.symbol = pair;1392  const data = await fmpRequest<ForexHistorical[]>('/historical-price-eod/full', params);13931394  // Stable API returns flat array; wrap to match legacy format1395  let historical = Array.isArray(data) ? data : (data as any).historical || [];13961397  // Limit to last 20 days1398  if (historical.length > 20) {1399    historical = historical.slice(0, 20);1400  }14011402  return { symbol: pair, historical };1403}14041405// SEC Filings1406export interface SECFiling {1407  symbol: string;1408  cik: string;1409  acceptedDate: string;1410  type: string;1411  link: string;1412  finalLink: string;1413}14141415export async function getSECFilings(symbol: string, type?: string, limit: number = 20): Promise<SECFiling[]> {1416  // Limit to 20 filings to avoid context overflow1417  const actualLimit = Math.min(limit, 20);1418  const params: Record<string, any> = { limit: actualLimit };1419  if (type) params.type = type;1420  return fmpRequest<SECFiling[]>('/sec-filings', { symbol, ...params });1421}14221423// Company Notes1424export interface CompanyNote {1425  symbol: string;1426  cik: string;1427  acceptedDate: string;1428  period: string;1429  formType: string;1430  notes: string;1431}14321433export async function getCompanyNotes(symbol: string): Promise<CompanyNote[]> {1434  return fmpRequest<CompanyNote[]>('/company-notes', { symbol });1435}14361437// Earnings Call Transcript1438export interface EarningsCallTranscript {1439  symbol: string;1440  quarter: number;1441  year: number;1442  date: string;1443  content: string;1444}14451446export async function getEarningsCallTranscript(symbol: string, year: number, quarter: number): Promise<EarningsCallTranscript[]> {1447  return fmpRequest<EarningsCallTranscript[]>('/earning-call-transcript', { symbol, quarter, year });1448}14491450// Advanced Chart Data APIs1451// fmpStableRequest now uses the same base URL as fmpRequest (all migrated to /stable)1452async function fmpStableRequest<T>(endpoint: string, params: Record<string, any> = {}): Promise<T> {1453  return fmpRequest<T>(endpoint, params);1454}14551456export interface ChartDataLight {1457  symbol: string;1458  date: string;1459  price: number;1460  volume: number;1461}14621463export interface ChartDataFull {1464  symbol: string;1465  date: string;1466  open: number;1467  high: number;1468  low: number;1469  close: number;1470  volume: number;1471  change: number;1472  changePercent: number;1473  vwap: number;1474}14751476export interface ChartDataIntraday {1477  date: string;1478  open: number;1479  high: number;1480  low: number;1481  close: number;1482  volume: number;1483}14841485// Stock Chart Light API1486export async function getChartLight(symbol: string, from?: string, to?: string): Promise<ChartDataLight[]> {1487  const params: Record<string, any> = { symbol };1488  if (from) params.from = from;1489  if (to) params.to = to;1490  return fmpStableRequest<ChartDataLight[]>('/historical-price-eod/light', params);1491}14921493// Stock Price and Volume Data API (Full)1494export async function getChartFull(symbol: string, from?: string, to?: string): Promise<ChartDataFull[]> {1495  const params: Record<string, any> = { symbol };1496  if (from) params.from = from;1497  if (to) params.to = to;1498  return fmpStableRequest<ChartDataFull[]>('/historical-price-eod/full', params);1499}15001501// Unadjusted Stock Price API1502export async function getChartUnadjusted(symbol: string, from?: string, to?: string): Promise<any[]> {1503  const params: Record<string, any> = { symbol };1504  if (from) params.from = from;1505  if (to) params.to = to;1506  return fmpStableRequest<any[]>('/historical-price-eod/non-split-adjusted', params);1507}15081509// Dividend Adjusted Price Chart API1510export async function getChartDividendAdjusted(symbol: string, from?: string, to?: string): Promise<any[]> {1511  const params: Record<string, any> = { symbol };1512  if (from) params.from = from;1513  if (to) params.to = to;1514  return fmpStableRequest<any[]>('/historical-price-eod/dividend-adjusted', params);1515}15161517// Intraday Chart APIs1518export async function getChartIntraday(1519  symbol: string,1520  interval: '1min' | '5min' | '15min' | '30min' | '1hour' | '4hour',1521  from?: string,1522  to?: string,1523  nonadjusted: boolean = false1524): Promise<ChartDataIntraday[]> {1525  const params: Record<string, any> = { symbol };1526  if (from) params.from = from;1527  if (to) params.to = to;1528  if (nonadjusted) params.nonadjusted = 'true';1529  return fmpStableRequest<ChartDataIntraday[]>(`/historical-chart/${interval}`, params);1530}15311532// ==========================================1533// SEARCH & DISCOVERY APIs1534// ==========================================15351536// Search Symbol API1537export async function searchSymbol(query: string): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string; exchangeShortName: string }>> {1538  return fmpStableRequest('/search-symbol', { query });1539}15401541// Search Name API1542export async function searchName(query: string): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string; exchangeShortName: string }>> {1543  return fmpStableRequest('/search-name', { query });1544}15451546// Search Exchange Variants API1547export async function searchExchangeVariants(symbol: string): Promise<Array<{ symbol: string; name: string; exchange: string }>> {1548  return fmpStableRequest('/search-exchange-variants', { symbol });1549}15501551// Stock List API1552export async function getStockList(): Promise<Array<{ symbol: string; name: string; price: number; exchange: string }>> {1553  return fmpStableRequest('/stock-list');1554}15551556// Financial Statement Symbol List API1557export async function getFinancialStatementSymbolList(): Promise<Array<{ symbol: string }>> {1558  return fmpStableRequest('/financial-statement-symbol-list');1559}15601561// CIK List API1562export async function getCIKList(page: number = 0, limit: number = 1000): Promise<Array<{ cik: string; name: string }>> {1563  return fmpStableRequest('/cik-list', { page, limit });1564}15651566// Symbol Change API1567export async function getSymbolChange(): Promise<Array<{ date: string; name: string; oldSymbol: string; newSymbol: string }>> {1568  return fmpStableRequest('/symbol-change');1569}15701571// ETF List API1572export async function getETFList(): Promise<Array<{ symbol: string; name: string; price: number; exchange: string }>> {1573  return fmpStableRequest('/etf-list');1574}15751576// Actively Trading List API1577export async function getActivelyTradingList(): Promise<Array<{ symbol: string; name: string; price: number; exchange: string }>> {1578  return fmpStableRequest('/actively-trading-list');1579}15801581// Earnings Transcript List API1582export async function getEarningsTranscriptList(): Promise<Array<{ symbol: string; numberOfEarningsTranscript: number }>> {1583  return fmpStableRequest('/earnings-transcript-list');1584}15851586// Available Exchanges API1587export async function getAvailableExchanges(): Promise<Array<{ name: string; code: string }>> {1588  return fmpStableRequest('/available-exchanges');1589}15901591// Available Sectors API1592export async function getAvailableSectors(): Promise<Array<{ sector: string }>> {1593  return fmpStableRequest('/available-sectors');1594}15951596// Available Industries API1597export async function getAvailableIndustries(): Promise<Array<{ industry: string }>> {1598  return fmpStableRequest('/available-industries');1599}16001601// Available Countries API1602export async function getAvailableCountries(): Promise<Array<{ country: string }>> {1603  return fmpStableRequest('/available-countries');1604}16051606// ==========================================1607// ADVANCED COMPANY DATA APIs1608// ==========================================16091610// Profile by CIK API1611export async function getProfileByCIK(cik: string): Promise<CompanyProfile[]> {1612  return fmpStableRequest<CompanyProfile[]>('/profile-cik', { cik });1613}16141615// Delisted Companies API1616export async function getDelistedCompanies(page: number = 0, limit: number = 100): Promise<Array<{ symbol: string; companyName: string; exchange: string; ipoDate: string; delistedDate: string }>> {1617  return fmpStableRequest('/delisted-companies', { page, limit });1618}16191620// Employee Count API1621export async function getEmployeeCount(symbol: string): Promise<Array<{ symbol: string; cik: string; acceptanceTime: string; periodOfReport: string; companyName: string; formType: string; filingDate: string; employeeCount: number; source: string }>> {1622  return fmpStableRequest('/employee-count', { symbol });1623}16241625// Historical Employee Count API1626export async function getHistoricalEmployeeCount(symbol: string): Promise<Array<{ symbol: string; cik: string; acceptanceTime: string; periodOfReport: string; companyName: string; formType: string; filingDate: string; employeeCount: number; source: string }>> {1627  return fmpStableRequest('/historical-employee-count', { symbol });1628}16291630// Market Capitalization API1631export async function getMarketCapitalization(symbol: string): Promise<Array<{ symbol: string; date: string; marketCap: number }>> {1632  return fmpStableRequest('/market-capitalization', { symbol });1633}16341635// Batch Market Capitalization API1636export async function getBatchMarketCapitalization(symbols: string): Promise<Array<{ symbol: string; marketCap: number }>> {1637  return fmpStableRequest('/market-capitalization-batch', { symbols });1638}16391640// Historical Market Capitalization API1641export async function getHistoricalMarketCapitalization(symbol: string, limit: number = 100): Promise<Array<{ symbol: string; date: string; marketCap: number }>> {1642  return fmpStableRequest('/historical-market-capitalization', { symbol, limit });1643}16441645// Shares Float API1646export async function getSharesFloat(symbol: string): Promise<Array<{ symbol: string; date: string; freeFloat: number; floatShares: number; outstandingShares: number; source: string }>> {1647  return fmpStableRequest('/shares-float', { symbol });1648}16491650// All Shares Float API1651export async function getAllSharesFloat(page: number = 0, limit: number = 1000): Promise<Array<{ symbol: string; date: string; freeFloat: number; floatShares: number; outstandingShares: number }>> {1652  return fmpStableRequest('/shares-float-all', { page, limit });1653}16541655// Latest Mergers and Acquisitions API1656export async function getLatestMergersAcquisitions(page: number = 0, limit: number = 100): Promise<Array<{ targetedCompany: string; acquiringCompany: string; transactionDate: string; acceptanceTime: string }>> {1657  return fmpStableRequest('/mergers-acquisitions-latest', { page, limit });1658}16591660// Search Mergers and Acquisitions API1661export async function searchMergersAcquisitions(name: string): Promise<Array<{ targetedCompany: string; acquiringCompany: string; transactionDate: string; acceptanceTime: string }>> {1662  return fmpStableRequest('/mergers-acquisitions-search', { name });1663}16641665// Key Executives API1666export async function getKeyExecutives(symbol: string): Promise<Array<{ title: string; name: string; pay: number; currencyPay: string; gender: string; yearBorn: number; titleSince: string }>> {1667  return fmpStableRequest('/key-executives', { symbol });1668}16691670// Executive Compensation API1671export async function getExecutiveCompensation(symbol: string): Promise<Array<{ cik: string; symbol: string; companyName: string; filingDate: string; acceptedDate: string; nameAndPosition: string; year: number; salary: number; bonus: number; stockAward: number; incentivePlanCompensation: number; allOtherCompensation: number; total: number; url: string }>> {1672  return fmpStableRequest('/governance-executive-compensation', { symbol });1673}16741675// Executive Compensation Benchmark API1676export async function getExecutiveCompensationBenchmark(year?: number): Promise<Array<{ industryTitle: string; year: number; averageSalary: number; averageBonus: number; averageStockAward: number; averageIncentivePlanCompensation: number; averageTotalCompensation: number; averageAllOtherCompensation: number }>> {1677  const params: Record<string, any> = {};1678  if (year) params.year = year;1679  return fmpStableRequest('/executive-compensation-benchmark', params);1680}16811682// ==========================================1683// QUOTES & MARKET DATA APIs1684// ==========================================16851686// Quote Short API1687export async function getQuoteShort(symbol: string): Promise<Array<{ symbol: string; price: number; volume: number }>> {1688  return fmpStableRequest('/quote-short', { symbol });1689}16901691// Aftermarket Trade API1692export async function getAftermarketTrade(symbol: string): Promise<Array<{ symbol: string; price: number; size: number; timestamp: number }>> {1693  return fmpStableRequest('/aftermarket-trade', { symbol });1694}16951696// Aftermarket Quote API1697export async function getAftermarketQuote(symbol: string): Promise<Array<{ symbol: string; ask: number; bid: number; asize: number; bsize: number; timestamp: number }>> {1698  return fmpStableRequest('/aftermarket-quote', { symbol });1699}17001701// Stock Price Change API1702export async function getStockPriceChange(symbol: string): Promise<Array<{ symbol: string; '1D': number; '5D': number; '1M': number; '3M': number; '6M': number; ytd: number; '1Y': number; '3Y': number; '5Y': number; '10Y': number; max: number }>> {1703  return fmpStableRequest('/stock-price-change', { symbol });1704}17051706// Batch Quote API1707export async function getBatchQuote(symbols: string): Promise<StockQuote[]> {1708  return fmpStableRequest<StockQuote[]>('/batch-quote', { symbols });1709}17101711// Batch Quote Short API1712export async function getBatchQuoteShort(symbols: string): Promise<Array<{ symbol: string; price: number; volume: number }>> {1713  return fmpStableRequest('/batch-quote-short', { symbols });1714}17151716// Batch Aftermarket Trade API1717export async function getBatchAftermarketTrade(symbols: string): Promise<Array<{ symbol: string; price: number; size: number; timestamp: number }>> {1718  return fmpStableRequest('/batch-aftermarket-trade', { symbols });1719}17201721// Batch Aftermarket Quote API1722export async function getBatchAftermarketQuote(symbols: string): Promise<Array<{ symbol: string; ask: number; bid: number; asize: number; bsize: number; timestamp: number }>> {1723  return fmpStableRequest('/batch-aftermarket-quote', { symbols });1724}17251726// Exchange Stock Quotes API1727export async function getBatchExchangeQuote(exchange: string): Promise<StockQuote[]> {1728  return fmpStableRequest<StockQuote[]>('/batch-exchange-quote', { exchange });1729}17301731// Mutual Fund Quotes API1732export async function getBatchMutualfundQuotes(): Promise<StockQuote[]> {1733  return fmpStableRequest<StockQuote[]>('/batch-mutualfund-quotes');1734}17351736// ETF Quotes API1737export async function getBatchETFQuotes(): Promise<StockQuote[]> {1738  return fmpStableRequest<StockQuote[]>('/batch-etf-quotes');1739}17401741// Commodity Quotes API (Batch)1742export async function getBatchCommodityQuotes(): Promise<CommodityQuote[]> {1743  return fmpStableRequest<CommodityQuote[]>('/batch-commodity-quotes');1744}17451746// Crypto Quotes API (Batch)1747export async function getBatchCryptoQuotes(): Promise<CryptoQuote[]> {1748  return fmpStableRequest<CryptoQuote[]>('/batch-crypto-quotes');1749}17501751// Forex Quotes API (Batch)1752export async function getBatchForexQuotes(): Promise<ForexQuote[]> {1753  return fmpStableRequest<ForexQuote[]>('/batch-forex-quotes');1754}17551756// Index Quotes API (Batch)1757export async function getBatchIndexQuotes(): Promise<StockQuote[]> {1758  return fmpStableRequest<StockQuote[]>('/batch-index-quotes');1759}17601761// ==========================================1762// FINANCIAL STATEMENTS - TTM & AS REPORTED1763// ==========================================17641765// Latest Financial Statements API1766export async function getLatestFinancialStatements(page: number = 0, limit: number = 250): Promise<Array<{ symbol: string; date: string }>> {1767  return fmpStableRequest('/latest-financial-statements', { page, limit });1768}17691770// Income Statement TTM API1771export async function getIncomeStatementTTM(symbol: string): Promise<IncomeStatement[]> {1772  return fmpStableRequest<IncomeStatement[]>('/income-statement-ttm', { symbol });1773}17741775// Balance Sheet TTM API1776export async function getBalanceSheetTTM(symbol: string): Promise<BalanceSheet[]> {1777  return fmpStableRequest<BalanceSheet[]>('/balance-sheet-statement-ttm', { symbol });1778}17791780// Cash Flow Statement TTM API1781export async function getCashflowStatementTTM(symbol: string): Promise<CashFlowStatement[]> {1782  return fmpStableRequest<CashFlowStatement[]>('/cash-flow-statement-ttm', { symbol });1783}17841785// Key Metrics TTM API1786export async function getKeyMetricsTTM(symbol: string): Promise<KeyMetrics[]> {1787  return fmpStableRequest<KeyMetrics[]>('/key-metrics-ttm', { symbol });1788}17891790// Ratios TTM API1791export async function getRatiosTTM(symbol: string): Promise<FinancialRatios[]> {1792  return fmpStableRequest<FinancialRatios[]>('/ratios-ttm', { symbol });1793}17941795// Financial Scores API1796export async function getFinancialScores(symbol: string): Promise<Array<{ symbol: string; altmanZScore: number; piotroskiScore: number; workingCapital: number; totalAssets: number; retainedEarnings: number; ebit: number; marketCap: number; totalLiabilities: number; revenue: number }>> {1797  return fmpStableRequest('/financial-scores', { symbol });1798}17991800// Owner Earnings API1801export async function getOwnerEarnings(symbol: string): Promise<Array<{ symbol: string; date: string; averagePPE: number; maintenanceCapex: number; ownersEarnings: number; growthCapex: number; ownersEarningsPerShare: number }>> {1802  return fmpStableRequest('/owner-earnings', { symbol });1803}18041805// Enterprise Values API1806export async function getEnterpriseValues(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<Array<{ symbol: string; date: string; stockPrice: number; numberOfShares: number; marketCapitalization: number; minusCashAndCashEquivalents: number; addTotalDebt: number; enterpriseValue: number }>> {1807  return fmpStableRequest('/enterprise-values', { symbol, period, limit });1808}18091810// Financial Reports Dates API1811export async function getFinancialReportsDates(symbol: string): Promise<Array<{ symbol: string; period: string; linkXlsx: string; linkJson: string }>> {1812  return fmpStableRequest('/financial-reports-dates', { symbol });1813}18141815// Annual Reports 10K JSON API1816export async function getAnnualReports10K(symbol: string, year: number, period: string): Promise<any> {1817  return fmpStableRequest('/financial-reports-json', { symbol, year, period });1818}18191820// Annual Reports 10K XLSX API1821export async function getAnnualReports10KXLSX(symbol: string, year: number, period: string): Promise<any> {1822  return fmpStableRequest('/financial-reports-xlsx', { symbol, year, period });1823}18241825// Revenue Product Segmentation API1826export async function getRevenueProductSegmentation(symbol: string, period: 'annual' | 'quarter' = 'annual'): Promise<Array<any>> {1827  return fmpStableRequest('/revenue-product-segmentation', { symbol, period });1828}18291830// Revenue Geographic Segmentation API1831export async function getRevenueGeographicSegmentation(symbol: string, period: 'annual' | 'quarter' = 'annual'): Promise<Array<any>> {1832  return fmpStableRequest('/revenue-geographic-segmentation', { symbol, period });1833}18341835// Income Statement As Reported API1836export async function getIncomeStatementAsReported(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<Array<any>> {1837  return fmpStableRequest('/income-statement-as-reported', { symbol, period, limit });1838}18391840// Balance Sheet As Reported API1841export async function getBalanceSheetAsReported(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<Array<any>> {1842  return fmpStableRequest('/balance-sheet-statement-as-reported', { symbol, period, limit });1843}18441845// Cash Flow As Reported API1846export async function getCashFlowAsReported(symbol: string, period: 'annual' | 'quarter' = 'annual', limit: number = 5): Promise<Array<any>> {1847  return fmpStableRequest('/cash-flow-statement-as-reported', { symbol, period, limit });1848}18491850// Full Financial Statement As Reported API1851export async function getFullFinancialStatementAsReported(symbol: string, period: 'annual' | 'quarter' = 'annual'): Promise<any> {1852  return fmpStableRequest('/financial-statement-full-as-reported', { symbol, period });1853}18541855// ==========================================1856// ECONOMIC DATA & DIVIDENDS1857// ==========================================18581859// Market Risk Premium API1860export async function getMarketRiskPremium(country?: string): Promise<Array<{ country: string; continent: string; totalEquityRiskPremium: number; countryRiskPremium: number }>> {1861  const params: Record<string, any> = {};1862  if (country) params.country = country;1863  return fmpStableRequest('/market-risk-premium', params);1864}18651866// Dividends Company API1867export async function getDividendsCompany(symbol: string): Promise<Dividend[]> {1868  return fmpStableRequest<Dividend[]>('/dividends', { symbol });1869}18701871// Dividends Calendar API1872export async function getDividendsCalendar(from?: string, to?: string): Promise<Array<{ date: string; label: string; adjDividend: number; symbol: string; dividend: number; recordDate: string; paymentDate: string; declarationDate: string }>> {1873  const params: Record<string, any> = {};1874  if (from) params.from = from;1875  if (to) params.to = to;1876  return fmpStableRequest('/dividends-calendar', params);1877}18781879// Earnings Report API1880export async function getEarningsReport(symbol: string): Promise<Array<{ date: string; symbol: string; eps: number; epsEstimated: number; time: string; revenue: number; revenueEstimated: number }>> {1881  return fmpStableRequest('/earnings', { symbol });1882}18831884// IPO Disclosures API1885export async function getIPODisclosures(from?: string, to?: string): Promise<Array<{ symbol: string; cik: string; form: string; filingDate: string; acceptanceTime: string; effectivenessDate: string }>> {1886  const params: Record<string, any> = {};1887  if (from) params.from = from;1888  if (to) params.to = to;1889  return fmpStableRequest('/ipos-disclosure', params);1890}18911892// IPO Prospectus API1893export async function getIPOProspectus(from?: string, to?: string): Promise<Array<{ symbol: string; cik: string; form: string; filingDate: string; acceptedDate: string; publicOfferingPrice: number; publicOfferingPricePercentageDiscount: number; commissions: number; commissionsPercentage: number; proceedsBeforeExpenses: number }>> {1894  const params: Record<string, any> = {};1895  if (from) params.from = from;1896  if (to) params.to = to;1897  return fmpStableRequest('/ipos-prospectus', params);1898}18991900// Splits API1901export async function getSplits(symbol: string): Promise<StockSplit[]> {1902  return fmpStableRequest<StockSplit[]>('/splits', { symbol });1903}19041905// Splits Calendar API1906export async function getSplitsCalendar(from?: string, to?: string): Promise<StockSplit[]> {1907  const params: Record<string, any> = {};1908  if (from) params.from = from;1909  if (to) params.to = to;1910  return fmpStableRequest<StockSplit[]>('/splits-calendar', params);1911}19121913// ==========================================1914// NEWS & TRANSCRIPTS APIs1915// ==========================================19161917// Latest Earning Transcripts API1918export async function getLatestEarningTranscripts(): Promise<Array<{ symbol: string; quarter: number; year: number; date: string }>> {1919  return fmpStableRequest('/earning-call-transcript-latest');1920}19211922// Earning Call Transcript Dates API1923export async function getEarningCallTranscriptDates(symbol: string): Promise<Array<{ symbol: string; quarter: number; year: number; date: string }>> {1924  return fmpStableRequest('/earning-call-transcript-dates', { symbol });1925}19261927// FMP Articles API1928export async function getFMPArticles(page: number = 0, limit: number = 20): Promise<Array<{ title: string; date: string; content: string; tickers: string; image: string; link: string; author: string; site: string }>> {1929  return fmpStableRequest('/fmp-articles', { page, limit });1930}19311932// General News API1933export async function getGeneralNews(page: number = 0, limit: number = 20): Promise<FinancialNews[]> {1934  return fmpStableRequest<FinancialNews[]>('/news/general-latest', { page, limit });1935}19361937// Press Releases Latest API1938export async function getPressReleasesLatest(page: number = 0, limit: number = 20): Promise<FinancialNews[]> {1939  return fmpStableRequest<FinancialNews[]>('/news/press-releases-latest', { page, limit });1940}19411942// Stock News Latest API1943export async function getStockNewsLatest(page: number = 0, limit: number = 20): Promise<FinancialNews[]> {1944  return fmpStableRequest<FinancialNews[]>('/news/stock-latest', { page, limit });1945}19461947// Crypto News API1948export async function getCryptoNews(page: number = 0, limit: number = 20): Promise<FinancialNews[]> {1949  return fmpStableRequest<FinancialNews[]>('/news/crypto-latest', { page, limit });1950}19511952// Forex News API1953export async function getForexNews(page: number = 0, limit: number = 20): Promise<FinancialNews[]> {1954  return fmpStableRequest<FinancialNews[]>('/news/forex-latest', { page, limit });1955}19561957// Search Press Releases API1958export async function searchPressReleasesNew(symbols: string): Promise<FinancialNews[]> {1959  return fmpStableRequest<FinancialNews[]>('/news/press-releases', { symbols });1960}19611962// Search Stock News API1963export async function searchStockNews(symbols: string): Promise<FinancialNews[]> {1964  return fmpStableRequest<FinancialNews[]>('/news/stock', { symbols });1965}19661967// Search Crypto News API1968export async function searchCryptoNews(symbols: string): Promise<FinancialNews[]> {1969  return fmpStableRequest<FinancialNews[]>('/news/crypto', { symbols });1970}19711972// Search Forex News API1973export async function searchForexNews(symbols: string): Promise<FinancialNews[]> {1974  return fmpStableRequest<FinancialNews[]>('/news/forex', { symbols });1975}19761977// ==========================================1978// FORM 13F & INSTITUTIONAL OWNERSHIP APIs1979// ==========================================19801981// Institutional Ownership Filings API1982export async function getInstitutionalOwnershipFilings(page: number = 0, limit: number = 100): Promise<Array<any>> {1983  return fmpStableRequest('/institutional-ownership/latest', { page, limit });1984}19851986// SEC Filings Extract API1987export async function extractSECFilings(cik: string, year: number, quarter: number): Promise<Array<any>> {1988  return fmpStableRequest('/institutional-ownership/extract', { cik, year, quarter });1989}19901991// Form 13F Filings Dates API1992export async function getForm13FFilingsDates(cik: string): Promise<Array<{ cik: string; date: string; year: number; quarter: number }>> {1993  return fmpStableRequest('/institutional-ownership/dates', { cik });1994}19951996// Filings Extract With Analytics By Holder API1997export async function getFilingsExtractWithAnalytics(symbol: string, year: number, quarter: number, page: number = 0, limit: number = 10): Promise<Array<any>> {1998  return fmpStableRequest('/institutional-ownership/extract-analytics/holder', { symbol, year, quarter, page, limit });1999}20002001// Holder Performance Summary API2002export async function getHolderPerformanceSummary(cik: string, page: number = 0): Promise<Array<any>> {2003  return fmpStableRequest('/institutional-ownership/holder-performance-summary', { cik, page });2004}20052006// Holders Industry Breakdown API2007export async function getHoldersIndustryBreakdown(cik: string, year: number, quarter: number): Promise<Array<any>> {2008  return fmpStableRequest('/institutional-ownership/holder-industry-breakdown', { cik, year, quarter });2009}20102011// Positions Summary API2012export async function getPositionsSummary(symbol: string, year: number, quarter: number): Promise<Array<any>> {2013  return fmpStableRequest('/institutional-ownership/symbol-positions-summary', { symbol, year, quarter });2014}20152016// Industry Performance Summary API2017export async function getIndustryPerformanceSummary(year: number, quarter: number): Promise<Array<any>> {2018  return fmpStableRequest('/institutional-ownership/industry-summary', { year, quarter });2019}20202021// ==========================================2022// ANALYST RATINGS & ESTIMATES APIs2023// ==========================================20242025// Ratings Snapshot API2026export async function getRatingsSnapshot(symbol: string): Promise<Array<{ symbol: string; date: string; rating: string; ratingScore: number; ratingRecommendation: string; ratingDetailsDCFScore: number; ratingDetailsDCFRecommendation: string; ratingDetailsROEScore: number; ratingDetailsROERecommendation: string; ratingDetailsROAScore: number; ratingDetailsROARecommendation: string; ratingDetailsDEScore: number; ratingDetailsDERecommendation: string; ratingDetailsPEScore: number; ratingDetailsPERecommendation: string; ratingDetailsPBScore: number; ratingDetailsPBRecommendation: string }>> {2027  return fmpStableRequest('/ratings-snapshot', { symbol });2028}20292030// Historical Ratings API2031export async function getHistoricalRatings(symbol: string, limit: number = 100): Promise<Array<any>> {2032  return fmpStableRequest('/ratings-historical', { symbol, limit });2033}20342035// Price Target Consensus API2036export async function getPriceTargetConsensus(symbol: string): Promise<Array<{ symbol: string; targetHigh: number; targetLow: number; targetConsensus: number; targetMedian: number }>> {2037  return fmpStableRequest('/price-target-consensus', { symbol });2038}20392040// Grades API2041export async function getGrades(symbol: string, limit: number = 100): Promise<Array<{ symbol: string; date: string; gradingCompany: string; previousGrade: string; newGrade: string; action: string }>> {2042  return fmpStableRequest('/grades', { symbol, limit });2043}20442045// Historical Grades API2046export async function getHistoricalGrades(symbol: string, limit: number = 100): Promise<Array<any>> {2047  return fmpStableRequest('/grades-historical', { symbol, limit });2048}20492050// Grades Summary API2051export async function getGradesSummary(symbol: string): Promise<Array<{ symbol: string; strongBuy: number; buy: number; hold: number; sell: number; strongSell: number; consensus: string }>> {2052  return fmpStableRequest('/grades-consensus', { symbol });2053}20542055// ==========================================2056// MARKET PERFORMANCE & SECTORS APIs2057// ==========================================20582059// Market Sector Performance Snapshot API2060export async function getMarketSectorPerformanceSnapshot(date?: string): Promise<Array<{ sector: string; changesPercentage: string }>> {2061  const params: Record<string, any> = {};2062  if (date) params.date = date;2063  return fmpStableRequest('/sector-performance-snapshot', params);2064}20652066// Industry Performance Snapshot API2067export async function getIndustryPerformanceSnapshot(date?: string): Promise<Array<{ industry: string; changesPercentage: string }>> {2068  const params: Record<string, any> = {};2069  if (date) params.date = date;2070  return fmpStableRequest('/industry-performance-snapshot', params);2071}20722073// Historical Sector Performance API2074export async function getHistoricalSectorPerformance(sector: string, limit: number = 100): Promise<Array<{ date: string; sector: string; changesPercentage: string }>> {2075  return fmpStableRequest('/historical-sector-performance', { sector, limit });2076}20772078// Historical Industry Performance API2079export async function getHistoricalIndustryPerformance(industry: string, limit: number = 100): Promise<Array<{ date: string; industry: string; changesPercentage: string }>> {2080  return fmpStableRequest('/historical-industry-performance', { industry, limit });2081}20822083// Sector P/E Snapshot API2084export async function getSectorPESnapshot(date?: string): Promise<Array<{ date: string; sector: string; pe: string }>> {2085  const params: Record<string, any> = {};2086  if (date) params.date = date;2087  return fmpStableRequest('/sector-pe-snapshot', params);2088}20892090// Industry P/E Snapshot API2091export async function getIndustryPESnapshot(date?: string): Promise<Array<{ date: string; industry: string; pe: string }>> {2092  const params: Record<string, any> = {};2093  if (date) params.date = date;2094  return fmpStableRequest('/industry-pe-snapshot', params);2095}20962097// Historical Sector P/E API2098export async function getHistoricalSectorPE(sector: string, limit: number = 100): Promise<Array<{ date: string; sector: string; pe: string }>> {2099  return fmpStableRequest('/historical-sector-pe', { sector, limit });2100}21012102// Historical Industry P/E API2103export async function getHistoricalIndustryPE(industry: string, limit: number = 100): Promise<Array<{ date: string; industry: string; pe: string }>> {2104  return fmpStableRequest('/historical-industry-pe', { industry, limit });2105}21062107// ==========================================2108// ADDITIONAL TECHNICAL INDICATORS APIs2109// ==========================================21102111// Weighted Moving Average API2112export async function getWMA(symbol: string, periodLength: number = 10, timeframe: string = '1day'): Promise<TechnicalIndicator[]> {2113  const result = await fmpStableRequest<TechnicalIndicator[]>('/technical-indicators/wma', { symbol, periodLength, timeframe });2114  return result.slice(0, 10);2115}21162117// Double Exponential Moving Average API2118export async function getDEMA(symbol: string, periodLength: number = 10, timeframe: string = '1day'): Promise<TechnicalIndicator[]> {2119  const result = await fmpStableRequest<TechnicalIndicator[]>('/technical-indicators/dema', { symbol, periodLength, timeframe });2120  return result.slice(0, 10);2121}21222123// Triple Exponential Moving Average API2124export async function getTEMA(symbol: string, periodLength: number = 10, timeframe: string = '1day'): Promise<TechnicalIndicator[]> {2125  const result = await fmpStableRequest<TechnicalIndicator[]>('/technical-indicators/tema', { symbol, periodLength, timeframe });2126  return result.slice(0, 10);2127}21282129// Standard Deviation API2130export async function getStandardDeviation(symbol: string, periodLength: number = 10, timeframe: string = '1day'): Promise<TechnicalIndicator[]> {2131  const result = await fmpStableRequest<TechnicalIndicator[]>('/technical-indicators/standarddeviation', { symbol, periodLength, timeframe });2132  return result.slice(0, 10);2133}21342135// ==========================================2136// ETF & MUTUAL FUNDS APIs2137// ==========================================21382139// ETF Asset Exposure API2140export async function getETFAssetExposure(symbol: string): Promise<Array<{ etfSymbol: string; assetExposure: string; sharesNumber: number; weightPercentage: string; marketValue: number }>> {2141  return fmpStableRequest('/etf/asset-exposure', { symbol });2142}21432144// Mutual Fund Disclosure Latest API2145export async function getMutualFundDisclosureLatest(symbol: string): Promise<Array<any>> {2146  return fmpStableRequest('/funds/disclosure-holders-latest', { symbol });2147}21482149// Mutual Fund Disclosure API2150export async function getMutualFundDisclosure(symbol: string, year: number, quarter: number): Promise<any> {2151  return fmpStableRequest('/funds/disclosure', { symbol, year, quarter });2152}21532154// Mutual Fund Disclosure Search API2155export async function getMutualFundDisclosureSearch(name: string): Promise<Array<any>> {2156  return fmpStableRequest('/funds/disclosure-holders-search', { name });2157}21582159// Fund Disclosure Dates API2160export async function getMutualFundDisclosureDates(symbol: string): Promise<Array<{ symbol: string; date: string; year: number; quarter: number }>> {2161  return fmpStableRequest('/funds/disclosure-dates', { symbol });2162}21632164// ==========================================2165// SEC FILINGS - ADVANCED APIs2166// ==========================================21672168// Latest 8-K SEC Filings API2169export async function getLatest8KSECFilings(from?: string, to?: string, page: number = 0, limit: number = 100): Promise<Array<SECFiling>> {2170  const params: Record<string, any> = { page, limit };2171  if (from) params.from = from;2172  if (to) params.to = to;2173  return fmpStableRequest<SECFiling[]>('/sec-filings-8k', params);2174}21752176// Latest SEC Filings API2177export async function getLatestSECFilings(from?: string, to?: string, page: number = 0, limit: number = 100): Promise<Array<SECFiling>> {2178  const params: Record<string, any> = { page, limit };2179  if (from) params.from = from;2180  if (to) params.to = to;2181  return fmpStableRequest<SECFiling[]>('/sec-filings-financials', params);2182}21832184// SEC Filings By Form Type API2185export async function getSECFilingsByFormType(formType: string, from?: string, to?: string, page: number = 0, limit: number = 100): Promise<Array<SECFiling>> {2186  const params: Record<string, any> = { formType, page, limit };2187  if (from) params.from = from;2188  if (to) params.to = to;2189  return fmpStableRequest<SECFiling[]>('/sec-filings-search/form-type', params);2190}21912192// SEC Filings By Symbol API2193export async function getSECFilingsBySymbol(symbol: string, from?: string, to?: string, page: number = 0, limit: number = 100): Promise<Array<SECFiling>> {2194  const params: Record<string, any> = { symbol, page, limit };2195  if (from) params.from = from;2196  if (to) params.to = to;2197  return fmpStableRequest<SECFiling[]>('/sec-filings-search/symbol', params);2198}21992200// SEC Filings By CIK API2201export async function getSECFilingsByCIK(cik: string, from?: string, to?: string, page: number = 0, limit: number = 100): Promise<Array<SECFiling>> {2202  const params: Record<string, any> = { cik, page, limit };2203  if (from) params.from = from;2204  if (to) params.to = to;2205  return fmpStableRequest<SECFiling[]>('/sec-filings-search/cik', params);2206}22072208// SEC Filings By Name API2209export async function getSECFilingsByName(company: string): Promise<Array<{ cik: string; name: string }>> {2210  return fmpStableRequest('/sec-filings-company-search/name', { company });2211}22122213// SEC Filings Company Search By Symbol API2214export async function getSECFilingsCompanySearchBySymbol(symbol: string): Promise<Array<{ cik: string; name: string; symbol: string }>> {2215  return fmpStableRequest('/sec-filings-company-search/symbol', { symbol });2216}22172218// SEC Filings Company Search By CIK API2219export async function getSECFilingsCompanySearchByCIK(cik: string): Promise<Array<{ cik: string; name: string }>> {2220  return fmpStableRequest('/sec-filings-company-search/cik', { cik });2221}22222223// SEC Company Full Profile API2224export async function getSECCompanyFullProfile(symbol: string): Promise<any> {2225  return fmpStableRequest('/sec-profile', { symbol });2226}22272228// Industry Classification List API2229export async function getIndustryClassificationList(): Promise<Array<{ sicCode: string; office: string; industryTitle: string }>> {2230  return fmpStableRequest('/standard-industrial-classification-list');2231}22322233// Industry Classification Search API2234export async function searchIndustryClassification(industryTitle?: string, sicCode?: string): Promise<Array<any>> {2235  const params: Record<string, any> = {};2236  if (industryTitle) params.industryTitle = industryTitle;2237  if (sicCode) params.sicCode = sicCode;2238  return fmpStableRequest('/industry-classification-search', params);2239}22402241// All Industry Classification API2242export async function getAllIndustryClassification(): Promise<Array<any>> {2243  return fmpStableRequest('/all-industry-classification');2244}22452246// ==========================================2247// INSIDER TRADES - ADVANCED APIs2248// ==========================================22492250// Latest Insider Trading API2251export async function getLatestInsiderTrading(page: number = 0, limit: number = 100): Promise<InsiderTrade[]> {2252  return fmpStableRequest<InsiderTrade[]>('/insider-trading/latest', { page, limit });2253}22542255// Search Insider Trades API2256export async function searchInsiderTrades(symbol?: string, companyName?: string, reportingName?: string, page: number = 0, limit: number = 100): Promise<InsiderTrade[]> {2257  const params: Record<string, any> = { page, limit };2258  if (symbol) params.symbol = symbol;2259  if (companyName) params.companyName = companyName;2260  if (reportingName) params.reportingName = reportingName;2261  return fmpStableRequest<InsiderTrade[]>('/insider-trading/search', params);2262}22632264// Search Insider Trades By Name API2265export async function searchInsiderTradesByName(name: string): Promise<InsiderTrade[]> {2266  return fmpStableRequest<InsiderTrade[]>('/insider-trading/reporting-name', { name });2267}22682269// All Insider Transaction Types API2270export async function getAllInsiderTransactionTypes(): Promise<Array<{ transactionType: string; description: string }>> {2271  return fmpStableRequest('/insider-trading-transaction-type');2272}22732274// Acquisition Of Beneficial Ownership API2275export async function getAcquisitionOfBeneficialOwnership(symbol: string): Promise<Array<any>> {2276  return fmpStableRequest('/acquisition-of-beneficial-ownership', { symbol });2277}22782279// ==========================================2280// INDEXES APIs2281// ==========================================22822283// Index List API2284export async function getIndexList(): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string; exchangeShortName: string }>> {2285  return fmpStableRequest('/index-list');2286}22872288// S&P 500 Constituent API2289export async function getSP500Constituent(): Promise<Array<{ symbol: string; name: string; sector: string; subSector: string; headQuarter: string; dateFirstAdded: string; cik: string; founded: string }>> {2290  return fmpStableRequest('/sp500-constituent');2291}22922293// Nasdaq Constituent API2294export async function getNasdaqConstituent(): Promise<Array<{ symbol: string; name: string; sector: string; subSector: string; headQuarter: string; dateFirstAdded: string; cik: string; founded: string }>> {2295  return fmpStableRequest('/nasdaq-constituent');2296}22972298// Dow Jones Constituent API2299export async function getDowJonesConstituent(): Promise<Array<{ symbol: string; name: string; sector: string; subSector: string; headQuarter: string; dateFirstAdded: string; cik: string; founded: string }>> {2300  return fmpStableRequest('/dowjones-constituent');2301}23022303// Historical S&P 500 Constituent API2304export async function getHistoricalSP500Constituent(): Promise<Array<{ dateAdded: string; addedSecurity: string; removedTicker: string; removedSecurity: string; date: string; reason: string }>> {2305  return fmpStableRequest('/historical-sp500-constituent');2306}23072308// Historical Nasdaq Constituent API2309export async function getHistoricalNasdaqConstituent(): Promise<Array<{ dateAdded: string; addedSecurity: string; removedTicker: string; removedSecurity: string; date: string; reason: string }>> {2310  return fmpStableRequest('/historical-nasdaq-constituent');2311}23122313// Historical Dow Jones Constituent API2314export async function getHistoricalDowJonesConstituent(): Promise<Array<{ dateAdded: string; addedSecurity: string; removedTicker: string; removedSecurity: string; date: string; reason: string }>> {2315  return fmpStableRequest('/historical-dowjones-constituent');2316}23172318// Exchange Market Hours API2319export async function getExchangeMarketHours(exchange: string): Promise<any> {2320  return fmpStableRequest('/exchange-market-hours', { exchange });2321}23222323// Holidays By Exchange API2324export async function getHolidaysByExchange(exchange: string): Promise<Array<{ year: number; holidays: Array<{ date: string; name: string }> }>> {2325  return fmpStableRequest('/holidays-by-exchange', { exchange });2326}23272328// All Exchange Market Hours API2329export async function getAllExchangeMarketHours(): Promise<Array<any>> {2330  return fmpStableRequest('/all-exchange-market-hours');2331}23322333// ==========================================2334// COMMODITIES APIs2335// ==========================================23362337// Commodities List API2338export async function getCommoditiesList(): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string; exchangeShortName: string }>> {2339  return fmpStableRequest('/commodities-list');2340}23412342// ==========================================2343// DCF VALUATION APIs2344// ==========================================23452346// DCF Valuation API2347export async function getDCFValuation(symbol: string): Promise<Array<{ symbol: string; date: string; dcf: number; stockPrice: number }>> {2348  return fmpStableRequest('/discounted-cash-flow', { symbol });2349}23502351// Levered DCF API2352export async function getLeveredDCF(symbol: string): Promise<Array<{ symbol: string; date: string; dcf: number; stockPrice: number }>> {2353  return fmpStableRequest('/levered-discounted-cash-flow', { symbol });2354}23552356// Custom DCF API2357export async function getCustomDCF(symbol: string, years?: number, growthRate?: number, discountRate?: number): Promise<any> {2358  const params: Record<string, any> = { symbol };2359  if (years) params.years = years;2360  if (growthRate) params.growthRate = growthRate;2361  if (discountRate) params.discountRate = discountRate;2362  return fmpStableRequest('/custom-discounted-cash-flow', params);2363}23642365// Custom Levered DCF API2366export async function getCustomLeveredDCF(symbol: string, years?: number, growthRate?: number, discountRate?: number): Promise<any> {2367  const params: Record<string, any> = { symbol };2368  if (years) params.years = years;2369  if (growthRate) params.growthRate = growthRate;2370  if (discountRate) params.discountRate = discountRate;2371  return fmpStableRequest('/custom-levered-discounted-cash-flow', params);2372}23732374// ==========================================2375// FOREX APIs2376// ==========================================23772378// Forex Currency Pairs API2379export async function getForexCurrencyPairs(): Promise<Array<{ symbol: string; name: string; currency: string; stockExchange: string }>> {2380  return fmpStableRequest('/forex-list');2381}23822383// ==========================================2384// SENATE & HOUSE TRADING APIs2385// ==========================================23862387// Latest Senate Disclosures API2388export async function getLatestSenateDisclosures(page: number = 0, limit: number = 100): Promise<CongressionalTrade[]> {2389  return fmpStableRequest<CongressionalTrade[]>('/senate-latest', { page, limit });2390}23912392// Latest House Disclosures API2393export async function getLatestHouseDisclosures(page: number = 0, limit: number = 100): Promise<CongressionalTrade[]> {2394  return fmpStableRequest<CongressionalTrade[]>('/house-latest', { page, limit });2395}23962397// Senate Trades API (by symbol)2398export async function getSenateTradesSymbol(symbol: string): Promise<CongressionalTrade[]> {2399  return fmpStableRequest<CongressionalTrade[]>('/senate-trades', { symbol });2400}24012402// Senate Trades By Name API2403export async function getSenateTradesByName(name: string): Promise<CongressionalTrade[]> {2404  return fmpStableRequest<CongressionalTrade[]>('/senate-trades-by-name', { name });2405}24062407// House Trades API (by symbol)2408export async function getHouseTradesSymbol(symbol: string): Promise<CongressionalTrade[]> {2409  return fmpStableRequest<CongressionalTrade[]>('/house-trades', { symbol });2410}24112412// House Trades By Name API2413export async function getHouseTradesByName(name: string): Promise<CongressionalTrade[]> {2414  return fmpStableRequest<CongressionalTrade[]>('/house-trades-by-name', { name });2415}24162417// ==========================================2418// ESG APIs2419// ==========================================24202421// ESG Disclosures API2422export async function getESGDisclosures(symbol: string): Promise<Array<any>> {2423  return fmpStableRequest('/esg-disclosures', { symbol });2424}24252426// ESG Ratings API2427export async function getESGRatings(symbol: string): Promise<ESGScore[]> {2428  return fmpStableRequest<ESGScore[]>('/esg-ratings', { symbol });2429}24302431// ESG Benchmark API2432export async function getESGBenchmark(year?: number): Promise<Array<any>> {2433  const params: Record<string, any> = {};2434  if (year) params.year = year;2435  return fmpStableRequest('/esg-benchmark', params);2436}24372438// ==========================================2439// COT (Commitment of Traders) APIs2440// ==========================================24412442// COT List API2443export async function getCOTList(): Promise<Array<{ tradingSymbol: string; name: string }>> {2444  return fmpStableRequest('/commitment-of-traders-list');2445}24462447// ==========================================2448// CROWDFUNDING & EQUITY OFFERINGS APIs2449// ==========================================24502451// Latest Crowdfunding Campaigns API2452export async function getLatestCrowdfundingCampaigns(page: number = 0, limit: number = 100): Promise<Array<any>> {2453  return fmpStableRequest('/crowdfunding-offerings-latest', { page, limit });2454}24552456// Search Crowdfunding Campaigns API2457export async function searchCrowdfundingCampaigns(name: string): Promise<Array<any>> {2458  return fmpStableRequest('/crowdfunding-offerings-search', { name });2459}24602461// Crowdfunding By CIK API2462export async function getCrowdfundingByCIK(cik: string): Promise<Array<any>> {2463  return fmpStableRequest('/crowdfunding-offerings', { cik });2464}24652466// Equity Offering Updates API2467export async function getEquityOfferingUpdates(page: number = 0, limit: number = 10): Promise<Array<any>> {2468  return fmpStableRequest('/fundraising-latest', { page, limit });2469}24702471// Search Equity Offerings API2472export async function searchEquityOfferings(name: string): Promise<Array<any>> {2473  return fmpStableRequest('/fundraising-search', { name });2474}24752476// Company Equity Offerings By CIK API2477export async function getCompanyEquityOfferingsByCIK(cik: string): Promise<Array<any>> {2478  return fmpStableRequest('/fundraising', { cik });2479}24802481// ==========================================2482// BULK APIs2483// ==========================================24842485// Profile Bulk API2486export async function getProfileBulk(part: number = 0): Promise<CompanyProfile[]> {2487  return fmpStableRequest<CompanyProfile[]>('/profile-bulk', { part });2488}24892490// Rating Bulk API2491export async function getRatingBulk(): Promise<Array<{ symbol: string; date: string; rating: string; ratingScore: number; ratingRecommendation: string }>> {2492  return fmpStableRequest('/rating-bulk');2493}24942495// DCF Bulk API2496export async function getDCFBulk(): Promise<Array<{ symbol: string; date: string; dcf: number; stockPrice: number }>> {2497  return fmpStableRequest('/dcf-bulk');2498}24992500// Scores Bulk API2501export async function getScoresBulk(): Promise<Array<any>> {2502  return fmpStableRequest('/scores-bulk');2503}25042505// Price Target Summary Bulk API2506export async function getPriceTargetSummaryBulk(): Promise<PriceTargetSummary[]> {2507  return fmpStableRequest<PriceTargetSummary[]>('/price-target-summary-bulk');2508}25092510// ETF Holder Bulk API2511export async function getETFHolderBulk(part: number = 1): Promise<Array<any>> {2512  return fmpStableRequest('/etf-holder-bulk', { part });2513}25142515// Upgrades Downgrades Consensus Bulk API2516export async function getUpgradesDowngradesConsensusBulk(): Promise<Array<any>> {2517  return fmpStableRequest('/upgrades-downgrades-consensus-bulk');2518}25192520// Key Metrics TTM Bulk API2521export async function getKeyMetricsTTMBulk(): Promise<KeyMetrics[]> {2522  return fmpStableRequest<KeyMetrics[]>('/key-metrics-ttm-bulk');2523}25242525// Ratios TTM Bulk API2526export async function getRatiosTTMBulk(): Promise<FinancialRatios[]> {2527  return fmpStableRequest<FinancialRatios[]>('/ratios-ttm-bulk');2528}25292530// Stock Peers Bulk API2531export async function getStockPeersBulk(): Promise<Array<{ symbol: string; peersList: string[] }>> {2532  return fmpStableRequest('/peers-bulk');2533}25342535// Earnings Surprises Bulk API2536export async function getEarningsSurprisesBulk(year: number): Promise<Array<any>> {2537  return fmpStableRequest('/earnings-surprises-bulk', { year });2538}25392540// Bulk Income Statement API2541export async function getBulkIncomeStatement(year: number, period: 'Q1' | 'Q2' | 'Q3' | 'Q4' | 'FY'): Promise<IncomeStatement[]> {2542  return fmpStableRequest<IncomeStatement[]>('/income-statement-bulk', { year, period });2543}25442545// Bulk Income Statement Growth API2546export async function getBulkIncomeStatementGrowth(year: number, period: 'Q1' | 'Q2' | 'Q3' | 'Q4' | 'FY'): Promise<Array<any>> {2547  return fmpStableRequest('/income-statement-growth-bulk', { year, period });2548}25492550// Bulk Balance Sheet API2551export async function getBulkBalanceSheet(year: number, period: 'Q1' | 'Q2' | 'Q3' | 'Q4' | 'FY'): Promise<BalanceSheet[]> {2552  return fmpStableRequest<BalanceSheet[]>('/balance-sheet-statement-bulk', { year, period });2553}25542555// Bulk Balance Sheet Growth API2556export async function getBulkBalanceSheetGrowth(year: number, period: 'Q1' | 'Q2' | 'Q3' | 'Q4' | 'FY'): Promise<Array<any>> {2557  return fmpStableRequest('/balance-sheet-statement-growth-bulk', { year, period });2558}25592560// Bulk Cash Flow Statement API2561export async function getBulkCashFlowStatement(year: number, period: 'Q1' | 'Q2' | 'Q3' | 'Q4' | 'FY'): Promise<CashFlowStatement[]> {2562  return fmpStableRequest<CashFlowStatement[]>('/cash-flow-statement-bulk', { year, period });2563}25642565// Bulk Cash Flow Statement Growth API2566export async function getBulkCashFlowStatementGrowth(year: number, period: 'Q1' | 'Q2' | 'Q3' | 'Q4' | 'FY'): Promise<Array<any>> {2567  return fmpStableRequest('/cash-flow-statement-growth-bulk', { year, period });2568}25692570// EOD Bulk API2571export async function getEODBulk(date: string): Promise<Array<{ symbol: string; date: string; open: number; high: number; low: number; close: number; adjClose: number; volume: number }>> {2572  return fmpStableRequest('/eod-bulk', { date });2573}2574