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.
Forsyt โ Geopolitical Risk Intelligence System for Indian Markets
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
- Overview
- Motivation & Problem Statement
- Features
- System Architecture
- Modules
- Tech Stack
- Getting Started
- Usage Examples
- API Reference
- Configuration
- Testing
- Project Structure
- Validation Strategy
- Deployment
- Contributing
- Team
- Roadmap
- FAQ
- License
- References & Acknowledgements
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
- 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
{ "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
- Quantifies portfolio exposure by sector sensitivity weights
- Input: portfolio holdings (ticker + weight)
- Output: total GPR exposure score + SHAP-based sector decomposition
- Geopolitical: daily India GPR regime from Forsyt news pipeline
- Market: NIFTY 5-day vol forecast using
market_onlyfeatures (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)
# 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/.envasDATABASEURL
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.envfile. 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 15forsyt-pipelineโ Data ingestion + NLP pipelineforsyt-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.exampleupdated if new env variables added - [ ]
CHANGELOG.mdupdated 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)
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