Skip to main content

Why It Matters

Understanding how countries are exposed to financial contagion and spillover effects from rising bond spreads is critical for sovereign risk assessment and macroeconomic stability analysis. As bond yields diverge and sovereign debt costs increase, policymakers and analysts must proactively assess exposure to financial market tensions, fiscal pressures, and potential contagion effects across Western European nations.

What It Does

The RiskAnalyzer class, part of the bigdata-research-tools package, is purpose-built to meet this challenge. Designed for risk analysts, portfolio managers, and investment professionals, it systematically analyzes entity exposure to specific risk channels using unstructured data from news, earnings calls, and regulatory filings.

How It Works

The RiskAnalyzer combines hybrid semantic search, risk factor taxonomies, and structured validation techniques to deliver:
  • Targeted extraction of risk signals and supporting evidence from massive unstructured datasets
  • Standardized exposure metrics to compare risk across different countries
  • Actionable insights that inform investment strategies and sovereign bond positioning decisions
  • Time-based monitoring to track how exposure levels shift in response to bond market developments

A Real-World Use Case

This cookbook illustrates the full workflow through a practical example: identifying Western European countries facing spillover risks from rising bond spreads. You’ll learn how to convert unstructured narrative (news articles) into structured, quantifiable sovereign risk intelligence, tracking bond market pressures across Germany, France, Italy, Spain, and other European nations. Ready to get started? Let’s dive in!
Open in GitHub

Prerequisites

To run the Rising Bond Spread Risks workflow, you can choose between two options:
  • 💻 GitHub cookbook
    • Use this if you prefer working locally or in a custom environment.
    • Follow the setup and execution instructions in the README.md.
    • API keys are required:
      • Option 1: Follow the key setup process described in the README.md
      • Option 2: Refer to this guide: How to initialise environment variables
        • ❗ When using this method, you must manually add the OpenAI API key:
          # OpenAI credentials
          OPENAI_API_KEY = "<YOUR_OPENAI_API_KEY>"
          
  • 🐳 Docker Installation
    • Docker installation is available for containerized deployment.
    • Provides an alternative setup method with containerized deployment, simplifying the environment configuration for those preferring Docker-based solutions.

Setup and Imports

Below is the Python code required for setting up our environment and importing necessary libraries.
import os
import sys
import pandas as pd
from dotenv import load_dotenv
from pathlib import Path

from bigdata_client import Bigdata
from bigdata_client.models.search import DocumentType

from bigdata_research_tools.workflows.risk_analyzer import RiskAnalyzer
from bigdata_research_tools.labeler.risk_labeler import RiskLabeler
from bigdata_research_tools.workflows.utils import get_scored_df

from src.search_entities import search_by_entities, post_process_dataframe
from src.entity_risk_prompt_labeler import (
    generate_risk_tree, 
    get_entity_risk_prompt,
    get_risk_entity_labeler_prompt, 
    label_search_results
)
from src.sentiment_analysis import create_full_grid_indicators
from src.report_generator import SummaryGenerator
from src.narrative_dashboard import (
    display_dashboard, 
    summarize_narratives, 
    get_narrative_windows
)
from src.visualization_tool import display_risk_figures_cookbooks

# Define output directory
output_dir = "output"
os.makedirs(output_dir, exist_ok=True)

# Load credentials
script_dir = Path(__file__).parent if '__file__' in globals() else Path.cwd()
load_dotenv()

BIGDATA_USERNAME = os.getenv('BIGDATA_USERNAME')
BIGDATA_PASSWORD = os.getenv('BIGDATA_PASSWORD')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')

if not all([BIGDATA_USERNAME, BIGDATA_PASSWORD, OPENAI_API_KEY]):
    raise ValueError("Missing required environment variables. Check your .env file.")

# Connect to Bigdata
bigdata = Bigdata(BIGDATA_USERNAME, BIGDATA_PASSWORD)

Defining Your Risk Analysis Parameters

