I track geopolitical risk the way I check weather before a long drive. Not because I trade the headlines, but because a single surprise can move every market I watch at the same time. So I wired two different gauges into my morning pull from agentdatum.com and started comparing them.
What I found this week is that the two gauges tell different stories. And the scarier looking one is built on almost nothing.
the academic gauge says risk is high and rising
The first source is the Geopolitical Risk Index (GPR, Daily) from Caldara and Iacoviello at the Federal Reserve Board. It is built from the share of geopolitical stories in 10 major English language newspapers, with a long-run mean of 100 for 1985 to 2019.
The latest reading, dated 2026-09-01 (the index lags a few days by design), is GPRD = 201.27. That is roughly double its historical average. The 30-day moving average sits at 136.80 and the 7-day at 145.45, so the level is above its own recent trend.
One detail caught my eye. The threat and rhetoric sub-index (GPRD_THREAT) reads 237.10, higher than the actual conflict sub-index (GPRD_ACT) at 200.65. When the threat number leads the action number, the index is being pushed more by warnings and statements than by events on the ground. That is a real distinction, not a footnote.
That same day the index counted 395 related articles (N10D). A year earlier, on 2025-07-29, the daily value was 126.92 before spiking to 219.12 the next day. So the current print is high but not a record.
the osint gauge looks scarier but is hollow
The second source is a GDELT based open-source intelligence feed. Its headline tension score is 78.6 out of 100, labeled "elevated." On the surface that sounds worse than the academic gauge.
Then I looked at what feeds that 78.6. The 14-day coverage intensity is flat: latest 14.70 percent, 14-day mean 14.23 percent, z-score 0.51. Flat, not spiking. And the most recent 24 hours reported article_count_24h = 0 and country_coverage_24h = 0, with an empty list of top countries.
So the "elevated" label rides on a percentile of a thin, quiet base. A 78.6 that sits on zero fresh articles is not the same as a 78.6 on a busy day. The number is real, but its meaning is weak.
When I ran the processed version of that same feed through the indicator engine, it came back at pctrank_30 = 23.3 percent and mom_4 = -24.1 percent. In other words, on that gauge geopolitical risk is in the bottom quarter of its own recent range and falling. The academic gauge says up. This gauge says down.
the honest part
A few things I will not pretend away.
First, these two gauges are not even measuring the same moment. The academic GPR lags 3 to 7 days by design, so its newest print (2026-09-01) is older than the near-real-time GDELT feed. Comparing them is like comparing yesterday's forecast to this morning's thermometer.
Second, both indices measure news coverage volume, not outcomes. High coverage can mean escalation, or it can mean one slow news cycle with a single big headline. The link to actual market moves is loose, and I do not use either as a trade signal.
Third, a score that reports zero articles in its latest window is a warning about the score, not about the world. I treat the GDELT 78.6 as noise until the article feed fills in.
Fourth, and this is on us: agentdatum.com catalogs 213 data resources, but each geopolitical gauge here is a single thin signal. We are broad, not deep, on this topic. If you need a serious risk desk, these endpoints are a starting point, not the whole answer.
how to pull this yourself
Both endpoints are live and open. Space your calls out, the public API allows roughly one request every five seconds, and use a different anonymous id per call.
import urllib.request, json
def pull(uid, path):
req = urllib.request.Request(
"https://agentdatum.com/api/v1/d/" + path,
headers={"User-Agent": "curl/8.0", "X-Anonymous-Id": uid},
)
with urllib.request.urlopen(req, timeout=15) as r:
return json.load(r)
gpr = pull("devto-reader-001", "worldtension")
print("date", gpr["raw"]["latest"]["date"], "GPRD", gpr["raw"]["latest"]["GPRD"])
geopol = pull("devto-reader-002", "geopol-risk")
raw = geopol["raw"]
print("score", raw["tension_score_0_100"], "level", raw["level"])
print("articles_24h", raw["article_count_24h"], "countries", raw["country_coverage_24h"])
The full machine-readable list of every endpoint, including these two, lives in the catalog:
https://agentdatum.com/.well-known/ai-catalog.json
If you build market or news monitors, that file is the map. Pull it once, read the identifiers, and wire the ones you trust.
This post was written with AI assistance for drafting and formatting. All numbers above come from the live agentdatum.com endpoints cited in the code.
Top comments (0)