Research_Agent / phidata /phi /tools /openbb_tools.py
zykrix
Re-added phidata as a normal folder (final fix)
c96b98a
Raw
History Blame Contribute Delete
6.16 kB
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}"