To perform a sovereign risk analysis, we need to define several key parameters:
  • Main Theme (main_theme): The risk scenario to analyze (e.g. Spillovers from Rising Bond Spreads in Western Europe)
  • Focus (analyst_focus): The analyst focus that provides an expert perspective on the scenario and helps break it down into risks
  • Entity Universe (dict_country_bank, entity_names_countries, entity_names_banks): The set of countries to screen (note: institutional entities are used internally to maximize data coverage)
  • Control Entities (control_entities): The set of entities to be always co-mentioned with your watchlist (e.g. people, places, organizations, etc)
  • Time Period (start_date and end_date): The date range over which to run the search
  • Document Type (document_type): Specify which documents to search over (transcripts, filings, news)
  • Sources (sources): Specify set of sources within a document type, for example which news outlets (available via Bigdata API) you wish to search over
  • Model Selection (llm_model): The AI model used for semantic analysis
  • Rerank Threshold (rerank_threshold): By setting this value, you’re enabling the cross-encoder which reranks the results and selects those whose relevance is above the percentile you specify (0.7 being the 70th percentile). More information on the re-ranker can be found here.
# ===== Theme Definition =====
main_theme = "Spillovers from Rising Bond Spreads in Western Europe"
analyst_focus = "Generate a mind map of current and future risks that western european countries can face as a result of rising bond spreads."

# ===== Entity Universe: Countries + Central Banks =====
dict_country_bank = {
    "Germany": "Deutsche Bundesbank",
    "France": "Bank of France",
    "Italy": "Central Bank of Italy",
    "Spain": "Central Bank of Spain",
    "The Netherlands": "Central Bank of the Netherlands",
    "Belgium": "National Bank of Belgium",
    "Austria": "National Bank of Austria",
    "Portugal": "Central Bank of Portugal",
    "Greece": "Central Bank of Greece",
    "Ireland": "Central Bank of Ireland"
}

entity_names_countries = list(dict_country_bank.keys())
entity_names_banks = list(dict_country_bank.values())

entities_countries = [bigdata.knowledge_graph.autosuggest(entity_name, limit=1)[0] 
                      for entity_name in entity_names_countries]
entities_banks = [[r for r in bigdata.knowledge_graph.autosuggest(entity_name, limit=3) 
                   if type(r).__name__ == 'Organization'][0] 
                  for entity_name in entity_names_banks]

control_entities = None

# ===== LLM Specification =====
llm_model = "openai::gpt-4o-mini"

# ===== Docs Configuration =====
document_type = DocumentType.NEWS
fiscal_year = None

# ===== Enable/Disable Reranker =====
rerank_threshold = None


# ===== Specify Time Range =====
start_date = "2025-07-01"
end_date = "2025-10-03"

Mindmap a Risk Taxonomy with Bigdata Research Tools

You can leverage Bigdata Research Tools to generate a comprehensive risk taxonomy with an LLM, breaking down the complex bond spread spillover scenario into well-defined risk factors and sub-scenarios for more targeted analysis.
theme_tree = generate_risk_tree(
    main_theme=main_theme,
    analyst_focus=analyst_focus,
    system_prompt=get_entity_risk_prompt(main_theme, analyst_focus),
)

theme_tree.visualize()
Risk Tree Visualization showing Bond Spread Spillover Risks broken down by risk factor
The taxonomy tree includes descriptive sentences that explicitly connect each sub-scenario back to the “Rising Bond Spreads” theme, ensuring all search results remain contextually relevant to our main risk channel.
node_summaries = list(theme_tree.get_terminal_label_summaries().values())
labels = list(theme_tree.get_terminal_label_summaries().keys())

Retrieve Content Using Bigdata’s Search Capabilities

With the risk taxonomy and screening parameters, you can leverage the Bigdata API to run a search on news articles. We need to define 3 more parameters for searching:
  • Frequency (freq): The frequency of the date ranges to search over. Supported values:
    • Y: Yearly intervals
    • M: Monthly intervals
    • W: Weekly intervals
    • D: Daily intervals
  • Document Limit (document_limit): The maximum number of documents to return per query to Bigdata API
  • Batch Size (batch_size): The number of entities to include in a single batched query
freq = "M"
document_limit = 20
batch_size = 10

