Spaces:
Running
Running
File size: 4,991 Bytes
80b408c 8ce1623 80b408c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
import logging
import yfinance as yf
class FundamentalAnalysis:
def __init__(
self,
ticker: str,
debug: bool=False):
"""
Initialize FundamentalAnalysis object.
Args:
ticker : str
Stock ticker to analyze.
debug : bool, optional, default: False
Whether to run in debug mode, so that logging is produced at debug level.
"""
# set up logging
if debug:
self.logger_level = logging.DEBUG
else:
self.logger_level = logging.INFO
self.logger = logging.getLogger(__name__)
logging.basicConfig(level=self.logger_level) # filename='FundamentalAnalysis.log',
# input args
self.ticker = ticker
# done initializing
self.logger.info(f'Initialized TechnicalAnalysis object for ticker: {ticker}')
def run(
self
) -> dict:
"""
Runs the fundamental analysis for the given ticker.
Returns:
dict: A dictionary with fundamental metrics for the given ticker.
"""
self.info = self.fetch_stock_info()
if len(self.info) > 0:
result = self.get_stock_fundamentals()
else:
result = {}
return result
def fetch_stock_info(
self
) -> dict:
"""
Fetches all available information for a given stock ticker using yfinance.
Returns:
dict: A dictionary of key-value pairs with available information for the given ticker.
"""
try:
stock = yf.Ticker(self.ticker)
info = stock.info # Fetch all available info
except Exception as e:
self.logger.error(f"Error fetching stock info for {self.ticker}: {str(e)}")
info = {}
if len(info) == 1:
info = {}
else:
self.logger.info(f"Fetched stock info for {self.ticker}")
return info
def get_stock_fundamentals(
self
) -> dict:
"""
Attempts to fetches key fundamental metrics for a given stock ticker using yfinance.
Returns:
dict: Dictionary of fundamental metrics with human-readable keys
"""
# Define a safe fetch method to avoid entire function failure
def safe_get(key, transform=None):
value = self.info.get(key, "Metric not available")
if value != "Metric not available" and transform:
try:
return transform(value)
except Exception:
return "metric not available"
return value
# Extract key financial metrics
fundamentals = {
"Company Name": safe_get("longName"),
"Sector": safe_get("sector"),
"Industry": safe_get("industry"),
"Market Capitalization": safe_get("marketCap"),
# Valuation Metrics
"P/E Ratio (Trailing)": safe_get("trailingPE"),
"P/E Ratio (Forward)": safe_get("forwardPE"),
"P/B Ratio (Price to Book)": safe_get("priceToBook"),
"P/S Ratio (Price to Sales)": safe_get("priceToSalesTrailing12Months"),
"Dividend Yield (%)": safe_get("dividendYield", lambda x: round(x * 100, 2)),
# Profitability Metrics
"Earnings Per Share (EPS)": safe_get("trailingEps"),
"Return on Equity (ROE)": safe_get("returnOnEquity"),
"Return on Assets (ROA)": safe_get("returnOnAssets"),
"Gross Margin (%)": safe_get("grossMargins", lambda x: round(x * 100, 2)),
"Operating Margin (%)": safe_get("operatingMargins", lambda x: round(x * 100, 2)),
# Financial Health Metrics
"Debt-to-Equity Ratio": safe_get("debtToEquity"),
"Current Ratio": safe_get("currentRatio"),
"Quick Ratio": safe_get("quickRatio"),
"Interest Coverage Ratio": safe_get(
"ebitda",
lambda ebitda: round(ebitda / self.info["totalDebt"], 2) if self.info.get("totalDebt") else "Metric not available"
),
# Growth Metrics
"Revenue Growth (%)": safe_get("revenueGrowth", lambda x: round(x * 100, 2)),
"EPS Growth (%)": safe_get("earningsGrowth", lambda x: round(x * 100, 2)),
# Market & Ownership
"Institutional Ownership (%)": safe_get("heldPercentInstitutions", lambda x: round(x * 100, 2)),
"Insider Ownership (%)": safe_get("heldPercentInsiders", lambda x: round(x * 100, 2)),
}
return fundamentals
if __name__ == '__main__':
dict_fundamentals = FundamentalAnalysis(ticker="GOOG").run()
if len(dict_fundamentals) > 0:
for key, value in dict_fundamentals.items():
print(f"{key}: {value}")
else:
print("No fundamental data available.")
|