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,
    })