AmmarFahmy
adding all files
105b369
import json
from phi.tools import Toolkit
try:
import yfinance as yf
except ImportError:
raise ImportError("`yfinance` not installed. Please install using `pip install yfinance`.")
class YFinanceTools(Toolkit):
def __init__(
self,
stock_price: bool = True,
company_info: bool = False,
stock_fundamentals: bool = False,
income_statements: bool = False,
key_financial_ratios: bool = False,
analyst_recommendations: bool = False,
company_news: bool = False,
technical_indicators: bool = False,
historical_prices: bool = False,
):
super().__init__(name="yfinance_tools")
if stock_price:
self.register(self.get_current_stock_price)
if company_info:
self.register(self.get_company_info)
if stock_fundamentals:
self.register(self.get_stock_fundamentals)
if income_statements:
self.register(self.get_income_statements)
if key_financial_ratios:
self.register(self.get_key_financial_ratios)
if analyst_recommendations:
self.register(self.get_analyst_recommendations)
if company_news:
self.register(self.get_company_news)
if technical_indicators:
self.register(self.get_technical_indicators)
if historical_prices:
self.register(self.get_historical_stock_prices)
def get_current_stock_price(self, symbol: str) -> str:
"""Use this function to get the current stock price for a given symbol.
Args:
symbol (str): The stock symbol.
Returns:
str: The current stock price or error message.
"""
try:
stock = yf.Ticker(symbol)
# Use "regularMarketPrice" for regular market hours, or "currentPrice" for pre/post market
current_price = stock.info.get("regularMarketPrice", stock.info.get("currentPrice"))
return f"{current_price:.4f}" if current_price else f"Could not fetch current price for {symbol}"
except Exception as e:
return f"Error fetching current price for {symbol}: {e}"
def get_company_info(self, symbol: str) -> str:
"""Use this function to get company information and overview for a given stock symbol.
Args:
symbol (str): The stock symbol.
Returns:
str: JSON containing company profile and overview.
"""
try:
company_info_full = yf.Ticker(symbol).info
if company_info_full is None:
return f"Could not fetch company info for {symbol}"
company_info_cleaned = {
"Name": company_info_full.get("shortName"),
"Symbol": company_info_full.get("symbol"),
"Current Stock Price": f"{company_info_full.get('regularMarketPrice', company_info_full.get('currentPrice'))} {company_info_full.get('currency', 'USD')}",
"Market Cap": f"{company_info_full.get('marketCap', company_info_full.get('enterpriseValue'))} {company_info_full.get('currency', 'USD')}",
"Sector": company_info_full.get("sector"),
"Industry": company_info_full.get("industry"),
"Address": company_info_full.get("address1"),
"City": company_info_full.get("city"),
"State": company_info_full.get("state"),
"Zip": company_info_full.get("zip"),
"Country": company_info_full.get("country"),
"EPS": company_info_full.get("trailingEps"),
"P/E Ratio": company_info_full.get("trailingPE"),
"52 Week Low": company_info_full.get("fiftyTwoWeekLow"),
"52 Week High": company_info_full.get("fiftyTwoWeekHigh"),
"50 Day Average": company_info_full.get("fiftyDayAverage"),
"200 Day Average": company_info_full.get("twoHundredDayAverage"),
"Website": company_info_full.get("website"),
"Summary": company_info_full.get("longBusinessSummary"),
"Analyst Recommendation": company_info_full.get("recommendationKey"),
"Number Of Analyst Opinions": company_info_full.get("numberOfAnalystOpinions"),
"Employees": company_info_full.get("fullTimeEmployees"),
"Total Cash": company_info_full.get("totalCash"),
"Free Cash flow": company_info_full.get("freeCashflow"),
"Operating Cash flow": company_info_full.get("operatingCashflow"),
"EBITDA": company_info_full.get("ebitda"),
"Revenue Growth": company_info_full.get("revenueGrowth"),
"Gross Margins": company_info_full.get("grossMargins"),
"Ebitda Margins": company_info_full.get("ebitdaMargins"),
}
return json.dumps(company_info_cleaned, indent=2)
except Exception as e:
return f"Error fetching company profile for {symbol}: {e}"
def get_historical_stock_prices(self, symbol: str, period: str = "1mo", interval: str = "1d") -> str:
"""Use this function to get the historical stock price for a given symbol.
Args:
symbol (str): The stock symbol.
period (str): The period for which to retrieve historical prices. Defaults to "1mo".
Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
interval (str): The interval between data points. Defaults to "1d".
Valid intervals: 1d,5d,1wk,1mo,3mo
Returns:
str: The current stock price or error message.
"""
try:
stock = yf.Ticker(symbol)
historical_price = stock.history(period="1d")
return historical_price.to_json(orient="index")
except Exception as e:
return f"Error fetching historical prices for {symbol}: {e}"
def get_stock_fundamentals(self, symbol: str) -> str:
"""Use this function to get fundamental data for a given stock symbol yfinance API.
Args:
symbol (str): The stock symbol.
Returns:
str: A JSON string containing fundamental data or an error message.
Keys:
- 'symbol': The stock symbol.
- 'company_name': The long name of the company.
- 'sector': The sector to which the company belongs.
- 'industry': The industry to which the company belongs.
- 'market_cap': The market capitalization of the company.
- 'pe_ratio': The forward price-to-earnings ratio.
- 'pb_ratio': The price-to-book ratio.
- 'dividend_yield': The dividend yield.
- 'eps': The trailing earnings per share.
- 'beta': The beta value of the stock.
- '52_week_high': The 52-week high price of the stock.
- '52_week_low': The 52-week low price of the stock.
"""
try:
stock = yf.Ticker(symbol)
info = stock.info
fundamentals = {
"symbol": symbol,
"company_name": info.get("longName", ""),
"sector": info.get("sector", ""),
"industry": info.get("industry", ""),
"market_cap": info.get("marketCap", "N/A"),
"pe_ratio": info.get("forwardPE", "N/A"),
"pb_ratio": info.get("priceToBook", "N/A"),
"dividend_yield": info.get("dividendYield", "N/A"),
"eps": info.get("trailingEps", "N/A"),
"beta": info.get("beta", "N/A"),
"52_week_high": info.get("fiftyTwoWeekHigh", "N/A"),
"52_week_low": info.get("fiftyTwoWeekLow", "N/A"),
}
return json.dumps(fundamentals, indent=2)
except Exception as e:
return f"Error getting fundamentals for {symbol}: {e}"
def get_income_statements(self, symbol: str) -> str:
"""Use this function to get income statements for a given stock symbol.
Args:
symbol (str): The stock symbol.
Returns:
dict: JSON containing income statements or an empty dictionary.
"""
try:
stock = yf.Ticker(symbol)
financials = stock.financials
return financials.to_json(orient="index")
except Exception as e:
return f"Error fetching income statements for {symbol}: {e}"
def get_key_financial_ratios(self, symbol: str) -> str:
"""Use this function to get key financial ratios for a given stock symbol.
Args:
symbol (str): The stock symbol.
Returns:
dict: JSON containing key financial ratios.
"""
try:
stock = yf.Ticker(symbol)
key_ratios = stock.info
return json.dumps(key_ratios, indent=2)
except Exception as e:
return f"Error fetching key financial ratios for {symbol}: {e}"
def get_analyst_recommendations(self, symbol: str) -> str:
"""Use this function to get analyst recommendations for a given stock symbol.
Args:
symbol (str): The stock symbol.
Returns:
str: JSON containing analyst recommendations.
"""
try:
stock = yf.Ticker(symbol)
recommendations = stock.recommendations
return recommendations.to_json(orient="index")
except Exception as e:
return f"Error fetching analyst recommendations for {symbol}: {e}"
def get_company_news(self, symbol: str, num_stories: int = 3) -> str:
"""Use this function to get company news and press releases for a given stock symbol.
Args:
symbol (str): The stock symbol.
num_stories (int): The number of news stories to return. Defaults to 3.
Returns:
str: JSON containing company news and press releases.
"""
try:
news = yf.Ticker(symbol).news
return json.dumps(news[:num_stories], indent=2)
except Exception as e:
return f"Error fetching company news for {symbol}: {e}"
def get_technical_indicators(self, symbol: str, period: str = "3mo") -> str:
"""Use this function to get technical indicators for a given stock symbol.
Args:
symbol (str): The stock symbol.
period (str): The time period for which to retrieve technical indicators.
Valid periods: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max. Defaults to 3mo.
Returns:
str: JSON containing technical indicators.
"""
try:
indicators = yf.Ticker(symbol).history(period=period)
return indicators.to_json(orient="index")
except Exception as e:
return f"Error fetching technical indicators for {symbol}: {e}"