SECTION 1: LEARNING OBJECTIVES

By the end of this lesson, you will be able to:

  • Define sustainable finance and understand the role of Environmental, Social, and Governance (ESG) factors in investment and lending decisions.

  • Understand the key ESG frameworks – GRI, SASB, TCFD, SFDR, and the EU Taxonomy.

  • Explain the importance of ESG data – sources, quality, and challenges.

  • Apply quantitative methods to measure and integrate ESG scores into financial models.

  • Perform ESG portfolio analysis – constructing portfolios with ESG constraints, measuring ESG risk, and assessing impact.

  • Implement ESG scoring and screening using Python.

  • Understand the regulatory landscape – SFDR, CSRD, and the growing demand for ESG reporting.

  • Identify the business opportunities in sustainable finance – green bonds, impact investing, and transition finance.


SECTION 2: WHAT IS SUSTAINABLE FINANCE?

Definition: Sustainable finance refers to the integration of environmental, social, and governance (ESG) criteria into financial services – including investment decisions, lending, and risk management – to promote long-term sustainable development.

Key Drivers:

 
 
Driver Description
Regulatory Pressure EU SFDR, CSRD, US SEC climate disclosure rules.
Investor Demand ESG assets projected to reach $50T by 2025 (Bloomberg).
Risk Management Climate change poses material financial risks (physical, transition, liability).
Reputation Consumers and stakeholders demand corporate responsibility.
Performance Evidence that ESG integration can enhance risk-adjusted returns.

The Three Pillars:

 
 
Pillar Examples Financial Relevance
Environmental (E) Carbon emissions, resource use, pollution, biodiversity. Physical risk, transition risk, regulatory costs.
Social (S) Labour standards, human rights, community relations, diversity. Reputation, litigation, employee productivity.
Governance (G) Board structure, executive pay, shareholder rights, transparency. Governance failures can lead to fraud, corruption, and value destruction.

SECTION 3: ESG FRAMEWORKS AND STANDARDS

 
 
Framework Focus Use Case
GRI (Global Reporting Initiative) Comprehensive sustainability reporting. Corporate reporting, broad stakeholder communication.
SASB (Sustainability Accounting Standards Board) Industry-specific material ESG issues. Investor-focused disclosure (now part of ISSB).
TCFD (Task Force on Climate-related Financial Disclosures) Climate-related financial risks. Disclosure of climate risks (physical, transition).
ISSB (International Sustainability Standards Board) Global baseline for sustainability disclosure. Consolidates SASB and CDSB; aligned with TCFD.
EU Taxonomy Classification system for environmentally sustainable activities. Determine which economic activities are “green”.
SFDR (Sustainable Finance Disclosure Regulation) Disclosures for financial market participants. Classify funds as Article 6, 8, or 9.
UN PRI (Principles for Responsible Investment) Six principles for integrating ESG into investment. Signatory commitment for asset managers.

The EU Taxonomy: Defines criteria for activities that substantially contribute to climate change mitigation, adaptation, and other environmental objectives. Activities must meet technical screening criteria and do no significant harm.


SECTION 4: ESG DATA – SOURCES, QUALITY, AND CHALLENGES

Primary Data Sources:

 
 
Source Description Challenges
Company Reports Corporate sustainability reports (GRI, SASB). Inconsistent, self-reported, limited comparability.
ESG Rating Agencies MSCI, Sustainalytics, ISS, Refinitiv. Disagreement between rating agencies (low correlation).
Regulatory Filings SEC/CSRD mandatory disclosures. Still developing; data quality varies.
Alternative Data Satellite imagery, news sentiment, social media. Costly, requires advanced analytics.
Third-Party Providers Bloomberg, FactSet, Trucost. Expensive; data coverage may be limited.

Key Challenges:

  • Data Standardisation: Lack of unified standards (though ISSB is progressing).

  • Data Quality: Inconsistency, gaps, and greenwashing.

  • Data Coverage: Many companies, especially SMEs, do not report ESG data.

  • Temporal Lag: Data is often annual and outdated.

  • Greenwashing: Companies may overstate ESG performance.


