Build a TTF/Brent Energy Ratio Tracker in 5 Minutes

•8 min read

Track the most important metric in global energy markets with 20 lines of code. The TTF/Brent ratio—European natural gas versus crude oil on an energy-equivalent basis—has become the single most important indicator for understanding global energy market structure.

At 0.87 (January 2026), the TTF/Brent ratio signals a fundamental shift from the pre-2021 average of 0.40. This tutorial shows you how to build a real-time ratio tracker using OilPriceAPI.

Deep Dive: Investment Analysis

For the full investment analysis explaining what this ratio means for global energy markets, LNG exporters, and European industrials, see our comprehensive analysis: The Ratio That Reveals Everything: How One Number Explains the Largest Energy Restructuring in 50 Years.

What You'll Build

A ratio tracker that:

  • Fetches live prices — Brent crude and Dutch TTF natural gas
  • Calculates the energy-equivalent ratio — Converting to common units (USD/MWh)
  • Compares to historical averages — Contextualize current levels
  • Alerts on key thresholds — Get notified when the ratio crosses critical levels

Prerequisites

The Math Behind the Ratio

Before we code, understand the calculation:

TTF/Brent Ratio = (TTF_EUR × EUR_USD) / (Brent_USD / 1.7)

Where:

  • TTF is priced in EUR/MWh
  • Brent is priced in USD/barrel
  • 1.7 converts barrels to MWh (1 barrel ≈ 1.7 MWh thermal energy)
  • EUR_USD exchange rate converts TTF to USD

Python Implementation

import requests
from datetime import datetime

API_KEY = "your_api_key_here"
BASE_URL = "https://api.oilpriceapi.com/v1"
HEADERS = {"Authorization": f"Token \{API_KEY\}"}

def get_latest_price(code: str) -> float:
    """Fetch latest price for a commodity code."""
    response = requests.get(
        f"\{BASE_URL\}/prices/latest",
        headers=HEADERS,
        params={"by_code": code}
    )
    response.raise_for_status()
    data = response.json()
    return data["data"]["price"]

def calculate_ttf_brent_ratio() -> dict:
    """Calculate the TTF/Brent energy-equivalent ratio."""
    # Fetch current prices
    ttf_eur = get_latest_price("DUTCH_TTF_EUR")      # EUR/MWh
    brent_usd = get_latest_price("BRENT_CRUDE_USD")   # USD/barrel
    eur_usd = get_latest_price("EUR_USD")             # USD per EUR

    # Convert TTF to USD/MWh
    ttf_usd = ttf_eur * eur_usd

    # Convert Brent to USD/MWh (1 barrel = 1.7 MWh)
    brent_usd_mwh = brent_usd / 1.7

    # Calculate ratio
    ratio = ttf_usd / brent_usd_mwh

    return {
        "ratio": round(ratio, 3),
        "ttf_eur_mwh": ttf_eur,
        "ttf_usd_mwh": round(ttf_usd, 2),
        "brent_usd_bbl": brent_usd,
        "brent_usd_mwh": round(brent_usd_mwh, 2),
        "eur_usd": eur_usd,
        "timestamp": datetime.utcnow().isoformat()
    }

def analyze_ratio(ratio: float) -> str:
    """Interpret the ratio relative to historical context."""
    if ratio < 0.50:
        return "CRISIS LOW: Below pre-2021 average. Check for data anomaly."
    elif ratio < 0.65:
        return "OVERSUPPLY: Gas discounted to oil. Bullish for industrials."
    elif ratio <= 0.90:
        return "NEW NORMAL: LNG-dominated market. Structural premium."
    elif ratio <= 1.20:
        return "STRESS: Gas at/above oil parity. Demand destruction likely."
    else:
        return "CRISIS: Extreme gas premium. Check for supply disruption."

# Run the tracker
if __name__ == "__main__":
    result = calculate_ttf_brent_ratio()
    analysis = analyze_ratio(result["ratio"])

    print(f"""
TTF/Brent Energy Ratio Tracker
==============================
Ratio: \{result['ratio']\} (Historical avg: 0.40)

Prices:
  TTF:   EUR \{result['ttf_eur_mwh']\}/MWh (USD \{result['ttf_usd_mwh']\}/MWh)
  Brent: USD \{result['brent_usd_bbl']\}/bbl (USD \{result['brent_usd_mwh']\}/MWh)
  EUR/USD: \{result['eur_usd']\}

Analysis: \{analysis\}

Updated: \{result['timestamp']\}
    """)

Node.js/TypeScript Implementation

const API_KEY = "your_api_key_here";
const BASE_URL = "https://api.oilpriceapi.com/v1";

interface PriceResponse {
  data: {
    price: number;
    code: string;
    updated_at: string;
  };
}

interface RatioResult {
  ratio: number;
  ttfEurMwh: number;
  ttfUsdMwh: number;
  brentUsdBbl: number;
  brentUsdMwh: number;
  eurUsd: number;
  timestamp: string;
}

async function getLatestPrice(code: string): Promise<number> {
  const response = await fetch(
    `${BASE_URL}/prices/latest?by_code=${code}`,
    {
      headers: { Authorization: `Token ${API_KEY}` },
    }
  );

  if (!response.ok) {
    throw new Error(`Failed to fetch ${code}: ${response.statusText}`);
  }

  const data: PriceResponse = await response.json();
  return data.data.price;
}

async function calculateTtfBrentRatio(): Promise<RatioResult> {
  // Fetch all prices in parallel
  const [ttfEur, brentUsd, eurUsd] = await Promise.all([
    getLatestPrice("DUTCH_TTF_EUR"),
    getLatestPrice("BRENT_CRUDE_USD"),
    getLatestPrice("EUR_USD"),
  ]);

  // Convert TTF to USD/MWh
  const ttfUsd = ttfEur * eurUsd;

  // Convert Brent to USD/MWh (1 barrel = 1.7 MWh)
  const brentUsdMwh = brentUsd / 1.7;

  // Calculate ratio
  const ratio = ttfUsd / brentUsdMwh;

  return {
    ratio: Math.round(ratio * 1000) / 1000,
    ttfEurMwh: ttfEur,
    ttfUsdMwh: Math.round(ttfUsd * 100) / 100,
    brentUsdBbl: brentUsd,
    brentUsdMwh: Math.round(brentUsdMwh * 100) / 100,
    eurUsd: eurUsd,
    timestamp: new Date().toISOString(),
  };
}

// Ratio interpretation bands
function analyzeRatio(ratio: number): string {
  if (ratio < 0.50) return "CRISIS LOW";
  if (ratio < 0.65) return "OVERSUPPLY";
  if (ratio <= 0.90) return "NEW NORMAL";
  if (ratio <= 1.20) return "STRESS";
  return "CRISIS";
}

// Run
calculateTtfBrentRatio().then((result) => {
  console.log(`TTF/Brent Ratio: ${result.ratio}`);
  console.log(`Status: ${analyzeRatio(result.ratio)}`);
  console.log(`Historical avg: 0.40 | Current: ${result.ratio}`);
});

Historical Ratio Analysis

Track how the ratio has evolved over time:

def get_historical_ratio(days: int = 30) -> list:
    """Fetch historical prices and calculate ratio over time."""
    # Get historical data for each commodity
    ttf_history = requests.get(
        f"{BASE_URL}/prices/historical",
        headers=HEADERS,
        params={"code": "DUTCH_TTF_EUR", "days": days}
    ).json()["data"]

    brent_history = requests.get(
        f"{BASE_URL}/prices/historical",
        headers=HEADERS,
        params={"code": "BRENT_CRUDE_USD", "days": days}
    ).json()["data"]

    # For simplicity, use a fixed EUR/USD rate
    # (For production, fetch historical EUR/USD as well)
    eur_usd = 1.168

    ratios = []
    for ttf, brent in zip(ttf_history, brent_history):
        ttf_usd = ttf["price"] * eur_usd
        brent_mwh = brent["price"] / 1.7
        ratio = ttf_usd / brent_mwh
        ratios.append({
            "date": ttf["created_at"][:10],
            "ratio": round(ratio, 3),
            "ttf": ttf["price"],
            "brent": brent["price"]
        })

    return ratios

Set Up Threshold Alerts

Get notified when the ratio moves into different regimes:

def check_ratio_alerts(ratio: float, previous_ratio: float = None) -> list:
    """Check if ratio has crossed key thresholds."""
    alerts = []
    thresholds = [
        (0.65, "OVERSUPPLY", "below"),
        (0.90, "NEW_NORMAL_TOP", "above"),
        (1.00, "OIL_PARITY", "above"),
        (1.20, "CRISIS", "above"),
    ]

    for threshold, name, direction in thresholds:
        if direction == "above" and ratio > threshold:
            if previous_ratio and previous_ratio <= threshold:
                alerts.append(f"ALERT: Ratio crossed ABOVE {threshold} ({name})")
        elif direction == "below" and ratio < threshold:
            if previous_ratio and previous_ratio >= threshold:
                alerts.append(f"ALERT: Ratio crossed BELOW {threshold} ({name})")

    return alerts

Available API Endpoints

OilPriceAPI provides all the data you need for energy market analysis:

EndpointCodeUnitDescription
/v1/prices/latest?by_code=DUTCH_TTF_EURDUTCH_TTF_EUREUR/MWhDutch TTF Natural Gas
/v1/prices/latest?by_code=BRENT_CRUDE_USDBRENT_CRUDE_USDUSD/bblBrent Crude Oil
/v1/prices/latest?by_code=EUR_USDEUR_USDrateEuro/USD Exchange
/v1/prices/latest?by_code=NATURAL_GAS_USDNATURAL_GAS_USDUSD/MMBtuHenry Hub Natural Gas
/v1/prices/latest?by_code=WTI_USDWTI_USDUSD/bblWTI Crude Oil
/v1/prices/historicalvarious-Historical price data

Use Cases

Energy Trading Desks

Monitor ratio for relative value opportunities between gas and oil markets.

Industrial Risk Management

Track the ratio to hedge energy input costs for manufacturing.

LNG Exporters

The ratio directly impacts LNG netback economics and contract negotiations.

Macro Funds

Use as leading indicator for European industrial competitiveness and EUR/USD direction.

Production Considerations

  • Caching: TTF and Brent update frequently during trading hours. Cache for 1-5 minutes depending on your latency requirements.
  • Timezone awareness: European gas markets close at different times than oil. Weekend data reflects Friday closes.
  • Error handling: Always handle API failures gracefully—markets close and data can be delayed.

Get Started

Ready to Build Your Ratio Tracker?

Get your free API key. 10,000 requests included in the 7-day trial, no credit card required.

broad commodity coverage • Real-time prices • Historical data • Python & Node.js SDKs