Eurostat

Macro Indicators

Introduction

The Macroeconomic Indicators dataset by Eurostat tracks consumer prices, producer prices, industrial production, retail trade, unemployment, and GDP for European economies. The data covers up to 46 European economies, starts in January 1975, and is delivered on a monthly frequency, with GDP delivered quarterly. This dataset is created by processing the statistics Eurostat publishes through its public API. The series are not seasonally adjusted, so they differ from the figures quoted in the press.

For more information about the Macro Indicators dataset, including CLI commands and pricing, see the dataset listing.

About the Provider

Eurostat is the statistical office of the European Union, founded in 1953 and based in Luxembourg. It collects data from the national statistics offices and publishes statistics that can be compared across European countries.

Getting Started

The following snippet demonstrates how to request data from the Macroeconomic Indicators dataset:

self.prices = self.add_data(EurostatConsumerPrices, Eurostat.Economies.EURO_AREA, Resolution.DAILY).symbol
self.production = self.add_data(EurostatIndustrialProduction, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol
_prices = AddData<EurostatConsumerPrices>(Eurostat.Economies.EuroArea, Resolution.Daily).Symbol;
_production = AddData<EurostatIndustrialProduction>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;

Data Summary

The following table describes the dataset properties:

PropertyValue
Start DateJanuary 1975
Asset Coverage51 economies
Data DensitySparse
ResolutionDaily*
TimezoneBrussels

* Monthly and quarterly data we fetch daily.

Requesting Data

To add Macroeconomic Indicators data to your algorithm, call the AddDataadd_data method. Save a reference to the dataset Symbol so you can access the data later in your algorithm.

class EurostatIndicatorsDataAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2018, 1, 1)
        self.set_end_date(2021, 3, 31)
        self.set_cash(100000)

        self.equity = self.add_equity("SPY", Resolution.DAILY).symbol

        self.prices = self.add_data(EurostatConsumerPrices, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol
        self.production = self.add_data(EurostatIndustrialProduction, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol
        self.gdp = self.add_data(EurostatGrossDomesticProduct, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol
public class EurostatIndicatorsDataAlgorithm : QCAlgorithm
{
    private Symbol _equity, _prices, _production, _gdp;

    public override void Initialize()
    {
        SetStartDate(2018, 1, 1);
        SetEndDate(2021, 3, 31);
        SetCash(100000);

        _equity = AddEquity("SPY", Resolution.Daily).Symbol;

        _prices = AddData<EurostatConsumerPrices>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;
        _production = AddData<EurostatIndustrialProduction>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;
        _gdp = AddData<EurostatGrossDomesticProduct>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;
    }
}

Accessing Data

To get the current Macroeconomic Indicators data, index the current Slice with the dataset Symbol. Slice objects deliver unique events to your algorithm as they happen, but the Slice may not contain data for your dataset at every time step. To avoid issues, check if the Slice contains the data you want before you index it.

def on_data(self, slice: Slice) -> None:
    if slice.contains_key(self.prices):
        data_point = slice[self.prices]
        self.log(f"{self.prices} HICP at {slice.time}: {data_point.all_items}")
public override void OnData(Slice slice)
{
    if (slice.ContainsKey(_prices))
    {
        var dataPoint = slice[_prices];
        Log($"{_prices} HICP at {slice.Time}: {dataPoint.AllItems}");
    }
}

To iterate through all of the dataset objects in the current Slice, call the Getget method.

def on_data(self, slice: Slice) -> None:
    for dataset_symbol, data_point in slice.get(EurostatIndustrialProduction).items():
        self.log(f"{dataset_symbol} industrial production at {slice.time}: {data_point.total_industry}")
public override void OnData(Slice slice)
{
    foreach (var kvp in slice.Get<EurostatIndustrialProduction>())
    {
        var datasetSymbol = kvp.Key;
        var dataPoint = kvp.Value;
        Log($"{datasetSymbol} industrial production at {slice.Time}: {dataPoint.TotalIndustry}");
    }
}

Historical Data

To get historical Macroeconomic Indicators data, call the Historyhistory method with the dataset Symbol. If there is no data in the period you request, the history result is empty.

# DataFrame
history_df = self.history(self.prices, timedelta(days=1825), Resolution.DAILY)

# Dataset objects
history_bars = self.history[EurostatConsumerPrices](self.prices, timedelta(days=1825), Resolution.DAILY)
var history = History<EurostatConsumerPrices>(_prices, TimeSpan.FromDays(1825), Resolution.Daily);

For more information about historical data, see History Requests.

Remove Subscriptions

To remove your subscription to Macroeconomic Indicators data, call the RemoveSecurityremove_security method.

self.remove_security(self.prices)
RemoveSecurity(_prices);

Supported Economies

The following table shows the accessor code you need to add each economy to your algorithm:

EconomyGeo codeConstant
Aggregates
Euro area (21 countries)EA21Eurostat.Economies.EuroAreaEurostat.Economies.EURO_AREA
Euro area (20 countries)EA20Eurostat.Economies.EuroArea20Eurostat.Economies.EURO_AREA_20
Euro area (19 countries)EA19Eurostat.Economies.EuroArea19Eurostat.Economies.EURO_AREA_19
Euro area (12 countries)EA12Eurostat.Economies.EuroArea12Eurostat.Economies.EURO_AREA_12
Euro area, chain linkedEAEurostat.Economies.EuroAreaChainedEurostat.Economies.EURO_AREA_CHAINED
European UnionEU27_2020Eurostat.Economies.EuropeanUnionEurostat.Economies.EUROPEAN_UNION
European Union, chain linkedEUEurostat.Economies.EuropeanUnionChainedEurostat.Economies.EUROPEAN_UNION_CHAINED
European Economic AreaEEAEurostat.Economies.EuropeanEconomicAreaEurostat.Economies.EUROPEAN_ECONOMIC_AREA
Countries
AlbaniaALEurostat.Economies.AlbaniaEurostat.Economies.ALBANIA
AustriaATEurostat.Economies.AustriaEurostat.Economies.AUSTRIA
BelgiumBEEurostat.Economies.BelgiumEurostat.Economies.BELGIUM
Bosnia and HerzegovinaBAEurostat.Economies.BosniaAndHerzegovinaEurostat.Economies.BOSNIA_AND_HERZEGOVINA
BulgariaBGEurostat.Economies.BulgariaEurostat.Economies.BULGARIA
CroatiaHREurostat.Economies.CroatiaEurostat.Economies.CROATIA
CyprusCYEurostat.Economies.CyprusEurostat.Economies.CYPRUS
CzechiaCZEurostat.Economies.CzechiaEurostat.Economies.CZECHIA
DenmarkDKEurostat.Economies.DenmarkEurostat.Economies.DENMARK
EstoniaEEEurostat.Economies.EstoniaEurostat.Economies.ESTONIA
FinlandFIEurostat.Economies.FinlandEurostat.Economies.FINLAND
FranceFREurostat.Economies.FranceEurostat.Economies.FRANCE
GeorgiaGEEurostat.Economies.GeorgiaEurostat.Economies.GEORGIA
GermanyDEEurostat.Economies.GermanyEurostat.Economies.GERMANY
GreeceELEurostat.Economies.GreeceEurostat.Economies.GREECE
HungaryHUEurostat.Economies.HungaryEurostat.Economies.HUNGARY
IcelandISEurostat.Economies.IcelandEurostat.Economies.ICELAND
IrelandIEEurostat.Economies.IrelandEurostat.Economies.IRELAND
ItalyITEurostat.Economies.ItalyEurostat.Economies.ITALY
JapanJPEurostat.Economies.JapanEurostat.Economies.JAPAN
KosovoXKEurostat.Economies.KosovoEurostat.Economies.KOSOVO
LatviaLVEurostat.Economies.LatviaEurostat.Economies.LATVIA
LithuaniaLTEurostat.Economies.LithuaniaEurostat.Economies.LITHUANIA
LuxembourgLUEurostat.Economies.LuxembourgEurostat.Economies.LUXEMBOURG
MaltaMTEurostat.Economies.MaltaEurostat.Economies.MALTA
MoldovaMDEurostat.Economies.MoldovaEurostat.Economies.MOLDOVA
MontenegroMEEurostat.Economies.MontenegroEurostat.Economies.MONTENEGRO
NetherlandsNLEurostat.Economies.NetherlandsEurostat.Economies.NETHERLANDS
North MacedoniaMKEurostat.Economies.NorthMacedoniaEurostat.Economies.NORTH_MACEDONIA
NorwayNOEurostat.Economies.NorwayEurostat.Economies.NORWAY
PolandPLEurostat.Economies.PolandEurostat.Economies.POLAND
PortugalPTEurostat.Economies.PortugalEurostat.Economies.PORTUGAL
RomaniaROEurostat.Economies.RomaniaEurostat.Economies.ROMANIA
SerbiaRSEurostat.Economies.SerbiaEurostat.Economies.SERBIA
SlovakiaSKEurostat.Economies.SlovakiaEurostat.Economies.SLOVAKIA
SloveniaSIEurostat.Economies.SloveniaEurostat.Economies.SLOVENIA
SpainESEurostat.Economies.SpainEurostat.Economies.SPAIN
SwedenSEEurostat.Economies.SwedenEurostat.Economies.SWEDEN
SwitzerlandCHEurostat.Economies.SwitzerlandEurostat.Economies.SWITZERLAND
TurkiyeTREurostat.Economies.TurkiyeEurostat.Economies.TURKIYE
UkraineUAEurostat.Economies.UkraineEurostat.Economies.UKRAINE
United KingdomUKEurostat.Economies.UnitedKingdomEurostat.Economies.UNITED_KINGDOM
United StatesUSEurostat.Economies.UnitedStatesEurostat.Economies.UNITED_STATES

Example Applications

The Macroeconomic Indicators dataset enables you to follow the European economy in your strategies. Examples include the following strategies:

  • Trading euro area rates or the euro around consumer price releases
  • Rotating country exposure based on industrial production across economies
  • Scaling risk up or down with unemployment and GDP growth

Classic Algorithm Example

The following example algorithm buys SPY when German industrial production rises. Otherwise, it liquidates the position.

from AlgorithmImports import *

class EurostatIndicatorsExampleAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2018, 1, 1)
        self.set_end_date(2021, 3, 31)
        self.set_cash(100000)

        self.equity = self.add_equity("SPY", Resolution.DAILY).symbol

        self.prices = self.add_data(EurostatConsumerPrices, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol
        self.production = self.add_data(EurostatIndustrialProduction, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol

        self.previous_production = None

    def on_data(self, slice):
        prices = slice.get(EurostatConsumerPrices)
        if self.prices in prices:
            data_point = prices[self.prices]
            self.debug(f"HICP all items: {data_point.all_items}, core: {data_point.core}, energy: {data_point.energy}")

        production = slice.get(EurostatIndustrialProduction)
        if self.production not in production:
            return

        total_industry = production[self.production].total_industry
        if total_industry is None:
            return

        # Buy SPY when output rises. Otherwise, liquidate.
        if self.previous_production is not None:
            if total_industry > self.previous_production:
                self.set_holdings(self.equity, 1)
            else:
                self.liquidate(self.equity)

        self.previous_production = total_industry
public class EurostatIndicatorsExampleAlgorithm : QCAlgorithm
{
    private Symbol _equity, _prices, _production;
    private decimal? _previousProduction;

    public override void Initialize()
    {
        SetStartDate(2018, 1, 1);
        SetEndDate(2021, 3, 31);
        SetCash(100000);

        _equity = AddEquity("SPY", Resolution.Daily).Symbol;

        _prices = AddData<EurostatConsumerPrices>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;
        _production = AddData<EurostatIndustrialProduction>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;
    }

    public override void OnData(Slice slice)
    {
        var prices = slice.Get<EurostatConsumerPrices>();
        if (prices.ContainsKey(_prices))
        {
            var dataPoint = prices[_prices];
            Debug($"HICP all items: {dataPoint.AllItems}, core: {dataPoint.Core}, energy: {dataPoint.Energy}");
        }

        var production = slice.Get<EurostatIndustrialProduction>();
        if (!production.ContainsKey(_production))
        {
            return;
        }

        var totalIndustry = production[_production].TotalIndustry;
        if (!totalIndustry.HasValue)
        {
            return;
        }

        // Buy SPY when output rises. Otherwise, liquidate.
        if (_previousProduction.HasValue)
        {
            if (totalIndustry > _previousProduction)
            {
                SetHoldings(_equity, 1);
            }
            else
            {
                Liquidate(_equity);
            }
        }

        _previousProduction = totalIndustry;
    }
}

Framework Algorithm Example

The following example algorithm emits up insights for SPY when German industrial production rises and unemployment does not. Otherwise, it emits flat insights.

from AlgorithmImports import *

class EurostatIndicatorsFrameworkAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2018, 1, 1)
        self.set_end_date(2021, 3, 31)
        self.set_cash(100000)

        self.universe_settings.resolution = Resolution.DAILY

        symbols = [Symbol.create("SPY", SecurityType.EQUITY, Market.USA)]
        self.set_universe_selection(ManualUniverseSelectionModel(symbols))

        self.add_alpha(EurostatMacroCycleAlphaModel(self))

        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
        self.set_execution(ImmediateExecutionModel())


class EurostatMacroCycleAlphaModel(AlphaModel):
    """Emits insights from the European macro cycle, read across output and unemployment."""

    def __init__(self, algorithm):
        self._production = algorithm.add_data(EurostatIndustrialProduction, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol
        self._labour = algorithm.add_data(EurostatLabourMarket, Eurostat.Economies.GERMANY, Resolution.DAILY).symbol

        history = algorithm.history(EurostatIndustrialProduction, self._production, timedelta(days=1825), Resolution.DAILY)
        algorithm.debug(f"Got {len(history)} historical industrial production rows")

        self._previous_production = None
        self._previous_unemployment = None
        self._symbols = []

    def update(self, algorithm, data):
        insights = []

        production = data.get(EurostatIndustrialProduction)
        if self._production not in production:
            return insights

        total_industry = production[self._production].total_industry
        if total_industry is None:
            return insights

        # Read the latest unemployment rate from the security cache.
        labour_point = algorithm.securities[self._labour].cache.get_data(EurostatLabourMarket)
        unemployment = labour_point.unemployment_rate if labour_point else None

        if self._previous_production is not None:
            expanding = total_industry > self._previous_production
            if expanding and unemployment is not None and self._previous_unemployment is not None:
                expanding = unemployment <= self._previous_unemployment

            direction = InsightDirection.UP if expanding else InsightDirection.FLAT
            insights = [Insight.price(symbol, timedelta(days=30), direction) for symbol in self._symbols]

        self._previous_production = total_industry
        if unemployment is not None:
            self._previous_unemployment = unemployment

        return insights

    def on_securities_changed(self, algorithm, changes):
        for security in changes.added_securities:
            self._symbols.append(security.symbol)

        for security in changes.removed_securities:
            if security.symbol in self._symbols:
                self._symbols.remove(security.symbol)
public class EurostatIndicatorsFrameworkAlgorithm : QCAlgorithm
{
    public override void Initialize()
    {
        SetStartDate(2018, 1, 1);
        SetEndDate(2021, 3, 31);
        SetCash(100000);

        UniverseSettings.Resolution = Resolution.Daily;

        var symbols = new[] { QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA) };
        SetUniverseSelection(new ManualUniverseSelectionModel(symbols));

        AddAlpha(new EurostatMacroCycleAlphaModel(this));

        SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
        SetExecution(new ImmediateExecutionModel());
    }
}

public class EurostatMacroCycleAlphaModel : AlphaModel
{
    private readonly Symbol _production;
    private readonly Symbol _labour;
    private readonly List<Symbol> _symbols = new();

    private decimal? _previousProduction;
    private decimal? _previousUnemployment;

    public EurostatMacroCycleAlphaModel(QCAlgorithm algorithm)
    {
        _production = algorithm.AddData<EurostatIndustrialProduction>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;
        _labour = algorithm.AddData<EurostatLabourMarket>(Eurostat.Economies.Germany, Resolution.Daily).Symbol;

        var history = algorithm.History<EurostatIndustrialProduction>(_production, TimeSpan.FromDays(1825), Resolution.Daily);
        algorithm.Debug($"Got {history.Count()} historical industrial production rows");
    }

    public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data)
    {
        var insights = new List<Insight>();

        var production = data.Get<EurostatIndustrialProduction>();
        if (!production.ContainsKey(_production))
        {
            return insights;
        }

        var totalIndustry = production[_production].TotalIndustry;
        if (!totalIndustry.HasValue)
        {
            return insights;
        }

        // Read the latest unemployment rate from the security cache.
        var labourPoint = algorithm.Securities[_labour].Cache.GetData<EurostatLabourMarket>();
        var unemployment = labourPoint?.UnemploymentRate;

        if (_previousProduction.HasValue)
        {
            var expanding = totalIndustry > _previousProduction;
            if (expanding && unemployment.HasValue && _previousUnemployment.HasValue)
            {
                expanding = unemployment <= _previousUnemployment;
            }

            var direction = expanding ? InsightDirection.Up : InsightDirection.Flat;
            insights = _symbols.Select(symbol => Insight.Price(symbol, TimeSpan.FromDays(30), direction)).ToList();
        }

        _previousProduction = totalIndustry;
        if (unemployment.HasValue)
        {
            _previousUnemployment = unemployment;
        }

        return insights;
    }

    public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
    {
        foreach (var security in changes.AddedSecurities)
        {
            _symbols.Add(security.Symbol);
        }

        foreach (var security in changes.RemovedSecurities)
        {
            _symbols.Remove(security.Symbol);
        }
    }
}

Data Point Attributes

The Macroeconomic Indicators dataset provides EurostatConsumerPrices, EurostatIndustrialProduction, EurostatProducerPrices, EurostatRetailTrade, EurostatLabourMarket and EurostatGrossDomesticProduct objects.

EurostatConsumerPrices

EurostatConsumerPrices objects have the following attributes:

EurostatIndustrialProduction

EurostatIndustrialProduction objects have the following attributes:

EurostatProducerPrices

EurostatProducerPrices objects have the following attributes:

EurostatRetailTrade

EurostatRetailTrade objects have the following attributes:

EurostatLabourMarket

EurostatLabourMarket objects have the following attributes:

EurostatGrossDomesticProduct

EurostatGrossDomesticProduct objects have the following attributes:

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: