Spaces:
Sleeping
Sleeping
| import json | |
| from os import getenv | |
| from typing import Optional, Literal, Any | |
| from phi.tools import Toolkit | |
| from phi.utils.log import logger | |
| try: | |
| from openbb import obb as openbb_app | |
| except ImportError: | |
| raise ImportError("`openbb` not installed. Please install using `pip install 'openbb[all]'`.") | |
| class OpenBBTools(Toolkit): | |
| def __init__( | |
| self, | |
| obb: Optional[Any] = None, | |
| openbb_pat: Optional[str] = None, | |
| provider: Literal["benzinga", "fmp", "intrinio", "polygon", "tiingo", "tmx", "yfinance"] = "yfinance", | |
| stock_price: bool = True, | |
| search_symbols: bool = False, | |
| company_news: bool = False, | |
| company_profile: bool = False, | |
| price_targets: bool = False, | |
| ): | |
| super().__init__(name="yfinance_tools") | |
| self.obb = obb or openbb_app | |
| try: | |
| if openbb_pat or getenv("OPENBB_PAT"): | |
| self.obb.account.login(pat=openbb_pat or getenv("OPENBB_PAT")) # type: ignore | |
| except Exception as e: | |
| logger.error(f"Error logging into OpenBB: {e}") | |
| self.provider: Literal["benzinga", "fmp", "intrinio", "polygon", "tiingo", "tmx", "yfinance"] = provider | |
| if stock_price: | |
| self.register(self.get_stock_price) | |
| if search_symbols: | |
| self.register(self.search_company_symbol) | |
| if company_news: | |
| self.register(self.get_company_news) | |
| if company_profile: | |
| self.register(self.get_company_profile) | |
| if price_targets: | |
| self.register(self.get_price_targets) | |
| def get_stock_price(self, symbol: str) -> str: | |
| """Use this function to get the current stock price for a stock symbol or list of symbols. | |
| Args: | |
| symbol (str): The stock symbol or list of stock symbols. | |
| Eg: "AAPL" or "AAPL,MSFT,GOOGL" | |
| Returns: | |
| str: The current stock prices or error message. | |
| """ | |
| try: | |
| result = self.obb.equity.price.quote(symbol=symbol, provider=self.provider).to_polars() # type: ignore | |
| clean_results = [] | |
| for row in result.to_dicts(): | |
| clean_results.append( | |
| { | |
| "symbol": row.get("symbol"), | |
| "last_price": row.get("last_price"), | |
| "currency": row.get("currency"), | |
| "name": row.get("name"), | |
| "high": row.get("high"), | |
| "low": row.get("low"), | |
| "open": row.get("open"), | |
| "close": row.get("close"), | |
| "prev_close": row.get("prev_close"), | |
| "volume": row.get("volume"), | |
| "ma_50d": row.get("ma_50d"), | |
| "ma_200d": row.get("ma_200d"), | |
| } | |
| ) | |
| return json.dumps(clean_results, indent=2, default=str) | |
| except Exception as e: | |
| return f"Error fetching current price for {symbol}: {e}" | |
| def search_company_symbol(self, company_name: str) -> str: | |
| """Use this function to get a list of ticker symbols for a company. | |
| Args: | |
| company_name (str): The name of the company. | |
| Returns: | |
| str: A JSON string containing the ticker symbols. | |
| """ | |
| logger.debug(f"Search ticker for {company_name}") | |
| result = self.obb.equity.search(company_name).to_polars() # type: ignore | |
| clean_results = [] | |
| if len(result) > 0: | |
| for row in result.to_dicts(): | |
| clean_results.append({"symbol": row.get("symbol"), "name": row.get("name")}) | |
| return json.dumps(clean_results, indent=2, default=str) | |
| def get_price_targets(self, symbol: str) -> str: | |
| """Use this function to get consensus price target and recommendations for a stock symbol or list of symbols. | |
| Args: | |
| symbol (str): The stock symbol or list of stock symbols. | |
| Eg: "AAPL" or "AAPL,MSFT,GOOGL" | |
| Returns: | |
| str: JSON containing consensus price target and recommendations. | |
| """ | |
| try: | |
| result = self.obb.equity.estimates.consensus(symbol=symbol, provider=self.provider).to_polars() # type: ignore | |
| return json.dumps(result.to_dicts(), indent=2, default=str) | |
| except Exception as e: | |
| return f"Error fetching company news for {symbol}: {e}" | |
| def get_company_news(self, symbol: str, num_stories: int = 10) -> str: | |
| """Use this function to get company news for a stock symbol or list of symbols. | |
| Args: | |
| symbol (str): The stock symbol or list of stock symbols. | |
| Eg: "AAPL" or "AAPL,MSFT,GOOGL" | |
| num_stories (int): The number of news stories to return. Defaults to 10. | |
| Returns: | |
| str: JSON containing company news and press releases. | |
| """ | |
| try: | |
| result = self.obb.news.company(symbol=symbol, provider=self.provider, limit=num_stories).to_polars() # type: ignore | |
| clean_results = [] | |
| if len(result) > 0: | |
| for row in result.to_dicts(): | |
| row.pop("images") | |
| clean_results.append(row) | |
| return json.dumps(clean_results[:num_stories], indent=2, default=str) | |
| except Exception as e: | |
| return f"Error fetching company news for {symbol}: {e}" | |
| def get_company_profile(self, symbol: str) -> str: | |
| """Use this function to get company profile and overview for a stock symbol or list of symbols. | |
| Args: | |
| symbol (str): The stock symbol or list of stock symbols. | |
| Eg: "AAPL" or "AAPL,MSFT,GOOGL" | |
| Returns: | |
| str: JSON containing company profile and overview. | |
| """ | |
| try: | |
| result = self.obb.equity.profile(symbol=symbol, provider=self.provider).to_polars() # type: ignore | |
| return json.dumps(result.to_dicts(), indent=2, default=str) | |
| except Exception as e: | |
| return f"Error fetching company profile for {symbol}: {e}" | |