StockPred-Backend / app /services /market_data.py
Anurag33Gaikwad's picture
Update app/services/market_data.py
e8aaca5 verified
Raw
History Blame
2.33 kB
from typing import Tuple
import pandas as pd
import requests
from fastapi import HTTPException
from app.config import get_settings
from app.indicators import add_technical_indicators
settings = get_settings()
ALPHA_VANTAGE_URL = "https://www.alphavantage.co/query"
def fetch_raw_history(ticker: str) -> pd.DataFrame:
"""
Fetch OHLCV daily data from Alpha Vantage (FREE endpoint).
Replaces yfinance for HF Spaces compatibility.
"""
params = {
"function": "TIME_SERIES_DAILY",
"symbol": ticker,
"apikey": settings.alpha_vantage_api_key,
"outputsize": "compact",
}
try:
response = requests.get(ALPHA_VANTAGE_URL, params=params, timeout=10)
data = response.json()
except Exception:
raise HTTPException(
status_code=503,
detail="Market data provider unavailable",
)
if "Time Series (Daily)" not in data:
raise HTTPException(
status_code=400,
detail="Invalid ticker or API rate limit exceeded",
)
ts = data["Time Series (Daily)"]
df = pd.DataFrame.from_dict(ts, orient="index").astype(float)
df.index = pd.to_datetime(df.index)
df.sort_index(inplace=True)
df.rename(
columns={
"1. open": "Open",
"2. high": "High",
"3. low": "Low",
"4. close": "Close",
"5. volume": "Volume",
},
inplace=True,
)
if df.empty or len(df) < settings.history_window + 60:
raise HTTPException(
status_code=400,
detail="Not enough historical data for this ticker.",
)
return df[["Open", "High", "Low", "Close", "Volume"]]
def get_enriched_history(ticker: str) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
Returns:
- Raw OHLCV dataframe
- Technical-indicator-enriched dataframe
"""
df_raw = fetch_raw_history(ticker)
df_tech = add_technical_indicators(df_raw)
return df_raw, df_tech
def last_n_candles(df: pd.DataFrame, n: int) -> list[dict]:
"""
Used by frontend for recent price chart
"""
tail = df.tail(n)
return [
{
"date": idx.strftime("%Y-%m-%d"),
"price": float(row["Close"]),
}
for idx, row in tail.iterrows()
]