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.
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;
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.
Supported Economies
The following table shows the accessor code you need to add each economy to your algorithm:
| Economy | Geo code | Constant |
|---|---|---|
Aggregates | ||
| Euro area (21 countries) | EA21 | Eurostat.Economies.EuroAreaEurostat.Economies.EURO_AREA |
| Euro area (20 countries) | EA20 | Eurostat.Economies.EuroArea20Eurostat.Economies.EURO_AREA_20 |
| Euro area (19 countries) | EA19 | Eurostat.Economies.EuroArea19Eurostat.Economies.EURO_AREA_19 |
| Euro area (12 countries) | EA12 | Eurostat.Economies.EuroArea12Eurostat.Economies.EURO_AREA_12 |
| Euro area, chain linked | EA | Eurostat.Economies.EuroAreaChainedEurostat.Economies.EURO_AREA_CHAINED |
| European Union | EU27_2020 | Eurostat.Economies.EuropeanUnionEurostat.Economies.EUROPEAN_UNION |
| European Union, chain linked | EU | Eurostat.Economies.EuropeanUnionChainedEurostat.Economies.EUROPEAN_UNION_CHAINED |
| European Economic Area | EEA | Eurostat.Economies.EuropeanEconomicAreaEurostat.Economies.EUROPEAN_ECONOMIC_AREA |
Countries | ||
| Albania | AL | Eurostat.Economies.AlbaniaEurostat.Economies.ALBANIA |
| Austria | AT | Eurostat.Economies.AustriaEurostat.Economies.AUSTRIA |
| Belgium | BE | Eurostat.Economies.BelgiumEurostat.Economies.BELGIUM |
| Bosnia and Herzegovina | BA | Eurostat.Economies.BosniaAndHerzegovinaEurostat.Economies.BOSNIA_AND_HERZEGOVINA |
| Bulgaria | BG | Eurostat.Economies.BulgariaEurostat.Economies.BULGARIA |
| Croatia | HR | Eurostat.Economies.CroatiaEurostat.Economies.CROATIA |
| Cyprus | CY | Eurostat.Economies.CyprusEurostat.Economies.CYPRUS |
| Czechia | CZ | Eurostat.Economies.CzechiaEurostat.Economies.CZECHIA |
| Denmark | DK | Eurostat.Economies.DenmarkEurostat.Economies.DENMARK |
| Estonia | EE | Eurostat.Economies.EstoniaEurostat.Economies.ESTONIA |
| Finland | FI | Eurostat.Economies.FinlandEurostat.Economies.FINLAND |
| France | FR | Eurostat.Economies.FranceEurostat.Economies.FRANCE |
| Georgia | GE | Eurostat.Economies.GeorgiaEurostat.Economies.GEORGIA |
| Germany | DE | Eurostat.Economies.GermanyEurostat.Economies.GERMANY |
| Greece | EL | Eurostat.Economies.GreeceEurostat.Economies.GREECE |
| Hungary | HU | Eurostat.Economies.HungaryEurostat.Economies.HUNGARY |
| Iceland | IS | Eurostat.Economies.IcelandEurostat.Economies.ICELAND |
| Ireland | IE | Eurostat.Economies.IrelandEurostat.Economies.IRELAND |
| Italy | IT | Eurostat.Economies.ItalyEurostat.Economies.ITALY |
| Japan | JP | Eurostat.Economies.JapanEurostat.Economies.JAPAN |
| Kosovo | XK | Eurostat.Economies.KosovoEurostat.Economies.KOSOVO |
| Latvia | LV | Eurostat.Economies.LatviaEurostat.Economies.LATVIA |
| Lithuania | LT | Eurostat.Economies.LithuaniaEurostat.Economies.LITHUANIA |
| Luxembourg | LU | Eurostat.Economies.LuxembourgEurostat.Economies.LUXEMBOURG |
| Malta | MT | Eurostat.Economies.MaltaEurostat.Economies.MALTA |
| Moldova | MD | Eurostat.Economies.MoldovaEurostat.Economies.MOLDOVA |
| Montenegro | ME | Eurostat.Economies.MontenegroEurostat.Economies.MONTENEGRO |
| Netherlands | NL | Eurostat.Economies.NetherlandsEurostat.Economies.NETHERLANDS |
| North Macedonia | MK | Eurostat.Economies.NorthMacedoniaEurostat.Economies.NORTH_MACEDONIA |
| Norway | NO | Eurostat.Economies.NorwayEurostat.Economies.NORWAY |
| Poland | PL | Eurostat.Economies.PolandEurostat.Economies.POLAND |
| Portugal | PT | Eurostat.Economies.PortugalEurostat.Economies.PORTUGAL |
| Romania | RO | Eurostat.Economies.RomaniaEurostat.Economies.ROMANIA |
| Serbia | RS | Eurostat.Economies.SerbiaEurostat.Economies.SERBIA |
| Slovakia | SK | Eurostat.Economies.SlovakiaEurostat.Economies.SLOVAKIA |
| Slovenia | SI | Eurostat.Economies.SloveniaEurostat.Economies.SLOVENIA |
| Spain | ES | Eurostat.Economies.SpainEurostat.Economies.SPAIN |
| Sweden | SE | Eurostat.Economies.SwedenEurostat.Economies.SWEDEN |
| Switzerland | CH | Eurostat.Economies.SwitzerlandEurostat.Economies.SWITZERLAND |
| Turkiye | TR | Eurostat.Economies.TurkiyeEurostat.Economies.TURKIYE |
| Ukraine | UA | Eurostat.Economies.UkraineEurostat.Economies.UKRAINE |
| United Kingdom | UK | Eurostat.Economies.UnitedKingdomEurostat.Economies.UNITED_KINGDOM |
| United States | US | Eurostat.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: