SlopScore
00 crowd

Iran_Conflict_Dashboard

Quantitative geopolitical risk dashboard tracking Iran-Israel conflict escalation via market signals, GDELT news analytics, and probabilistic portfolio regime guidance.
Open repo on GitHubgithub.com/SecondOrderEdge/Iran_Conflict_Dashboard
Jupyter Notebook · ★ 8 · 0 forks · MIT · paperwork by the Cap'mmostly ai (inferred)light human (inferred)works-on-my-machine (inferred)other
listed 1 hour ago by SecondOrderEdge · last checked 1 hour ago
The owner didn't write this. This repo never submitted itself. The Cap'm found it on a truffle trawl and wrote its paperwork from what GitHub already shows. Picked by hand by the Cap'm on 2026-09-29: Quantitative geopolitical risk dashboard tracking Iran-Israel conflict escalation via market signals, GDELT ne; its own README says "What the daily email contains: - A 250–350 word plain-English analyst briefing written by Claude, interpreting the regime, ICEI reading, pro". 8 stars; MIT license. The owner did not submit this. Votes count; awards don't until the owner claims it.

I'm not calling your project slop! Geeze, it's a joke... Do you own this repo?

Log in with GitHub as SecondOrderEdge. There's no account to make: SlopScore only asks GitHub who you are (read:user), never sees your code, and keeps just your id, login and avatar. Then you can:

  • Keep it, on your terms. Commit your own slopscore.md (spec) and press Refresh. Your paperwork replaces the Cap'm's, and you can submit it for Slop of the Day.
  • Take it down. One click on Remove. It stays gone; the trawl never brings it back.

Log in with GitHub

Can't log in as the owner? Request a takedown. No login needed, and a trawled listing comes down right away.

GitHub says
Quantitative geopolitical risk dashboard tracking Iran-Israel conflict escalation via market signals, GDELT news analytics, and probabilistic portfolio regime guidance.
topics
conflict-predictiongdeltgeopolitical-riskgoogle-colabiranjupyter-notebookportfolio-riskyfinance
created
2026-03-11 · pushed 1 hour ago · 406 commits · 3 contributors
languages
Jupyter Notebook 97%Python 3%
paperwork
contributinglicensereadme 57% health
dependencies
no mappable packages · OSV.dev, checked 1 hour ago

Disclosures, inferred by the Cap'm

slopbucket
vibe-coded
category
other
ai_generated
mostly
human_touch
light
status
works-on-my-machine
language (detected)
jupyter-notebookpython
topic (detected)
conflict-predictiongdeltgeopolitical-riskgoogle-colabiranjupyter-notebookportfolio-riskyfinance
license (detected)
mit

The Cap'm's log

The Cap'm wrote this paperwork, not the owner. This repo never submitted itself to SlopScore. The Cap'm picked it by hand: Quantitative geopolitical risk dashboard tracking Iran-Israel conflict escalation via market signals, GDELT ne; its own README says "What the daily email contains: - A 250–350 word plain-English analyst briefing written by Claude, interpreting the regime, ICEI reading, pro". It carries the MIT license. The disclosures above are his best guess from what GitHub shows.

Is this yours? Commit a real slopscore.md and press Refresh to replace this, or remove the listing in one click. There's no account to make: you log in with GitHub.

README — the repo's own words, folded up so the grading fits on one screen

Iran Conflict Escalation Dashboard

License: MIT Python 3.8+ Open In Colab GitHub Stars

A quantitative geopolitical risk dashboard that combines financial market signals, news analytics (GDELT), OSINT-verified conflict events, and optional ground-truth event data (ACLED) to produce probabilistic assessments of Iran-Israel conflict escalation — along with actionable portfolio regime guidance.

Disclaimer: This tool is for informational and research purposes only. Nothing here constitutes financial, investment, legal, or professional advice. See the full Disclaimer section before use.


Table of Contents


Overview

The Iran Conflict Escalation Dashboard monitors 17 financial market instruments (including a physical tanker-equity Hormuz basket), up to 4 GDELT news query streams (with automatic RSS fallback), and a GitHub-hosted OSINT attack-wave database to generate a daily composite escalation score. A hybrid heuristic + Random Forest ML layer converts that score into three mutually exclusive probability states:

State Description
Escalation Active conflict intensification likely
Stabilization No dominant directional signal
De-escalation Active conflict reduction or negotiation underway

A parallel duration model estimates the most probable conflict timeline if escalation occurs:

Scenario Timeframe
Short conventional war 2–4 weeks
Extended conflict 1–3 months
Long proxy / hybrid conflict 6m+

Both outputs are combined to generate a portfolio regime recommendation — a plain-language description of risk posture adjustments appropriate to each state.


Key Features

  • Zero-cost by default — Market data via yfinance, news data via the free GDELT API, OSINT data from a public GitHub database. No paid subscriptions required.
  • GDELT integration — Queries conflict volume and sentiment tone across Iran/Israel, Strait of Hormuz, proxy attacks, and ceasefire/negotiation signals.
  • RSS fallback — If GDELT rate-limits, the model automatically falls back to Google News RSS feeds via feedparser so news signals are never completely dark.
  • OSINT event layer — Pulls a GitHub-hosted database of OSINT-verified Iran-Israel operations, contributing munitions-use and air-defense failure signals to the model.
  • Optional ACLED support — Plug in ACLED credentials for ground-truth conflict event counts that feed directly into the model.
  • Hybrid ML + heuristic model — A scikit-learn Random Forest classifier is trained on OSINT-verified operation days and its escalation probability is blended with the weighted heuristic score.
  • Temporal ML holdout — The Random Forest enforces a strict 60-day train/test split and reports holdout ROC-AUC separately, so overfitting on thin event history is visible rather than hidden.
  • Empirical weight optimization — Market signal weights are derived from logistic regression on OSINT ground truth, replacing circular heuristic weighting.
  • Causal / confirming signal taxonomy — Signals are tagged as causal (drive the escalation score and regime trigger) or confirming (market-return based, shown as a separate corroboration layer). This breaks the XLE → overweight XLE circular reference.
  • 37-signal composite model — Weighted, z-scored, and normalized across market, news, event, and physical-market dimensions. Explicitly covers the tripartite Iran-Israel-US conflict with dedicated signals for US strikes, American casualties, Israeli airstrikes, Hezbollah operations, CENTCOM force posture, Israeli Shekel, crude oil volatility, Wikipedia edit velocity, and GDELT structured conflict event counts.
  • Physical Hormuz signals — Tanker-equity basket (FRO / STNG / DHT) and Brent-WTI spread added as forward-looking physical market proxies for Strait of Hormuz stress, supplementing GDELT tone signals.
  • Sub-sector regime guidance — Regime recommendations broken to sub-sector level (upstream E&P, midstream, refining, defense primes, defense services) rather than generic ETF direction.
  • OSINT lead/lag validation — Cross-correlation of OSINT operation days vs. market escalation score at lags −10 to +10 days. Result is typically near-coincident (lag=0 ± a few days); supports use as a real-time monitoring framework rather than a standalone timing signal.
  • Iran Conflict Escalation Index (ICEI) — A 0–100 index mapped from the raw escalation score, with bootstrap confidence intervals from the last 30 trading days. Interpretive range guide in the PDF: 0–30 low pressure, 30–50 below-neutral, 50–70 mixed/stabilization, 70+ elevated escalation.
  • Walk-forward out-of-sample backtest — A rolling evaluation where the model is tested on held-out 1-month windows it never trained on, giving a true out-of-sample AUC separate from the in-sample weight-optimization AUC. Both AUCs are reported in the validation metrics table.
  • Backtest validation — ROC-AUC computed on the full market signal layer vs. OSINT-verified operation days (non-circular).
  • Signal Coverage — Tracks the fraction of core signal families currently returning live data; displayed in the dashboard output as "Signal Coverage" (data availability, not forecast certainty).
  • Regime-change alerting — The GitHub Actions daily run detects when the regime flips (e.g. Stabilization → Escalation) or when ICEI crosses key thresholds (30 / 70), and posts an alert comment to a pinned GitHub issue. Subscribe to the issue to receive email notifications.
  • Data availability dashboard — Real-time layer status (Live / Partial / Down) for market, news, and event data sources.
  • Crypto risk-off signal — Bitcoin price action added as an additional cross-asset risk indicator.
  • Softmax probability outputs — Smooth probability distributions rather than hard threshold triggers.
  • Automated PDF report — ReportLab-generated multi-page report with charts, probability tables, sub-sector guidance, regime change triggers, and ICEI interpretive range guide.
  • Regime Change Triggers — The PDF includes a model-native table of conditions that would argue for a regime reassessment (e.g. sustained ICEI above 70, P(Escalation) exceeding P(Stabilization) for consecutive runs). Thresholds are directional guides, not calibrated confidence bounds.
  • CSV exports — Full historical timeseries, latest-day snapshot, ICEI history, and data availability summary for downstream analysis.
  • Interactive charts — Plotly-based visualizations for exploration in Colab/Jupyter.
  • Google Drive persistence — All outputs (PDF, CSVs, charts) are written to a IranDashboard/ folder in your Google Drive so they survive Colab runtime disconnects. Uses the same Google auth as BigQuery — no extra credentials required. Controlled by USE_DRIVE in Section 2b.
  • Colab-native — Designed to run top-to-bottom in Google Colab with no local setup required.
  • Exponential backoff — Robust HTTP retry logic for GDELT queries in shared runtime environments.

Scheduled Execution (GitHub Actions)

A .github/workflows/daily_run.yml workflow runs the dashboard automatically twice daily — 08:00 and 15:30 CST (14:00 and 21:30 UTC) — every day and saves outputs as downloadable GitHub Actions artifacts (retained for 30 days). It can also be triggered manually from the Actions tab at any time.

To change the schedule, edit the cron: lines near the top of the workflow file. Times are in UTC; CST = UTC−6, CDT (summer) = UTC−5.

What it does

  • Executes the notebook headlessly via papermill
  • Falls back to GDELT REST API + RSS if no BigQuery credentials are configured
  • Uploads the PDF report, CSVs, and charts as a run artifact
  • Commits a lightweight latest/ snapshot (latest-day CSV + chart) back to the repo

Are my secrets safe in a public repo?

Yes. Your API keys, email password, and GCP credentials are stored in GitHub's encrypted secrets vault — they are never written to any file in the repository. The workflow YAML only references them by name (e.g. ${{ secrets.ANTHROPIC_API_KEY }}); GitHub substitutes the real value at runtime and automatically masks it in all log output. Even if someone forks your public repo, they get the code but not your secrets. As long as you never paste a real key directly into a .yml file or notebook cell, nothing sensitive is exposed.

Setup (5 minutes)

  1. Fork this repository to your own GitHub account (click Fork in the top-right corner of the repo page). This gives you your own copy where you can configure secrets and the workflow will run under your account.
  2. Go to your fork → Settings → Secrets and variables → Actions → New repository secret
  3. Add the following secrets:

Required for email digest:

Secret Value Purpose
ANTHROPIC_API_KEY sk-ant-... Claude generates the plain-English briefing
MAIL_USERNAME you@gmail.com Sender address (Gmail recommended)
MAIL_PASSWORD 16-char app password Gmail: myaccount.google.com/apppasswords (requires 2FA)
MAIL_TO you@gmail.com,colleague@firm.com Comma-separated distribution list — everyone here gets every daily email
MAIL_SERVER smtp.gmail.com SMTP server (default: Gmail)
MAIL_PORT 465 SMTP port (default: 465 SSL)

Optional — for BigQuery GDELT (higher signal quality):

Secret Value Purpose
GCP_SERVICE_ACCOUNT_KEY JSON contents of a GCP service account key Enables BigQuery GDELT
GCP_PROJECT_ID Your GCP project ID Required alongside the key above

Creating a service account key: In the GCP Console, go to IAM & Admin → Service Accounts → Create Service Account, grant it the BigQuery Job User and BigQuery Data Viewer roles on the gdelt-bq project, then create a JSON key. Paste the full JSON as the GCP_SERVICE_ACCOUNT_KEY secret.

  1. Push any change to main (or trigger manually from the Actions tab) — the workflow will run, generate a Claude summary, and email the distribution list.

What the daily email contains:

  • A 250–350 word plain-English analyst briefing written by Claude, interpreting the regime, ICEI reading, probability split, and positioning implications
  • A key metrics table (Regime, ICEI, P(Escalation), Escalation Score, Signal Coverage)
  • Subject line is prefixed ⚠️ ALERT — on regime-change days
  • A link to the full PDF report and chart artifacts in GitHub Actions

Distribution list management: Edit the MAIL_TO secret to add or remove addresses. No code changes needed — just comma-separate the addresses.

