Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

News-Driven Market Analysis ETL Pipeline

Project Overview

A free-tier event-driven ETL pipeline that ingests news events and market data, aligns them by timestamp, and analyzes how crypto (BTC), oil, and gold react to breaking news.

This project correlates news events with price movements to detect:

  • Sudden price moves after relevant news
  • Measurable returns following market-moving events
  • Asset reaction comparisons (which asset reacts most to the same news)
  • Abnormal spikes compared to normal volatility patterns

Main Analysis Questions

  1. Did a sudden price move happen after relevant news?

    • Example: Iran/war news β†’ oil spikes after
  2. How much did the asset move after the news?

    • Example: BTC moves +2% in 1 hour after a headline
  3. Which asset reacted the most to the same news?

    • Example: oil +3%, gold +1%, BTC -0.5%
  4. Was the move abnormal?

    • Example: oil jumps above its normal volatility range after news

Data Sources

Crypto (Real-time & Batch)

  • Binance WebSocket API β†’ real-time streaming data
  • Binance REST API β†’ historical/batch data
  • Primary asset: Bitcoin (BTC)
  • Documentation: Binance API Docs

Commodities (Periodic Polling)

  • Yahoo Finance (yfinance) β†’ batch ingestion
  • Assets: Oil (Crude) & Gold
  • Documentation: yfinance Docs

News Events (Micro-batch)

  • GDELT 2.0 β†’ near-real-time news ingestion
  • Documentation: GDELT 2.0 API

Architecture & Tech Stack

Core Technologies

Component Technology Purpose
Data Ingestion Python (requests, python-binance) Batch & real-time API polling
Streaming Apache Kafka Event streaming for real-time market data
Transformation Apache Spark (PySpark) Distributed data processing & analysis
Data Lake MinIO (S3-compatible) Raw & processed data storage (Bronze/Silver/Gold layers)
Database Neon PostgreSQL Analytical tables & metadata
Orchestration Prefect Workflow scheduling & monitoring
Visualization Streamlit Interactive dashboards & insights
Containerization Docker & Docker Compose Multi-service deployment
Monitoring Grafana Metrics & observability

Project Structure

