aiofmp 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. aiofmp/__init__.py +186 -0
  2. aiofmp/analyst.py +317 -0
  3. aiofmp/analyst_tools.py +615 -0
  4. aiofmp/base.py +244 -0
  5. aiofmp/calendar.py +260 -0
  6. aiofmp/calendar_tools.py +471 -0
  7. aiofmp/chart.py +349 -0
  8. aiofmp/chart_tools.py +601 -0
  9. aiofmp/cli.py +116 -0
  10. aiofmp/commodity.py +216 -0
  11. aiofmp/commodity_tools.py +416 -0
  12. aiofmp/company.py +352 -0
  13. aiofmp/company_tools.py +734 -0
  14. aiofmp/cot.py +96 -0
  15. aiofmp/cot_tools.py +155 -0
  16. aiofmp/crypto.py +235 -0
  17. aiofmp/crypto_tools.py +456 -0
  18. aiofmp/dcf.py +265 -0
  19. aiofmp/dcf_tools.py +308 -0
  20. aiofmp/directory.py +159 -0
  21. aiofmp/directory_tools.py +359 -0
  22. aiofmp/economics.py +131 -0
  23. aiofmp/economics_tools.py +212 -0
  24. aiofmp/etf.py +139 -0
  25. aiofmp/etf_tools.py +280 -0
  26. aiofmp/fmp_client.py +30 -0
  27. aiofmp/forex.py +235 -0
  28. aiofmp/forex_tools.py +454 -0
  29. aiofmp/form13f.py +234 -0
  30. aiofmp/form13f_tools.py +462 -0
  31. aiofmp/indexes.py +239 -0
  32. aiofmp/indexes_tools.py +454 -0
  33. aiofmp/insider_trades.py +184 -0
  34. aiofmp/insider_trades_tools.py +332 -0
  35. aiofmp/market_performance.py +335 -0
  36. aiofmp/market_performance_tools.py +581 -0
  37. aiofmp/mcp_server.py +117 -0
  38. aiofmp/mcp_tools.py +295 -0
  39. aiofmp/news.py +392 -0
  40. aiofmp/news_tools.py +622 -0
  41. aiofmp/quote.py +97 -0
  42. aiofmp/quote_tools.py +192 -0
  43. aiofmp/search.py +184 -0
  44. aiofmp/search_tools.py +222 -0
  45. aiofmp/senate.py +149 -0
  46. aiofmp/senate_tools.py +300 -0
  47. aiofmp/statements.py +407 -0
  48. aiofmp/statements_tools.py +707 -0
  49. aiofmp/technical_indicators.py +380 -0
  50. aiofmp/technical_indicators_tools.py +691 -0
  51. aiofmp-1.0.0.dist-info/METADATA +611 -0
  52. aiofmp-1.0.0.dist-info/RECORD +55 -0
  53. aiofmp-1.0.0.dist-info/WHEEL +4 -0
  54. aiofmp-1.0.0.dist-info/entry_points.txt +2 -0
  55. aiofmp-1.0.0.dist-info/licenses/LICENSE +201 -0
