Spaces:
Running
Running
File size: 13,576 Bytes
66dc1bf |
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
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,
})
|