Skip to main content

fmp_rust_sdk/endpoints/
methods.rs

1//! Stable endpoint methods grouped behind the public query options.
2
3use super::*;
4
5symbol_endpoint!(
6    profile,
7    "profile",
8    Profile,
9    "Company information from Stable `profile`."
10);
11symbol_endpoint!(
12    stock_peers,
13    "stock-peers",
14    Peer,
15    "Comparable companies from Stable `stock-peers`."
16);
17symbol_endpoint!(
18    quote,
19    "quote",
20    Quote,
21    "A full quote from Stable `quote` for any supported stock, ETF, index, crypto, forex, or commodity symbol."
22);
23symbol_endpoint!(
24    quote_short,
25    "quote-short",
26    ShortQuote,
27    "A compact quote from Stable `quote-short`."
28);
29symbol_endpoint!(
30    aftermarket_trade,
31    "aftermarket-trade",
32    AftermarketTrade,
33    "The latest after-hours trade from Stable `aftermarket-trade`."
34);
35symbol_endpoint!(
36    aftermarket_quote,
37    "aftermarket-quote",
38    AftermarketQuote,
39    "After-hours bid and ask data from Stable `aftermarket-quote`."
40);
41symbol_endpoint!(
42    stock_price_change,
43    "stock-price-change",
44    PriceChange,
45    "Changes across multiple time horizons from Stable `stock-price-change`."
46);
47symbol_endpoint!(
48    market_capitalization,
49    "market-capitalization",
50    MarketCapitalization,
51    "Current market capitalization from Stable `market-capitalization`."
52);
53symbol_endpoint!(
54    shares_float,
55    "shares-float",
56    ShareFloat,
57    "Available share float from Stable `shares-float`."
58);
59symbol_endpoint!(
60    income_statement_ttm,
61    "income-statement-ttm",
62    IncomeStatement,
63    "Trailing twelve-month income statements from Stable `income-statement-ttm`."
64);
65symbol_endpoint!(
66    balance_sheet_statement_ttm,
67    "balance-sheet-statement-ttm",
68    BalanceSheetStatement,
69    "Trailing twelve-month balance sheets from Stable `balance-sheet-statement-ttm`."
70);
71symbol_endpoint!(
72    cash_flow_statement_ttm,
73    "cash-flow-statement-ttm",
74    CashFlowStatement,
75    "Trailing twelve-month cash flow statements from Stable `cash-flow-statement-ttm`."
76);
77symbol_endpoint!(
78    key_metrics_ttm,
79    "key-metrics-ttm",
80    KeyMetricsTtm,
81    "Trailing twelve-month metrics from Stable `key-metrics-ttm`."
82);
83symbol_endpoint!(
84    ratios_ttm,
85    "ratios-ttm",
86    FinancialRatiosTtm,
87    "Trailing twelve-month ratios from Stable `ratios-ttm`."
88);
89symbol_endpoint!(
90    earnings,
91    "earnings",
92    Earnings,
93    "Company earnings history and scheduled reports from Stable `earnings`."
94);
95symbol_endpoint!(
96    dividends,
97    "dividends",
98    Dividend,
99    "Company dividend events from Stable `dividends`."
100);
101symbol_endpoint!(
102    splits,
103    "splits",
104    StockSplit,
105    "Company split events from Stable `splits`."
106);
107symbol_endpoint!(
108    price_target_consensus,
109    "price-target-consensus",
110    PriceTargetConsensus,
111    "Consensus analyst price targets from Stable `price-target-consensus`."
112);
113symbol_endpoint!(
114    ratings_snapshot,
115    "ratings-snapshot",
116    RatingSnapshot,
117    "Fundamental ratings from Stable `ratings-snapshot`."
118);
119symbol_endpoint!(
120    discounted_cash_flow,
121    "discounted-cash-flow",
122    DiscountedCashFlow,
123    "Company DCF valuation from Stable `discounted-cash-flow`."
124);
125symbol_endpoint!(
126    levered_discounted_cash_flow,
127    "levered-discounted-cash-flow",
128    DiscountedCashFlow,
129    "Levered company DCF valuation from Stable `levered-discounted-cash-flow`."
130);
131symbol_endpoint!(
132    etf_holdings,
133    "etf/holdings",
134    EtfHolding,
135    "Underlying securities and weights from Stable `etf/holdings`."
136);
137
138batch_endpoint!(
139    batch_quote,
140    "batch-quote",
141    Quote,
142    "Full quotes for multiple symbols from Stable `batch-quote`."
143);
144batch_endpoint!(
145    batch_quote_short,
146    "batch-quote-short",
147    ShortQuote,
148    "Compact quotes for multiple symbols from Stable `batch-quote-short`."
149);
150batch_endpoint!(
151    batch_aftermarket_trade,
152    "batch-aftermarket-trade",
153    AftermarketTrade,
154    "After-hours trades for multiple symbols from Stable `batch-aftermarket-trade`."
155);
156batch_endpoint!(
157    batch_aftermarket_quote,
158    "batch-aftermarket-quote",
159    AftermarketQuote,
160    "After-hours quotes for multiple symbols from Stable `batch-aftermarket-quote`."
161);
162batch_endpoint!(
163    batch_market_capitalization,
164    "market-capitalization-batch",
165    MarketCapitalization,
166    "Market capitalizations for multiple symbols from Stable `market-capitalization-batch`."
167);
168
169directory_endpoint!(
170    stock_list,
171    "stock-list",
172    DirectorySymbol,
173    "Company symbols from Stable `stock-list`."
174);
175directory_endpoint!(
176    etf_list,
177    "etf-list",
178    DirectorySymbol,
179    "ETF symbols from Stable `etf-list`."
180);
181directory_endpoint!(
182    actively_trading_list,
183    "actively-trading-list",
184    DirectorySymbol,
185    "Actively traded symbols from Stable `actively-trading-list`."
186);
187directory_endpoint!(
188    biggest_gainers,
189    "biggest-gainers",
190    MarketMover,
191    "Top gaining stocks from Stable `biggest-gainers`."
192);
193directory_endpoint!(
194    biggest_losers,
195    "biggest-losers",
196    MarketMover,
197    "Top losing stocks from Stable `biggest-losers`."
198);
199directory_endpoint!(
200    most_actives,
201    "most-actives",
202    MarketMover,
203    "Most active stocks from Stable `most-actives`."
204);
205directory_endpoint!(
206    etf_quotes,
207    "batch-etf-quotes",
208    Quote,
209    "ETF quotes from Stable `batch-etf-quotes`."
210);
211directory_endpoint!(
212    crypto_quotes,
213    "batch-crypto-quotes",
214    Quote,
215    "Cryptocurrency quotes from Stable `batch-crypto-quotes`."
216);
217directory_endpoint!(
218    forex_quotes,
219    "batch-forex-quotes",
220    Quote,
221    "Forex quotes from Stable `batch-forex-quotes`."
222);
223directory_endpoint!(
224    commodity_quotes,
225    "batch-commodity-quotes",
226    Quote,
227    "Commodity quotes from Stable `batch-commodity-quotes`."
228);
229directory_endpoint!(
230    index_quotes,
231    "batch-index-quotes",
232    Quote,
233    "Index quotes from Stable `batch-index-quotes`."
234);
235
236statement_endpoint!(
237    income_statement,
238    "income-statement",
239    IncomeStatement,
240    "Historical income statements from Stable `income-statement`."
241);
242statement_endpoint!(
243    balance_sheet_statement,
244    "balance-sheet-statement",
245    BalanceSheetStatement,
246    "Historical balance sheets from Stable `balance-sheet-statement`."
247);
248statement_endpoint!(
249    cash_flow_statement,
250    "cash-flow-statement",
251    CashFlowStatement,
252    "Historical cash flow statements from Stable `cash-flow-statement`."
253);
254statement_endpoint!(
255    key_metrics,
256    "key-metrics",
257    KeyMetrics,
258    "Historical key metrics from Stable `key-metrics`."
259);
260statement_endpoint!(
261    ratios,
262    "ratios",
263    FinancialRatios,
264    "Historical financial ratios from Stable `ratios`."
265);
266statement_endpoint!(
267    financial_growth,
268    "financial-growth",
269    FinancialGrowth,
270    "Growth rates from Stable `financial-growth`."
271);
272
273impl Client {
274    /// Find symbols through Stable `search-symbol`.
275    pub async fn search_symbol(
276        &self,
277        query: &str,
278        options: SearchOptions<'_>,
279    ) -> Result<Vec<SearchResult>> {
280        required_value("query", query)?;
281        if let Some(limit) = options.limit {
282            positive_limit(limit)?;
283        }
284        self.get(
285            "search-symbol",
286            &SearchQuery {
287                query,
288                options: &options,
289            },
290        )
291        .await
292    }
293
294    /// Find company names through Stable `search-name`.
295    pub async fn search_name(
296        &self,
297        query: &str,
298        options: SearchOptions<'_>,
299    ) -> Result<Vec<SearchResult>> {
300        required_value("query", query)?;
301        if let Some(limit) = options.limit {
302            positive_limit(limit)?;
303        }
304        self.get(
305            "search-name",
306            &SearchQuery {
307                query,
308                options: &options,
309            },
310        )
311        .await
312    }
313
314    /// Get company profiles through Stable `profile-cik`.
315    pub async fn profile_by_cik(&self, cik: &str) -> Result<Vec<Profile>> {
316        required_value("cik", cik)?;
317        self.get("profile-cik", &[("cik", cik)]).await
318    }
319
320    /// Get all quotes for an exchange through Stable `batch-exchange-quote`.
321    pub async fn exchange_quotes(&self, exchange: &str) -> Result<Vec<Quote>> {
322        required_value("exchange", exchange)?;
323        self.get("batch-exchange-quote", &[("exchange", exchange)])
324            .await
325    }
326
327    /// Daily split-adjusted OHLCV bars from Stable `historical-price-eod/full`.
328    pub async fn historical_prices(
329        &self,
330        symbol: &str,
331        dates: DateRange,
332    ) -> Result<Vec<HistoricalPrice>> {
333        required_value("symbol", symbol)?;
334        valid_dates(dates)?;
335        self.get(
336            "historical-price-eod/full",
337            &HistoricalQuery { symbol, dates },
338        )
339        .await
340    }
341
342    /// Daily closes from Stable `historical-price-eod/light`.
343    pub async fn historical_prices_light(
344        &self,
345        symbol: &str,
346        dates: DateRange,
347    ) -> Result<Vec<HistoricalPriceLight>> {
348        required_value("symbol", symbol)?;
349        valid_dates(dates)?;
350        self.get(
351            "historical-price-eod/light",
352            &HistoricalQuery { symbol, dates },
353        )
354        .await
355    }
356
357    /// Intraday OHLCV bars at the chosen documented Stable chart interval.
358    pub async fn intraday_prices(
359        &self,
360        symbol: &str,
361        interval: IntradayInterval,
362        dates: DateRange,
363    ) -> Result<Vec<IntradayPrice>> {
364        required_value("symbol", symbol)?;
365        valid_dates(dates)?;
366        self.get(interval.path(), &HistoricalQuery { symbol, dates })
367            .await
368    }
369
370    /// Market cap history through Stable `historical-market-capitalization`.
371    pub async fn historical_market_capitalization(
372        &self,
373        symbol: &str,
374        dates: DateRange,
375        limit: u32,
376    ) -> Result<Vec<MarketCapitalization>> {
377        required_value("symbol", symbol)?;
378        valid_dates(dates)?;
379        positive_limit(limit)?;
380        self.get(
381            "historical-market-capitalization",
382            &HistoricalMarketCapQuery {
383                symbol,
384                dates,
385                limit,
386            },
387        )
388        .await
389    }
390
391    /// Analyst projections through Stable `analyst-estimates`.
392    pub async fn analyst_estimates(
393        &self,
394        symbol: &str,
395        period: EstimatePeriod,
396        pagination: Pagination,
397    ) -> Result<Vec<AnalystEstimate>> {
398        required_value("symbol", symbol)?;
399        positive_limit(pagination.limit)?;
400        self.get(
401            "analyst-estimates",
402            &AnalystQuery {
403                symbol,
404                period,
405                pagination,
406            },
407        )
408        .await
409    }
410
411    /// Full earnings call content through Stable `earning-call-transcript`.
412    pub async fn earnings_transcript(
413        &self,
414        symbol: &str,
415        year: u16,
416        quarter: u8,
417    ) -> Result<Vec<EarningsTranscript>> {
418        required_value("symbol", symbol)?;
419        if year == 0 || !(1..=4).contains(&quarter) {
420            return Err(Error::Configuration {
421                reason: format!(
422                    "earnings transcript requires a positive year and quarter 1..=4, received year={year}, quarter={quarter}"
423                ),
424            });
425        }
426        self.get(
427            "earning-call-transcript",
428            &TranscriptQuery {
429                symbol,
430                year,
431                quarter,
432            },
433        )
434        .await
435    }
436
437    /// Earnings calendar through Stable `earnings-calendar`.
438    pub async fn earnings_calendar(&self, dates: DateRange) -> Result<Vec<Earnings>> {
439        valid_dates(dates)?;
440        self.get("earnings-calendar", &dates).await
441    }
442
443    /// Dividend calendar through Stable `dividends-calendar`.
444    pub async fn dividends_calendar(&self, dates: DateRange) -> Result<Vec<Dividend>> {
445        valid_dates(dates)?;
446        self.get("dividends-calendar", &dates).await
447    }
448
449    /// Split calendar through Stable `splits-calendar`.
450    pub async fn splits_calendar(&self, dates: DateRange) -> Result<Vec<StockSplit>> {
451        valid_dates(dates)?;
452        self.get("splits-calendar", &dates).await
453    }
454
455    /// Latest company news through Stable `news/stock-latest`.
456    pub async fn latest_stock_news(&self, options: NewsOptions) -> Result<Vec<NewsArticle>> {
457        valid_dates(options.dates)?;
458        positive_limit(options.pagination.limit)?;
459        self.get("news/stock-latest", &options).await
460    }
461
462    /// General news through Stable `news/general-latest`.
463    pub async fn general_news(&self, options: NewsOptions) -> Result<Vec<NewsArticle>> {
464        valid_dates(options.dates)?;
465        positive_limit(options.pagination.limit)?;
466        self.get("news/general-latest", &options).await
467    }
468
469    /// Latest press releases through Stable `news/press-releases-latest`.
470    pub async fn latest_press_releases(&self, options: NewsOptions) -> Result<Vec<NewsArticle>> {
471        valid_dates(options.dates)?;
472        positive_limit(options.pagination.limit)?;
473        self.get("news/press-releases-latest", &options).await
474    }
475
476    /// Company news selected by symbol through Stable `news/stock`.
477    pub async fn stock_news(
478        &self,
479        symbols: &[&str],
480        options: NewsOptions,
481    ) -> Result<Vec<NewsArticle>> {
482        valid_dates(options.dates)?;
483        positive_limit(options.pagination.limit)?;
484        let symbols = joined_symbols(symbols)?;
485        self.get(
486            "news/stock",
487            &NewsQuery {
488                symbols: &symbols,
489                options,
490            },
491        )
492        .await
493    }
494
495    /// Press releases selected by symbol through Stable `news/press-releases`.
496    pub async fn press_releases(
497        &self,
498        symbols: &[&str],
499        options: NewsOptions,
500    ) -> Result<Vec<NewsArticle>> {
501        valid_dates(options.dates)?;
502        positive_limit(options.pagination.limit)?;
503        let symbols = joined_symbols(symbols)?;
504        self.get(
505            "news/press-releases",
506            &NewsQuery {
507                symbols: &symbols,
508                options,
509            },
510        )
511        .await
512    }
513
514    /// Cryptocurrency news through Stable `news/crypto`.
515    pub async fn crypto_news(
516        &self,
517        symbols: &[&str],
518        options: NewsOptions,
519    ) -> Result<Vec<NewsArticle>> {
520        valid_dates(options.dates)?;
521        positive_limit(options.pagination.limit)?;
522        let symbols = joined_symbols(symbols)?;
523        self.get(
524            "news/crypto",
525            &NewsQuery {
526                symbols: &symbols,
527                options,
528            },
529        )
530        .await
531    }
532
533    /// Foreign exchange news through Stable `news/forex`.
534    pub async fn forex_news(
535        &self,
536        symbols: &[&str],
537        options: NewsOptions,
538    ) -> Result<Vec<NewsArticle>> {
539        valid_dates(options.dates)?;
540        positive_limit(options.pagination.limit)?;
541        let symbols = joined_symbols(symbols)?;
542        self.get(
543            "news/forex",
544            &NewsQuery {
545                symbols: &symbols,
546                options,
547            },
548        )
549        .await
550    }
551
552    /// Historical Treasury yields through Stable `treasury-rates`.
553    pub async fn treasury_rates(&self, dates: DateRange) -> Result<Vec<TreasuryRate>> {
554        valid_dates(dates)?;
555        self.get("treasury-rates", &dates).await
556    }
557
558    /// A named economic series through Stable `economic-indicators`.
559    /// Indicator names are supplied explicitly as documented by FMP.
560    pub async fn economic_indicators(
561        &self,
562        name: &str,
563        dates: DateRange,
564    ) -> Result<Vec<EconomicIndicator>> {
565        #[derive(Serialize)]
566        struct Query<'a> {
567            name: &'a str,
568            #[serde(flatten)]
569            dates: DateRange,
570        }
571        required_value("name", name)?;
572        valid_dates(dates)?;
573        self.get("economic-indicators", &Query { name, dates })
574            .await
575    }
576
577    /// Scheduled economic releases through Stable `economic-calendar`.
578    pub async fn economic_calendar(&self, dates: DateRange) -> Result<Vec<EconomicEvent>> {
579        valid_dates(dates)?;
580        self.get("economic-calendar", &dates).await
581    }
582
583    /// Sector performance for a date through Stable `sector-performance-snapshot`.
584    pub async fn sector_performance(
585        &self,
586        date: NaiveDate,
587        exchange: Option<&str>,
588        sector: Option<&str>,
589    ) -> Result<Vec<SectorPerformance>> {
590        self.get(
591            "sector-performance-snapshot",
592            &SectorSnapshotQuery {
593                date,
594                exchange,
595                sector,
596            },
597        )
598        .await
599    }
600
601    /// Industry performance for a date through Stable `industry-performance-snapshot`.
602    pub async fn industry_performance(
603        &self,
604        date: NaiveDate,
605        exchange: Option<&str>,
606        industry: Option<&str>,
607    ) -> Result<Vec<IndustryPerformance>> {
608        self.get(
609            "industry-performance-snapshot",
610            &IndustrySnapshotQuery {
611                date,
612                exchange,
613                industry,
614            },
615        )
616        .await
617    }
618}