Dmitry Beresnev
app refactoring
50e9fe0
"""Data fetching and processing utilities for the financial dashboard."""
import pandas as pd
from openbb import sdk
def load_stock_data(symbol: str) -> pd.DataFrame:
"""Load historical stock price data."""
df = sdk.equity.price.historical(symbol=symbol).to_dataframe()
return df
def load_company_profile(symbol: str):
"""Load company profile information."""
profile_response = sdk.equity.profile(symbol=symbol)
profile_info = profile_response.results[0] if hasattr(profile_response, 'results') and profile_response.results else None
return profile_info
def load_income_statement(symbol: str) -> pd.DataFrame:
"""Load company income statement data."""
income_stmt = sdk.equity.fundamental.income(symbol=symbol).to_dataframe()
return income_stmt
def calculate_technical_indicators(df: pd.DataFrame, period: int) -> pd.DataFrame:
"""Calculate SMA, EMA, and RSI indicators."""
df["SMA"] = df["close"].rolling(period).mean()
df["EMA"] = df["close"].ewm(span=period, adjust=False).mean()
# Calculate RSI
delta = df["close"].diff()
gain = delta.clip(lower=0)
loss = -1 * delta.clip(upper=0)
avg_gain = gain.rolling(period).mean()
avg_loss = loss.rolling(period).mean()
rs = avg_gain / avg_loss
df["RSI"] = 100 - (100 / (1 + rs))
return df
def format_financial_value(value) -> str:
"""Format financial values with appropriate units."""
if pd.isna(value):
return "N/A"
if abs(value) >= 1e9:
return f"${value/1e9:.2f}B"
elif abs(value) >= 1e6:
return f"${value/1e6:.2f}M"
else:
return f"${value:.2f}"
def get_price_metrics(df: pd.DataFrame) -> dict:
"""Calculate key price metrics."""
current_price = df["close"].iloc[-1]
prev_close = df["close"].iloc[-2] if len(df) > 1 else df["close"].iloc[0]
price_change = current_price - prev_close
price_change_pct = (price_change / prev_close) * 100 if prev_close != 0 else 0
return {
"current_price": current_price,
"price_change": price_change,
"price_change_pct": price_change_pct,
"high_52w": df['high'].max(),
"low_52w": df['low'].min(),
}
def get_profitability_metrics(income_data: pd.Series) -> dict:
"""Calculate profitability metrics from income statement."""
total_rev = income_data.get('total_revenue', 0)
gross_prof = income_data.get('gross_profit', 0)
net_inc = income_data.get('net_income', 0)
operating_inc = income_data.get('operating_income', 0)
metrics = {}
if total_rev and total_rev > 0:
metrics["gross_margin"] = (gross_prof / total_rev) * 100 if pd.notna(gross_prof) else 0
metrics["net_margin"] = (net_inc / total_rev) * 100 if pd.notna(net_inc) else 0
if operating_inc:
metrics["operating_margin"] = (operating_inc / total_rev) * 100
else:
metrics = {"gross_margin": 0, "net_margin": 0}
return metrics