Spaces:
Sleeping
Sleeping
Create utils/finance_utils.py
Browse files- utils/finance_utils.py +82 -0
utils/finance_utils.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import yfinance as yf
|
| 2 |
+
import pandas as pd
|
| 3 |
+
from datetime import datetime, timedelta
|
| 4 |
+
|
| 5 |
+
class FinanceUtils:
|
| 6 |
+
def __init__(self):
|
| 7 |
+
pass
|
| 8 |
+
|
| 9 |
+
def get_stock_quote(self, ticker):
|
| 10 |
+
"""Get current stock quote and basic info"""
|
| 11 |
+
try:
|
| 12 |
+
stock = yf.Ticker(ticker)
|
| 13 |
+
info = stock.info
|
| 14 |
+
|
| 15 |
+
if not info or info.get('regularMarketPrice') is None:
|
| 16 |
+
return f"β No stock data found for {ticker}"
|
| 17 |
+
|
| 18 |
+
price = info.get('regularMarketPrice', 'N/A')
|
| 19 |
+
prev_close = info.get('previousClose', 'N/A')
|
| 20 |
+
change = price - prev_close if (price != 'N/A' and prev_close != 'N/A') else 'N/A'
|
| 21 |
+
change_pct = (change / prev_close * 100) if change != 'N/A' else 'N/A'
|
| 22 |
+
|
| 23 |
+
result = f"π° **Stock Quote for {ticker}**\n\n"
|
| 24 |
+
result += f"β’ **Current Price**: ${price:.2f}\n"
|
| 25 |
+
result += f"β’ **Previous Close**: ${prev_close:.2f}\n"
|
| 26 |
+
|
| 27 |
+
if change != 'N/A':
|
| 28 |
+
change_emoji = "π" if change >= 0 else "π"
|
| 29 |
+
result += f"β’ **Change**: {change_emoji} ${change:.2f} ({change_pct:.2f}%)\n"
|
| 30 |
+
|
| 31 |
+
result += f"β’ **Volume**: {info.get('volume', 'N/A'):,}\n"
|
| 32 |
+
result += f"β’ **Market Cap**: ${info.get('marketCap', 0):,}\n"
|
| 33 |
+
result += f"β’ **52W High**: ${info.get('fiftyTwoWeekHigh', 'N/A')}\n"
|
| 34 |
+
result += f"β’ **52W Low**: ${info.get('fiftyTwoWeekLow', 'N/A')}\n\n"
|
| 35 |
+
|
| 36 |
+
return result
|
| 37 |
+
|
| 38 |
+
except Exception as e:
|
| 39 |
+
return f"β Error fetching stock quote: {str(e)}"
|
| 40 |
+
|
| 41 |
+
def get_financial_summary(self, ticker):
|
| 42 |
+
"""Get key financial metrics"""
|
| 43 |
+
try:
|
| 44 |
+
stock = yf.Ticker(ticker)
|
| 45 |
+
info = stock.info
|
| 46 |
+
|
| 47 |
+
if not info:
|
| 48 |
+
return f"β No financial data found for {ticker}"
|
| 49 |
+
|
| 50 |
+
result = f"π **Financial Summary for {ticker}**\n\n"
|
| 51 |
+
|
| 52 |
+
# Revenue and Profit
|
| 53 |
+
revenue = info.get('totalRevenue', 'N/A')
|
| 54 |
+
if revenue != 'N/A':
|
| 55 |
+
result += f"β’ **Revenue (TTM)**: ${revenue:,}\n"
|
| 56 |
+
|
| 57 |
+
net_income = info.get('netIncomeToCommon', 'N/A')
|
| 58 |
+
if net_income != 'N/A':
|
| 59 |
+
result += f"β’ **Net Income**: ${net_income:,}\n"
|
| 60 |
+
|
| 61 |
+
# Ratios
|
| 62 |
+
pe_ratio = info.get('trailingPE', 'N/A')
|
| 63 |
+
if pe_ratio != 'N/A':
|
| 64 |
+
result += f"β’ **P/E Ratio**: {pe_ratio:.2f}\n"
|
| 65 |
+
|
| 66 |
+
pb_ratio = info.get('priceToBook', 'N/A')
|
| 67 |
+
if pb_ratio != 'N/A':
|
| 68 |
+
result += f"β’ **P/B Ratio**: {pb_ratio:.2f}\n"
|
| 69 |
+
|
| 70 |
+
debt_to_equity = info.get('debtToEquity', 'N/A')
|
| 71 |
+
if debt_to_equity != 'N/A':
|
| 72 |
+
result += f"β’ **Debt/Equity**: {debt_to_equity:.2f}\n"
|
| 73 |
+
|
| 74 |
+
# Dividend
|
| 75 |
+
dividend_yield = info.get('dividendYield', 'N/A')
|
| 76 |
+
if dividend_yield != 'N/A':
|
| 77 |
+
result += f"β’ **Dividend Yield**: {dividend_yield:.2%}\n"
|
| 78 |
+
|
| 79 |
+
return result
|
| 80 |
+
|
| 81 |
+
except Exception as e:
|
| 82 |
+
return f"β Error fetching financial data: {str(e)}"
|