|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import logging |
|
|
from typing import List, Literal, Optional |
|
|
|
|
|
from camel.toolkits.base import BaseToolkit |
|
|
from camel.toolkits.function_tool import FunctionTool |
|
|
from camel.utils import api_keys_required, dependencies_required |
|
|
|
|
|
|
|
|
class OpenBBToolkit(BaseToolkit): |
|
|
r"""A toolkit for accessing financial data and analysis through OpenBB |
|
|
Platform. |
|
|
|
|
|
This toolkit provides methods for retrieving and analyzing financial market |
|
|
data, including stocks, ETFs, cryptocurrencies, economic indicators, and |
|
|
more through the OpenBB Platform SDK. For credential configuration, please |
|
|
refer to the OpenBB documentation |
|
|
https://my.openbb.co/app/platform/credentials . |
|
|
""" |
|
|
|
|
|
@dependencies_required("openbb") |
|
|
@api_keys_required( |
|
|
[ |
|
|
(None, "OPENBB_TOKEN"), |
|
|
] |
|
|
) |
|
|
def __init__(self) -> None: |
|
|
r"""Initialize the OpenBBToolkit. |
|
|
|
|
|
This method sets up the OpenBB client and initializes the OpenBB |
|
|
Hub account system. |
|
|
""" |
|
|
import os |
|
|
|
|
|
from openbb import obb |
|
|
|
|
|
self.client = obb |
|
|
|
|
|
token = os.getenv("OPENBB_TOKEN") |
|
|
self.client.account.login(pat=token) |
|
|
|
|
|
def _handle_api_error( |
|
|
self, |
|
|
error: Exception, |
|
|
operation: str, |
|
|
log_level: str = "warning", |
|
|
**format_args, |
|
|
) -> List: |
|
|
r"""Handle API operation errors consistently. |
|
|
|
|
|
Args: |
|
|
error (Exception): The caught exception. |
|
|
operation (str): Description of the failed operation |
|
|
(e.g., "get_historical_data"). |
|
|
log_level (str): Logging level to use ("warning" or "error"). |
|
|
format_args: Additional format arguments for the error message . |
|
|
|
|
|
Returns: |
|
|
List: List with error message. |
|
|
""" |
|
|
logger = logging.getLogger(__name__) |
|
|
log_func = getattr(logger, log_level) |
|
|
|
|
|
error_msg = f"Failed to {operation}" |
|
|
if format_args: |
|
|
error_msg += ": " + ", ".join( |
|
|
f"{k}={v}" for k, v in format_args.items() |
|
|
) |
|
|
error_msg += f". Error: {error!s}" |
|
|
|
|
|
log_func(error_msg) |
|
|
return [error_msg] |
|
|
|
|
|
def search_equity( |
|
|
self, |
|
|
query: str, |
|
|
provider: Literal["intrinio", "sec"] = "sec", |
|
|
) -> List: |
|
|
r"""Search for equity symbols and company information. |
|
|
|
|
|
For SEC provider, an empty query ("") returns the complete list of |
|
|
companies sorted by market cap. |
|
|
|
|
|
Args: |
|
|
query (str): Search query (company name or symbol), use "" for |
|
|
complete SEC list. |
|
|
provider (Literal["intrinio", "sec"]): Data provider. Available |
|
|
options: |
|
|
- sec: SEC EDGAR Database (sorted by market cap) |
|
|
- intrinio: Intrinio Financial Data |
|
|
|
|
|
Returns: |
|
|
List: Search results. |
|
|
""" |
|
|
try: |
|
|
data = self.client.equity.search(query, provider=provider) |
|
|
|
|
|
return data.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="search equity", |
|
|
log_level="warning", |
|
|
query=query, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def search_institution(self, query: str) -> List: |
|
|
r"""Search for financial institutions in SEC database. |
|
|
|
|
|
Args: |
|
|
query (str): Institution name to search (e.g., "Berkshire |
|
|
Hathaway"). |
|
|
|
|
|
Returns: |
|
|
List: Institution search results. |
|
|
""" |
|
|
try: |
|
|
data = self.client.regulators.sec.institutions_search(query) |
|
|
|
|
|
return data.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="search institution", |
|
|
log_level="warning", |
|
|
query=query, |
|
|
) |
|
|
|
|
|
def search_filings( |
|
|
self, |
|
|
symbol: str, |
|
|
provider: Literal["fmp", "intrinio", "sec"] = "sec", |
|
|
form_type: Optional[str] = None, |
|
|
) -> List: |
|
|
r"""Search for SEC filings by CIK or ticker symbol. |
|
|
|
|
|
Args: |
|
|
symbol (str): Symbol to get data for (e.g., "MAXD"). |
|
|
provider (Literal["fmp", "intrinio", "sec"]): Data provider. |
|
|
(default: :obj:`sec`) |
|
|
form_type (Optional[str]): Filter by form type. Check the data |
|
|
provider for available types. Multiple comma separated items |
|
|
allowed for provider(s): sec. (default: :obj:`None`) |
|
|
|
|
|
Returns: |
|
|
List: Filing search results. |
|
|
""" |
|
|
try: |
|
|
data = self.client.equity.fundamental.filings( |
|
|
symbol=symbol, |
|
|
form_type=form_type, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
return data.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="search filings", |
|
|
log_level="warning", |
|
|
symbol=symbol, |
|
|
form_type=form_type, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def search_etf( |
|
|
self, |
|
|
query: str, |
|
|
provider: Literal["fmp", "intrinio"] = "fmp", |
|
|
) -> List: |
|
|
r"""Search for ETF information. |
|
|
|
|
|
Args: |
|
|
query (str): Search query (ETF name or symbol). |
|
|
provider (Literal["fmp", "intrinio"]): Data provider. (default: |
|
|
:obj:`fmp`) |
|
|
|
|
|
Returns: |
|
|
List: ETF search results. |
|
|
""" |
|
|
try: |
|
|
data = self.client.etf.search(query, provider=provider) |
|
|
return data.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="search ETF", |
|
|
log_level="warning", |
|
|
query=query, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def screen_market( |
|
|
self, |
|
|
provider: Literal["fmp", "yfinance"] = "fmp", |
|
|
country: Optional[str] = None, |
|
|
exchange: Optional[str] = None, |
|
|
sector: Optional[str] = None, |
|
|
industry: Optional[str] = None, |
|
|
mktcap_min: Optional[float] = None, |
|
|
mktcap_max: Optional[float] = None, |
|
|
beta_min: Optional[float] = None, |
|
|
beta_max: Optional[float] = None, |
|
|
) -> List: |
|
|
r"""Screen stocks based on market and fundamental criteria. |
|
|
|
|
|
Args: |
|
|
provider (Literal["fmp", "yfinance"]): Data provider. |
|
|
(default: :obj:`fmp`) |
|
|
country (Optional[str]): Two-letter ISO country code (e.g., 'US', |
|
|
'IN', 'CN'). (default: :obj:`None`) |
|
|
exchange(Optional[str]) : Stock exchange code (e.g., 'NYSE', |
|
|
'AMEX', 'NSE'). (default: :obj:`None`) |
|
|
sector (Optional[str]): Market sector (e.g., 'Financial Services', |
|
|
'Healthcare). (default: :obj:`None`) |
|
|
industry (Optional[str]): Industry within sector (e.g., |
|
|
'Banks—Regional','Drug Manufacturers'). (default: :obj:`None`) |
|
|
mktcap_min (Optional[float]): Minimum market cap in USD. |
|
|
(default: :obj:`None`) |
|
|
mktcap_max (Optional[float]): Maximum market cap in USD. |
|
|
(default: :obj:`None`) |
|
|
beta_min (Optional[float]): Minimum beta value. |
|
|
(default: :obj:`None`) |
|
|
beta_max (Optional[float]): Maximum beta value. |
|
|
(default: :obj:`None`) |
|
|
|
|
|
Returns: |
|
|
List: Screened stocks. |
|
|
""" |
|
|
try: |
|
|
params = { |
|
|
k: v |
|
|
for k, v in { |
|
|
'country': country, |
|
|
'exchange': exchange, |
|
|
'sector': sector, |
|
|
'industry': industry, |
|
|
'mktcap_min': mktcap_min, |
|
|
'mktcap_max': mktcap_max, |
|
|
'beta_min': beta_min, |
|
|
'beta_max': beta_max, |
|
|
}.items() |
|
|
if v is not None |
|
|
} |
|
|
|
|
|
data = self.client.equity.screener(provider=provider, **params) |
|
|
|
|
|
return data.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="screen market", |
|
|
log_level="warning", |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_available_indices( |
|
|
self, |
|
|
provider: Literal['fmp', 'yfinance'] = 'fmp', |
|
|
) -> List: |
|
|
r"""Get list of available market indices. |
|
|
|
|
|
Args: |
|
|
provider (Literal["fmp", "yfinance"]): Data provider. |
|
|
(default: :obj:`fmp`) |
|
|
|
|
|
Returns: |
|
|
List: Available indices. |
|
|
""" |
|
|
try: |
|
|
data = self.client.index.available(provider=provider) |
|
|
|
|
|
return data.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get available indices", |
|
|
log_level="warning", |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_stock_quote( |
|
|
self, |
|
|
symbol: str, |
|
|
provider: Literal['fmp', 'intrinio', 'yfinance'] = "fmp", |
|
|
) -> List: |
|
|
r"""Get current stock quote for a given symbol. |
|
|
|
|
|
Args: |
|
|
symbol (str): Stock symbol (e.g., 'AAPL' for Apple Inc.) |
|
|
provider (Literal["fmp", "intrinio", "yfinance"]): Data source. |
|
|
(default: :obj:`fmp`) |
|
|
|
|
|
Returns: |
|
|
List: Stock quote data in requested format |
|
|
""" |
|
|
try: |
|
|
data = self.client.equity.price.quote( |
|
|
symbol=symbol, provider=provider |
|
|
) |
|
|
|
|
|
return data.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get stock quote", |
|
|
log_level="error", |
|
|
symbol=symbol, |
|
|
) |
|
|
|
|
|
def get_historical_data( |
|
|
self, |
|
|
symbol: str, |
|
|
provider: Literal['fmp', 'polygon', 'tiingo', 'yfinance'] = "fmp", |
|
|
asset_type: Literal[ |
|
|
"equity", |
|
|
"currency", |
|
|
"crypto", |
|
|
] = "equity", |
|
|
start_date: Optional[str] = None, |
|
|
end_date: Optional[str] = None, |
|
|
interval: Literal["1m", "5m", "15m", "30m", "1h", "4h", "1d"] = "1d", |
|
|
) -> List: |
|
|
r"""Retrieves historical market data from OpenBB Platform providers. |
|
|
|
|
|
Args: |
|
|
symbol (str): Stock symbol (e.g., 'AAPL' for Apple Inc.). |
|
|
provider (Literal["fmp", "polygon", "tiingo", "yfinance"]): Data |
|
|
source. (default: :obj:`fmp`) |
|
|
asset_type (Literal["equity", "currency", "crypto"]): Asset type. |
|
|
(default: :obj:`equity`) |
|
|
start_date: Start date in YYYY-MM-DD format. If None, uses |
|
|
provider's default lookback. (default: :obj:`None`) |
|
|
end_date: End date in YYYY-MM-DD format. If None, uses current |
|
|
date. (default: :obj:`None`) |
|
|
interval: Data frequency/timeframe. (default: :obj:`1d`) |
|
|
|
|
|
Returns: |
|
|
List: Historical market data. |
|
|
""" |
|
|
try: |
|
|
if asset_type == "currency": |
|
|
response = self.client.currency.price.historical( |
|
|
symbol=symbol, |
|
|
start_date=start_date, |
|
|
end_date=end_date, |
|
|
interval=interval, |
|
|
provider=provider, |
|
|
) |
|
|
elif asset_type == "crypto": |
|
|
response = self.client.crypto.price.historical( |
|
|
symbol=symbol, |
|
|
start_date=start_date, |
|
|
end_date=end_date, |
|
|
interval=interval, |
|
|
provider=provider, |
|
|
) |
|
|
else: |
|
|
response = self.client.equity.price.historical( |
|
|
symbol=symbol, |
|
|
start_date=start_date, |
|
|
end_date=end_date, |
|
|
interval=interval, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
return response.results |
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get historical data", |
|
|
log_level="error", |
|
|
symbol=symbol, |
|
|
) |
|
|
|
|
|
def get_market_data( |
|
|
self, |
|
|
category: Literal["gainers", "losers", "active"] = "active", |
|
|
) -> List: |
|
|
r"""Get market movers data. |
|
|
|
|
|
Args: |
|
|
category(Literal["gainers", "losers", "active"]): Type of market |
|
|
data. Must be 'gainers', 'losers', or 'active'. (default: |
|
|
:obj:`active`) |
|
|
|
|
|
Returns: |
|
|
List: Market movers data. |
|
|
""" |
|
|
try: |
|
|
if category == "gainers": |
|
|
response = self.client.equity.discovery.gainers() |
|
|
elif category == "losers": |
|
|
response = self.client.equity.discovery.losers() |
|
|
else: |
|
|
response = self.client.equity.discovery.active() |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get market data", |
|
|
log_level="error", |
|
|
category=category, |
|
|
) |
|
|
|
|
|
def get_earnings_calendar( |
|
|
self, |
|
|
start_date: Optional[str] = None, |
|
|
end_date: Optional[str] = None, |
|
|
) -> List: |
|
|
r"""Get company earnings calendar with filtering and sorting options. |
|
|
|
|
|
Args: |
|
|
start_date (Optional[str]): Start date in YYYY-MM-DD format. |
|
|
(default: :obj:`None`) |
|
|
end_date (Optional[str]): End date in YYYY-MM-DD format. (default: |
|
|
:obj:`None`) |
|
|
|
|
|
Returns: |
|
|
List: Earnings calendar. |
|
|
""" |
|
|
try: |
|
|
response = self.client.equity.calendar.earnings( |
|
|
start_date=start_date, end_date=end_date |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get earnings calendar", |
|
|
log_level="warning", |
|
|
) |
|
|
|
|
|
def get_dividend_calendar( |
|
|
self, |
|
|
start_date: Optional[str] = None, |
|
|
end_date: Optional[str] = None, |
|
|
) -> List: |
|
|
r"""Get dividend calendar with optional yield calculations. |
|
|
|
|
|
Args: |
|
|
start_date (Optional[str]): Start date in YYYY-MM-DD format. |
|
|
(default: :obj:`None`) |
|
|
end_date (Optional[str]): End date in YYYY-MM-DD format. (default: |
|
|
:obj:`None`) |
|
|
|
|
|
Returns: |
|
|
List: Dividend calendar. |
|
|
""" |
|
|
try: |
|
|
response = self.client.equity.calendar.dividend( |
|
|
start_date=start_date, end_date=end_date |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get dividend calendar", |
|
|
log_level="warning", |
|
|
) |
|
|
|
|
|
def get_ipo_calendar( |
|
|
self, |
|
|
start_date: Optional[str] = None, |
|
|
end_date: Optional[str] = None, |
|
|
) -> List: |
|
|
r"""Get IPO/SPO calendar with comprehensive filtering options. |
|
|
|
|
|
Args: |
|
|
start_date (Optional[str]): Start date in YYYY-MM-DD format. |
|
|
(default: :obj:`None`) |
|
|
end_date (Optional[str]): End date in YYYY-MM-DD format. (default: |
|
|
:obj:`None`) |
|
|
|
|
|
Returns: |
|
|
List: IPO/SPO calendar. |
|
|
""" |
|
|
try: |
|
|
response = self.client.equity.calendar.ipo( |
|
|
start_date=start_date, end_date=end_date |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get IPO calendar", |
|
|
log_level="warning", |
|
|
) |
|
|
|
|
|
def get_available_indicators( |
|
|
self, |
|
|
provider: Literal["econdb", "imf"] = "econdb", |
|
|
) -> List: |
|
|
r"""Get list of available economic indicators. |
|
|
|
|
|
Args: |
|
|
provider (Literal["econdb", "imf"]): Data provider. |
|
|
(default: :obj:`econdb`) |
|
|
|
|
|
Returns: |
|
|
List: Available indicators. |
|
|
""" |
|
|
try: |
|
|
response = self.client.economy.available_indicators( |
|
|
provider=provider |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get available indicators", |
|
|
log_level="warning", |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_indicator_data( |
|
|
self, |
|
|
symbol: str, |
|
|
country: str, |
|
|
provider: Literal["econdb", "imf"] = "econdb", |
|
|
) -> List: |
|
|
r"""Get detailed metadata for an economic indicator. |
|
|
|
|
|
Args: |
|
|
symbol (str): Stock symbol (e.g., 'AAPL' for Apple Inc.). |
|
|
country (str): Country code (e.g., 'US' for United States). |
|
|
provider (Literal["econdb", "imf"]): Data provider. (default: |
|
|
:obj:`econdb`) |
|
|
|
|
|
Returns: |
|
|
List: Indicator data. |
|
|
""" |
|
|
try: |
|
|
response = self.client.economy.indicators( |
|
|
country=country, provider=provider, symbol=symbol |
|
|
) |
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get indicator data", |
|
|
log_level="warning", |
|
|
symbol=symbol, |
|
|
country=country, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_financial_metrics( |
|
|
self, |
|
|
symbol: str, |
|
|
provider: Literal['fmp', 'intrinio', 'yfinance'] = "fmp", |
|
|
period: Literal["annual", "quarter"] = "annual", |
|
|
limit: int = 5, |
|
|
) -> List: |
|
|
r"""Get company financial metrics and ratios. |
|
|
|
|
|
Args: |
|
|
symbol (str): Stock symbol (e.g., 'AAPL' for Apple Inc.). |
|
|
provider (Literal["fmp", "intrinio", "yfinance"]): Data source. |
|
|
(default: :obj:`fmp`) |
|
|
period (Literal["annual", "quarter"]): Reporting period, "annual": |
|
|
Annual metrics, "quarter": Quarterly metrics. (default: |
|
|
:obj:`annual`) |
|
|
limit (int): Number of periods to return. (default: :obj:`5`) |
|
|
|
|
|
Returns: |
|
|
List: Financial metric. |
|
|
""" |
|
|
try: |
|
|
response = self.client.equity.fundamental.metrics( |
|
|
symbol=symbol, period=period, provider=provider, limit=limit |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get financial metrics", |
|
|
log_level="warning", |
|
|
symbol=symbol, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_company_profile( |
|
|
self, |
|
|
symbol: str, |
|
|
provider: Literal["fmp", "intrinio", "yfinance"] = "fmp", |
|
|
) -> List: |
|
|
r"""Get company profile information. |
|
|
|
|
|
Args: |
|
|
symbol (str): Stock symbol (e.g., 'AAPL' for Apple Inc.). |
|
|
provider (Literal["fmp", "intrinio", "yfinance"]): Data provider. |
|
|
(default: :obj:`fmp`) |
|
|
|
|
|
Returns: |
|
|
List: Company profile. |
|
|
""" |
|
|
try: |
|
|
response = self.client.equity.profile( |
|
|
symbol=symbol, provider=provider |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get company profile", |
|
|
log_level="warning", |
|
|
symbol=symbol, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_financial_statement( |
|
|
self, |
|
|
symbol: str, |
|
|
provider: Literal["fmp", "intrinio", "polygon", "yfinance"] = "fmp", |
|
|
statement_type: Literal["balance", "income", "cash"] = "balance", |
|
|
period: Literal["annual", "quarter"] = "annual", |
|
|
limit: int = 5, |
|
|
) -> List: |
|
|
r"""Get company financial statements. |
|
|
|
|
|
Access balance sheet, income statement, or cash flow statement data. |
|
|
Data availability and field names vary by provider and company type. |
|
|
|
|
|
Args: |
|
|
symbol (str): Stock symbol (e.g., 'AAPL' for Apple Inc.). |
|
|
provider (Literal["fmp", "intrinio", "polygon", "yfinance"]): Data |
|
|
provider. (default: :obj:`fmp`) |
|
|
statement_type (Literal["balance", "income", "cash"]): Type of |
|
|
financial statement, "balance": Balance sheet, "income": |
|
|
Income statement, "cash": Cash flow statement. (default: |
|
|
:obj:`balance`) |
|
|
period (Literal["annual", "quarter"]): Reporting period, "annual": |
|
|
Annual reports, "quarter": Quarterly reports. (default: |
|
|
:obj:`annual`) |
|
|
limit (int): Number of periods to return. (default: :obj:`5`) |
|
|
|
|
|
Returns: |
|
|
List: Financial statement data. |
|
|
""" |
|
|
try: |
|
|
|
|
|
endpoint_map = { |
|
|
"balance": self.client.equity.fundamental.balance, |
|
|
"income": self.client.equity.fundamental.income, |
|
|
"cash": self.client.equity.fundamental.cash, |
|
|
} |
|
|
|
|
|
endpoint = endpoint_map.get(statement_type) |
|
|
if not endpoint: |
|
|
raise ValueError(f"Invalid statement_type: {statement_type}") |
|
|
|
|
|
response = endpoint( |
|
|
symbol=symbol, period=period, provider=provider, limit=limit |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get financial statement", |
|
|
log_level="warning", |
|
|
symbol=symbol, |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_financial_attributes( |
|
|
self, |
|
|
symbol: str, |
|
|
tag: str, |
|
|
frequency: Literal[ |
|
|
"daily", "weekly", "monthly", "quarterly", "yearly" |
|
|
] = "yearly", |
|
|
) -> List: |
|
|
r"""Get historical values for a specific financial attribute. |
|
|
|
|
|
Args: |
|
|
symbol (str): Stock symbol (e.g., 'AAPL' for Apple Inc.). |
|
|
tag (str): Financial attribute tag (use |
|
|
search_financial_attributes to find tags). |
|
|
frequency (Literal["daily", "weekly", "monthly", "quarterly", |
|
|
"yearly"]): Data frequency, "daily", "weekly", "monthly", |
|
|
"quarterly", "yearly". (default: :obj:`yearly`) |
|
|
|
|
|
Returns: |
|
|
List: Historical values. |
|
|
""" |
|
|
try: |
|
|
response = self.client.equity.fundamental.historical_attributes( |
|
|
symbol=symbol, tag=tag, frequency=frequency |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get financial attribute", |
|
|
log_level="warning", |
|
|
symbol=symbol, |
|
|
tag=tag, |
|
|
) |
|
|
|
|
|
def search_financial_attributes( |
|
|
self, |
|
|
query: str, |
|
|
) -> List: |
|
|
r"""Search for available financial attributes/tags. |
|
|
|
|
|
Args: |
|
|
query (str): Search term (e.g., "marketcap", "revenue", "assets"). |
|
|
|
|
|
Returns: |
|
|
List: Matching attributes. |
|
|
""" |
|
|
try: |
|
|
response = self.client.equity.fundamental.search_attributes( |
|
|
query=query |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="search financial attributes", |
|
|
log_level="warning", |
|
|
query=query, |
|
|
) |
|
|
|
|
|
def get_economic_calendar( |
|
|
self, |
|
|
provider: Literal["fmp", "tradingeconomics"] = "fmp", |
|
|
start_date: Optional[str] = None, |
|
|
end_date: Optional[str] = None, |
|
|
) -> List: |
|
|
r"""Get economic calendar events. |
|
|
|
|
|
Args: |
|
|
provider (Literal["fmp", "tradingeconomics"]): Data provider. |
|
|
(default: :obj:`fmp`) |
|
|
start_date (Optional[str]): Start date in YYYY-MM-DD format. |
|
|
(default: :obj:`None`) |
|
|
end_date (Optional[str]): End date in YYYY-MM-DD format. (default: |
|
|
:obj:`None`) |
|
|
|
|
|
Returns: |
|
|
List: Economic calendar. |
|
|
""" |
|
|
try: |
|
|
response = self.client.economy.calendar( |
|
|
start_date=start_date, end_date=end_date, provider=provider |
|
|
) |
|
|
|
|
|
return response.results |
|
|
|
|
|
except Exception as e: |
|
|
return self._handle_api_error( |
|
|
error=e, |
|
|
operation="get economic calendar", |
|
|
log_level="warning", |
|
|
provider=provider, |
|
|
) |
|
|
|
|
|
def get_tools(self) -> List[FunctionTool]: |
|
|
r"""Returns a list of available OpenBB financial tools. |
|
|
|
|
|
Returns: |
|
|
List[FunctionTool]: List of available tools. |
|
|
""" |
|
|
return [ |
|
|
FunctionTool( |
|
|
func=self.search_equity, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.search_etf, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.search_institution, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.search_filings, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.screen_market, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_available_indices, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_stock_quote, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_historical_data, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_market_data, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_earnings_calendar, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_dividend_calendar, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_ipo_calendar, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_available_indicators, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_indicator_data, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_financial_metrics, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_company_profile, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_financial_statement, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_financial_attributes, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.search_financial_attributes, |
|
|
), |
|
|
FunctionTool( |
|
|
func=self.get_economic_calendar, |
|
|
), |
|
|
] |
|
|
|