data_engineering/
β”œβ”€β”€ db/                          # Database layer
β”‚   β”œβ”€β”€ schemas/                # SQLAlchemy ORM models
β”‚   β”‚   β”œβ”€β”€ dim_asset.py       # Asset dimension table (BTC, Oil, Gold)
β”‚   β”‚   β”œβ”€β”€ dim_news.py        # News dimension table (headlines, sources)
β”‚   β”‚   β”œβ”€β”€ fact_news_market.py # Fact table linking news & prices
β”‚   β”‚   β”œβ”€β”€ pipeline_run.py    # Pipeline execution metadata
β”‚   β”‚   └── task.py            # Task execution tracking
β”‚   β”œβ”€β”€ config_db.py           # Database configuration
β”‚   β”œβ”€β”€ init_db.py             # Schema initialization
β”‚   β”œβ”€β”€ session_db.py          # SQLAlchemy session management
β”‚   └── base_db.py             # Base database classes
β”‚
β”œβ”€β”€ ingestion/                  # Batch ingestion layer
β”‚   β”œβ”€β”€ ingestion.py           # Main ingestion orchestration
β”‚   └── sources/               # Individual data source clients
β”‚       β”œβ”€β”€ binance_client/    # Binance REST API client (BTC prices)
β”‚       β”œβ”€β”€ news_client/       # GDELT news client
β”‚       └── yfinance_client/   # Yahoo Finance client (Oil, Gold)
β”‚
β”œβ”€β”€ streaming/                 # Real-time streaming layer
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   └── configuration.py   # Kafka & streaming config
β”‚   └── streaming/
β”‚       β”œβ”€β”€ producer.py        # Kafka producer (publish market events)
β”‚       └── consumer.py        # Kafka consumer (subscribe to streams)
β”‚
β”œβ”€β”€ spark/                     # PySpark transformations (core processing)
β”‚   β”œβ”€β”€ jobs/                 # Spark job scripts
β”‚   β”‚   β”œβ”€β”€ bitcoin.py        # BTC analysis job
β”‚   β”‚   β”œβ”€β”€ gold.py           # Gold analysis job
β”‚   β”‚   β”œβ”€β”€ news.py           # News processing job
β”‚   β”‚   β”œβ”€β”€ oil.py            # Oil analysis job
β”‚   β”‚   └── bronze_to_silver/ # Raw β†’ Cleaned data transformation
β”‚   β”‚       └── crypto/stream.py
β”‚   └── transformation/        # Spark utilities
β”‚       β”œβ”€β”€ utils.py          # Spark utility functions
β”‚       └── silver_to_gold/   # Cleaned β†’ Analytics transformation
β”‚           └── aggregate.py  # Aggregations & correlations
β”‚
β”œβ”€β”€ pipeline/                  # Pipeline orchestration (Prefect)
β”‚   β”œβ”€β”€ main_flow.py          # Master Prefect flow
β”‚   └── pipeline_per_source.py # Per-source pipeline definitions
β”‚
β”œβ”€β”€ load/                      # Data loading layer
β”‚   └── load.py               # Load transformations into Neon DB
β”‚
β”œβ”€β”€ transformation/            # Additional ETL utilities
β”‚   └── transformation.py      # Data transformation helpers
β”‚
β”œβ”€β”€ utils/                    # Utility modules
β”‚   β”œβ”€β”€ minio_client/         # MinIO S3 client wrapper
β”‚   └── time_client/          # Timestamp & time utilities
β”‚
β”œβ”€β”€ docker/                   # Docker image definitions
β”‚   β”œβ”€β”€ base/                # Base image with dependencies
β”‚   β”œβ”€β”€ client/              # Client-side container
β”‚   β”œβ”€β”€ master/              # Prefect Master scheduler
β”‚   β”œβ”€β”€ worker/              # Prefect Worker executor
β”‚   └── streamlit/           # Streamlit dashboard container
β”‚       β”œβ”€β”€ Dockerfile
β”‚       β”œβ”€β”€ requirements.txt
β”‚       └── streamlit.py     # Dashboard application
β”‚
β”œβ”€β”€ grafana/                 # Monitoring & observability
β”‚   └── provisioning/        # Grafana datasources config
β”‚       └── datasources/postgres.yaml
β”‚
β”œβ”€β”€ minio_data/              # Local MinIO storage (S3-compatible)
β”‚   β”œβ”€β”€ raw-data/            # Bronze layer - raw ingested data
β”‚   β”‚   β”œβ”€β”€ binance/bitcoin/ (JSON files)
β”‚   β”‚   β”œβ”€β”€ news/arabic/     (JSON files)
β”‚   β”‚   └── yfinance/oil/ & gold/
β”‚   β”œβ”€β”€ raw-data-staging/    # Temporary staging area
β”‚   β”œβ”€β”€ silver-data/         # Silver layer - cleaned data
β”‚   β”‚   └── {source}/{asset}/ (_SUCCESS markers)
β”‚   β”œβ”€β”€ silver-data-staging/ # Temporary staging
β”‚   β”‚   └── {source}/{asset}/
β”‚   └── gold-data/           # Gold layer - analytics-ready data (Parquet)
β”‚
β”œβ”€β”€ docs/                    # Detailed documentation
β”‚   β”œβ”€β”€ batch-ingestion.md   # Batch ingestion workflow & commands
β”‚   β”œβ”€β”€ streaming-ingestion.md # Kafka streaming setup
β”‚   └── spark-transformation.md # Spark job details
β”‚
β”œβ”€β”€ docker-compose.yml       # Multi-service orchestration
β”œβ”€β”€ Dockerfile              # Main application image
β”œβ”€β”€ requirements.txt        # Python dependencies (Flask, Spark, etc.)
└── README.md              # This file

