US Bureau of Economic Analysis
GDP by Industry
Introduction
The GDP by Industry dataset by the US Bureau of Economic Analysis (BEA) tracks how much each US industry contributes to gross domestic product. The data covers 100 US industries, starts in January 2005, and is delivered on a quarterly frequency. This dataset is created by processing the BEA Industry Economic Accounts.
For more information about the GDP by Industry dataset, including CLI commands and pricing, see the dataset listing.
Getting Started
The following snippet demonstrates how to request data from the GDP by Industry dataset:
self.dataset_symbol = self.add_data(BEAGDPByIndustry, BEA.Industries.MANUFACTURING, Resolution.DAILY).symbol
_datasetSymbol = AddData<BEAGDPByIndustry>(BEA.Industries.Manufacturing, Resolution.Daily).Symbol;
Requesting Data
To add GDP by Industry 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 BEAGDPByIndustryDataAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2019, 1, 1)
self.set_end_date(2020, 12, 31)
self.set_cash(100000)
self.dataset_symbol = self.add_data(BEAGDPByIndustry, BEA.Industries.MANUFACTURING, Resolution.DAILY).symbol public class BEAGDPByIndustryDataAlgorithm : QCAlgorithm
{
private Symbol _datasetSymbol;
public override void Initialize()
{
SetStartDate(2019, 1, 1);
SetEndDate(2020, 12, 31);
SetCash(100000);
_datasetSymbol = AddData<BEAGDPByIndustry>(BEA.Industries.Manufacturing, Resolution.Daily).Symbol;
}
}
Accessing Data
To get the current GDP by Industry 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.dataset_symbol):
data_point = slice[self.dataset_symbol]
self.log(f"{self.dataset_symbol} value added at {slice.time}: {data_point.value_added}") public override void OnData(Slice slice)
{
if (slice.ContainsKey(_datasetSymbol))
{
var dataPoint = slice[_datasetSymbol];
Log($"{_datasetSymbol} value added at {slice.Time}: {dataPoint.ValueAdded}");
}
}
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(BEAGDPByIndustry).items():
self.log(f"{dataset_symbol} value added at {slice.time}: {data_point.value_added}") public override void OnData(Slice slice)
{
foreach (var kvp in slice.Get<BEAGDPByIndustry>())
{
var datasetSymbol = kvp.Key;
var dataPoint = kvp.Value;
Log($"{datasetSymbol} value added at {slice.Time}: {dataPoint.ValueAdded}");
}
}
Historical Data
To get historical GDP by Industry 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.dataset_symbol, 100, Resolution.DAILY) # Dataset objects history_bars = self.history[BEAGDPByIndustry](self.dataset_symbol, 100, Resolution.DAILY)
var history = History<BEAGDPByIndustry>(_datasetSymbol, 100, Resolution.Daily);
For more information about historical data, see History Requests.
Supported Industries
The following table shows the accessor code you need to add some example industries to your algorithm:
| Constant | Industry |
|---|---|
BEA.Industries.ManufacturingBEA.Industries.MANUFACTURING | Manufacturing |
BEA.Industries.ConstructionBEA.Industries.CONSTRUCTION | Construction |
BEA.Industries.FinanceAndInsuranceBEA.Industries.FINANCE_AND_INSURANCE | Finance and insurance |
BEA.Industries.RetailTradeBEA.Industries.RETAIL_TRADE | Retail trade |
BEA.Industries.OilAndGasExtractionBEA.Industries.OIL_AND_GAS_EXTRACTION | Oil and gas extraction |
BEA.Industries.GrossDomesticProductBEA.Industries.GROSS_DOMESTIC_PRODUCT | Gross domestic product (all industries) |
Example Applications
The GDP by Industry dataset enables you to see which parts of the US economy are growing. Examples include the following strategies:
- Rotating into sectors when their industry output starts to grow again
- Tilting a sector portfolio toward the fastest-growing industries
- Using industry price indexes to gauge inflation in each sector
Classic Algorithm Example
The following example algorithm buys SPY when Manufacturing real value added rises quarter over quarter. Otherwise, it liquidates the position.
from AlgorithmImports import *
class BEAGDPByIndustryDataAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2019, 1, 1)
self.set_end_date(2020, 12, 31)
self.set_cash(100000)
self._spy = self.add_equity("SPY", Resolution.DAILY).symbol
self._manufacturing = self.add_data(BEAGDPByIndustry, BEA.Industries.MANUFACTURING, Resolution.DAILY).symbol
self._previous_real_value_added = None
def on_data(self, slice):
if not slice.contains_key(self._manufacturing):
return
# Buy SPY when real value added rises quarter over quarter. Otherwise, liquidate.
real = slice[self._manufacturing].real_value_added
if self._previous_real_value_added is not None and real is not None:
if real > self._previous_real_value_added:
self.set_holdings(self._spy, 1)
else:
self.liquidate(self._spy)
self._previous_real_value_added = real public class BEAGDPByIndustryDataAlgorithm : QCAlgorithm
{
private Symbol _spy, _manufacturing;
private decimal? _previousRealValueAdded;
public override void Initialize()
{
SetStartDate(2019, 1, 1);
SetEndDate(2020, 12, 31);
SetCash(100000);
_spy = AddEquity("SPY", Resolution.Daily).Symbol;
_manufacturing = AddData<BEAGDPByIndustry>(BEA.Industries.Manufacturing, Resolution.Daily).Symbol;
}
public override void OnData(Slice slice)
{
if (!slice.ContainsKey(_manufacturing))
{
return;
}
// Buy SPY when real value added rises quarter over quarter. Otherwise, liquidate.
var real = slice.Get<BEAGDPByIndustry>(_manufacturing).RealValueAdded;
if (_previousRealValueAdded.HasValue && real.HasValue)
{
if (real > _previousRealValueAdded)
{
SetHoldings(_spy, 1);
}
else
{
Liquidate(_spy);
}
}
_previousRealValueAdded = real;
}
}
Framework Algorithm Example
The following example algorithm emits up insights for SPY when Manufacturing real value added rises quarter over quarter. Otherwise, it emits down insights.
from AlgorithmImports import *
class BEAGDPByIndustryFrameworkAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2019, 1, 1)
self.set_end_date(2020, 12, 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(BEAGDPByIndustryAlphaModel(self))
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
class BEAGDPByIndustryAlphaModel(AlphaModel):
def __init__(self, algorithm):
self._manufacturing = algorithm.add_data(BEAGDPByIndustry, BEA.Industries.MANUFACTURING, Resolution.DAILY).symbol
self._previous_real_value_added = None
self._tradable_symbols = []
def update(self, algorithm, slice):
insights = []
if not slice.contains_key(self._manufacturing):
return insights
real = slice[self._manufacturing].real_value_added
if self._previous_real_value_added is not None and real is not None:
direction = InsightDirection.UP if real > self._previous_real_value_added else InsightDirection.DOWN
insights = [Insight.price(symbol, timedelta(days=90), direction) for symbol in self._tradable_symbols]
self._previous_real_value_added = real
return insights
def on_securities_changed(self, algorithm, changes):
for security in changes.added_securities:
if security.symbol != self._manufacturing:
self._tradable_symbols.append(security.symbol)
for security in changes.removed_securities:
if security.symbol in self._tradable_symbols:
self._tradable_symbols.remove(security.symbol) public class BEAGDPByIndustryFrameworkAlgorithm : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2019, 1, 1);
SetEndDate(2020, 12, 31);
SetCash(100000);
UniverseSettings.Resolution = Resolution.Daily;
var symbols = new[] { QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA) };
SetUniverseSelection(new ManualUniverseSelectionModel(symbols));
AddAlpha(new BEAGDPByIndustryAlphaModel(this));
SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
}
}
public class BEAGDPByIndustryAlphaModel : AlphaModel
{
private readonly Symbol _manufacturing;
private decimal? _previousRealValueAdded;
private readonly List<Symbol> _tradableSymbols = new();
public BEAGDPByIndustryAlphaModel(QCAlgorithm algorithm)
{
_manufacturing = algorithm.AddData<BEAGDPByIndustry>(BEA.Industries.Manufacturing, Resolution.Daily).Symbol;
}
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
{
var insights = new List<Insight>();
if (!slice.ContainsKey(_manufacturing))
{
return insights;
}
var real = slice.Get<BEAGDPByIndustry>(_manufacturing).RealValueAdded;
if (_previousRealValueAdded.HasValue && real.HasValue)
{
var direction = real > _previousRealValueAdded ? InsightDirection.Up : InsightDirection.Down;
foreach (var symbol in _tradableSymbols)
{
insights.Add(Insight.Price(symbol, TimeSpan.FromDays(90), direction));
}
}
_previousRealValueAdded = real;
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
foreach (var security in changes.AddedSecurities)
{
if (security.Symbol != _manufacturing)
{
_tradableSymbols.Add(security.Symbol);
}
}
foreach (var security in changes.RemovedSecurities)
{
_tradableSymbols.Remove(security.Symbol);
}
}
}