VanshGupta18
Forsyt
Python

Forsyt is an AI-powered, real-time geopolitical risk intelligence platform built specifically for Indian financial markets. It transforms global and regional news into the localized "India AI-GPR Index" to assess risks across trade corridors, sectors, and investment portfolios.

Last updated Aug 6, 2026
10
Stars
1
Forks
0
Issues
0
Stars/day
Attention Score
42
Language breakdown
Python 68.9%
TypeScript 25.2%
CSS 2.9%
JavaScript 2.1%
HTML 0.9%
โ–ธ Files click to expand
README

Forsyt โ€” Geopolitical Risk Intelligence System for Indian Markets

Forsyt Banner

Python License [Status]() [Institution]() [Capstone]() PRs Welcome

An AI-powered, real-time geopolitical risk intelligence platform built specifically for Indian financial markets.

Overview ยท Features ยท Getting Started ยท Architecture ยท Modules ยท API ยท Contributing ยท Roadmap


Table of Contents

- Prerequisites - Installation - Environment Configuration - Database Setup - Running the Data Pipeline - Running the NLP Extraction - Running the GPR Index Builder - Running ML Models - Running the Dashboard

Overview

Forsyt is a daily India geopolitical risk intelligence platform. It transforms unstructured Indian news into structured risk insights: a daily GPR index, 12 trade-corridor scores, a tagged event feed, and a dual-signal dashboard (geo risk + NIFTY vol side-by-side โ€” honest, not "GPR predicts NIFTY").

At its core, Forsyt builds the India GPR Index from 9 Indian news sources, validated against the Caldara-Iacoviello benchmark. The product surface is the unified API + dashboard โ€” see docs/PRODUCT.md for the full product definition.

Capstone Project โ€” BE Third Year, Computer Science & Engineering, Thapar Institute of Engineering & Technology, Patiala | CPG No. 300 | Marchโ€“December 2026

Motivation & Problem Statement

India's financial markets are increasingly sensitive to global geopolitical events โ€” border conflicts, sanctions, commodity shocks, diplomatic crises โ€” yet no dedicated, real-time, India-specific geopolitical intelligence platform exists.

Existing tools fall short in three critical ways:

| Gap | Problem | Forsyt's Solution | |-----|---------|-------------------| | Western Bias | Tools rely on Western media (NYT, FT, WSJ), missing India-specific regional events | 15โ€“20 curated Indian news sources | | Temporal Lag | Caldara GPR published monthly with 1-month delay | Daily index, updated every 24 hours | | No India Mapping | Global tools don't map risk to Indian sectors, corridors, or portfolios | Sector-level + corridor-level risk mapping |

With 170 million+ active Demat accounts in India as of 2024 โ€” a 3.6ร— increase since 2020 โ€” the demand for localized, data-driven geopolitical intelligence has never been greater.


Features

Core Capabilities

  • Automated News Aggregation โ€” Monitors 9 Indian news sources (RSS) continuously
  • NLP Event Extraction โ€” Themes, tone, locations tagged on every article
  • India GPR Index โ€” Daily normalized geopolitical risk score validated against Caldara-Iacoviello
  • Corridor Risk Board โ€” 12 trade routes (Hormuz, LAC, Malacca, Red Seaโ€ฆ)
  • Dual-Signal Dashboard โ€” Geo GPR regime + NIFTY vol (market_only) + joint stress score
  • Historical Event Overlays โ€” Galwan, Pulwama, 26/11 markers on GPR charts

Product Surface (shipped)

  • ๐Ÿ“ฐ Event Feed โ€” Searchable tagged news via /api/events/feed
  • ๐Ÿšข Corridor Monitor โ€” Daily corridor scores via /api/corridors
  • ๐Ÿ“Š Dual-Signal Panel โ€” /api/market/dual-signal (geo + market vol side-by-side)
  • ๐Ÿ–ฅ๏ธ Dashboard MVP โ€” 4 screens at / (home, chart, corridors, events)

Research / Future (not product hero)

  • Academic validation (VAR, OOS backtest) in nifty-50/research/ โ€” internal QA only
  • Portfolio advisor and SHAP waterfall โ€” planned, not in capstone demo

System Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        DATA SOURCES                                 โ”‚
โ”‚  15-20 Indian News RSS Feeds + Web Scrapers + Official Sources      โ”‚
โ”‚  (Times of India, Economic Times, Hindu, PIB, MEA, Mint...)         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚  300-500 articles/day
                          โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              PHASE 1 โ€” DATA AGGREGATION PIPELINE                    โ”‚
โ”‚  RSS Parser โ†’ Full Article Extractor โ†’ Text Cleaner โ†’ Deduplicator  โ”‚
โ”‚  Output: raw_articles table (PostgreSQL)                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚
                          โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              PHASE 2 โ€” NLP EVENT EXTRACTION                         โ”‚
โ”‚  NER โ†’ Event Classification โ†’ Severity Scoring โ†’                   โ”‚
โ”‚  India Exposure Scoring โ†’ Sector Tagging โ†’ Geo Tagging              โ”‚
โ”‚  Output: structured_events table (PostgreSQL)                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ”‚
                          โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              PHASE 3 โ€” GPR INDEX CONSTRUCTION                       โ”‚
โ”‚  Daily Aggregation โ†’ Temporal Smoothing โ†’ Z-Score Normalization     โ”‚
โ”‚  Output: gpr_index table + Sub-indices (sector/corridor)            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
               โ”‚                              โ”‚
               โ–ผ                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  PHASE 4 โ€” VALIDATION    โ”‚    โ”‚  PHASE 5 โ€” FEATURE ENGINEERING      โ”‚
โ”‚  Caldara Correlation     โ”‚    โ”‚  GPR Lags + Market Features +       โ”‚
โ”‚  Event Backtesting       โ”‚    โ”‚  Corridor Features + Sector Weights โ”‚
โ”‚  Market Alignment Tests  โ”‚    โ”‚  Train/Test Split (2020โ€“22/23โ€“26)   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                   โ”‚
                                                   โ–ผ
                                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                โ”‚  PHASE 6 โ€” ML MODEL DEVELOPMENT     โ”‚
                                โ”‚  Logistic Regression (Baseline)     โ”‚
                                โ”‚  XGBoost (Primary)                  โ”‚
                                โ”‚  LSTM (Optional)                    โ”‚
                                โ”‚  SHAP Explainability Framework      โ”‚
                                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                   โ”‚
                                                   โ–ผ
                                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                โ”‚  PHASE 7 โ€” INTELLIGENCE DASHBOARD   โ”‚
                                โ”‚  React.js Frontend + REST APIs      โ”‚
                                โ”‚  GPR Charts, Corridor Map,          โ”‚
                                โ”‚  Portfolio Calculator, XAI Views    โ”‚
                                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                   โ”‚
                                                   โ–ผ
                                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                โ”‚  PHASE 8 โ€” USER TESTING & VALIDATIONโ”‚
                                โ”‚  Two-Wave Testing (12-18 Users)     โ”‚
                                โ”‚  Finance / Supply Chain / Retail    โ”‚
                                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Modules

Module 1: Data Aggregation Pipeline (/ingestion)

Continuously monitors and collects articles from 15โ€“20 curated Indian news sources.

Sources covered:

  • National: Times of India, The Hindu, Hindustan Times, Indian Express, NDTV
  • Business/Finance: Economic Times, Mint, Business Standard, Financial Express, Moneycontrol
  • Regional: Deccan Herald, Telegraph India, Tribune India
  • Official: PIB (Press Information Bureau), Ministry of External Affairs
  • Optional Hindi: Dainik Jagran, Amar Ujala
Key functions:
  • RSS feed parsing (feedparser)
  • Full article extraction (newspaper3k)
  • Text cleaning and normalization
  • URL-based deduplication (SHA-256 hashing)
  • Automated scheduling (every 6 hours)

Module 2: NLP Event Extraction (/extraction)

Transforms unstructured article text into structured geopolitical event records.

Pipeline stages:

  • Named Entity Recognition (NER) โ€” actors, locations, organizations
  • Event type classification โ€” 8 categories (militaryconflict, sanctions, terrorism, protest, policychange, diplomatictension, cyberattack, economic_shock)
  • Severity scoring (0.0โ€“1.0)
  • India exposure scoring (0.0โ€“1.0)
  • Confidence scoring (0.0โ€“1.0)
  • Sector tagging (IT, Energy, Banking, Pharma, etc.)
  • Geographic/corridor tagging
Output schema per event:
{   "eventid": "sha256hash",   "date": "YYYY-MM-DD",   "eventtype": "borderconflict",   "severity": 0.78,   "india_exposure": 0.85,   "confidence": 0.92,   "actors": ["China", "India"],   "location": "Ladakh",   "sectors_affected": ["Defense", "Energy"],   "corridor_affected": "China-India (Ladakh)",   "summary": "One-sentence event description" }


Module 3: India AI-GPR Index Builder (/gpr_index)

Aggregates structured events into a daily, normalized geopolitical risk index.

Methodology:

Step 1 โ€” Raw Aggregation:   GPRraw(t) = ฮฃ [severityi ร— indiaexposurei ร— confidence_i]                for all events on day t

Step 2 โ€” Temporal Smoothing (3-day moving average): GPRsmoothed(t) = [GPRraw(t-1) + GPRraw(t) + GPRraw(t+1)] / 3

Step 3 โ€” Z-Score Normalization (rolling 12-month window): IndiaAIGPR(t) = [GPRsmoothed(t) - ฮผ12m(t)] / ฯƒ_12m(t)

Interpretation scale: | Score | Level | Interpretation | |-------|-------|----------------| | < 0 | Low | Below-average geopolitical risk | | 0 โ€“ 1 | Moderate | Slightly elevated risk | | 1 โ€“ 2 | Elevated | Significant risk above baseline | | 2 โ€“ 3 | High | Major geopolitical event detected | | > 3 | Critical | Extreme geopolitical stress |


Module 4: ML Models & Explainability (/ml_inference)

Three application-specific ML models backed by a unified SHAP explainability framework.

Application 1 โ€” Supply Chain Corridor Risk:

  • Predicts risk scores (0โ€“100) for 8โ€“12 major trade corridors
  • 7โ€“14 day temporal forecast
  • SHAP: explains which events drive corridor risk
Application 2 โ€” Portfolio Geopolitical Exposure:
  • Quantifies portfolio exposure by sector sensitivity weights
  • Input: portfolio holdings (ticker + weight)
  • Output: total GPR exposure score + SHAP-based sector decomposition
Application 3 โ€” Dual-Signal Market Context (product):
  • Geopolitical: daily India GPR regime from Forsyt news pipeline
  • Market: NIFTY 5-day vol forecast using market_only features (no GPR in forecast)
  • Joint stress: transparent 60% geo + 40% vol percentile composite
  • Historical analog: what NIFTY did on past days with similar GPR levels

Module 5: Intelligence Dashboard (/dashboard)

React.js web application with five core views:

| View | Description | |------|-------------| | Home | Real-time India AI-GPR score, risk level, event feed | | Corridor Risk | Interactive map of 8โ€“12 trade corridors color-coded by risk | | Portfolio Advisor | Input holdings โ†’ exposure score + sector decomposition | | Macro Regime | Current Nifty volatility regime + contributing factor chart | | Event Explorer | Searchable event database with filters (type, severity, date) |


Tech Stack

| Layer | Technology | |-------|------------| | Language | Python 3.10+ | | NLP Models | Hugging Face Transformers (BERT-based), open-source | | ML Models | XGBoost, scikit-learn, PyTorch (LSTM optional) | | Explainability | SHAP (TreeExplainer, DeepExplainer) | | Database | PostgreSQL 15+ | | Web Scraping | feedparser, newspaper3k, BeautifulSoup4, Scrapy | | Market Data | yfinance | | Frontend | React.js, Recharts / D3.js, Tailwind CSS | | Backend API | REST APIs (Python) | | Scheduling | APScheduler / cron | | Version Control | GitHub | | Development | VS Code, Jupyter Notebook | | Cloud Execution | Google Colab (model training) | | Containerization | Docker (optional, for deployment) |


Getting Started

Prerequisites

Ensure the following are installed and configured on your system before proceeding.

System Requirements:

  • OS: Ubuntu 22.04 / macOS 13+ / Windows 11 (WSL2 recommended)
  • RAM: 8 GB minimum (16 GB recommended for model training)
  • Storage: 10 GB free space minimum
  • Internet connection required (for RSS feeds, API access, market data)
Required Software:

# Python 3.10 or higher
python --version   # Should output Python 3.10.x or above

Node.js 18+ (for dashboard)

node --version # Should output v18.x.x or above

PostgreSQL 15+

psql --version # Should output psql 15.x or above

Git

git --version

Install Python (if not installed):

# Ubuntu/Debian sudo apt update && sudo apt install python3.10 python3.10-venv python3-pip -y

macOS (using Homebrew)

brew install python@3.10

Windows

Download from https://www.python.org/downloads/

PostgreSQL (Supabase โ€” required):

Forsyt uses a hosted Supabase Postgres database. You do not need a local PostgreSQL install.

  • Create a project at supabase.com
  • Copy the Transaction pooler URI (port 6543) from Project Settings โ†’ Database
  • Paste it into newsdataset/.env as DATABASEURL
Tables are created automatically on first import of news_dataset.db.

Installation

Step 1 โ€” Clone the Repository

git clone https://github.com/[YOURGITHUBORG]/forsyt.git
cd forsyt

Step 2 โ€” Create and Activate a Virtual Environment

# Create virtual environment
python3.10 -m venv venv

Activate (Linux/macOS)

source venv/bin/activate

Activate (Windows)

.\venv\Scripts\activate

Step 3 โ€” Install Python Dependencies

# Upgrade pip first
pip install --upgrade pip

Install all dependencies

pip install -r requirements.txt

Step 4 โ€” Install Frontend Dependencies

cd dashboard
npm install
cd ..

Step 5 โ€” Download NLP Model Weights

# Run the model download script
python scripts/download_models.py
This downloads the pre-trained transformer models from Hugging Face (~500 MB). Ensure a stable internet connection.

Environment Configuration

Step 1 โ€” Copy the Example Environment File

cp newsdataset/.env.example newsdataset/.env

Step 2 โ€” Fill in Required Values

Open news_dataset/.env and set your Supabase connection string:

# โ”€โ”€โ”€ DATABASE (Supabase) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
DATABASE_URL=postgresql://postgres.xxxx:password@aws-0-region.pooler.supabase.com:6543/postgres

โ”€โ”€โ”€ PIPELINE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

SCRAPE_INTERVAL=86400 FLASK_ENV=production
Security Note: Never commit your .env file. It is already listed in .gitignore.

Database Setup

Forsyt stores all news and indices in Supabase Postgres. Tables (articles, gprdaily, corridordaily, etc.) are created automatically when you first run any module that imports news_dataset.db.

No local PostgreSQL server or migration script is required. Set DATABASEURL in newsdataset/.env and start the API:

python -m news_dataset.api.server

Also add DATABASE_URL as a GitHub Actions secret for automated scrape and daily-index workflows.


Running the Project

Running the Data Pipeline

# Run once manually (fetch today's articles)
python ingestion/run_pipeline.py --mode once

Run continuously on schedule (every 6 hours, as per .env)

python ingestion/run_pipeline.py --mode scheduled

Run for a specific date range (backfill)

python ingestion/run_pipeline.py --mode backfill --start 2024-01-01 --end 2024-12-31

Dry run (test without writing to database)

python ingestion/run_pipeline.py --mode once --dry-run

Sample output:

[2026-03-24 03:00:12] INFO  Starting ingestion run... [2026-03-24 03:00:15] INFO  Fetching Times of India... 42 articles [2026-03-24 03:00:18] INFO  Fetching Economic Times... 38 articles [2026-03-24 03:00:20] INFO  Fetching The Hindu... 35 articles ... [2026-03-24 03:04:01] INFO  Total fetched: 487 articles [2026-03-24 03:04:03] INFO  After deduplication: 183 unique articles [2026-03-24 03:04:04] INFO  Stored to database: 183 records [2026-03-24 03:04:04] INFO  Ingestion complete. Duration: 232s


Running the NLP Extraction

# Process articles from today
python extraction/run_extraction.py --date today

Process articles from a specific date

python extraction/run_extraction.py --date 2026-03-24

Process a date range

python extraction/run_extraction.py --start 2026-01-01 --end 2026-03-24

Run with verbose output (shows each article processed)

python extraction/run_extraction.py --date today --verbose

Run quality check (outputs accuracy report for sampled events)

python extraction/quality_check.py --sample-size 100

Sample output:

[2026-03-24 04:00:02] INFO  Loading NLP model... [2026-03-24 04:00:08] INFO  Model loaded. Processing 183 articles... [2026-03-24 04:02:41] INFO  Extracted 183 raw event records [2026-03-24 04:02:42] INFO  After deduplication: 67 unique events [2026-03-24 04:02:43] INFO  Events by type:                             - border_conflict: 8                             - policy_change: 22                             - diplomatic_tension: 15                             - economic_shock: 12                             - other: 10 [2026-03-24 04:02:44] INFO  Average confidence: 0.81 [2026-03-24 04:02:44] INFO  Stored 67 structured events to database


Running the GPR Index Builder

# Build GPR index for today
python gprindex/buildindex.py --date today

Build GPR index for a date range

python gprindex/buildindex.py --start 2020-01-01 --end 2026-03-24

Build full historical backfill (2020โ€“present)

python gprindex/buildindex.py --mode backfill

View current GPR score

python gprindex/queryindex.py --date today

Export GPR series to CSV

python gprindex/exportindex.py --start 2020-01-01 --end 2026-03-24 --output gpr_export.csv

Sample output:

[2026-03-24 05:00:01] INFO  Building GPR index for 2026-03-24... [2026-03-24 05:00:02] INFO  Events loaded: 67 [2026-03-24 05:00:02] INFO  GPR_raw: 12.43 [2026-03-24 05:00:02] INFO  GPR_smoothed: 11.87 (3-day moving average) [2026-03-24 05:00:02] INFO  Rolling mean (12m): 10.52 [2026-03-24 05:00:02] INFO  Rolling std  (12m): 2.31 [2026-03-24 05:00:02] INFO  IndiaAIGPR (normalized): +0.58ฯƒ โ†’ MODERATE [2026-03-24 05:00:03] INFO  Index record stored successfully.


Running ML Models

# โ”€โ”€โ”€ TRAIN MODELS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

Train all models (baseline + XGBoost)

python ml_inference/train.py --model all

Train specific model

python ml_inference/train.py --model xgboost python mlinference/train.py --model logisticregression python ml_inference/train.py --model lstm # Optional

โ”€โ”€โ”€ EVALUATE MODELS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

Evaluate on test set (2023-2026)

python ml_inference/evaluate.py --model xgboost

