Dmitry Beresnev
app refactoring
50e9fe0
Raw
History Blame Contribute Delete
2.97 kB
"""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