from flask import Flask, jsonify import pandas as pd import yfinance as yf import numpy as np def get_fundamental_details(ticker): # Fetch the stock data using yfinance stock = yf.Ticker(ticker) # Fetch fundamental data and financial statements fundamental_data = stock.info income_statement = stock.financials balance_sheet = stock.balance_sheet cash_flow_statement = stock.cashflow current_net_income = income_statement.loc['Net Income'].iloc[0] previous_net_income = income_statement.loc['Net Income'].iloc[1] earnings_growth_yoy = 'N/A' # Calculate Earnings Growth (YoY) if current_net_income is not None and previous_net_income is not None: earnings_growth_yoy = ((current_net_income - previous_net_income) / previous_net_income) * 100 current_assets = balance_sheet.loc['Current Assets'].iloc[0] if 'Current Assets' in balance_sheet.index else None current_liabilities = balance_sheet.loc['Current Liabilities'].iloc[0] if 'Current Liabilities' in balance_sheet.index else None current_ratio = 'N/A' # Calculate Earnings Growth (YoY) if current_assets is not None and current_liabilities is not None: current_ratio = current_assets/current_liabilities # Ensure data is transposed for proper indexing balance_sheet = balance_sheet.T # Get the latest non-null Debt-to-Equity Ratio debt_to_equity = "N/A" total_liabilities_series = total_equity_series = None if "Total Liabilities Net Minority Interest" in balance_sheet.columns and "Ordinary Shares Number" in balance_sheet.columns: total_liabilities_series = balance_sheet["Total Liabilities Net Minority Interest"].dropna() total_equity_series = balance_sheet["Ordinary Shares Number"].dropna() if not total_liabilities_series.empty and not total_equity_series.empty: total_liabilities = total_liabilities_series.iloc[0] # Get the latest non-null value total_equity = total_equity_series.iloc[0] # Get the latest non-null value if total_liabilities is not None and total_equity is not None and total_equity != 0: debt_to_equity = total_liabilities / total_equity fundamental_metrics = { 'EPS': fundamental_data.get('epsTrailingTwelveMonths', None), 'P/E Ratio': fundamental_data.get('trailingPE', None), 'Revenue Growth': fundamental_data.get('revenueGrowth', None), 'Debt-to-Equity Ratio': debt_to_equity, 'Earnings Growth(YoY)': earnings_growth_yoy } eps = fundamental_metrics['EPS'] pe_ratio = fundamental_metrics['P/E Ratio'] revenue_growth = fundamental_metrics['Revenue Growth'] debt_to_equity = fundamental_metrics['Debt-to-Equity Ratio'] earnings_growth_yoy = fundamental_metrics['Earnings Growth(YoY)'] # Initialize status variables earnings_growth_status = "none" debt_to_equity_status = "none" pe_ratio_status = "none" revenue_growth_status = "none" eps_status = "none" # Updated Thresholds earnings_growth_threshold = 0.12 # Earnings Growth > 12% (good) debt_to_equity_threshold = 1.5 # D/E < 1.5 (good) pe_ratio_threshold = 25 # P/E < 25 (good) revenue_growth_threshold = 0.12 # Revenue Growth > 12% (good) eps_threshold = 0 # EPS > 0 (good) # Updated Weightages earnings_growth_weight = 2 # 3.5% weight for earnings growth debt_to_equity_weight = 1.5 # 2.75% weight for debt-to-equity ratio pe_ratio_weight = 1.5 # 2.5% weight for P/E ratio revenue_growth_weight = 2 # 3.5% weight for revenue growth eps_weight = 3 # 3.75% weight for EPS # Check and assign status for EPS, if available if eps is not None: if eps > eps_threshold: eps_status = "good" else: eps_status = "bad" # Check and assign status for earnings growth, if available if earnings_growth_yoy is not None: if earnings_growth_yoy >= earnings_growth_threshold: earnings_growth_status = "good" else: earnings_growth_status = "bad" # Check and assign status for debt-to-equity, if available if debt_to_equity is not None: if debt_to_equity <= debt_to_equity_threshold: debt_to_equity_status = "good" else: debt_to_equity_status = "bad" # Check and assign status for P/E ratio, if available if pe_ratio is not None: if pe_ratio <= pe_ratio_threshold: pe_ratio_status = "good" else: pe_ratio_status = "bad" # Check and assign status for revenue growth, if available if revenue_growth is not None: if revenue_growth >= revenue_growth_threshold: revenue_growth_status = "good" else: revenue_growth_status = "bad" # Calculate overall score overall_fa_score = 0 overall_fa_score += eps_weight if eps_status == "good" else 0 overall_fa_score += earnings_growth_weight if earnings_growth_status == "good" else 0 overall_fa_score += debt_to_equity_weight if debt_to_equity_status == "good" else 0 overall_fa_score += pe_ratio_weight if pe_ratio_status == "good" else 0 overall_fa_score += revenue_growth_weight if revenue_growth_status == "good" else 0 earnings_growth = stock.info.get('earningsGrowth', None) peg_ratio = None if pe_ratio is not None and earnings_growth is not None and earnings_growth != 0: peg_ratio = pe_ratio / earnings_growth # Financial Metrics (Valuation, Profitability, etc.) financialMetrics = { 'Market Cap': fundamental_data.get('marketCap', None), 'Price-to-Book (P/B) Ratio': fundamental_data.get('priceToBook', None), 'Price-to-Sales (P/S) Ratio': fundamental_data.get('priceToSalesTrailing12Months', None), 'PEG Ratio': peg_ratio, 'EV/EBITDA': fundamental_data.get('enterpriseToEbitda', None) } # Balance Sheet Data balanceSheetInformation = { 'Total Assets': balance_sheet.loc['Total Assets'].iloc[0] if 'Total Assets' in balance_sheet.index else None, 'Total Liabilities': balance_sheet.loc['Total Liabilities Net Minority Interest'].iloc[0] if 'Total Liabilities Net Minority Interest' in balance_sheet.index else None, 'Total Stockholder Equity': (balance_sheet.loc['Total Assets'].iloc[0] - balance_sheet.loc['Total Liabilities Net Minority Interest'].iloc[0]) if 'Total Assets' in balance_sheet.index and 'Total Liabilities Net Minority Interest' in balance_sheet.index else None, 'Long Term Debt': balance_sheet.loc['Long Term Debt'].iloc[0] if 'Long Term Debt' in balance_sheet.index else None, 'Current Assets': balance_sheet.loc['Current Assets'].iloc[0] if 'Current Assets' in balance_sheet.index else None, 'Current Liabilities': balance_sheet.loc['Current Liabilities'].iloc[0] if 'Current Liabilities' in balance_sheet.index else None, 'Inventory': balance_sheet.loc['Inventory'].iloc[0] if 'Inventory' in balance_sheet.index else None } # Income Statement Data incomeStatement = { 'Total Revenue': income_statement.loc['Total Revenue'].iloc[0] if 'Total Revenue' in income_statement.index else None, 'Operating Income': income_statement.loc['Operating Income'].iloc[0] if 'Operating Income' in income_statement.index else None, 'Net Income': income_statement.loc['Net Income'].iloc[0] if 'Net Income' in income_statement.index else None, 'Gross Profit': income_statement.loc['Gross Profit'].iloc[0] if 'Gross Profit' in income_statement.index else None } # Growth Indicators growthIndicators = { 'Revenue Growth (YoY)': income_statement.loc['Revenue Growth'].iloc[0] if 'Revenue Growth' in income_statement.index else None, 'Profit Margins': (incomeStatement['Net Income'] / incomeStatement['Total Revenue']) * 100 if incomeStatement['Total Revenue'] else None, 'ROE (Return on Equity)': balanceSheetInformation.get('Return on Equity (ROE)', None), 'ROA (Return on Assets)': balanceSheetInformation.get('Return on Assets (ROA)', None) } # Assuming your original cashFlowStatement dict is defined here cashFlowStatement = { 'Operating Cash Flow': cash_flow_statement.loc['Operating Cash Flow'].iloc[0] if 'Operating Cash Flow' in cash_flow_statement.index else None, 'Investing Cash Flow': cash_flow_statement.loc['Investing Cash Flow'].iloc[0] if 'Investing Cash Flow' in cash_flow_statement.index else None, 'Financing Cash Flow': cash_flow_statement.loc['Financing Cash Flow'].iloc[0] if 'Financing Cash Flow' in cash_flow_statement.index else None, 'Cash Flow to Debt Ratio': ( cash_flow_statement.loc['Operating Cash Flow'].iloc[0] / balance_sheet.loc['Long Term Debt'].iloc[0] if 'Operating Cash Flow' in cash_flow_statement.index and 'Long Term Debt' in balance_sheet.index else None ) } # Replace NaN or None values with 'N/A' cashFlowStatement = {k: ('N/A' if pd.isna(v) else v) for k, v in cashFlowStatement.items()} # Company Overview Data companyOverview = { 'Company Name': fundamental_data.get('longName', None), 'Sector': fundamental_data.get('sector', None), 'Industry': fundamental_data.get('industry', None) } # Risk Indicators riskIndicators = { 'Debt-to-Equity Ratio(Risk)': balanceSheetInformation.get('Long Term Debt', None) / balanceSheetInformation.get('Total Stockholder Equity', None) if balanceSheetInformation.get('Long Term Debt') and balanceSheetInformation.get('Total Stockholder Equity') else None, 'Interest Coverage Ratio': income_statement.loc['Interest Coverage'].iloc[0] if 'Interest Coverage' in income_statement.index else None, 'Beta (Stock Volatility)': fundamental_data.get('beta', None), 'Quick Ratio': (balanceSheetInformation.get('Current Assets', None) - balanceSheetInformation.get('Inventory', None)) / balanceSheetInformation.get('Current Liabilities', None) if balanceSheetInformation.get('Current Assets') and balanceSheetInformation.get('Inventory') and balanceSheetInformation.get('Current Liabilities') else None } # Dividends dividends = { 'Payout Ratio': fundamental_data.get('payoutRatio', None), 'Dividend Growth Rate': fundamental_data.get('dividendGrowthRate', None) } # Profitability Indicators profitabilityIndicators = { 'Gross Margin': (income_statement.loc['Gross Profit'].iloc[0] / income_statement.loc['Total Revenue'].iloc[0]) * 100 if 'Gross Profit' in income_statement.index and 'Total Revenue' in income_statement.index else None, 'Operating Margin': (income_statement.loc['Operating Income'].iloc[0] / income_statement.loc['Total Revenue'].iloc[0]) * 100 if 'Operating Income' in income_statement.index and 'Total Revenue' in income_statement.index else None, 'Net Margin': (income_statement.loc['Net Income'].iloc[0] / income_statement.loc['Total Revenue'].iloc[0]) * 100 if 'Net Income' in income_statement.index and 'Total Revenue' in income_statement.index else None } # Liquidity Indicators liquidityIndicators = { 'Cash Ratio': balance_sheet.loc['Cash And Cash Equivalents'].iloc[0] / balance_sheet.loc['Current Liabilities'].iloc[0] if 'Cash And Cash Equivalents' in balance_sheet.index and 'Current Liabilities' in balance_sheet.index else None, 'Working Capital': balance_sheet.loc['Current Assets'].iloc[0] - balance_sheet.loc['Current Liabilities'].iloc[0] if 'Current Assets' in balance_sheet.index and 'Current Liabilities' in balance_sheet.index else None } investorInsightMetrics = { 'EPS': eps, 'P/E Ratio': pe_ratio, 'Revenue Growth': revenue_growth, 'Debt-to-Equity Ratio': debt_to_equity, 'Earnings Growth(YoY)': earnings_growth_yoy } result = { 'EPS': eps_status, 'P/E Ratio': pe_ratio_status, 'Revenue Growth': revenue_growth_status, 'Debt-to-Equity Ratio': debt_to_equity_status, 'Earnings Growth(YoY)': earnings_growth_status } def replace_nan_with_na(data): if isinstance(data, dict): return {k: replace_nan_with_na(v) for k, v in data.items()} elif isinstance(data, list): return [replace_nan_with_na(v) for v in data] elif pd.isna(data): return 'N/A' else: return data return replace_nan_with_na({ "fa_strategy": result, "overall_fa_score": round(overall_fa_score, 2), "Investor Insight Metrics": investorInsightMetrics, "Company Overview": companyOverview, "Growth Indicators": growthIndicators, "Risk Indicators": riskIndicators, "Dividends": dividends, "Cash Flow Statement": cashFlowStatement, "Financial Metrics": financialMetrics, "Income Statement": incomeStatement, "BalanceSheet Information": balanceSheetInformation, "Profitability Indicators": profitabilityIndicators, "Liquidity Indicators": liquidityIndicators, })