Run walk-forward validation

python ml_inference/evaluate.py --model xgboost --walk-forward

โ”€โ”€โ”€ RUN INFERENCE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

Get today's volatility regime prediction

python ml_inference/predict.py --date today

Get SHAP explanation for today's prediction

python ml_inference/explain.py --date today

Generate SHAP summary plot (saves to /outputs/shap_summary.png)

python ml_inference/explain.py --plot summary

โ”€โ”€โ”€ CORRIDOR & PORTFOLIO MODELS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

Run corridor risk assessment

python mlinference/corridorrisk.py --corridor "China-India"

Run portfolio exposure analysis

python mlinference/portfoliorisk.py --holdings portfolio_sample.json

Running the Dashboard

# Start backend API server
python api/server.py --port 8000

In a separate terminal, start the React frontend

cd dashboard npm start

Open your browser at: http://localhost:3000

Production build:

cd dashboard npm run build 

Serve build/ with any static server or Nginx


Usage Examples

Example 1: Get the Current India AI-GPR Score

from forsyt.gpr_index import GPRIndex

gpr = GPRIndex() result = gpr.get_current()

print(f"Date: {result['date']}") print(f"GPR Score: {result['gpr_normalized']:.2f}ฯƒ") print(f"Risk Level: {result['risk_level']}") print(f"Top Contributing Events: {result['top_events']}")

Output:

Date: 2026-03-24 GPR Score: +0.58ฯƒ Risk Level: MODERATE Top Contributing Events: ['Iran oil tensions', 'India-China border talks', 'RBI policy review']


Example 2: Analyze Portfolio Geopolitical Exposure

from forsyt.ml_inference import PortfolioAdvisor

advisor = PortfolioAdvisor()