High-Level Pipeline Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    1. DATA INGESTION                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   Binance    β”‚  β”‚  Yahoo Fin.  β”‚  β”‚ GDELT News       β”‚ β”‚
β”‚  β”‚ REST API     β”‚  β”‚  (yfinance)  β”‚  β”‚ Micro-batches    β”‚ β”‚
β”‚  β”‚ (BTC prices) β”‚  β”‚ (Oil, Gold)  β”‚  β”‚ (Headlines)      β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚         β”‚                 β”‚                   β”‚           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                 β”‚                   β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          2. STORE RAW DATA (MinIO Bronze Layer)           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  β”œβ”€β”€ minio_data/raw-data/binance/bitcoin/                β”‚
β”‚  β”œβ”€β”€ minio_data/raw-data/yfinance/oil/ & gold/           β”‚
β”‚  └── minio_data/raw-data/news/arabic/                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      3. SPARK TRANSFORMATION (PySpark Distributed)         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  Bronze β†’ Silver (spark/jobs/bronze_to_silver/)           β”‚
β”‚  β”œβ”€β”€ Normalize timestamps to UTC                          β”‚
β”‚  β”œβ”€β”€ Parse & validate JSON                               β”‚
β”‚  β”œβ”€β”€ Remove duplicates & null values                      β”‚
β”‚  β”œβ”€β”€ Partition by asset & date for optimization          β”‚
β”‚  └── Output: Parquet files to silver-data/               β”‚
β”‚                                                             β”‚
β”‚  Silver β†’ Gold (spark/transformation/silver_to_gold/)    β”‚
β”‚  β”œβ”€β”€ Calculate returns (1h, 4h, 24h windows)             β”‚
β”‚  β”œβ”€β”€ Compute volatility metrics                          β”‚
β”‚  β”œβ”€β”€ Detect price spikes & anomalies                     β”‚
β”‚  β”œβ”€β”€ Correlate news events with price moves              β”‚
β”‚  └── Output: Analytics-ready Parquet to gold-data/       β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   4. STORE PROCESSED DATA (MinIO Silver/Gold Layers)        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  β”œβ”€β”€ minio_data/silver-data/ (cleaned Parquet)           β”‚
β”‚  └── minio_data/gold-data/ (analytics-ready Parquet)     β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    5. LOAD INTO DATABASE (Neon PostgreSQL)                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  β”œβ”€β”€ dim_asset (BTC, Oil, Gold metadata)                 β”‚
β”‚  β”œβ”€β”€ dim_news (news headlines & metadata)                β”‚
β”‚  β”œβ”€β”€ fact_news_market (correlations & analysis)          β”‚
β”‚  └── pipeline_run & task (execution tracking)            β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   6. ORCHESTRATION & MONITORING                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  Prefect (Orchestration)                                  β”‚
β”‚  β”œβ”€β”€ Schedule daily/hourly jobs                          β”‚
β”‚  β”œβ”€β”€ Handle retries & failures                           β”‚
β”‚  └── Track pipeline runs in DB                           β”‚
β”‚                                                             β”‚
β”‚  Grafana (Monitoring)                                    β”‚
β”‚  β”œβ”€β”€ Query metrics from PostgreSQL                       β”‚
β”‚  β”œβ”€β”€ Display dashboards & alerts                         β”‚
β”‚  └── Monitor Spark job performance                       β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    7. VISUALIZATION & INSIGHTS (Streamlit)                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                             β”‚
β”‚  β”œβ”€β”€ Interactive price movement charts                    β”‚
β”‚  β”œβ”€β”€ News event timeline visualization                    β”‚
β”‚  β”œβ”€β”€ Correlation heatmaps (news vs prices)               β”‚
β”‚  β”œβ”€β”€ Anomaly detection alerts                            β”‚
β”‚  └── Asset reaction comparison dashboard                 β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

MVP Focus

The initial release includes:

  • Binance REST API for BTC historical data
  • Yahoo Finance for Oil & Gold periodic polling
  • GDELT 2.0 for news micro-batch ingestion
  • MinIO for data lake storage (Bronze/Silver/Gold layers)
  • Neon PostgreSQL for analytical tables
  • Streamlit dashboard for real-time insights
  • PySpark for distributed data transformations
  • Kafka for streaming architecture (simulated)
  • Prefect for workflow orchestration
  • Docker Compose for local development & deployment

Quick Start

Prerequisites

  • Docker & Docker Compose
  • Python 3.9+
  • Git