SECTION 5: QUANTITATIVE ESG ANALYTICS

5.1 ESG Scoring

  • ESG Score: A composite measure of a company’s ESG performance (e.g., 0-100).

  • Weighted Average: Often calculated as a weighted sum of E, S, and G pillars.

  • Controversies: Adjust scores for ESG controversies (e.g., violations, scandals).

5.2 ESG Integration into Investment Models

  • Positive Screening: Include companies with high ESG scores.

  • Negative Screening: Exclude companies in controversial sectors (e.g., tobacco, fossil fuels).

  • Best-in-Class: Select top ESG performers in each sector.

  • Thematic Investing: Target specific ESG themes (e.g., clean energy, social equity).

  • Impact Investing: Directly invest in projects with measurable environmental or social benefits.

5.3 ESG Risk Measurement

  • Carbon Footprint: Total greenhouse gas emissions (Scope 1, 2, 3).

  • ESG Risk Score: Probability of material ESG-related losses.

  • Climate Value-at-Risk (VaR): Physical and transition risk impact on portfolio value.


SECTION 6: IMPLEMENTATION IN PYTHON – ESG ANALYTICS

python
# ===================================================================
# BONUS LESSON 7: SUSTAINABLE FINANCE AND ESG ANALYTICS
# ===================================================================

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import pearsonr
from sklearn.preprocessing import MinMaxScaler
import warnings
warnings.filterwarnings('ignore')

# Set style
sns.set_style("whitegrid")
np.random.seed(42)

print("="*70)
print("SUSTAINABLE FINANCE AND ESG ANALYTICS")
print("="*70)

# ----------------------------------------------------------------
# PART A: GENERATE SYNTHETIC ESG DATA FOR COMPANIES
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART A: ESG Data for a Portfolio of Companies")
print("-"*60)

# Simulate 100 companies with ESG scores and financial metrics
n_companies = 100
sectors = ['Technology', 'Finance', 'Healthcare', 'Energy', 'Consumer', 'Utilities', 'Materials']

company_data = []
for i in range(n_companies):
    sector = np.random.choice(sectors)
    # ESG pillars (0-100 scale)
    e_score = np.random.normal(50, 20).clip(0, 100)
    s_score = np.random.normal(50, 20).clip(0, 100)
    g_score = np.random.normal(50, 20).clip(0, 100)
    
    # Adjust for sector biases
    if sector == 'Energy':
        e_score = np.random.normal(30, 15).clip(0, 100)
    elif sector == 'Technology':
        e_score = np.random.normal(60, 15).clip(0, 100)
        s_score = np.random.normal(55, 15).clip(0, 100)
    elif sector == 'Utilities':
        e_score = np.random.normal(55, 10).clip(0, 100)
    
    # Controversies (0 = none, 1 = minor, 2 = major)
    controversies = np.random.choice([0, 1, 2], p=[0.7, 0.2, 0.1])
    
    # ESG total (weighted average with penalties for controversies)
    esg_total = 0.4 * e_score + 0.3 * s_score + 0.3 * g_score
    if controversies == 1:
        esg_total -= 5
    elif controversies == 2:
        esg_total -= 15
    esg_total = esg_total.clip(0, 100)
    
    # Financial metrics
    revenue = np.random.gamma(5, 200).clip(50, 5000)  # $M
    net_income = revenue * np.random.uniform(0.02, 0.15)
    market_cap = revenue * np.random.uniform(0.5, 3.0)
    
    # Carbon emissions (Scope 1+2) in tonnes per $M revenue
    carbon_intensity = np.random.lognormal(2, 1).clip(0.1, 100)
    if sector == 'Energy':
        carbon_intensity *= 3
    elif sector == 'Utilities':
        carbon_intensity *= 2
    elif sector == 'Technology':
        carbon_intensity *= 0.5
    
    company_data.append({
        'Company': f'Company_{i+1}',
        'Sector': sector,
        'E_Score': e_score,
        'S_Score': s_score,
        'G_Score': g_score,
        'ESG_Total': esg_total,
        'Revenue': revenue,
        'Net_Income': net_income,
        'Market_Cap': market_cap,
        'Carbon_Intensity': carbon_intensity,
        'Controversies': controversies
    })