portfolio = { "TCS": 0.25, # 25% IT "Infosys": 0.15, # 15% IT "ONGC": 0.20, # 20% Energy "HDFC": 0.20, # 20% Banking "SunPharma": 0.20 # 20% Pharma }

result = advisor.analyze(portfolio)

print(f"Total GPR Exposure: {result['total_exposure']}/100") print("\nSector Breakdown:") for sector, data in result['sector_breakdown'].items(): print(f" {sector}: {data['exposure']:.0f}/100 ({data['shap_contribution']:.1%} of total risk)") print(f"\nExplanation: {result['naturallanguageexplanation']}")

Output:

Total GPR Exposure: 68/100

Sector Breakdown: IT (40%): 82/100 (48% of total risk) Energy (20%): 71/100 (28% of total risk) Banking (20%): 45/100 (18% of total risk) Pharma (20%): 22/100 (6% of total risk)

Explanation: Your portfolio carries HIGH geopolitical risk. IT holdings are most exposed due to US-China tech decoupling tensions. Consider reducing IT concentration or hedging with defensive Pharma/FMCG holdings.


Example 3: Assess Trade Corridor Risk

from forsyt.ml_inference import CorridorRisk

corridor = CorridorRisk() result = corridor.assess("China-India-Ladakh")

print(f"Corridor: {result['corridor']}") print(f"Risk Score: {result['riskscore']}/100 [{result['risklevel']}]") print(f"7-Day Forecast: {result['forecast_7d']}/100") print(f"\nSHAP Drivers:") for driver in result['shap_drivers']: print(f" +{driver['contribution']} โ€” {driver['factor']}: {driver['explanation']}")

Output:

Corridor: China-India (Ladakh Border) Risk Score: 82/100  [HIGH] 7-Day Forecast: 78/100

SHAP Drivers: +38 โ€” Border Tension Index: Ladakh GPR sub-index at +2.4ฯƒ (3-month high) +24 โ€” Diplomatic Events: 0 high-level bilateral meetings in past 30 days +12 โ€” Historical Pattern: Monsoon season historically correlates with patrol incidents +8 โ€” INR/CNY Volatility: Currency stress elevated during border tensions


Example 4: Predict Nifty Volatility Regime

from forsyt.ml_inference import MacroForecaster
from forsyt.explainability import SHAPExplainer

forecaster = MacroForecaster() explainer = SHAPExplainer(forecaster.model)

prediction = forecaster.predict_today() explanation = explainer.explain(prediction['features'])

print(f"Regime: {prediction['regime']}") print(f"Probability: {prediction['probabilityhighvol']:.1%}") print(f"\nTop Drivers:") for i, driver in enumerate(explanation['top_drivers'][:3], 1): print(f" {i}. {driver['feature']}: {driver['direction']} (+{driver['contribution']:.1%} risk)")

Output:

Regime: NORMAL (leaning elevated) Probability HIGH_VOL: 61%

Top Drivers: 1. Crude Oil Return (+3.5% today): Increases risk (+15.2%) 2. GPR_lag1 (+0.58ฯƒ): Moderate geopolitical elevation (+8.4%) 3. Nifty Return yesterday (-0.8%): Negative momentum (+10.1%)


API Reference

The Forsyt backend exposes a REST API consumed by the dashboard (news_dataset/api/server.py).

Implemented product endpoints:

| Endpoint | Description | |----------|-------------| | GET /api/gpr/current | Latest India GPR | | GET /api/gpr/history?start=&end= | GPR time series | | GET /api/corridors | All corridor scores (latest day) | | GET /api/corridors/{id} | Single corridor history | | GET /api/events/feed | NLP-tagged articles | | GET /api/market/dual-signal | Geo + NIFTY vol + joint stress | | GET /health, GET /stats, GET /news | Legacy ops endpoints |

Serve dashboard at GET /. Run: cd news_dataset/api && python server.py

Base URL

Development:  http://localhost:8000

Endpoints

GET /api/gpr/current

Returns the latest India AI-GPR score.

Response:

{   "date": "2026-03-24",   "gpr_normalized": 0.58,   "gpr_raw": 12.43,   "risk_level": "MODERATE",   "num_events": 67,   "top_events": [     {       "summary": "Iran oil facility strike raises crude prices",       "eventtype": "economicshock",       "severity": 0.68,       "sectors_affected": ["Energy", "Aviation"]     }   ],   "updated_at": "2026-03-24T05:00:03Z" }


GET /api/gpr/history

Returns historical GPR series.

Query Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | start_date | string (YYYY-MM-DD) | Yes | Start of date range | | end_date | string (YYYY-MM-DD) | Yes | End of date range | | format | string | No | json (default) or csv |

Response:

{   "start_date": "2024-01-01",   "end_date": "2024-12-31",   "count": 365,   "data": [     { "date": "2024-01-01", "gprnormalized": 0.32, "risklevel": "LOW" },     { "date": "2024-01-02", "gprnormalized": 0.45, "risklevel": "MODERATE" },     ...   ] }


GET /api/events/feed

Returns structured geopolitical events with optional filtering.

Query Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | date | string | No | Filter by specific date | | event_type | string | No | Filter by event type | | min_severity | float | No | Minimum severity threshold (0.0โ€“1.0) | | sector | string | No | Filter by affected sector | | limit | integer | No | Max results (default: 50) |


GET /api/volatility/signal

Returns ML-based volatility regime prediction with SHAP explanation.

Response:

{   "date": "2026-03-24",   "regime": "NORMAL",   "probabilityhighvol": 0.61,   "confidence": "MEDIUM",   "shap_drivers": [     {       "feature": "crudeoilreturn",       "value": 0.035,       "contribution": 0.152,       "direction": "increases_risk",       "explanation": "Oil up 3.5% โ€” historically linked to elevated market stress"     }   ] }


POST /api/portfolio/exposure

Analyzes geopolitical exposure for a given portfolio.

Request Body:

{   "holdings": {     "TCS.NS": 0.25,     "ONGC.NS": 0.20,     "HDFCBANK.NS": 0.20,     "SUNPHARMA.NS": 0.20,     "INFY.NS": 0.15   } }

Response:

{   "total_exposure": 68,   "risk_level": "HIGH",   "sector_breakdown": {     "IT": { "weight": 0.40, "exposure": 82, "shap_contribution": 0.48 },     "Energy": { "weight": 0.20, "exposure": 71, "shap_contribution": 0.28 }   },   "naturallanguageexplanation": "Your portfolio carries HIGH geopolitical risk...",   "recommendations": ["Reduce IT concentration", "Consider increasing Pharma allocation"] }


GET /api/corridor/risk

Returns risk scores for all or a specific trade corridor.

Query Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | corridor | string | Specific corridor name (optional โ€” returns all if omitted) | | forecast_days | integer | Number of days to forecast (default: 7) |


Configuration

All configurable parameters are managed through .env (for secrets/environment) and config/settings.yaml (for application logic).

config/settings.yaml

# โ”€โ”€โ”€ NEWS SOURCES โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
news_sources:
  max_sources: 20
  requesttimeoutseconds: 10
  max_retries: 3
  backoff_factor: 2
  minarticlewords: 100
  user_agent: "Forsyt-Bot/1.0 (Research Project; contact@forsyt.dev)"

โ”€โ”€โ”€ NLP PIPELINE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

nlp: model_name: "bert-base-multilingual-cased" # Change to preferred model batch_size: 32 maxtokenlength: 512 confidence_threshold: 0.50 # Events below this are excluded highconfidencethreshold: 0.80

โ”€โ”€โ”€ GPR INDEX โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

gpr_index: smoothingwindowdays: 3 normalizationwindowdays: 365 alertthresholdsigma: 2.0 # GPR spike alert (in ฯƒ)

โ”€โ”€โ”€ ML MODELS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

ml: train_start: "2020-01-01" train_end: "2022-12-31" test_start: "2023-01-01" volatilitywindowdays: 10 volatilityregimepercentile: 75 walkforwardretrain_months: 6 xgboost: n_estimators: 100 max_depth: 5 learning_rate: 0.1 subsample: 0.8

โ”€โ”€โ”€ CORRIDORS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

corridors: monitored: - "China-India-Ladakh" - "Pakistan-India-Wagah" - "Bangladesh-India-Petrapole" - "Nepal-India-Raxaul" - "Strait-of-Malacca" - "Persian-Gulf" - "Red-Sea-Suez" - "Delhi-Mumbai-Industrial"

โ”€โ”€โ”€ SECTORS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

sectors: monitored: - "IT" - "Energy" - "Banking" - "Pharma" - "Manufacturing" - "Agriculture" - "Defense" - "Telecom" - "Metals" - "Automobiles"

Testing

We maintain a comprehensive test suite across all modules.

Running Tests

# Run all tests
pytest tests/ -v

Run tests for a specific module

pytest tests/test_ingestion.py -v pytest tests/test_extraction.py -v pytest tests/testgprindex.py -v pytest tests/testmlmodels.py -v pytest tests/test_api.py -v

Run with coverage report

pytest tests/ --cov=forsyt --cov-report=html

Open htmlcov/index.html in browser to view coverage

Run only fast tests (skip slow integration tests)

pytest tests/ -v -m "not slow"

Run integration tests only

pytest tests/ -v -m "integration"

Test Coverage Targets

| Module | Target Coverage | |--------|----------------| | ingestion/ | โ‰ฅ 80% | | extraction/ | โ‰ฅ 75% | | gpr_index/ | โ‰ฅ 85% | | ml_inference/ | โ‰ฅ 75% | | api/ | โ‰ฅ 80% | | Overall | โ‰ฅ 78% |

Test Categories

tests/
โ”œโ”€โ”€ unit/                    # Fast, isolated unit tests
โ”‚   โ”œโ”€โ”€ testrssparser.py
โ”‚   โ”œโ”€โ”€ test_deduplication.py
โ”‚   โ”œโ”€โ”€ testgprformula.py
โ”‚   โ””โ”€โ”€ testshapoutput.py
โ”œโ”€โ”€ integration/             # Slower tests requiring DB connection
โ”‚   โ”œโ”€โ”€ testpipelineendtoend.py
โ”‚   โ”œโ”€โ”€ testmltraining.py
โ”‚   โ””โ”€โ”€ testapiendpoints.py
โ”œโ”€โ”€ validation/              # Backtesting and benchmark validation
โ”‚   โ”œโ”€โ”€ testcaldaracorrelation.py
โ”‚   โ”œโ”€โ”€ testeventbacktesting.py
โ”‚   โ””โ”€โ”€ testmlperformance.py
โ””โ”€โ”€ fixtures/                # Sample data for tests
    โ”œโ”€โ”€ sample_articles.json
    โ”œโ”€โ”€ sample_events.json
    โ””โ”€โ”€ sample_portfolio.json

Key Validation Tests

# Run Caldara GPR correlation test (requires historical index data)
pytest tests/validation/testcaldaracorrelation.py -v

Target: r โ‰ฅ 0.60, p < 0.05

Run event backtesting (17 major Indian geopolitical events)

pytest tests/validation/testeventbacktesting.py -v

Target: hit rate โ‰ฅ 80% (14/17 events)

Run ML performance benchmark

pytest tests/validation/testmlperformance.py -v

Target: F1 โ‰ฅ 0.60, ROC-AUC โ‰ฅ 0.65


Project Structure

forsyt/
โ”‚
โ”œโ”€โ”€ ingestion/                    # Phase 1: Data aggregation pipeline
โ”‚   โ”œโ”€โ”€ rss_parser.py             # RSS feed fetcher and parser
โ”‚   โ”œโ”€โ”€ web_scraper.py            # Web scraper for non-RSS sources
โ”‚   โ”œโ”€โ”€ article_extractor.py      # Full article text extraction
โ”‚   โ”œโ”€โ”€ text_cleaner.py           # Text normalization and cleaning
โ”‚   โ”œโ”€โ”€ deduplicator.py           # URL-hash-based deduplication
โ”‚   โ”œโ”€โ”€ scheduler.py              # APScheduler-based scheduling
โ”‚   โ”œโ”€โ”€ run_pipeline.py           # Pipeline entry point
โ”‚   โ””โ”€โ”€ sources.yaml              # List of all 15-20 news sources
โ”‚
โ”œโ”€โ”€ extraction/                   # Phase 2: NLP event extraction
โ”‚   โ”œโ”€โ”€ ner_tagger.py             # Named entity recognition
โ”‚   โ”œโ”€โ”€ event_classifier.py       # Event type classification
โ”‚   โ”œโ”€โ”€ severity_scorer.py        # Severity + India exposure scoring
โ”‚   โ”œโ”€โ”€ sector_tagger.py          # Sector and corridor tagging
โ”‚   โ”œโ”€โ”€ deduplicator.py           # Semantic event deduplication
โ”‚   โ”œโ”€โ”€ quality_check.py          # Accuracy validation on samples
โ”‚   โ””โ”€โ”€ run_extraction.py         # Extraction entry point
โ”‚
โ”œโ”€โ”€ gpr_index/                    # Phase 3: GPR index construction
โ”‚   โ”œโ”€โ”€ aggregator.py             # Daily event aggregation
โ”‚   โ”œโ”€โ”€ smoother.py               # Temporal smoothing
โ”‚   โ”œโ”€โ”€ normalizer.py             # Z-score normalization
โ”‚   โ”œโ”€โ”€ build_index.py            # Index builder entry point
โ”‚   โ”œโ”€โ”€ query_index.py            # Index query utilities
โ”‚   โ””โ”€โ”€ export_index.py           # CSV/JSON export
โ”‚
โ”œโ”€โ”€ validation/                   # Phase 4: Validation suite
โ”‚   โ”œโ”€โ”€ caldara_correlation.py    # Caldara GPR benchmark test
โ”‚   โ”œโ”€โ”€ event_backtesting.py      # 17-event backtesting
โ”‚   โ”œโ”€โ”€ market_alignment.py       # GPR vs Nifty volatility test
โ”‚   โ””โ”€โ”€ events_list.yaml          # 17 major events + expected spikes
โ”‚
โ”œโ”€โ”€ ml_inference/                 # Phases 5-6: ML models
โ”‚   โ”œโ”€โ”€ feature_engineering.py    # Feature construction (GPR + market)
โ”‚   โ”œโ”€โ”€ label_construction.py     # Volatility regime labels
โ”‚   โ”œโ”€โ”€ train.py                  # Model training entry point
โ”‚   โ”œโ”€โ”€ evaluate.py               # Performance evaluation
โ”‚   โ”œโ”€โ”€ predict.py                # Inference entry point
โ”‚   โ”œโ”€โ”€ corridor_risk.py          # Corridor risk models
โ”‚   โ”œโ”€โ”€ portfolio_risk.py         # Portfolio exposure models
โ”‚   โ”œโ”€โ”€ macro_forecaster.py       # Nifty regime predictor
โ”‚   โ””โ”€โ”€ explain.py                # SHAP explainability
โ”‚
โ”œโ”€โ”€ api/                          # REST API layer
โ”‚   โ”œโ”€โ”€ server.py                 # API server entry point
โ”‚   โ”œโ”€โ”€ routes/
โ”‚   โ”‚   โ”œโ”€โ”€ gpr_routes.py
โ”‚   โ”‚   โ”œโ”€โ”€ event_routes.py
โ”‚   โ”‚   โ”œโ”€โ”€ volatility_routes.py
โ”‚   โ”‚   โ”œโ”€โ”€ portfolio_routes.py
โ”‚   โ”‚   โ””โ”€โ”€ corridor_routes.py
โ”‚   โ””โ”€โ”€ schemas.py                # Pydantic response schemas
โ”‚
โ”œโ”€โ”€ dashboard/                    # React.js frontend
โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ GPRChart.jsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ CorridorMap.jsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ PortfolioAdvisor.jsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ RegimeIndicator.jsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ EventExplorer.jsx
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ SHAPExplainer.jsx
โ”‚   โ”‚   โ”œโ”€โ”€ pages/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Home.jsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Corridors.jsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Portfolio.jsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Macro.jsx
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ Events.jsx
โ”‚   โ”‚   โ””โ”€โ”€ App.jsx
โ”‚   โ”œโ”€โ”€ public/
โ”‚   โ””โ”€โ”€ package.json
โ”‚
โ”œโ”€โ”€ models/                       # Saved model artifacts
โ”‚   โ”œโ”€โ”€ xgboostregimev1.pkl
โ”‚   โ”œโ”€โ”€ lrbaselinev1.pkl
โ”‚   โ”œโ”€โ”€ corridorriskmodels/
โ”‚   โ””โ”€โ”€ sectorsensitivityweights.json
โ”‚
โ”œโ”€โ”€ notebooks/                    # Jupyter notebooks (exploration/analysis)
โ”‚   โ”œโ”€โ”€ 01edanews_data.ipynb
โ”‚   โ”œโ”€โ”€ 02gprindex_analysis.ipynb
โ”‚   โ”œโ”€โ”€ 03caldaravalidation.ipynb
โ”‚   โ”œโ”€โ”€ 04mlmodel_training.ipynb
โ”‚   โ””โ”€โ”€ 05shapanalysis.ipynb
โ”‚
โ”œโ”€โ”€ data/                         # Sample/reference data
โ”‚   โ”œโ”€โ”€ caldaraindiagpr.xlsx    # Caldara benchmark (downloaded)
โ”‚   โ”œโ”€โ”€ nifty50_historical.csv    # Nifty 50 historical prices
โ”‚   โ””โ”€โ”€ validation_events.yaml   # 17 backtesting events
โ”‚
โ”œโ”€โ”€ scripts/                      # Utility scripts
โ”‚   โ”œโ”€โ”€ download_models.py        # Download NLP model weights
โ”‚   โ”œโ”€โ”€ init_database.py          # Database initialization
โ”‚   โ”œโ”€โ”€ verify_setup.py           # Setup verification
โ”‚   โ””โ”€โ”€ backfill_history.py       # Backfill 2020-present index
โ”‚
โ”œโ”€โ”€ tests/                        # Full test suite (see Testing section)
โ”œโ”€โ”€ config/
โ”‚   โ””โ”€โ”€ settings.yaml             # Application configuration
โ”œโ”€โ”€ logs/                         # Pipeline execution logs (gitignored)
โ”œโ”€โ”€ outputs/                      # Generated reports/plots (gitignored)
โ”œโ”€โ”€ docs/                         # Extended documentation
โ”‚   โ”œโ”€โ”€ methodology.md
โ”‚   โ”œโ”€โ”€ validation_report.md
โ”‚   โ””โ”€โ”€ api_docs.md
โ”‚
โ”œโ”€โ”€ .env.example                  # Environment template
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ requirements.txt              # Python dependencies
โ”œโ”€โ”€ docker-compose.yml            # Docker configuration (optional)
โ”œโ”€โ”€ Dockerfile                    # Container definition (optional)
โ””โ”€โ”€ README.md                     # This file

Validation Strategy

Forsyt uses product KPIs (pipeline reliability + index credibility), not ML headline scores. Research backtests live in nifty-50/research/.

Product Success Metrics

| Metric | Target | Method | |--------|--------|--------| | Pipeline uptime | 30 consecutive daily runs | GitHub Actions daily_index.yml | | Index freshness | GPR updated within 24h | gprdaily.updatedat vs scrape time | | Caldara correlation | Monthly r โ‰ฅ 0.50 | gprindex/scripts/validategpr.py | | Event detection | GPR spike within 3 days | Galwan, Pulwama, 26/11 manual check | | Corridor sanity | Top corridor matches news | Compare /api/corridors to event feed |

Research Validation (internal QA)

| Check | Location | |-------|----------| | OOS NIFTY vol backtest | nifty-50/research/analysis/03_backtest.py | | Caldara VAR reproduction | nifty-50/research/run_application.py | | Full write-up | nifty-50/research/REPORT.md |

Honest finding: GPR does not beat market-only vol forecasts OOS โ€” the product shows both signals side-by-side instead of overclaiming.


Deployment

Option 1: Local Development (Default)

Already covered in Running the Project. Suitable for development and testing.

Option 2: Docker (Recommended for Reproducibility)

# Build and start all services
docker-compose up --build

Run in background

docker-compose up -d

Stop services

docker-compose down

The docker-compose.yml starts:

  • forsyt-db โ€” PostgreSQL 15
  • forsyt-pipeline โ€” Data ingestion + NLP pipeline
  • forsyt-api โ€” REST API server (port 8000)
  • forsyt-dashboard โ€” React frontend (port 3000)

Option 3: Cloud Deployment (Google Cloud Run)

# Authenticate with Google Cloud
gcloud auth login
gcloud config set project YOURPROJECTID

Build and push container

gcloud builds submit --tag gcr.io/YOURPROJECTID/forsyt-api

Deploy to Cloud Run

gcloud run deploy forsyt-api \ --image gcr.io/YOURPROJECTID/forsyt-api \ --platform managed \ --region asia-south1 \ --allow-unauthenticated \ --set-env-vars DATABASEURL=$DATABASEURL

Environment-Specific Notes

| Environment | Database | Pipeline | Dashboard | |-------------|----------|----------|-----------| | Development | Local PostgreSQL | Manual trigger | npm start | | Docker | Docker PostgreSQL | Scheduled via cron | Docker container | | Production | Cloud SQL | Cloud Scheduler | Static build + CDN |


Contributing

We welcome contributions from the community and teammates. Please follow this workflow.

Development Workflow

# 1. Fork the repository and clone your fork
git clone https://github.com/YOUR_USERNAME/forsyt.git
cd forsyt

2. Create a feature branch

git checkout -b feature/your-feature-name

3. Make your changes (follow code style guidelines below)

4. Run tests to ensure nothing is broken

pytest tests/ -v

5. Commit with a descriptive message

git add . git commit -m "feat: add corridor risk forecast endpoint"

6. Push to your fork

git push origin feature/your-feature-name

7. Open a Pull Request on GitHub targeting the main branch

Commit Message Convention

We follow Conventional Commits:

feat:     New feature
fix:      Bug fix
docs:     Documentation changes
test:     Adding or updating tests
refactor: Code restructuring without feature change
chore:    Build process or auxiliary tool changes
perf:     Performance improvement

Examples:

feat: add SHAP waterfall plot to portfolio advisor fix: correct z-score normalization for edge case on sparse event days docs: update API reference for /api/portfolio/exposure endpoint test: add unit tests for text cleaning module

Code Style

# Format code
black forsyt/ tests/

Lint code

flake8 forsyt/ tests/ --max-line-length=100

Type checking

mypy forsyt/

Sort imports

isort forsyt/ tests/

Run all style checks at once

make lint

Pull Request Checklist

Before opening a PR, ensure:

  • [ ] Code follows PEP 8 and project style (run make lint)
  • [ ] All new functions have docstrings
  • [ ] Tests written for new functionality
  • [ ] All existing tests pass (pytest tests/ -v)
  • [ ] .env.example updated if new env variables added
  • [ ] CHANGELOG.md updated with a brief description
  • [ ] PR description explains what changes were made and why
  • [ ] No secrets, API keys, or personal data committed

Reporting Issues

When reporting a bug, include:

  • Description โ€” What happened vs. what you expected
  • Steps to reproduce โ€” Minimal, reproducible example
  • Environment โ€” OS, Python version, relevant package versions
  • Logs โ€” Relevant error messages or stack traces
  • Screenshots โ€” If applicable (especially for dashboard issues)
Use the GitHub Issues template at: https://github.com/[YOURGITHUBORG]/forsyt/issues/new

Team

| Name | Role | Responsibilities | |------|------|-----------------| | Devasya Kanwar (102303749) | AI/ML Engineer | NLP pipeline design and predictive analytics | | Aaditi Verma (102303603) | Domain Analyst | Geopolitical analysis and risk modelling | | Aadi Jain (102303629) | Backend Developer | Data pipeline architecture and API development | | Vansh Gupta (102303909) | Frontend Engineer | Dashboard design and data visualization | | Arianna Vohra (102303934) | Project Manager | Financial analysis and project coordination |

Mentors:

  • Dr. Jasmeet Singh โ€” Assistant Professor, CSE, Thapar Institute
  • Dr. Kapil Tomar โ€” Assistant Professor, CSE, Thapar Institute

Roadmap

Phase I โ€” Core Development (Weeks 1โ€“10)

  • [x] Repository setup and team onboarding
  • [ ] Data aggregation pipeline (15-20 sources)
  • [ ] NLP event extraction (โ‰ฅ75% accuracy)
  • [ ] India AI-GPR Index construction (2020โ€“present)

Phase II โ€” Validation & ML (Weeks 11โ€“20)

  • [ ] Caldara GPR correlation validation (target r โ‰ฅ 0.60)
  • [ ] 17-event historical backtesting (target โ‰ฅ 80% hit rate)
  • [ ] Feature engineering (14-15 features)
  • [ ] XGBoost model training + evaluation (target F1 โ‰ฅ 0.60)
  • [ ] SHAP explainability integration

Phase III โ€” Dashboard & Deployment (Weeks 21โ€“27)

  • [ ] REST API layer (5 core endpoints)
  • [ ] React.js dashboard (5 modules)
  • [ ] Corridor risk and portfolio advisor modules
  • [ ] Performance optimization (API response < 500ms)

Phase IV โ€” Testing & Finalization (Weeks 28โ€“34)

  • [ ] Two-wave user testing (12โ€“18 users)
  • [ ] Wave 1 feedback implementation
  • [ ] Wave 2 validation (target satisfaction โ‰ฅ 7.5/10)
  • [ ] Final documentation and video demonstration
  • [ ] Capstone presentation (December 2026)

Future Enhancements (Post-Capstone)

  • [ ] Hindi/regional language NLP support (Dainik Jagran, Amar Ujala)
  • [ ] Social media signals integration (Twitter/X geopolitical sentiment)
  • [ ] Real-time intraday GPR updates (sub-hourly)
  • [ ] Options market volatility integration (India VIX)
  • [ ] Expanded corridor coverage (50+ routes)
  • [ ] Mobile application (React Native)
  • [ ] B2B SaaS API offering for institutional clients
  • [ ] Integration with NSE/BSE live data feeds

FAQ

Q: Does Forsyt provide financial advice?

No. Forsyt is a research and intelligence tool for informational purposes only. It is not a SEBI-registered investment advisor and should not be used as the sole basis for financial decisions.

Q: How accurate is the India AI-GPR Index?

The index targets a Pearson correlation of โ‰ฅ 0.60 with the Caldara-Iacoviello benchmark and โ‰ฅ 80% detection rate on 17 historical events. Actual accuracy depends on news source quality and NLP model performance.

Q: Can I use Forsyt for my own research project?

Yes, subject to the project's license. If you use Forsyt in academic work, please cite the project and relevant references.

Q: Why Indian news sources instead of GDELT?

GDELT relies heavily on Western media and misses regional Indian events, state-level politics, and regulatory changes. Indian sources provide better coverage of events that actually affect Indian markets.

Q: How much does it cost to run Forsyt?

The core system runs on free and open-source components. Optional paid components include LLM APIs for assisted extraction (~โ‚น8,000โ€“10,000 for 6 months) and cloud hosting (~โ‚น3,000). Total estimated cost: ~โ‚น17,000 for the full project duration.

Q: What happens when an RSS feed breaks?

The pipeline logs the failure and sends an email alert. If a source fails for 3+ consecutive runs, it is flagged for manual review. Each source has a scraper fallback.

Q: Can I add new news sources?

Yes. Add the source configuration to ingestion/sources.yaml and run the pipeline. New sources are automatically picked up on the next scheduled run.

Q: Does Forsyt work offline?

No. The system requires an internet connection for RSS feeds, market data (yfinance), and optional LLM API calls.


License

MIT License

Copyright (c) 2026 Forsyt Team โ€” Thapar Institute of Engineering & Technology

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

See the full LICENSE file for details.


References & Acknowledgements

Core References

  • Caldara, D., & Iacoviello, M. (2022). Measuring Geopolitical Risk. American Economic Review, 112(4), 1194โ€“1225.
  • Iacoviello, M., & Tong, J. (2026). The AI-GPR Index: Measuring Geopolitical Risk using Artificial Intelligence. Federal Reserve Board Working Paper.
  • Baker, S. R., Bloom, N., & Davis, S. J. (2016). Measuring Economic Policy Uncertainty. Quarterly Journal of Economics, 131(4), 1593โ€“1636.
  • Devlin, J., et al. (2018). BERT: Pre-training of Deep Bidirectional Transformers. arXiv:1810.04805.
  • Chen, T., & Guestrin, C. (2016). XGBoost: A Scalable Tree Boosting System. ACM SIGKDD 2016.
  • Lundberg, S. M., & Lee, S.-I. (2017). A Unified Approach to Interpreting Model Predictions. NeurIPS 2017.
  • Hochreiter, S., & Schmidhuber, J. (1997). Long Short-Term Memory. Neural Computation, 9(8), 1735โ€“1780.

Acknowledgements

  • Thapar Institute of Engineering & Technology โ€” Institutional support and mentorship
  • Dr. Jasmeet Singh & Dr. Kapil Tomar โ€” Project guidance and mentorship
  • Hugging Face โ€” Open-source transformer model ecosystem
  • Caldara & Iacoviello โ€” Public release of India GPR benchmark data
  • NSE India โ€” Nifty 50 methodology and market data access

Forsyt โ€” Built at Thapar Institute of Engineering & Technology, Patiala

Capstone Project CPG #300 | Computer Science & Engineering | 2025โ€“2026

GitHub

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท VanshGupta18/Forsyt ยท Updated daily from GitHub