finance_query/lib.rs
1//! # finance-query
2//!
3//! A Rust library for querying financial data.
4//! Inspired by yfinance, with smart lazy loading for efficient data fetching.
5//!
6//! ## Quick Start
7//!
8//! ```no_run
9//! use finance_query::Ticker;
10//!
11//! #[tokio::main]
12//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
13//! // Simple: Create a ticker with default configuration
14//! let ticker = Ticker::new("AAPL").await?;
15//!
16//! // First access to any quote property fetches ALL quote modules in one request
17//! if let Some(financials) = ticker.financial_data().await? {
18//! println!("Financial data: {:?}", financials);
19//! }
20//!
21//! // Subsequent accesses use cached data (no additional network calls)
22//! if let Some(profile) = ticker.asset_profile().await? {
23//! println!("Company profile: {:?}", profile);
24//! }
25//!
26//! // Chart data is fetched separately and cached by interval/range
27//! let chart = ticker.chart(
28//! finance_query::Interval::OneDay,
29//! finance_query::TimeRange::OneMonth
30//! ).await?;
31//! println!("Candles: {}", chart.candles.len());
32//!
33//! // Builder pattern: Fluent configuration
34//! let ticker_jp = Ticker::builder("7203.T")
35//! .lang("ja-JP")
36//! .region_code("JP")
37//! .timeout(std::time::Duration::from_secs(30))
38//! .build()
39//! .await?;
40//!
41//! Ok(())
42//! }
43//! ```
44//!
45//! ## Lazy Loading
46//!
47//! The library uses lazy loading:
48//! - **Quote data**: All ~30 quote modules fetched together on first property access
49//! - **Chart data**: Fetched per (interval, range) combination and cached
50//! - **Recommendations**: Fetched once and cached
51//!
52//! This approach minimizes network requests while keeping memory usage efficient.
53
54#![warn(missing_docs)]
55#![warn(rustdoc::missing_crate_level_docs)]
56
57// === Modules ===
58// Public modules
59/// External data source adapters (internal — use the public API modules).
60pub(crate) mod adapters;
61/// Error types and result definitions.
62pub mod error;
63/// Non-symbol-specific operations (search, lookup, screeners, market data, etc.).
64pub mod finance;
65pub mod edgar {
66 //! SEC EDGAR API client (keyless — always available, no feature flag needed).
67 //!
68 //!
69 //! Requires a one-time [`init`] call with a contact email address.
70 pub use crate::adapters::edgar::{
71 company_facts, filing_index, init, init_with_config, resolve_cik, search, submissions,
72 };
73}
74
75// Internal modules
76mod constants;
77mod models;
78mod providers;
79pub(crate) mod rate_limiter;
80mod scrapers;
81mod ticker;
82mod tickers;
83mod utils;
84
85// Feature-gated external data source modules
86#[cfg(feature = "fred")]
87pub mod fred {
88 //! FRED economic data API (requires `fred` feature).
89 //!
90 //! Access 800k+ macroeconomic time series and US Treasury yield curve data.
91 pub use crate::adapters::fred::{init, init_with_timeout, series, treasury_yields};
92 pub use crate::models::economic::{MacroObservation, MacroSeries, TreasuryYield};
93}
94
95#[cfg(feature = "crypto")]
96pub mod crypto {
97 //! CoinGecko cryptocurrency data (requires `crypto` feature).
98 pub use crate::adapters::coingecko::{CoinQuote, coin, coins};
99}
100
101pub mod feeds;
102
103#[cfg(feature = "risk")]
104pub mod risk;
105
106#[cfg(feature = "translation")]
107pub mod translation;
108
109// ============================================================================
110// High-level API - Primary interface for most use cases
111// ============================================================================
112pub mod domains;
113pub use providers::config::{Providers, ProvidersBuilder};
114pub use providers::{Capability, Fetch, Operation, Provider};
115pub use ticker::{ClientHandle, Ticker, TickerBuilder};
116
117// Domain-specific query handles — constructable via Providers factory methods.
118#[cfg(any(
119 feature = "alphavantage",
120 feature = "crypto",
121 feature = "fmp",
122 feature = "polygon"
123))]
124pub use domains::CryptoCoin;
125#[cfg(any(feature = "alphavantage", feature = "polygon", feature = "fred"))]
126pub use domains::EconomicIndicator;
127#[cfg(any(feature = "alphavantage", feature = "fmp", feature = "polygon"))]
128pub use domains::ForexPair;
129
130// Remaining Capability handles — indices, futures, commodities, filings
131#[cfg(any(feature = "fmp", feature = "alphavantage"))]
132pub use domains::Commodity;
133pub use domains::Filings;
134#[cfg(feature = "polygon")]
135pub use domains::FuturesContract;
136#[cfg(any(feature = "polygon", feature = "fmp"))]
137pub use domains::Index;
138
139// Provider-specific financial data functions
140// (FMP, Polygon, Alpha Vantage — defined in the finance module)
141#[cfg(feature = "polygon")]
142pub use finance::symbol_sentiment;
143#[cfg(feature = "fmp")]
144pub use finance::{
145 AnalystEstimate, AnalystRecommendation, InsiderTransaction, Period, analyst_estimates,
146 analyst_recommendations, insider_trading,
147};
148#[cfg(feature = "alphavantage")]
149pub use finance::{EarningsCalendarEntry, IpoCalendarEntry, earnings_calendar, ipo_calendar};
150
151pub use tickers::{
152 BatchCapitalGainsResponse, BatchChartsResponse, BatchDividendsResponse,
153 BatchFinancialsResponse, BatchNewsResponse, BatchOptionsResponse, BatchQuotesResponse,
154 BatchRecommendationsResponse, BatchSparksResponse, BatchSplitsResponse, Tickers,
155 TickersBuilder,
156};
157
158#[cfg(feature = "indicators")]
159pub use tickers::BatchIndicatorsResponse;
160
161// ============================================================================
162// Error types and results
163// ============================================================================
164pub use error::{ErrorCategory, FinanceError, Result};
165
166// ============================================================================
167// Options - Configure API requests
168// ============================================================================
169pub use finance::{LookupOptions, LookupType, SearchOptions};
170
171// ============================================================================
172// Parameter enums - Used with Ticker and finance methods
173// ============================================================================
174pub use constants::indices::Region as IndicesRegion;
175pub use constants::screeners::Screener;
176pub use constants::sectors::Sector;
177pub use constants::{Frequency, Interval, Region, StatementType, TimeRange, ValueFormat};
178
179// ============================================================================
180// Response types - Top-level types returned by API methods
181// ============================================================================
182pub use models::{
183 calendar::{CalendarEvent, EventKind},
184 chart::Chart,
185 chart::spark::Spark,
186 corporate::news::News,
187 corporate::recommendation::Recommendation,
188 corporate::transcript::{Transcript, TranscriptWithMeta},
189 discovery::lookup::LookupResults,
190 discovery::screeners::ScreenerResults,
191 discovery::search::SearchResults,
192 discovery::trending::TrendingQuote,
193 filings::{
194 CompanyFacts, EdgarSearchResults, EdgarSubmissions, ProviderFiling, ProviderFilings,
195 },
196 fundamentals::FinancialStatement,
197 market::currencies::Currency,
198 market::exchanges::Exchange,
199 market::hours::MarketHours,
200 market::industries::IndustryData,
201 market::market_summary::MarketSummaryQuote,
202 market::sectors::SectorData,
203 options::Options,
204 quote::Quote,
205 sentiment::{FearAndGreed, FearGreedLabel, SymbolSentiment},
206};
207// Offline VADER sentiment scoring (feature-gated)
208#[cfg(feature = "sentiment")]
209pub use models::sentiment::{Sentiment, SentimentLabel, analyze as analyze_sentiment};
210// Multi-provider capability response types (feature-gated)
211#[cfg(any(feature = "fmp", feature = "alphavantage"))]
212pub use models::commodities::CommodityQuote;
213#[cfg(any(
214 feature = "crypto",
215 feature = "alphavantage",
216 feature = "fmp",
217 feature = "polygon"
218))]
219pub use models::crypto::CryptoQuote;
220#[cfg(any(feature = "fred", feature = "alphavantage", feature = "polygon"))]
221pub use models::economic::EconomicSeries;
222#[cfg(any(feature = "alphavantage", feature = "fmp", feature = "polygon"))]
223pub use models::forex::ForexQuote;
224#[cfg(feature = "polygon")]
225pub use models::futures::FuturesQuote;
226#[cfg(any(feature = "polygon", feature = "fmp"))]
227pub use models::indices::IndexQuote;
228
229// ============================================================================
230// Nested types - Commonly accessed fields within response types
231// ============================================================================
232pub use models::{
233 chart::{Candle, CapitalGain, ChartMeta, Dividend, DividendAnalytics, Split},
234 corporate::recommendation::SimilarSymbol,
235 discovery::lookup::LookupQuote,
236 discovery::screeners::ScreenerQuote,
237 discovery::search::{
238 ResearchReport, ResearchReports, SearchNews, SearchNewsList, SearchQuote, SearchQuotes,
239 },
240 filings::filing_index::{EdgarFilingIndex, EdgarFilingIndexItem},
241 filings::{
242 CikEntry, EdgarFiling, EdgarFilingFile, EdgarFilingRecent, EdgarFilings, EdgarSearchHit,
243 EdgarSearchHitsContainer, EdgarSearchSource, EdgarSearchTotal, FactConcept, FactUnit,
244 FactsByTaxonomy,
245 },
246 market::hours::MarketTime,
247 market::market_summary::SparkData,
248 options::{Contracts, OptionChain, OptionContract, OptionsQuote},
249 quote::FormattedValue,
250};
251
252// ============================================================================
253// Query builders - Types for constructing custom screener queries
254// ============================================================================
255pub use constants::exchange_codes::ExchangeCode;
256pub use constants::industries::Industry;
257pub use models::discovery::screeners::{
258 ConditionValue, EquityField, EquityScreenerQuery, FundField, FundScreenerQuery,
259 LogicalOperator, Operator, QueryCondition, QueryGroup, QueryOperand, QuoteType, ScreenerField,
260 ScreenerFieldExt, ScreenerFundCategory, ScreenerPeerGroup, ScreenerQuery, SortType,
261};
262
263// ============================================================================
264// Real-time streaming
265// ============================================================================
266// WebSocket-based real-time price streaming with a Flow-like Stream API.
267pub mod streaming;
268
269// ============================================================================
270// Format type parameters — phantom types for compile-time format selection
271// ============================================================================
272
273/// Compile-time format type parameters for [`Quote`](crate::Quote) and other
274/// `FormattedValue`-bearing structs.
275///
276/// | Marker | `F::Value<f64>` | Access pattern |
277/// |---|---|---|
278/// | [`format::Both`] | `FormattedValue<f64>` | `.raw` / `.fmt` / `.long_fmt` |
279/// | [`format::Raw`] | `f64` | direct (no unwrapping) |
280/// | [`format::Pretty`] | `String` | human-readable string |
281///
282/// ```no_run
283/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
284/// use finance_query::{format, Ticker};
285/// let ticker = Ticker::new("AAPL").await?;
286/// let quote: finance_query::Quote<format::Raw> = ticker.quote().await?;
287/// # Ok(())
288/// # }
289/// ```
290pub mod format {
291 pub use crate::models::format::{Both, Pretty, Raw};
292}
293
294// ============================================================================
295// DataFrame support (requires "dataframe" feature)
296// ============================================================================
297// When enabled, structs with #[derive(ToDataFrame)] get a to_dataframe() method.
298// The derive macro auto-generates DataFrame conversion for all scalar fields.
299#[cfg(feature = "dataframe")]
300pub use finance_query_derive::ToDataFrame;
301
302// ============================================================================
303// Technical Indicators (requires "indicators" feature)
304// ============================================================================
305// Technical analysis indicators for price data (SMA, EMA, RSI, MACD, Bollinger Bands).
306// When enabled, Chart gets extension methods: chart.sma(), chart.ema(), chart.rsi(), etc.
307#[cfg(feature = "indicators")]
308pub mod indicators;
309
310#[cfg(feature = "indicators")]
311pub use indicators::{
312 // Summary types
313 AroonData,
314 // Individual indicator types
315 BollingerBands,
316 BollingerBandsData,
317 BullBearPowerData,
318 // Candlestick pattern types
319 CandlePattern,
320 DonchianChannelsData,
321 ElderRayData,
322 IchimokuData,
323 Indicator,
324 IndicatorError,
325 IndicatorResult,
326 IndicatorsSummary,
327 KeltnerChannelsData,
328 MacdData,
329 MacdResult,
330 PatternSentiment,
331 StochasticData,
332 SuperTrendData,
333 atr,
334 patterns,
335};
336
337// ============================================================================
338// Backtesting Engine (requires "backtesting" feature)
339// ============================================================================
340// Strategy backtesting with pre-built and custom strategies, position tracking,
341// stop-loss/take-profit, comprehensive performance metrics, parameter optimization,
342// walk-forward validation, Monte Carlo simulation, and multi-symbol portfolio.
343#[cfg(feature = "backtesting")]
344pub mod backtesting;
345
346// ============================================================================
347// Compile-time thread-safety assertions
348// ============================================================================
349// Ticker and Tickers must be Send + Sync so they can be shared across
350// async tasks and held across .await points (e.g., in Arc, tokio::spawn).
351const _: () = {
352 const fn assert_send_sync<T: Send + Sync>() {}
353 let _ = assert_send_sync::<Ticker>;
354 let _ = assert_send_sync::<Tickers>;
355};