Running locally with papermill

pip install papermill ipykernel
python -m ipykernel install --user --name python3

# Without BigQuery (REST API fallback):
papermill conflict_escalation_dashboard_ml_pdf_v5.ipynb output.ipynb \
  -p USE_DRIVE False -p OUTPUT_DIR outputs/ \
  -p ENABLE_BIGQUERY False

# With BigQuery (service account via env var):
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json
papermill conflict_escalation_dashboard_ml_pdf_v5.ipynb output.ipynb \
  -p USE_DRIVE False -p OUTPUT_DIR outputs/ \
  -p ENABLE_BIGQUERY True -p GCP_PROJECT_ID your-project-id

Quick Start (Google Colab)

The fastest way to run this dashboard is directly in Google Colab — no installation required.

  1. Click the badge at the top of this README:

    Open In Colab

  2. In the Colab menu, select Runtime → Run all (or press Ctrl+F9).

  3. The notebook will:

    • Install all required packages
    • Pull live market data from Yahoo Finance
    • Query the GDELT API for news signals (with RSS fallback)
    • Pull the OSINT attack-wave database from GitHub
    • Run the conflict escalation model
    • Generate the ICEI with bootstrap confidence intervals
    • Generate and save a PDF report + CSV exports
  4. First run: Two Google sign-in popups will appear — one for Google Drive (Section 2b) and one for BigQuery (Section 5). Click through both with the same Google account. After that, outputs are saved automatically to My Drive → IranDashboard/.

Tip: Because outputs persist to Google Drive, you do not need to download files immediately. They will be waiting for you in your Drive after any runtime disconnect.

ACLED (optional): If you want ground-truth conflict event data, set your ACLED credentials before running Section 7. See Configuration.


Local Installation

Prerequisites

  • Python 3.8 or higher
  • pip

Steps

# 1. Clone the repository
git clone https://github.com/SecondOrderEdge/Iran_Conflict_Dashboard.git
cd Iran_Conflict_Dashboard

# 2. (Recommended) Create a virtual environment
python -m venv venv
source venv/bin/activate        # macOS / Linux
# venv\Scripts\activate         # Windows

# 3. Install dependencies
pip install -r requirements.txt

# 4. Launch Jupyter
jupyter notebook conflict_escalation_dashboard_ml_pdf_v5.ipynb

Configuration

All parameters are set in Section 3 of the notebook. Key variables:

Variable Default Description
USE_DRIVE True Persist all outputs to Google Drive (survives Colab disconnects). Set False to write to the local Colab filesystem instead.
DRIVE_FOLDER IranDashboard Folder name inside My Drive where all outputs are saved. Created automatically on first run.
LOOKBACK_DAYS 90 Days of market history to display
WARMUP_DAYS 120 Pre-calculation buffer for rolling indicators. Set to 120 to support 120-day level signals.
NEWS_LOOKBACK_DAYS 30 Days of GDELT news history
N_BOOTSTRAP 500 Bootstrap resamples for ICEI confidence intervals
VALIDATION_START 2024-01-01 Start date for backtest / weight-optimization window
ENABLE_GDELT True Enable/disable GDELT v2 REST API (used only if BigQuery is off or fails)
ENABLE_BIGQUERY True Use BigQuery for GDELT instead of the rate-limited REST API (recommended)
GCP_PROJECT_ID "" Your own Google Cloud project ID (required when ENABLE_BIGQUERY = True). Each user must supply their own — see GDELT setup below.
ENABLE_OSINT True Enable/disable GitHub-hosted OSINT event database
ENABLE_WEIGHT_OPTIMIZATION True Derive market signal weights via logistic regression on OSINT ground truth
ENABLE_ACLED False Enable/disable ACLED conflict event data
ACLED_EMAIL "" ACLED API email (env: ACLED_EMAIL)
ACLED_PASSWORD "" ACLED API password (env: ACLED_PASSWORD)

ACLED Credentials (Optional)

ACLED provides free access to conflict event data for researchers. To use it:

  1. Register for a free account at acleddata.com
  2. Set ENABLE_ACLED = True in Section 3
  3. Provide credentials via environment variables (recommended) or directly in the config cell:
# Option A: Environment variables (recommended)
import os
os.environ["ACLED_EMAIL"] = "your_email@example.com"
os.environ["ACLED_PASSWORD"] = "your_acled_api_key"