# Search 1: Western European Countries
df_sentences_countries = search_by_entities(
    entities=entities_countries,
    sentences=node_summaries,
    start_date=start_date,
    end_date=end_date,
    scope=document_type,
    control_entities=control_entities,
    sources=None,
    fiscal_year=None,
    freq=freq,
    document_limit=document_limit,
    batch_size=batch_size
)
df_sentences_countries = df_sentences_countries.rename(columns={"sentiment": "bigdata_sentiment"})

# Search 2: Institutional Entities
df_sentences_banks = search_by_entities(
    entities=entities_banks,
    sentences=node_summaries,
    start_date=start_date,
    end_date=end_date,
    scope=document_type,
    control_entities=control_entities,
    sources=None,
    fiscal_year=None,
    freq=freq,
    document_limit=document_limit,
    batch_size=batch_size
)
df_sentences_banks = df_sentences_banks.rename(columns={"sentiment": "bigdata_sentiment"})

# Map institutional entities back to countries and combine
df_sentences_banks_mapped = df_sentences_banks.copy()
reverse_dict = {v: k for k, v in dict_country_bank.items()}
df_sentences_banks_mapped["entity_name"] = df_sentences_banks_mapped["entity_name"].map(reverse_dict)

# Combine both searches
df_combined = pd.concat([df_sentences_banks_mapped, df_sentences_countries], ignore_index=True)
df_combined = df_combined.drop_duplicates(subset=["entity_name", "sentence_id"], keep="first")

Label the Results

Use an LLM to analyze each text chunk and determine its relevance to the sub-themes. Any chunks which aren’t explicitly linked to our main theme will be filtered out.
labeler = RiskLabeler(
    llm_model=llm_model, 
    label_prompt=get_risk_entity_labeler_prompt(main_theme, labels).strip()
)

df, df_labels = label_search_results(
    df_sentences=df_combined,
    terminal_labels=labels,
    risk_tree=theme_tree,
    labeler=labeler,
    additional_prompt_fields=['headline'],
    main_theme=main_theme
)
Retain only results with negative sentiment to focus on risk-related narratives and adverse developments in the bond spread and sovereign debt landscape.
df_labels = df_labels.loc[df_labels.Sentiment.eq('negative')].copy()

Assess Country-Level Risk Exposure

The function get_scored_df will calculate the composite thematic score, summing up the scores across the sub-scenarios for each country (df_entity).
df_entity = pd.DataFrame()

df_entity = get_scored_df(
    df_labels, 
    index_columns=["Entity", "Country"], 
    pivot_column="Sub-Scenario"
)

Create Daily Sentiment Indicators

Generates a complete daily time grid for all entities and calculates rolling sentiment indicators (30/90 days), news volumes, and normalized metrics for temporal analysis.
daily_sentiment = create_full_grid_indicators(df_labels, start_date, end_date)

Identify Peak Coverage and Sentiment Windows

Identifies time windows of maximum media coverage and most negative sentiment for each country, useful for analyzing critical risk moments.
peak_coverage_windows, peak_coverage_data = get_narrative_windows(
    daily_sentiment, 
    df_labels, 
    sentiment_col="Sent_Rolling_30Days", 
    min_max='min', 
    lookback_days=30
)

Generate AI-Powered Narrative Summaries

Uses an LLM to synthesize the main narratives in peak windows, providing a qualitative summary of the risks that emerged for each country during the most critical moments.
summarizer = SummaryGenerator()
entity_narratives = summarize_narratives(
    df_labels, 
    entities_countries, 
    summarizer, 
    peak_coverage_windows
)
Ranks countries based on the most negative sentiment values recorded, identifying which nations show the highest level of concern for bond spread risks and sovereign debt pressures.
ranked_countries = pd.DataFrame.from_dict(
    peak_coverage_data, 
    orient='index'
).sort_values(by='sentiment_value', ascending=True)

ranked_countries

Visualizations

Generates interactive dashboards for each country with sentiment time series charts, gauge indicators, and qualitative narratives at peak coverage or negativity moments. For each country, the analysis produces:
  • Sentiment Gauge: Visual indicator showing the mean (or minimum not normalized) of the rolling sentiment values over the entire period
  • Sentiment Time Series: Rolling sentiment trends over time (30-day rolling window) with rolling volume (30-day) for smoother visualization
  • Peak Negative Sentiment Narrative: AI-generated summary of risks during the most negative sentiment period
  • Peak Volume Narrative: AI-generated summary of risks during the highest daily media coverage period