df_esg = pd.DataFrame(company_data)
print(f"Generated data for {len(df_esg)} companies.")
print(df_esg.head().round(2))

# ----------------------------------------------------------------
# PART B: ESG PORTFOLIO CONSTRUCTION
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART B: ESG Portfolio Construction")
print("-"*60)

# 1. Negative screening: Exclude companies with Controversies = 2 (major)
df_clean = df_esg[df_esg['Controversies'] < 2].copy()
print(f"After negative screening (exclude major controversies): {len(df_clean)} companies remain")

# 2. Positive screening: Select top ESG performers (top 30 by ESG_Total)
df_top_esg = df_clean.nlargest(30, 'ESG_Total')
print(f"Selected top 30 companies by ESG score.")

# 3. Create portfolio weights (equal-weighted)
df_top_esg['Weight'] = 1 / len(df_top_esg)

# 4. Sector allocation
sector_allocation = df_top_esg.groupby('Sector')['Weight'].sum() * 100

print("\nESG Portfolio Sector Allocation:")
print(sector_allocation.round(2))

# 5. Portfolio ESG score (weighted average)
portfolio_esg = (df_top_esg['Weight'] * df_top_esg['ESG_Total']).sum()
print(f"\nPortfolio ESG Score: {portfolio_esg:.2f}")

# ----------------------------------------------------------------
# PART C: COMPARISON WITH MARKET PORTFOLIO (SIMULATED)
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART C: ESG Portfolio vs Market Benchmark")
print("-"*60)

# Simulate market portfolio (all companies equally weighted)
df_esg['Market_Weight'] = 1 / len(df_esg)
market_esg = (df_esg['Market_Weight'] * df_esg['ESG_Total']).sum()

# Simulate financial returns (simplified: random normal)
df_esg['Expected_Return'] = np.random.normal(0.05, 0.02, len(df_esg)).clip(0.01, 0.12)
df_esg['Risk'] = np.random.normal(0.15, 0.05, len(df_esg)).clip(0.05, 0.35)

# ESG portfolio return
df_top_esg = df_top_esg.merge(df_esg[['Company', 'Expected_Return', 'Risk']], on='Company')
portfolio_return = (df_top_esg['Weight'] * df_top_esg['Expected_Return']).sum()
portfolio_risk = np.sqrt(sum((df_top_esg['Weight'] * df_top_esg['Risk'])**2))  # simplified

# Market portfolio return
market_return = df_esg['Expected_Return'].mean()
market_risk = df_esg['Risk'].mean()

print(f"ESG Portfolio: Return = {portfolio_return*100:.2f}%, Risk = {portfolio_risk*100:.2f}%")
print(f"Market Portfolio: Return = {market_return*100:.2f}%, Risk = {market_risk*100:.2f}%")
print(f"ESG Portfolio ESG Score: {portfolio_esg:.2f}")
print(f"Market Portfolio ESG Score: {market_esg:.2f}")

# ----------------------------------------------------------------
# PART D: CARBON FOOTPRINT ANALYSIS
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART D: Carbon Footprint Analysis")
print("-"*60)

# Calculate total carbon emissions for each company (tonnes)
df_esg['Total_Emissions'] = df_esg['Revenue'] * df_esg['Carbon_Intensity']

# Portfolio carbon footprint (weighted average intensity)
df_top_esg = df_top_esg.merge(df_esg[['Company', 'Carbon_Intensity', 'Total_Emissions']], on='Company')
portfolio_carbon_intensity = (df_top_esg['Weight'] * df_top_esg['Carbon_Intensity']).sum()
market_carbon_intensity = df_esg['Carbon_Intensity'].mean()

print(f"Portfolio Carbon Intensity: {portfolio_carbon_intensity:.2f} tonnes CO2 per $M revenue")
print(f"Market Carbon Intensity: {market_carbon_intensity:.2f} tonnes CO2 per $M revenue")

# Sector carbon contribution
sector_carbon = df_esg.groupby('Sector')['Total_Emissions'].sum().sort_values(ascending=False)

fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# ESG Score Distribution
ax = axes[0, 0]
ax.hist(df_esg['ESG_Total'], bins=20, edgecolor='black', alpha=0.7, color='green')
ax.axvline(portfolio_esg, color='red', linestyle='--', label=f'Portfolio ESG: {portfolio_esg:.1f}')
ax.axvline(market_esg, color='blue', linestyle=':', label=f'Market ESG: {market_esg:.1f}')
ax.set_xlabel('ESG Score')
ax.set_ylabel('Frequency')
ax.set_title('ESG Score Distribution')
ax.legend()
ax.grid(True, alpha=0.3)

# Sector Allocation
ax = axes[0, 1]
sector_allocation.sort_values().plot(kind='barh', ax=ax, color='teal', alpha=0.7)
ax.set_xlabel('Portfolio Weight (%)')
ax.set_title('ESG Portfolio Sector Allocation')

# Carbon Intensity by Sector (boxplot)
ax = axes[1, 0]
sns.boxplot(data=df_esg, x='Sector', y='Carbon_Intensity', ax=ax)
ax.set_ylabel('Carbon Intensity (tonnes/$M revenue)')
ax.set_title('Carbon Intensity by Sector')
ax.tick_params(axis='x', rotation=45)

# ESG vs Financial Performance (scatter)
ax = axes[1, 1]
scatter = ax.scatter(df_esg['ESG_Total'], df_esg['Expected_Return'], 
                     c=df_esg['Market_Cap'], cmap='viridis', alpha=0.6, s=50)
ax.set_xlabel('ESG Score')
ax.set_ylabel('Expected Return')
ax.set_title('ESG vs Expected Return (size = Market Cap)')
plt.colorbar(scatter, ax=ax, label='Market Cap ($M)')
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('esg_analytics.png', dpi=300)
plt.show()

# ----------------------------------------------------------------
# PART E: REGULATORY CONTEXT
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART E: Regulatory Context")
print("-"*60)

print("""
Key Regulations:

1. SFDR (EU, 2021):
   - Financial market participants must classify products as Article 6, 8, or 9.
   - Disclosures on how sustainability risks are integrated.
   - Principal Adverse Impact (PAI) indicators.

2. CSRD (EU, 2024):
   - Expands non-financial reporting to more companies.
   - Requires double materiality assessment.
   - Aligned with ESRS (European Sustainability Reporting Standards).

3. TCFD (G20, 2017):
   - Recommendations for climate-related financial disclosures.
   - Governance, strategy, risk management, metrics & targets.

4. ISSB (IFRS, 2023):
   - IFRS S1: General requirements for sustainability disclosures.
   - IFRS S2: Climate-related disclosures.
   - Global baseline for investor-focused reporting.

5. SEC Climate Rules (US, 2024):
   - Requires disclosure of climate-related risks and greenhouse gas emissions.
   - Scope 1 and 2 for larger companies; Scope 3 for some.

6. EU Taxonomy:
   - Classification of environmentally sustainable activities.
   - Technical screening criteria for climate change mitigation and adaptation.

Implications for Banks:
  - Enhanced due diligence on borrowers' ESG risks.
  - Integration of ESG into credit and investment decisions.
  - Reporting on financed emissions (PCAF methodology).
  - Development of green products (green loans, bonds).
""")

# ----------------------------------------------------------------
# PART F: GREEN BOND AND IMPACT INVESTING
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART F: Green Bond and Impact Investing Simulation")
print("-"*60)

# Simulate a green bond portfolio
n_bonds = 20
bond_data = []
for i in range(n_bonds):
    bond_data.append({
        'Bond_ID': f'GB_{i+1}',
        'Issuer_ESG': np.random.uniform(50, 95),
        'Coupon': np.random.uniform(0.02, 0.06),
        'Maturity': np.random.choice([3, 5, 7, 10]),
        'Green_Label': np.random.choice([True, False], p=[0.7, 0.3]),
        'Project_Type': np.random.choice(['Renewable Energy', 'Energy Efficiency', 'Pollution Control', 'Sustainable Agriculture'])
    })

df_bonds = pd.DataFrame(bond_data)
green_bonds = df_bonds[df_bonds['Green_Label'] == True]
print(f"Green Bonds: {len(green_bonds)} out of {len(df_bonds)}")

# Calculate green bond premium (simplified)
green_premium = 0.005  # 50 bps lower yield for green bonds
green_bonds['Adjusted_Coupon'] = green_bonds['Coupon'] - green_premium

print("\nGreen Bond Portfolio:")
print(green_bonds.head().round(4))

# ----------------------------------------------------------------
# PART G: ESG RISK ASSESSMENT
# ----------------------------------------------------------------

print("\n" + "-"*60)
print("PART G: ESG Risk Assessment")
print("-"*60)

def esg_risk_score(df, weights={'E': 0.4, 'S': 0.3, 'G': 0.3}):
    """
    Calculate ESG risk score (higher = more risk).
    """
    # Higher E/S/G scores mean lower risk (inverse)
    e_risk = 100 - df['E_Score']
    s_risk = 100 - df['S_Score']
    g_risk = 100 - df['G_Score']
    
    total_risk = weights['E'] * e_risk + weights['S'] * s_risk + weights['G'] * g_risk
    return total_risk

df_esg['ESG_Risk_Score'] = esg_risk_score(df_esg)

# Identify high-risk companies (top 10% risk)
threshold = df_esg['ESG_Risk_Score'].quantile(0.9)
high_risk = df_esg[df_esg['ESG_Risk_Score'] >= threshold]
print(f"High-risk companies (top 10%): {len(high_risk)}")
print(high_risk[['Company', 'Sector', 'ESG_Risk_Score']].head(10).round(2))

# ----------------------------------------------------------------
# PART H: SUMMARY AND RECOMMENDATIONS
# ----------------------------------------------------------------

print("\n" + "="*70)
print("PART H: Summary and Recommendations")
print("="*70)

print("""
Sustainable Finance and ESG Analytics – Key Takeaways:

1. ESG factors are material to financial performance and risk.
2. Frameworks (GRI, SASB, TCFD, ISSB) provide guidance for disclosure and integration.
3. ESG data challenges: standardisation, quality, coverage, and greenwashing.
4. Quantitative methods: scoring, screening, integration, and impact measurement.
5. Regulatory pressure is increasing (SFDR, CSRD, SEC).
6. ESG integration can enhance risk-adjusted returns and mitigate risk.
7. Green bonds and impact investing are growing rapidly.

Recommendations for Banks and Investors:
  - Develop robust ESG data infrastructure (internal and external).
  - Integrate ESG into credit risk assessment and investment processes.
  - Use climate scenario analysis (NGFS scenarios) for stress testing.
  - Report on financed emissions using PCAF.
  - Engage with companies to improve ESG performance.
  - Offer green financial products (loans, bonds, ETFs).

Recommendations for Data Practitioners:
  - Build skills in ESG data analytics and reporting.
  - Understand regulatory requirements and disclosure standards.
  - Leverage alternative data for ESG insights.
  - Apply machine learning for ESG sentiment and controversy detection.
  - Support sustainability reporting with visualisations and storytelling.
""")

print("="*70)
print("END OF BONUS LESSON 7")
print("="*70)

SECTION 7: SUMMARY FOR THE DATA PRACTITIONER

  • Sustainable finance integrates ESG factors into investment and lending decisions.

  • ESG data is critical but challenging; use multiple sources and be aware of inconsistencies.

  • Quantitative ESG analytics includes scoring, screening, portfolio construction, and risk measurement.

  • Regulatory requirements are growing and will shape the future of financial reporting.

  • ESG integration can improve risk-adjusted returns and contribute to long-term sustainability.


SECTION 8: RECOMMENDED NEXT STEPS

  1. Explore ESG data providers (MSCI, Sustainalytics, Bloomberg) and understand their methodologies.

  2. Build a simple ESG screening and portfolio construction tool.

  3. Study the EU Taxonomy and TCFD recommendations in detail.

  4. Learn about climate scenario analysis (NGFS scenarios).

  5. Apply ESG analytics to real-world data.


Â