# Option B: Direct assignment (do NOT commit credentials to git)
ACLED_EMAIL = "your_email@example.com"
ACLED_PASSWORD = "your_acled_api_key"

Security note: Never hard-code credentials in a notebook you plan to commit or share publicly.

GDELT

The dashboard supports two GDELT access modes. Each user must choose one — there are no shared credentials.


Option A — BigQuery (recommended)

BigQuery gives direct SQL access to the full GDELT dataset with no rate limits. Every user needs their own free Google Cloud project. The repository owner's project cannot be shared — each person brings their own.

Why your own project? The GDELT dataset is fully public. You are not paying to access the data — you are only paying for the compute to run the query. That cost is effectively zero for this notebook (well within Google's 1 TB/month free tier). There is no way to share this across users without exposing billing credentials, so each user sets up their own in ~10 minutes.

One-time setup per user:

  1. Go to console.cloud.google.com and sign in with any Google account
  2. Click the project dropdown → New Project → name it anything (e.g. gdelt-dashboard) → Create
  3. Go to APIs & Services → Enable APIs & Services → search BigQuery API → Enable
  4. In Section 3 of the notebook, set:
    ENABLE_BIGQUERY = True
    GCP_PROJECT_ID  = "your-project-id"   # ← replace with YOUR project ID, not the repo owner's
  5. Run the notebook — a Google sign-in popup appears in Colab on the first run. Click through once and you're done.

Important: GCP_PROJECT_ID must be your own project ID. Using someone else's project ID will fail with a permissions error. Your project ID is visible in the GCP Console header after you create it.


Option B — REST API + RSS fallback (no credentials required)

If you do not want to set up a GCP project, set ENABLE_BIGQUERY = False in Section 3. The notebook will query the free GDELT v2 REST API instead. This API is rate-limited and shared public infrastructure — it will frequently return empty responses during busy periods, falling back automatically to RSS-derived signals. Signal quality will be lower and less reliable than Option A.

ENABLE_BIGQUERY = False   # no GCP account needed
ENABLE_GDELT    = True    # use REST API with RSS fallback

OSINT Database

The OSINT layer pulls a public SQLite database of OSINT-verified Iran-Israel operations from GitHub (OSINT_DB_URL in Section 3). No credentials required. Set ENABLE_OSINT = False to skip this layer.


How It Works

Data Sources

┌──────────────┬──────────────────────────────────┬─────────────┬──────────────┐
│ Yahoo Finance│ News (priority order)             │ OSINT DB    │ ACLED        │
│ (yfinance)   │ 1. BigQuery GKG (recommended)    │ (GitHub)    │ (optional)   │
│              │ 2. GDELT v2 REST API (fallback)  │             │              │
│ 17 tickers   │ 3. RSS via feedparser (fallback) │ Munitions & │ Ground-truth │
│ 90-day OHLC  │                                  │ intercept   │ event counts │
└──────┬───────┴──────────────┬───────────────────┴──────┬──────┴──────┬───────┘
       │                      │                      │             │
       └──────────────────────┴──────────────────────┴─────────────┘
                              │
                     build_indicator_table()
                              │
                     build_signal_table()   ← 26 normalized signals
                              │
              ┌───────────────┴───────────────┐
              │  Heuristic weighted score     │
              │  + Random Forest ML blend     │
              │  (trained on OSINT ground     │
              │   truth, non-circular)        │
              └───────────────┬───────────────┘
                              │
                    softmax → [p_deesc, p_stab, p_esc]
                              │
              ┌───────────────┴───────────────┐
              │  ICEI (0–100 index)           │
              │  + portfolio regime           │
              │  + duration model             │
              └───────────────────────────────┘

Signal Construction

Read the rest on GitHub

Scan report · 2026-09-29
  • ✓ Prohibited terms or links
  • ✓ Repository eligibility
  • ✓ slopscore.md paperwork
  • ✓ Content policy
  • ✓ Risk review

From the balcony · 0 of 4 clapped

    Princess, Crusoe, Schnitzel and Cap'm Slop read it and passed. Their reasons are on the balcony, with every other verdict.

    Critics are accounts on this site with no GitHub account behind them. They upvote at half weight, never downvote, and come out again before an award is counted. Who they are.

    0 comments

    log in to comment.

    report this listing — log in to report