gauge_value = "mean"  # Options: "min", "mean"
sentiment_col_to_use = 'Sent_Rolling_30Days_Normalized'
volume_type = "rolling"  # Options: "daily", "rolling"

for entity in ranked_countries.index:
    display_dashboard(
        daily_sentiment, 
        entity, 
        'Sent_Rolling_30Days_Normalized', 
        narratives=entity_narratives,
        export_mode=True, 
        gauge_value=gauge_value,
        volume_type=volume_type
    )

Example: France Risk Dashboard

France risk gauge indicator showing overall risk level
France sentiment time series showing rolling 30-day sentiment trends

Peak Volume Narrative - Date: 26-08-2025

France is currently facing significant refinancing risk in real estate, exacerbated by a confluence of political instability, rising borrowing costs, and deteriorating investor sentiment. Recent headlines highlight the European Central Bank’s cautious stance amid global trade tensions, with ECB President Christine Lagarde warning of persistent downside risks, including the impact of U.S. tariffs on European economies. The introduction of a 15% tariff on most European goods has led to skepticism about the economic balance of the new EU-U.S. trade deal, with French officials labeling it an act of “submission.” This has contributed to a sharp decline in the euro and heightened concerns over France’s export sectors. Furthermore, the country’s long-term borrowing costs have surged, with yields on 10-year bonds approaching those of Italy for the first time since the financial crisis, reflecting investor anxiety over France’s fiscal sustainability amid a record public deficit and political turmoil. The government’s potential collapse could trigger a further spike in borrowing costs, complicating fiscal consolidation efforts and limiting policy flexibility. As a result, the risk of increased default rates looms large, particularly for the banking sector, which is heavily exposed to government bonds. The combination of these factors signals a precarious outlook for France’s real estate market, as higher financing costs and political uncertainty could stifle investment and economic growth, leading to a potential downturn in property values.

Peak Negative Sentiment Narrative - Date: 23-09-2025

France is currently facing significant refinancing risk in its real estate and broader financial markets, as highlighted by a series of alarming news reports from August and September 2025. The yield on French 10-year bonds has surged to levels surpassing those of historically troubled economies like Greece and Portugal, reflecting a loss of investor confidence amid escalating political instability and a looming government collapse. The yield spread between French and German bonds has widened dramatically, indicating that investors are demanding higher compensation for holding French debt due to concerns over the country’s fiscal sustainability and political gridlock. The government’s inability to implement necessary austerity measures, coupled with a budget deficit projected at 5.8% of GDP, has exacerbated fears of a potential credit rating downgrade, which could further increase borrowing costs. Analysts warn that if the current political turmoil continues, France could find itself on the periphery of the eurozone, with borrowing costs exceeding those of Italy for the first time in decades. This situation poses severe risks not only to France’s financial stability but also to the broader eurozone, as a crisis in France could have spillover effects on neighboring economies. The combination of high debt levels, rising interest rates, and political uncertainty creates a precarious environment for investors, who are increasingly wary of the sustainability of French assets. Immediate actions are needed to restore confidence, including decisive fiscal reforms and political stability, to prevent a deeper crisis that could threaten the viability of the eurozone itself.

Example: Germany Risk Dashboard

Germany risk gauge indicator showing overall risk level
Germany sentiment time series showing rolling 30-day sentiment trends

Peak Volume Narrative - Date: 30-09-2025

Germany is currently facing significant refinancing risk in its real estate and broader financial markets, as highlighted by a series of concerning developments in September 2025. The yield on Germany’s 30-year bonds has surged to its highest level in over a decade, reaching 3.40%, amid a broader selloff in European bond markets driven by rising public debt and inflationary pressures. This trend is exacerbated by political instability in France, which has led to increased risk premiums on French bonds and a widening spread between French and German yields, now at its highest since the Eurozone debt crisis. The implications for Germany are severe; as the country prepares to issue new government bonds to finance its spending, the elevated borrowing costs could strain public finances and hinder economic recovery efforts. Additionally, rising unemployment, which recently topped 3 million, coupled with a decline in exports to the U.S., signals a weakening economic outlook that could further complicate refinancing efforts. The European Central Bank’s reluctance to intervene aggressively to stabilize the bond market adds to the uncertainty, leaving Germany vulnerable to potential liquidity issues and increased default rates among its SMEs. As such, stakeholders must closely monitor these developments, as the interplay of rising yields, political instability, and economic stagnation poses a significant threat to Germany’s financial stability and market access.