aiofmp/__init__.py ADDED
@@ -0,0 +1,186 @@
1
+ """
2
+ Financial Modeling Prep (FMP) API Client
3
+
4
+ This module provides a comprehensive async client for the FMP API with
5
+ category-based organization for better code management.
6
+ """
7
+
8
+ from .analyst import AnalystCategory
9
+ from .base import (
10
+ FMPAuthenticationError,
11
+ FMPBaseClient,
12
+ FMPError,
13
+ FMPRateLimitError,
14
+ FMPResponseError,
15
+ )
16
+ from .calendar import CalendarCategory
17
+ from .chart import ChartCategory
18
+ from .commodity import CommodityCategory
19
+ from .company import CompanyCategory
20
+ from .cot import CommitmentOfTradersCategory
21
+ from .crypto import CryptoCategory
22
+ from .dcf import DiscountedCashFlowCategory
23
+ from .directory import DirectoryCategory
24
+ from .economics import EconomicsCategory
25
+ from .etf import EtfAndMutualFundsCategory
26
+ from .forex import ForexCategory
27
+ from .form13f import Form13FCategory
28
+ from .indexes import IndexesCategory
29
+ from .insider_trades import InsiderTradesCategory
30
+ from .market_performance import MarketPerformanceCategory
31
+ from .news import NewsCategory
32
+ from .quote import QuoteCategory
33
+ from .search import SearchCategory
34
+ from .senate import SenateCategory
35
+ from .statements import StatementsCategory
36
+ from .technical_indicators import TechnicalIndicatorsCategory
37
+
38
+ __all__ = [
39
+ "FmpClient",
40
+ "FMPError",
41
+ "FMPAuthenticationError",
42
+ "FMPRateLimitError",
43
+ "FMPResponseError",
44
+ ]
45
+
46
+
47
+ class FmpClient(FMPBaseClient):
48
+ """
49
+ Main FMP API client with category-based organization
50
+
51
+ This client provides access to all FMP API endpoints organized by category
52
+ for better code management and maintainability.
53
+
54
+ Usage:
55
+ client = FmpClient(api_key="your_api_key")
56
+
57
+ # Search category
58
+ symbols = await client.search.symbols("AAPL", limit=10)
59
+ companies = await client.search.companies("Apple", limit=5)
60
+ screener = await client.search.screener(sector="Technology", limit=100)
61
+
62
+ # Directory category
63
+ all_symbols = await client.directory.company_symbols()
64
+ etfs = await client.directory.etf_list()
65
+ exchanges = await client.directory.available_exchanges()
66
+
67
+ # Analyst category
68
+ estimates = await client.analyst.financial_estimates("AAPL", "annual", limit=10)
69
+ ratings = await client.analyst.ratings_snapshot("AAPL")
70
+ price_targets = await client.analyst.price_target_consensus("AAPL")
71
+
72
+ # Calendar category
73
+ dividends = await client.calendar.dividends_company("AAPL", limit=100)
74
+ earnings = await client.calendar.earnings_company("AAPL", limit=20)
75
+ upcoming_ipos = await client.calendar.ipos_calendar("2025-01-01", "2025-06-30")
76
+
77
+ # Chart category
78
+ price_data = await client.chart.historical_price_full("AAPL", "2025-01-01", "2025-03-31")
79
+ intraday_data = await client.chart.intraday_1hour("AAPL", "2025-01-01", "2025-01-02")
80
+
81
+ # Company category
82
+ profile = await client.company.profile("AAPL")
83
+ executives = await client.company.executives("AAPL")
84
+ market_cap = await client.company.market_cap("AAPL")
85
+
86
+ # Commitment of Traders category
87
+ cot_report = await client.cot.cot_report("KC", "2024-01-01", "2024-03-01")
88
+ cot_analysis = await client.cot.cot_analysis("B6", "2024-01-01", "2024-03-01")
89
+
90
+ # Discounted Cash Flow category
91
+ dcf_valuation = await client.dcf.dcf_valuation("AAPL")
92
+ levered_dcf = await client.dcf.levered_dcf("AAPL")
93
+
94
+ # Economics category
95
+ treasury_rates = await client.economics.treasury_rates("2025-04-24", "2025-07-24")
96
+ gdp_data = await client.economics.economic_indicators("GDP", "2024-07-24", "2025-07-24")
97
+
98
+ # ETF And Mutual Funds category
99
+ etf_holdings = await client.etf.holdings("SPY")
100
+ etf_info = await client.etf.info("SPY")
101
+
102
+ # Commodity category
103
+ commodities = await client.commodity.commodities_list()
104
+ gold_quote = await client.commodity.quote("GCUSD")
105
+
106
+ # Crypto category
107
+ crypto_list = await client.crypto.cryptocurrency_list()
108
+ btc_quote = await client.crypto.quote("BTCUSD")
109
+
110
+ # Forex category
111
+ forex_list = await client.forex.forex_list()
112
+ eur_usd_quote = await client.forex.quote("EURUSD")
113
+
114
+ # Statements category
115
+ income_stmt = await client.statements.income_statement("AAPL", limit=5)
116
+ balance_sheet = await client.statements.balance_sheet_statement("AAPL", limit=5)
117
+
118
+ # Form 13F category
119
+ latest_filings = await client.form13f.latest_filings(page=0, limit=100)
120
+ berkshire_holdings = await client.form13f.filings_extract("0001067983", "2023", "3")
121
+
122
+ # Indexes category
123
+ sp500_quote = await client.indexes.index_quote("^GSPC")
124
+ all_indexes = await client.indexes.index_list()
125
+
126
+ # Insider Trades category
127
+ latest_trades = await client.insider_trades.latest_insider_trades(page=0, limit=100)
128
+ apple_insider_stats = await client.insider_trades.insider_trade_statistics("AAPL")
129
+
130
+ # Market Performance category
131
+ sector_performance = await client.market_performance.sector_performance_snapshot(date.today())
132
+ biggest_gainers = await client.market_performance.biggest_gainers()
133
+
134
+ # News category
135
+ fmp_articles = await client.news.fmp_articles(page=0, limit=20)
136
+ stock_news = await client.news.stock_news(page=0, limit=10)
137
+
138
+ # Technical Indicators category
139
+ sma_data = await client.technical_indicators.simple_moving_average("AAPL", 10, "1day")
140
+ rsi_data = await client.technical_indicators.relative_strength_index("AAPL", 14, "1day")
141
+
142
+ # Quote category
143
+ stock_quote = await client.quote.stock_quote("AAPL")
144
+ price_changes = await client.quote.stock_price_change("AAPL")
145
+
146
+ # Senate category
147
+ senate_disclosures = await client.senate.latest_senate_disclosures(page=0, limit=100)
148
+ house_trades = await client.senate.house_trading_activity("AAPL")
149
+ """
150
+
151
+ def __init__(self, api_key: str, **kwargs):
152
+ """
153
+ Initialize the FMP client
154
+
155
+ Args:
156
+ api_key: FMP API key (required)
157
+ **kwargs: Additional arguments passed to base client
158
+ """
159
+ super().__init__(api_key, **kwargs)
160
+
161
+ # Initialize category modules
162
+ self.search = SearchCategory(self)
163
+ self.directory = DirectoryCategory(self)
164
+ self.analyst = AnalystCategory(self)
165
+ self.calendar = CalendarCategory(self)
166
+ self.chart = ChartCategory(self)
167
+ self.company = CompanyCategory(self)
168
+ self.cot = CommitmentOfTradersCategory(self)
169
+ self.dcf = DiscountedCashFlowCategory(self)
170
+ self.economics = EconomicsCategory(self)
171
+ self.etf = EtfAndMutualFundsCategory(self)
172
+ self.commodity = CommodityCategory(self)
173
+ self.crypto = CryptoCategory(self)
174
+ self.forex = ForexCategory(self)
175
+ self.statements = StatementsCategory(self)
176
+ self.form13f = Form13FCategory(self)
177
+ self.indexes = IndexesCategory(self)
178
+ self.insider_trades = InsiderTradesCategory(self)
179
+ self.market_performance = MarketPerformanceCategory(self)
180
+ self.news = NewsCategory(self)
181
+ self.technical_indicators = TechnicalIndicatorsCategory(self)
182
+ self.quote = QuoteCategory(self)
183
+ self.senate = SenateCategory(self)
184
+
185
+ # Future categories will be added here:
186
+ # self.financial = FinancialCategory(self)
aiofmp/analyst.py ADDED
@@ -0,0 +1,317 @@
1
+ """
2
+ Analyst category for FMP API
3
+
4
+ This module provides analyst functionality including financial estimates, ratings,
5
+ price targets, stock grades, and related news and historical data.
6
+ """
7
+
8
+ from typing import Any
9
+
10
+ from .base import FMPBaseClient
11
+
12
+
13
+ class AnalystCategory:
14
+ """Analyst category for FMP API endpoints"""
15
+
16
+ def __init__(self, client: FMPBaseClient):
17
+ """
18
+ Initialize the analyst category
19
+
20
+ Args:
21
+ client: Base FMP client instance
22
+ """
23
+ self._client = client
24
+
25
+ async def financial_estimates(
26
+ self,
27
+ symbol: str,
28
+ period: str,
29
+ page: int | None = None,
30
+ limit: int | None = None,
31
+ ) -> list[dict[str, Any]]:
32
+ """
33
+ Get analyst financial estimates for a stock symbol
34
+
35
+ Endpoint: /analyst-estimates
36
+
37
+ Args:
38
+ symbol: Stock symbol (required)
39
+ period: Period type - 'annual' or 'quarter' (required)
40
+ page: Page number for pagination (default: 0)
41
+ limit: Number of results per page (default: 10)
42
+
43
+ Returns:
44
+ List of financial estimates with analyst projections
45
+
46
+ Example:
47
+ >>> estimates = await client.analyst.financial_estimates("AAPL", "annual", limit=20)
48
+ >>> # Returns: [{"symbol": "AAPL", "date": "2029-09-28", "revenueAvg": 483093000000, ...}]
49
+ """
50
+ params = {"symbol": symbol, "period": period}
51
+ if page is not None:
52
+ params["page"] = page
53
+ if limit is not None:
54
+ params["limit"] = limit
55
+
56
+ return await self._client._make_request("analyst-estimates", params)
57
+
58
+ async def ratings_snapshot(
59
+ self, symbol: str, limit: int | None = None
60
+ ) -> list[dict[str, Any]]:
61
+ """
62
+ Get current financial ratings snapshot for a stock symbol
63
+
64
+ Endpoint: /ratings-snapshot
65
+
66
+ Args:
67
+ symbol: Stock symbol (required)
68
+ limit: Number of results (default: 1)
69
+
70
+ Returns:
71
+ List of current ratings with financial scores
72
+
73
+ Example:
74
+ >>> ratings = await client.analyst.ratings_snapshot("AAPL")
75
+ >>> # Returns: [{"symbol": "AAPL", "rating": "A-", "overallScore": 4, ...}]
76
+ """
77
+ params = {"symbol": symbol}
78
+ if limit is not None:
79
+ params["limit"] = limit
80
+
81
+ return await self._client._make_request("ratings-snapshot", params)
82
+
83
+ async def historical_ratings(
84
+ self, symbol: str, limit: int | None = None
85
+ ) -> list[dict[str, Any]]:
86
+ """
87
+ Get historical financial ratings for a stock symbol
88
+
89
+ Endpoint: /ratings-historical
90
+
91
+ Args:
92
+ symbol: Stock symbol (required)
93
+ limit: Number of historical ratings (default: 1)
94
+
95
+ Returns:
96
+ List of historical ratings with dates and scores
97
+
98
+ Example:
99
+ >>> historical = await client.analyst.historical_ratings("AAPL", limit=10)
100
+ >>> # Returns: [{"symbol": "AAPL", "date": "2025-02-04", "rating": "A-", ...}]
101
+ """
102
+ params = {"symbol": symbol}
103
+ if limit is not None:
104
+ params["limit"] = limit
105
+
106
+ return await self._client._make_request("ratings-historical", params)
107
+
108
+ async def price_target_summary(self, symbol: str) -> list[dict[str, Any]]:
109
+ """
110
+ Get price target summary from analysts for a stock symbol
111
+
112
+ Endpoint: /price-target-summary
113
+
114
+ Args:
115
+ symbol: Stock symbol (required)
116
+
117
+ Returns:
118
+ List of price target summaries across different timeframes
119
+
120
+ Example:
121
+ >>> summary = await client.analyst.price_target_summary("AAPL")
122
+ >>> # Returns: [{"symbol": "AAPL", "lastMonthAvgPriceTarget": 200.75, ...}]
123
+ """
124
+ params = {"symbol": symbol}
125
+ return await self._client._make_request("price-target-summary", params)
126
+
127
+ async def price_target_consensus(self, symbol: str) -> list[dict[str, Any]]:
128
+ """
129
+ Get price target consensus from analysts for a stock symbol
130
+
131
+ Endpoint: /price-target-consensus
132
+
133
+ Args:
134
+ symbol: Stock symbol (required)
135
+
136
+ Returns:
137
+ List of consensus price targets (high, low, median, consensus)
138
+
139
+ Example:
140
+ >>> consensus = await client.analyst.price_target_consensus("AAPL")
141
+ >>> # Returns: [{"symbol": "AAPL", "targetHigh": 300, "targetConsensus": 251.7, ...}]
142
+ """
143
+ params = {"symbol": symbol}
144
+ return await self._client._make_request("price-target-consensus", params)
145
+
146
+ async def price_target_news(
147
+ self, symbol: str, page: int | None = None, limit: int | None = None
148
+ ) -> list[dict[str, Any]]:
149
+ """
150
+ Get news about analyst price targets for a stock symbol
151
+
152
+ Endpoint: /price-target-news
153
+
154
+ Args:
155
+ symbol: Stock symbol (required)
156
+ page: Page number for pagination (default: 0)
157
+ limit: Number of results per page (default: 10)
158
+
159
+ Returns:
160
+ List of price target news articles with analyst insights
161
+
162
+ Example:
163
+ >>> news = await client.analyst.price_target_news("AAPL", limit=5)
164
+ >>> # Returns: [{"symbol": "AAPL", "newsTitle": "...", "analystName": "...", ...}]
165
+ """
166
+ params = {"symbol": symbol}
167
+ if page is not None:
168
+ params["page"] = page
169
+ if limit is not None:
170
+ params["limit"] = limit
171
+
172
+ return await self._client._make_request("price-target-news", params)
173
+
174
+ async def price_target_latest_news(
175
+ self, page: int | None = None, limit: int | None = None
176
+ ) -> list[dict[str, Any]]:
177
+ """
178
+ Get latest analyst price target news for all stock symbols
179
+
180
+ Endpoint: /price-target-latest-news
181
+
182
+ Args:
183
+ page: Page number for pagination (default: 0)
184
+ limit: Number of results per page (default: 10)
185
+
186
+ Returns:
187
+ List of latest price target news across all symbols
188
+
189
+ Example:
190
+ >>> latest_news = await client.analyst.price_target_latest_news(limit=20)
191
+ >>> # Returns: [{"symbol": "OLN", "newsTitle": "...", "analystName": "...", ...}]
192
+ """
193
+ params = {}
194
+ if page is not None:
195
+ params["page"] = page
196
+ if limit is not None:
197
+ params["limit"] = limit
198
+
199
+ return await self._client._make_request("price-target-latest-news", params)
200
+
201
+ async def stock_grades(self, symbol: str) -> list[dict[str, Any]]:
202
+ """
203
+ Get latest stock grades from analysts for a stock symbol
204
+
205
+ Endpoint: /grades
206
+
207
+ Args:
208
+ symbol: Stock symbol (required)
209
+
210
+ Returns:
211
+ List of analyst grades with grading company and actions
212
+
213
+ Example:
214
+ >>> grades = await client.analyst.stock_grades("AAPL")
215
+ >>> # Returns: [{"symbol": "AAPL", "gradingCompany": "Morgan Stanley", "newGrade": "Overweight", ...}]
216
+ """
217
+ params = {"symbol": symbol}
218
+ return await self._client._make_request("grades", params)
219
+
220
+ async def historical_stock_grades(
221
+ self, symbol: str, limit: int | None = None
222
+ ) -> list[dict[str, Any]]:
223
+ """
224
+ Get historical analyst grades for a stock symbol
225
+
226
+ Endpoint: /grades-historical
227
+
228
+ Args:
229
+ symbol: Stock symbol (required)
230
+ limit: Number of historical grades (default: 100)
231
+
232
+ Returns:
233
+ List of historical analyst ratings breakdowns
234
+
235
+ Example:
236
+ >>> historical_grades = await client.analyst.historical_stock_grades("AAPL", limit=50)
237
+ >>> # Returns: [{"symbol": "AAPL", "analystRatingsBuy": 8, "analystRatingsHold": 14, ...}]
238
+ """
239
+ params = {"symbol": symbol}
240
+ if limit is not None:
241
+ params["limit"] = limit
242
+
243
+ return await self._client._make_request("grades-historical", params)
244
+
245
+ async def stock_grades_summary(self, symbol: str) -> list[dict[str, Any]]:
246
+ """
247
+ Get summary of analyst grades consensus for a stock symbol
248
+
249
+ Endpoint: /grades-consensus
250
+
251
+ Args:
252
+ symbol: Stock symbol (required)
253
+
254
+ Returns:
255
+ List of grade summaries with consensus ratings
256
+
257
+ Example:
258
+ >>> summary = await client.analyst.stock_grades_summary("AAPL")
259
+ >>> # Returns: [{"symbol": "AAPL", "strongBuy": 1, "buy": 29, "consensus": "Buy", ...}]
260
+ """
261
+ params = {"symbol": symbol}
262
+ return await self._client._make_request("grades-consensus", params)
263
+
264
+ async def stock_grade_news(
265
+ self, symbol: str, page: int | None = None, limit: int | None = None
266
+ ) -> list[dict[str, Any]]:
267
+ """
268
+ Get news about analyst grade changes for a stock symbol
269
+
270
+ Endpoint: /grades-news
271
+
272
+ Args:
273
+ symbol: Stock symbol (required)
274
+ page: Page number for pagination (default: 0)
275
+ limit: Number of results per page (default: 1)
276
+
277
+ Returns:
278
+ List of grade change news articles
279
+
280
+ Example:
281
+ >>> grade_news = await client.analyst.stock_grade_news("AAPL", limit=5)
282
+ >>> # Returns: [{"symbol": "AAPL", "newsTitle": "...", "newGrade": "Buy", ...}]
283
+ """
284
+ params = {"symbol": symbol}
285
+ if page is not None:
286
+ params["page"] = page
287
+ if limit is not None:
288
+ params["limit"] = limit
289
+
290
+ return await self._client._make_request("grades-news", params)
291
+
292
+ async def stock_grade_latest_news(
293
+ self, page: int | None = None, limit: int | None = None
294
+ ) -> list[dict[str, Any]]:
295
+ """
296
+ Get latest analyst grade change news for all stock symbols
297
+
298
+ Endpoint: /grades-latest-news
299
+
300
+ Args:
301
+ page: Page number for pagination (default: 0)
302
+ limit: Number of results per page (default: 10)
303
+
304
+ Returns:
305
+ List of latest grade change news across all symbols
306
+
307
+ Example:
308
+ >>> latest_grades = await client.analyst.stock_grade_latest_news(limit=20)
309
+ >>> # Returns: [{"symbol": "PYPL", "newsTitle": "...", "newGrade": "Overweight", ...}]
310
+ """
311
+ params = {}
312
+ if page is not None:
313
+ params["page"] = page
314
+ if limit is not None:
315
+ params["limit"] = limit
316
+
317
+ return await self._client._make_request("grades-latest-news", params)