Contents

Trading Pipelines — End-to-End Financial ML Framework

A proof-of-concept project that proposes an end-to-end architecture for a financial machine learning framework. It covers the full lifecycle — from raw market data ingestion and feature engineering to model training, hyperparameter optimization, model serving, and interactive visualization — all orchestrated as reproducible pipelines.

Architecture

The system is composed of five main layers:

Data Ingestion

Raw financial data is loaded into a local DuckDB database using dlt incremental pipelines, orchestrated by Apache Airflow:

  • Yahoo Finance — daily, weekly, and monthly OHLCV prices, company metadata, and news for 50+ US equities via the yfinance API.
  • HuggingFace (FNSPID) — a large external dataset of historical stock news article titles.

Feature Engineering

SQLMesh transforms raw data into a rich feature store inside DuckDB:

  • Technical indicators — returns, log returns, SMA/EMA, RSI, MACD, Bollinger Bands, ATR, stochastic oscillator, momentum, and more (~60+ features per row).
  • Calendar features — hour, day of week, month, quarter, year with cyclical sin/cos encodings.
  • LLM-powered embeddings — semantic descriptions and vector embeddings for each ticker generated via Ollama (Gemma 3), plus news article title embeddings.

Machine Learning Models

Three model families, all tracked in MLflow:

FamilyPurposeImplementations
ForecastPredict next-period stock returnsDense NN, Conv1D+LSTM, Transformer encoder, XGBoost
EncodingCompress ticker behavior into a latent spacePCA, KMeans, β-VAE (Conv1D+LSTM encoder/decoder)
AgentsRL-based portfolio allocationBranching DQN, PPO (continuous), Threshold (rule-based baseline)

Dataset generation creates lagged feature matrices with randomized lag intervals, logged as MLflow artifacts. Hyperparameter optimization is powered by Optuna with nested MLflow tracking. Forecast and encoding models feed into the trading agents — the agent observes predicted returns plus latent encodings and outputs portfolio weight allocations.

Model Serving

An orchestrator polls the MLflow model registry for models tagged with a "serve" alias, spawns inference instances, and routes traffic through an Nginx reverse proxy with automatic config reloading.

Dashboard

An interactive Plotly Dash application with three pages:

PageDescription
OverviewTicker embedding space visualization (PCA scatter), semantic descriptions, price charts, filterable data table
ForecastSelect a served model and visualize predicted vs. actual returns for any ticker and time range
AgentsRun full agent simulations with KPIs (Sharpe ratio, max drawdown, win rate), portfolio value over time, daily returns, and per-ticker trade logs

Tech Stack

LayerTechnologies
OrchestrationApache Airflow 3, Docker Compose
Ingestiondlt, yfinance, HuggingFace API
StorageDuckDB
Feature EngineeringSQLMesh
ML / DLTensorFlow/Keras, XGBoost, scikit-learn, JAX
Experiment TrackingMLflow
OptimizationOptuna
EmbeddingsOllama (Gemma 3)
RL EnvironmentCustom Gym-style trading environment
ServingMLflow Model Serving, Nginx
VisualizationPlotly Dash

Running It

The entire stack runs via Docker Compose:

1
2
make up    # Start all services (Airflow, MLflow, model serving, dashboard, Postgres)
make down  # Stop all services

Airflow DAGs are executed in sequence: data ingestion → feature engineering → dataset generation → (optional) hyperparameter optimization → model training. After training, assigning a "serve" alias to a model version in MLflow makes it available through the serving endpoint and the dashboard.

Code is available HERE