Peak Negative Sentiment Narrative - Date: 15-09-2025

Germany is currently facing significant refinancing risks in real estate and broader economic challenges, as highlighted by a series of concerning news reports from August and September 2025. The Bundesbank’s refurbishment project has encountered substantial cost overruns, coinciding with a period of massive losses attributed to prolonged zero interest rates and extensive bond purchases by the European Central Bank (ECB), raising alarms about financial stability. Concurrently, the German government is grappling with rising borrowing costs, with 30-year yields surpassing 3%, the highest since 2011, driven by plans to increase infrastructure and defense spending. This shift towards higher debt levels has raised concerns among economists about a potential transition from long-term to short-term debt, increasing vulnerability to interest rate fluctuations. The economic backdrop is further strained by a rising unemployment rate, which recently exceeded 3 million for the first time in a decade, reflecting a stagnant labor market and declining consumer confidence. The combination of these factors—cost overruns, increased borrowing costs, and a deteriorating job market—signals a precarious financial landscape for Germany, with implications for its real estate sector and overall economic growth. As the country navigates these challenges, stakeholders must remain vigilant to the evolving risks and consider strategic adjustments to mitigate potential fallout from rising refinancing pressures and market instability.

Cross-Country Comparison

Creates comparative visualizations of risk scores across countries, showing aggregated exposure to different risk channels identified in the thematic analysis.
display_risk_figures_cookbooks(df_entity, interactive=False, n_entities=10)
Risk exposure heatmap
Risk exposure composite scores
Top risk thematics
Risk scores by country

Export Results

Save all generated datasets (labeled results, risk scores, daily indicators, country rankings) to CSV files in the output folder for further analysis or reporting.
try:
    df_labels.to_csv(f"{output_dir}/labeled_search_results.csv", index=False)
    df_entity.to_csv(f"{output_dir}/entity_risk_scores.csv")
    daily_sentiment.to_csv(f"{output_dir}/daily_sentiment_indicators.csv")
    ranked_countries.to_csv(f"{output_dir}/peak_coverage_analysis.csv")
    df_combined.to_csv(f"{output_dir}/raw_search_results.csv", index=False)
except Exception as e:
    print(f"❌ Export error: {e}")

Conclusion

The Rising Bond Spread Risks workflow provides a comprehensive framework for identifying and quantifying sovereign exposure to bond market vulnerabilities and financial contagion across Western Europe. By leveraging advanced information retrieval and LLM-powered analysis, this workflow transforms unstructured news data into actionable sovereign risk intelligence. Through the automated analysis of bond spread spillover risks, you can:
  1. Identify vulnerable countries - Discover which Western European nations face the highest exposure to bond market pressures through their debt structures, fiscal positions, and market sentiment
  2. Compare across countries - Understand how different European markets are affected by bond spread pressures, enabling geographic diversification and hedging strategies
  3. Assess contagion risks - Understand how bond market stress in one country can create spillover effects across the Eurozone, enabling proactive risk management
  4. Track risk evolution - Monitor how country exposure changes over time as bond yields fluctuate, fiscal conditions evolve, or political dynamics shift
  5. Generate investment insights - Use risk exposure scores to inform sovereign bond positioning, duration management, and cross-country relative value strategies in European fixed income markets
  6. Support risk management - Provide quantitative backing for credit risk committees, sovereign exposure decisions, and portfolio stress testing
Whether you’re conducting sovereign credit analysis, managing fixed income portfolios, or assessing systemic risks in European bond markets, this workflow automates the research process while maintaining the depth and rigor required for professional sovereign risk assessment. The standardized scoring methodology ensures consistent evaluation across countries and time periods, making it an invaluable tool for systematic bond market risk analysis in Western Europe.
I