Case Study 01

Stock Price Prediction Using LSTM

Bidirectional LSTM + attention, retrained daily on fresh data

PythonTensorFlowFastAPIStreamlitDockerAWS EC2
View on GitHub (opens in new tab)

The Problem

Stock price movement is notoriously hard to predict from raw historical prices alone — a lot of naive forecasting models effectively just lag the actual price by one time step and call it a prediction. The goal was to build something that goes beyond that: pulling in technical indicators and daily news sentiment as auxiliary signals, then packaging the whole thing as a pipeline that keeps itself current rather than going stale the day after training.

Approach

  1. 01Ran a daily cron job (weekdays) that pulled fresh OHLC data via yfinance and computed a full technical-indicator set — SMA, MACD, RSI, Bollinger Bands, Stochastic Oscillator, ATR, and OBV.
  2. 02In parallel, pulled the day's news headlines via NewsAPI and scored each one with VADER sentiment analysis.
  3. 03Merged the two streams by trading day, rolling weekend and holiday sentiment forward onto the next trading day so no signal was silently dropped.
  4. 04Retrained a Bidirectional LSTM with an attention mechanism on 16 features across 120-day sequences, using Huber loss for robustness to price outliers.
  5. 05Served predictions two ways: a FastAPI /predict endpoint (containerized with Docker, deployed on AWS EC2) for programmatic access, and a Streamlit dashboard for interactive use.

Visuals

Architecture diagram showing two parallel daily pipelines — fetching OHLC data and computing technical indicators, and fetching news and scoring sentiment with VADER — merging by trading day, feeding a Bidirectional LSTM with attention, served through both a FastAPI endpoint and a Streamlit dashboard, all triggered by a daily cron job
Pipeline: parallel stock + news ingestion → trading-day merge → BiLSTM with attention → served via FastAPI and Streamlit, retrained every weekday.

Results

15% improvement in prediction accuracy over baseline models.

MAE of 1.73 and RMSE of 2.91 on held-out test data.

Fully automated daily refresh — new data, new sentiment, and a retrained model with zero manual steps.

Reflection

The architecture ended up mattering as much as the data — moving from a plain LSTM to a bidirectional model with attention, and handling the weekend/holiday sentiment gap explicitly, both came from hitting real edge cases while building this rather than being obvious upfront. If I revisited this, I'd backtest the model against an actual trading strategy rather than point-accuracy metrics alone, since a lower MAE doesn't always translate into profitable decisions.