Installation & Setup

  1. Clone the repository

    git clone <repo-url>
    cd data_engineering
  2. Create environment file (.env)

    # Neon Database
    DATABASE_URL=postgresql://user:password@neon-host/dbname
    
    # MinIO
    MINIO_ROOT_USER=minioadmin
    MINIO_ROOT_PASSWORD=minioadmin
    MINIO_ENDPOINT=http://minio:9000
    
    # Binance API
    BINANCE_API_KEY=your_key
    BINANCE_API_SECRET=your_secret
    
    # Prefect
    PREFECT_API_URL=http://prefect:4200/api
    
  3. Start all services

    docker-compose up -d
  4. Initialize database

    docker-compose exec master python -m db.init_db
  5. Run first ingestion

    docker-compose exec master python -m ingestion.ingestion
  6. Run Spark transformations

    docker-compose exec master python -m spark.jobs.bitcoin
  7. View Streamlit dashboard

    http://localhost:8501
    

Data Schema

Dimension Tables

dim_asset

β”œβ”€β”€ asset_id (PK)
β”œβ”€β”€ asset_name (BTC, Oil, Gold)
β”œβ”€β”€ asset_type (Crypto, Commodity)
└── created_at

dim_news

β”œβ”€β”€ news_id (PK)
β”œβ”€β”€ headline
β”œβ”€β”€ source
β”œβ”€β”€ language
β”œβ”€β”€ published_at
└── gdelt_event_code

Fact Table

fact_news_market

β”œβ”€β”€ fact_id (PK)
β”œβ”€β”€ asset_id (FK)
β”œβ”€β”€ news_id (FK)
β”œβ”€β”€ price_before
β”œβ”€β”€ price_after
β”œβ”€β”€ price_change_pct
β”œβ”€β”€ returns_1h, 4h, 24h
β”œβ”€β”€ volatility_metric
β”œβ”€β”€ is_anomaly
β”œβ”€β”€ event_window (seconds after news)
└── created_at

Configuration

MinIO Buckets (S3-compatible, 3-tier data architecture)

  • raw-data/ β†’ Bronze layer (raw JSON/CSV from APIs)
  • silver-data/ β†’ Silver layer (cleaned Parquet, deduplicated)
  • gold-data/ β†’ Gold layer (analytics-ready, aggregated)

Neon Database

  • Multi-region support (default: US-East)
  • Autoscaling enabled for query spikes
  • Database branching for team collaboration

Kafka Topics (Streaming)

  • binance-btc-trades β†’ Real-time BTC price updates
  • news-events β†’ GDELT news stream
  • market-alerts β†’ Anomaly detections

βš™οΈ Spark Configuration

Spark Jobs Location

spark/jobs/          # Individual asset analysis jobs
spark/transformation/ # Shared utilities & aggregations

Execution Models

  • Batch: Run via Prefect on schedule (daily/hourly)
  • Streaming: Consume from Kafka topics in real-time

Performance Tuning

  • Partitioning: By asset & date for optimized queries
  • Format: Parquet for efficient compression & columnar reads
  • Caching: In-memory caching for frequently accessed datasets
  • Shuffle Optimization: Coalesce partitions before writes

πŸ“Š Monitoring & Observability


πŸ› οΈ Development

Adding a New Data Source

  1. Create client in sources/<source_name>/
  2. Add ORM schema to db/schemas/
  3. Define ingestion task in pipeline/pipeline_per_source.py
  4. Add Spark transformation job in spark/jobs/
  5. Update Prefect flow in pipeline/main_flow.py

Performance Considerations

  • Spark: Partitioned by asset & date for optimized queries
  • Database: Indexes on (asset_id, timestamp) for fast lookups
  • MinIO: Parquet format for 80% compression & columnar efficiency
  • Kafka: 3 replicas for high availability & fault tolerance
  • Caching: Spark RDD caching for repeated transformations

Security Best Practices

  • All API credentials stored in .env (never commit!)
  • PostgreSQL password rotation recommended monthly
  • MinIO enabled with IAM policies per service
  • Docker secrets for production deployments
  • VPC isolation for cloud deployments

Contact & Support

For questions or issues:


Last Updated: April 28, 2026
Version: 0.1.0 (MVP)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages