An Error Occured While Uploading the File Please Try Again Gdp
Evolution Tools & Resources
The case code demonstrating the utilise instance is based on the following development tools and resources:
- Refinitiv's DataStream Web Services (DSWS): Access to DataStream data. A DataStream or Refinitiv Workspace IDentification (ID) volition be needed to run the lawmaking bellow.
- Python Surround: Tested with Python iii.7
- Packages: DatastreamDSWS, Numpy, Pandas, statsmodel, scipy and Matplotlib. The Python congenital in modules warnings, statistics, datetime and dateutil are too required.
Tutorial Video Role 1 - Introduction to the Theory, Codebook and Python Libraries
Import libraries
# The ' from ... import ' structure here allows us to but import the
# module ' python_version ' from the library ' platform ':
from platform import python_version
print("This code runs on Python version " + python_version() + "\north")
This code runs on Python version three.7.iv
We need to gather our data. SinceRefinitiv's DataStream Web Services (DSWS) allows for admission to the most accurate and wholesome finish-of-day (EOD) economic database (DB), naturally it is more than appropriate. We tin access DSWS via the Python library "DatastreamDSWS" that can be installed simply past using pip install.
import DatastreamDSWS as DSWS
# We tin use our Refinitiv's Datastream Web Socket (DSWS) API keys that allows the states to exist identified by Refinitiv'due south back-end services and enables us to request (and fetch) data:
# The username and password is placed in a text file so that it may be used in this code without showing it itself.
DSWS_username = open("Datastream_username.txt","r")
DSWS_password = open up("Datastream_password.txt","r")
ds = DSWS.Datastream(username = str(DSWS_username.read()), countersign = str(DSWS_password.read()))
# Information technology is all-time to shut the files we opened in order to make certain that we don't terminate whatsoever other services/programs from accessing them if they demand to.
DSWS_username.close()
DSWS_password.close()
import eikon every bit ek
# The cardinal is placed in a text file so that information technology may be used in this lawmaking without showing it itself:
eikon_key = open("eikon.txt","r")
ek.set_app_key(str(eikon_key.read()))
# Information technology is best to shut the files nosotros opened in order to make sure that nosotros don't stop any other services/programs from accessing them if they need to:
eikon_key.shut()
The following are Python-built-in module/library, therefore it does not have a specific version number.
import os # os is a library used to dispense files on machines
import datetime # datetime volition let us to manipulate Western World dates
import dateutil # dateutil will allow us to manipulate dates in equations
import warnings # warnings will allow the states to manupulate alarm messages (such equally depretiation messages)
statistics, numpy, scipy and statsmodels are needed for datasets' statistical and mathematical manipulations
import statistics # This is a Python-built-in module/library, therefore information technology does not have a specific version number.
import numpy
import statsmodels
from statsmodels.tsa.api import ExponentialSmoothing, SimpleExpSmoothing, Holt
import scipy
from scipy import stats
for i,j in zip(["numpy", "statsmodels", "scipy"], [numpy, statsmodels, scipy]):
impress("The " + str(i) + " library imported in this lawmaking is version: " + j.__version__)
The numpy library imported in this code is version: 1.16.5
The statsmodels library imported in this lawmaking is version: 0.ten.i
The scipy library imported in this lawmaking is version: one.3.i
pandas will be needed to manipulate data sets
import pandas
pandas.set_option('brandish.max_columns', None) # This line will ensure that all columns of our dataframes are e'er shown
print("The pandas library imported in this code is version: " + pandas.__version__)
The pandas library imported in this code is version: 0.25.ane
matplotlib is needed to plot graphs of all kinds
import matplotlib
import matplotlib.pyplot equally plt
print("The matplotlib library imported in this code is version: "+ matplotlib.__version__)
The matplotlib library imported in this code is version: three.1.ane
Setup Original Functions
Tutorial Video Role 2 - Introduction to Some Python Fundamentals and Our First Set of Functions
Setup information sets
The cell below defines a function that translates DataStream data into a shape nosotros tin can work with: a Pandas Dafaframe normalised to the 1st of the calendar month that it was collected in.
# This part will put Refinitiv's DataStream data into a Pandas Dafaframe and normalise it to the 1st of the month it was collected in.
def Translate_to_First_of_the_Month(data, dataname):
# The first 8 characters of the alphabetize is the ' yyyy-mm- ', onto which will be added '01'.
information.index = information.index.astype("str").str.slice_replace(viii, repl = "01")
# This line resets the index to a pandas datetime format
data.index = pandas.to_datetime(information.alphabetize)
# This line renames the cavalcade as specified in the office
data.columns = [dataname]
return data
The cell below defines a role that appends our monthly data-frame with chosen data
df = pandas.DataFrame([])
def Add_to_df(data, dataname):
# The ' global df ' allows the role to take the pre-deffined variable ' df ' for granted and work from there
global df
DS_Data_monthly = Translate_to_First_of_the_Month(data, dataname)
# Note that the bellow is (purposefully) different to ' df[dataname] = DS_Data_monthly'
df = pandas.merge(df, DS_Data_monthly,
how = "outer",
left_index = Truthful,
right_index=True)
Setup plot functions
The jail cell below defines a role to plot data on 1 y axis.
pandas.plotting.register_matplotlib_converters() # Using an implicitly registered datetime converter for a matplotlib plotting method is no longer supported by matplotlib. Current versions of pandas requires explicitly registering matplotlib converters.
def Plot1ax(dataset, ylabel = "", championship = "", xlabel = "Year",
datasubset = [0], datarange = False,
linescolor = False, figuresize = (12,iv),
facecolor = "0.25", grid = True):
""" Plot1ax Version 2.0:
This office returns a Matplotlib graph with default colours and dimentions
on ane y axis (on the left equally oppose to two, one on the left and one on the right).
datasubset (listing): Needs to be a list of the number of each column within
the dtaset that needs to be labled on the left.
datarange (bool): If wanting to plot graph from and to a specific point,
make datarange a list of kickoff and finish date.
linescolor (bool/list): (Default: False) This needs to exist a list of the color of each
vector to be ploted, in guild they are shown in their dataframe from left to right.
figuresize (tuple): (Default: (12,4)) This can be changed to give graphs of different
proportions. It is defaulted to a 12 by four (ratioed) graph.
facecolor (str): (Default: "0.25") This allows the user to modify the
background colour every bit needed.
grid (bool): (Default: "Truthful") This allows the states to make up one's mind wether or
not to include a grid in our pharphs.
"""
# This function works if the dataset is specified in names of columns
# or their placement (first column being the '0th').
if type(datasubset[0]) == int:
if datarange == Faux:
start_date = str(dataset.iloc[:,datasubset].index[0])
end_date = str(dataset.iloc[:,datasubset].alphabetize[-one])
else:
start_date = str(datarange[0])
if datarange[-1] == -1:
end_date = str(dataset.iloc[:,datasubset].index[-1])
else:
end_date = str(datarange[-i])
else:
if datarange == Simulated:
start_date = str(dataset[datasubset].index[0])
end_date = str(dataset[datasubset].alphabetize[-1])
else:
start_date = str(datarange[0])
if datarange[-1] == -one:
end_date = str(dataset[datasubset].alphabetize[-ane])
else:
end_date = str(datarange[-1])
fig, ax1 = plt.subplots(figsize = figuresize, facecolor = facecolor)
ax1.tick_params(axis = 'both', colors = 'w')
ax1.set_facecolor(facecolor)
fig.autofmt_xdate()
plt.ylabel(ylabel, color = 'due west')
ax1.set_xlabel(str(xlabel), colour = 'west')
if blazon(datasubset[0]) == int:
if linescolor == False:
for i in datasubset: # This is to label all the lines in order to allow matplot lib to create a fable
ax1.plot(dataset.iloc[:, i].loc[start_date : end_date],
characterization = str(dataset.columns[i]))
else:
for i in datasubset: # This is to label all the lines in society to allow matplot lib to create a legend
ax1.plot(dataset.iloc[:, i].loc[start_date : end_date],
label = str(dataset.columns[i]),
color = linescolor)
else:
if linescolor == False:
for i in datasubset: # This is to characterization all the lines in order to allow matplot lib to create a legend
ax1.plot(dataset[i].loc[start_date : end_date],
label = i)
else:
for i in datasubset: # This is to label all the lines in order to let matplot lib to create a fable
ax1.plot(dataset[i].loc[start_date : end_date],
label = i,
colour = linescolor)
ax1.tick_params(axis = 'y')
if grid == True:
ax1.grid(color='black', linewidth = 0.5)
ax1.set_title(str(title) + " \n", color = 'w')
plt.fable()
plt.show()
The cell below defines a function to plot data on two y axis.
def Plot2ax(dataset, rightaxisdata, y1label, y2label, leftaxisdata,
title = "", xlabel = "Year", y2color = "C1", y1labelcolor = "C0",
figuresize = (12,four), leftcolors = ('C1'), facecolor = "0.25"):
""" Plot2ax Version two.0:
This function returns a Matplotlib graph with default colours and dimentions
on two y axis (one on the left and one on the correct)
leftaxisdata (list): Needs to be a list of the number of each column within
the dtaset that needs to exist labled on the left
figuresize (tuple): (Default: (12,4)) This can exist changed to give graphs of
dissimilar proportions. It is defaulted to a 12 by four (ratioed) graph
leftcolors (str / tuple of (a) list(s)): This sets upwards the line color for data
expressed with the left hand y-axis. If there is more ane line,
the list needs to be specified with each line color specified in a tuple.
facecolor (str): (Default: "0.25") This allows the user to modify the
background colour as needed
"""
fig, ax1 = plt.subplots(figsize = figuresize, facecolor = facecolor)
ax1.tick_params(axis = 'both', colors = 'w')
ax1.set_facecolor(facecolor)
fig.autofmt_xdate()
plt.ylabel(y1label, color = y1labelcolor)
ax1.set_xlabel(str(xlabel), color = 'w')
ax1.set_ylabel(str(y1label))
for i in leftaxisdata: # This is to label all the lines in order to let matplot lib to create a fable
ax1.plot(dataset.iloc[:, i])
ax1.tick_params(axis = 'y')
ax1.filigree(color='black', linewidth = 0.5)
ax2 = ax1.twinx() # instantiate a second axes that shares the aforementioned x-axis
colour = str(y2color)
ax2.set_ylabel(str(y2label), color=color) # we already handled the x-label with ax1
plt.plot(dataset.iloc[:, list(rightaxisdata)], color=color)
ax2.tick_params(axis='y', labelcolor='w')
ax1.set_title(str(title) + " \n", color='w')
fig.tight_layout() # otherwise the correct y-characterization is slightly clipped
plt.show()
The jail cell below defines a function to plot data regressed on fourth dimension.
def Plot_Regression(x, y, slope, intercept, ylabel,
championship = "", xlabel = "Twelvemonth", facecolor = "0.25", data_point_type = ".", original_data_color = "C1",
time_index = [], time_index_step = 48,
figuresize = (12,4),
line_of_best_fit_color = "b"):
""" Plot_Regression Version one.0:
Plots the regression line with its data with appropriate defult Refinitiv colours.
facecolor (str): (Default: "0.25") This allows the user to change the background colour as needed
figuresize (tuple): (Default: (12,4)) This tin can exist inverse to give graphs of different proportions. It is defaulted to a 12 by 4 (ratioed) graph
line_of_best_fit_color (str): This allows the user to change the background color as needed.
' time_index ' and ' time_index_step ' let us to dictate the fequency of the ticks on the x-centrality of our graph.
"""
fig, ax1 = plt.subplots(figsize = figuresize, facecolor = facecolor)
ax1.tick_params(axis = "both", colors = "westward")
ax1.set_facecolor(facecolor)
fig.autofmt_xdate()
plt.ylabel(ylabel, color = 'due west')
ax1.set_xlabel(xlabel, color = 'w')
ax1.plot(x, y, data_point_type, label='original data', color = original_data_color)
ax1.plot(x, intercept + slope * x, 'r', label = 'fitted line', color = line_of_best_fit_color)
ax1.tick_params(axis = 'y')
ax1.grid(color='blackness', linewidth = 0.v)
ax1.set_title(championship + " \northward", color='due west')
plt.legend()
if len(time_index) != 0:
# locs, labels = plt.xticks()
plt.xticks(numpy.arange(len(y), stride = time_index_step),
[i for i in time_index[0::time_index_step]])
plt.show()
def Single_period_Geometric_Growth(information):
data = list(data)
single_period_geometric_growth = ( (data[-1]/data[0])**(ane/((len(data))-1)) ) - 1 # note that nosotros use ' len(data) - 1 ' instead of ' len(data) ' as the former already lost its degree of freedom simply like we want information technology to.
return single_period_geometric_growth
The cell beneath defines a function that creates and displays a tabular array of statistics for all vectors (columns) within whatsoever two specified datasets.
def Statistics_Table(dataset1, dataset2 = ""):
Statistics_Table_Columns = list(dataset1.columns)
if str(dataset2) != "":
[Statistics_Table_Columns.append(str(i)) for i in dataset2.columns]
Statistics_Table = pandas.DataFrame(columns = ["Mean", "Mean of Absolute Values",
"Standard Difference",
"Median", "Skewness",
"Kurtosis",
"Unmarried Menstruation Growth Geometric Average"],
index = [c for c in Statistics_Table_Columns])
def Statistics_Table_function(data):
for c in data.columns:
Statistics_Table["Mean"][str(c)] = numpy.mean(data[str(c)].dropna())
Statistics_Table["Mean of Accented Values"][str(c)] = numpy.mean(abs(data[str(c)].dropna()))
Statistics_Table["Standard Deviation"][str(c)] = numpy.std(data[str(c)].dropna())
Statistics_Table["Median"][str(c)] = numpy.median(data[str(c)].dropna())
Statistics_Table["Skewness"][str(c)] = scipy.stats.skew(data[str(c)].dropna())
Statistics_Table["Kurtosis"][str(c)] = scipy.stats.kurtosis(data[str(c)].dropna())
if len(data[str(c)].dropna()) != 1 or data[str(c)].dropna()[0] != 0: # This if statement is needed in case we stop up asking for the ciphering of a value divided past 0.
Statistics_Table["Unmarried Period Growth Geometric Boilerplate"][str(c)] = Single_period_Geometric_Growth(data[str(c)].dropna())
Statistics_Table_function(dataset1)
if str(dataset2) != "":
Statistics_Table_function(dataset2)
return Statistics_Table
Add_to_df(data = ds.get_data(tickers = 'USPERCONB', # this is the ticker for United States, Personal Outlays, Personal Consumption Expenditure, Overall, Total, Current Prices, AR, SA, USD
fields = "X", # DataStream'south default field is 'Ten'
offset = '1950-02-01',
freq = 'Thou') * 1000000000, # This data is given in units of 1000000000
dataname = "Consumption (monthly data)")
Tutorial Video Part 3 - Collect Data and Our Second Set of Functions
Quarterly Data
# Our data is released quarterly, so we accept to shape it into a monthly database. The function below will allow for this:
def Quarterly_To_Monthly(information, dataname, deflator = False):
"""Quarterly data can sometimes exist recorded in a monthly data-frames.
This function returns a pandas data-frame in which inter-quarterly cells are populatd.
data (pandas.DataFrame): a pandas data-frame of the quarterly data
that is wanted in a monthly pandas data-frame
dataname (str): a string of the name wanted for the column of returned data-frame
deflator (bool): Fix to Faux by default. If the data passed is an inflator,
setting ' deflator ' to True will inverse it)
"""
data_proper, data_full_index = [], []
for i in range(0, len(data)):
[data_proper.append(float(data.iloc[j])) for j in [i,i,i]]
[data_full_index.suspend(datetime.datetime.strptime(str(data.index[i])[0:eight] + "01", "%Y-%k-%d") + dateutil.relativedelta.relativedelta(months =+ j)) for j in range(0,3)]
data = pandas.DataFrame(data = data_proper, columns = [dataname], index = data_full_index)
if deflator == True:
data = pandas.DataFrame(data = i / (data / data.iloc[-1]), columns = [dataname], index = data_full_index)
data.index = pandas.to_datetime(data.index)
render data
def Collect_Quarterly_Data(ticker, data_name, field = "X", offset = "1950-02-01", freq = "M",
multiplier = 1):
""" This function was created specifically for this script/article. It decreases the
number of repeated lawmaking lines collecting data in several forms in our df.
ticker (str/list): cord of the 1 DataStream ticker or listing of multiple DataStream
tickers to be collected.
field (str): Fix to "X" by default. Field to be collected fo rthe ticker(s) in question.
beginning (str): Set to "1950-02-01" by default. This is the appointment at which the data is to be
collected from on DataStream.
freq (str): Set to "M" by default. This is the frequency at which you would like the
data to be nerveless from DataStream. "M" for monthly, "Q" for quarterly, "A" for
annually, et cetera. If ' freq ' is ready to a higher frequency than is bachelor on
DataSream, the highest possible one volition be used (exempli gratia: if asking for "Thousand"
when only "Q" data is available, data volition exist collected as if freq = "Q").
multiplier (int/bladder): Set up to ' 1 ' by default. Our nerveless data will be multiplied
by this multiplier.
"""
# But DataStream requests returning numbers are meant to be ask for in this function.
# The post-obit try loop will account for the case where DataStream returns something
# else (or somenthing else is asked of it):
try:
# The multiplier tin can only be used if information in ' dsdata ' is numeric
dsdata = ds.get_data(tickers = ticker, fields = field,
first = '1950-02-01', freq = 'M') * multiplier
except:
dsdata = ds.get_data(tickers = ticker, fields = field,
start = '1950-02-01', freq = 'Thousand')
# Adding data for every quarter in our df:
Add_to_df(data = dsdata.re-create(), dataname = data_name + " (quarterly data)")
# Adding quarterly data for every month in our df:
Add_to_df(information = Quarterly_To_Monthly(dsdata.re-create(),
dataname = data_name + " (quarterly data)",
deflator = Simulated),
dataname = data_name + " (monthly step information)")
Collect_Quarterly_Data(ticker = "USGFCF..B", data_name = "Investment", multiplier = 1000000000)
Collect_Quarterly_Data(ticker = "USCNGOV.B", data_name = "Government Investment", multiplier = 1000000000)
Collect_Quarterly_Data(ticker = "USBALGSVB", data_name = "Net Exports", multiplier = 1000000000)
Tutorial Video Function 4 - Dataframe manipulations and Plots
G.D.P. Component Sum
df["GDP Component Sum (quarterly data)"] = df.dropna()["Consumption (monthly data)"] + df.dropna()["Investment (quarterly information)"] + df.dropna()["Regime Investment (quarterly data)"] + df.dropna()["Internet Exports (quarterly data)"]
Plot1ax(dataset = pandas.DataFrame(df["GDP Component Sum (quarterly information)"].dropna()),
title = "Sum of USA Gross domestic product Components on a QUARTERLY Footing\n(Consumption, Investment, Government Investment and Net Exports)")
df["GDP Component Sum (monthly step data)"] = df["Consumption (monthly data)"] + df["Investment (monthly pace information)"] + df["Government Investment (monthly pace data)"] + df["Internet Exports (monthly footstep information)"]
Plot1ax(dataset = pandas.DataFrame(df["GDP Component Sum (monthly step data)"].dropna()),
title = "Sum of The states Gross domestic product Components on a MONTHLY Footing\due north(Consumption, Investment, Regime Investment and Net Exports)")
Add_to_df(information = ds.get_data(tickers = 'USGDP...B',
fields = "X",
start = '1950-02-01',
freq = 'M') * 1000000000,
dataname = "Gdp (every quarter)")
df["Gdp (monthly step data)"] = Quarterly_To_Monthly(data = df["Gdp (every quarter)"],
dataname = "Gdp (monthly step data)").dropna()
Information Résumé
Plot1ax(title = "USA Gdp and its components (quarterly data)",
dataset = df.dropna(), ylabel = "Today's $",
datasubset = ["Investment (quarterly data)",
"Government Investment (quarterly data)",
"Net Exports (quarterly information)",
"Net Exports (quarterly information)",
"GDP Component Sum (quarterly data)",
"GDP (every quarter)"])
Note that the GDP and Gross domestic product Component Sum datapoints align and then well that they are indistinguishable in the graph above
Consumption (monthly data) | Investment (quarterly data) | Investment (monthly footstep data) | Government Investment (quarterly data) | Government Investment (monthly step information) | Cyberspace Exports (quarterly information) | Net Exports (monthly step data) | GDP Component Sum (quarterly data) | Gross domestic product Component Sum (monthly pace data) | GDP (every quarter) | GDP (monthly step information) | |
01/02/1950 | NaN | 4.47E+10 | four.47E+x | 4.90E+ten | 4.90E+10 | 2.20E+09 | 2.20E+09 | NaN | NaN | 2.81E+xi | two.81E+11 |
01/03/1950 | NaN | NaN | 4.47E+10 | NaN | 4.90E+10 | NaN | 2.20E+09 | NaN | NaN | NaN | 2.81E+11 |
01/04/1950 | NaN | NaN | iv.47E+10 | NaN | four.90E+10 | NaN | 2.20E+09 | NaN | NaN | NaN | two.81E+11 |
01/05/1950 | NaN | 4.95E+ten | four.95E+x | 4.96E+10 | 4.96E+x | 1.64E+09 | 1.64E+09 | NaN | NaN | 2.90E+11 | 2.90E+11 |
01/06/1950 | NaN | NaN | 4.95E+10 | NaN | iv.96E+ten | NaN | 1.64E+09 | NaN | NaN | NaN | 2.90E+eleven |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
01/03/2020 | 1.39E+13 | NaN | 3.67E+12 | NaN | 3.85E+12 | NaN | -v.26E+11 | NaN | two.09E+xiii | NaN | 2.15E+13 |
01/04/2020 | 1.20E+xiii | NaN | 3.67E+12 | NaN | 3.85E+12 | NaN | -5.26E+eleven | NaN | 1.90E+13 | NaN | 2.15E+13 |
01/05/2020 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
01/06/2020 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
01/07/2020 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Tutorial Video Part v - The Holt Winters Model for Positive Values
Tutorial Video Part 6 - The Holt Winters Model for Negative Values
def Hot_Winters_Method(name, forecast_period = 3, negative_accounting = Imitation, silence_warings = True,
figure_size = (xv,4), face_color = "0.25", point_style = "-", plot_color = "bluish",
fitted_point_style = "-", fitted_point_color = "C1", xlabel = "Years",
forecasted_point_style = "-", forecasted_point_color = "#328203"):
""" This function was created specifically for this script/article. It uses the Holt-Winters
method to construct estimates and forecasts, adds it to ' df 'and plots the original data against
the estimates and forecasts.
Necessitates the function ' Quarterly_To_Monthly '
name (str): Name of the GDP component in question. This component must be included in ' df '.
forecast_period (int): Set to ' iii ' as default. Number of periods we wish to brandish forecasts for.
negative_accounting (bool): Set to False by default. If gear up to True, this accounts for negative values
in that it does not display forecasted values explicitly or the graph because they would be shifted upward.
figure_size, face_color, point_style, plot_color, fitted_point_style, fitted_point_color, xlabel,
forecasted_point_style, and forecasted_point_color are variables to modify the plot returned.
"""
global df
if negative_accounting == True:
# Beginning: nosotros need to notation that the Holt-Winters model merely works for positive datasets.
# the following is to account for negative values:
_data_min_p1 = numpy.absolute(pandas.DataFrame.min(df[name + " (monthly pace data)"])) + one
_data = (_data_min_p1 + df[name + " (monthly step data)"].copy()).dropna()
df[name + " (monthly stride data) positive"] = _data
else:
_data_min_p1 = 0
_data = df[name + " (monthly footstep data)"].dropna()
if silence_warings == True:
# The following will throw errors informing us that the unspecified Holt-Winters Exponential Smoother
# parameters volition be chosen by the default ' statsmodels.tsa.api.ExponentialSmoothing ' optimal ones.
# This is preferable and doesn't need to be stated for each iteration in the loop.
warnings.simplefilter("ignore")
model_fit = statsmodels.tsa.holtwinters.ExponentialSmoothing(_data.dropna(),
seasonal_periods = 12,
trend = 'add',
damped=Truthful).fit(use_boxcox=True)
df[name + " fitted values (monthly step data)"] = model_fit.fittedvalues - _data_min_p1
df[name + " forecasts (monthly step data)"] = model_fit.forecast(forecast_period) - _data_min_p1
df[proper name + " fitted values' existent errors (monthly stride information)"] = df[proper name + " fitted values (monthly step data)"] - df[proper name + " (monthly step data)"]
if negative_accounting == False:
# Run across the HW model'due south forecasts:
print(name + " forecasts:")
display(model_fit.forecast(forecast_period))
# Plot the newly created Exponential Smoothing data
fig1, ax1 = plt.subplots(figsize = figure_size, facecolor = face_color)
df[proper name + " (monthly step data)"].dropna().plot(style = point_style,
colour = plot_color,
fable = Truthful).legend([name + " (monthly step data)"])
model_fit.fittedvalues.plot(style = fitted_point_style,
color = fitted_point_color,
label = name + " model fit",
legend = True)
model_fit.forecast(forecast_period).plot(style = forecasted_point_style,
color = forecasted_point_color,
label = proper name + " model forecast",
legend = Truthful)
ax1.set_facecolor(face_color)
ax1.tick_params(axis = "both", colors = "w")
plt.ylabel("Ratio", color = "due west")
ax1.set_xlabel(xlabel, color = "w")
ax1.filigree(color='black', linewidth = 0.five)
# The default 'forecasted_point_color' is "#328203", i.due east.: dark-green
if forecasted_point_color == "#328203":
ax1.set_title("Forecasting USA Real GDP's "+ proper noun + " component of backdrop" +
"\nusing the Holt-Winters method (HW) (monthly information) (forecasts in green)" +
" \north", color='w')
else:
ax1.set_title("Forecasting U.S.A. Real Thousand.D.P.'southward "+ proper name + " component of properties" +
"\nusing the Holt-Winters method (HW) (monthly data) (forecasts in " +
forecasted_point_color + ") \n", colour='w')
ax1.legend()
plt.show()
if silence_warings == True:
# We want our program to allow us know of warnings from at present on; they were only disabled for the for loop above.
warnings.simplefilter("default")
United states of americaA.'s Investments' Estimates using the HW method
Hot_Winters_Method(name = "Investment")
Investment forecasts:
2020-05-01 iii.666572e+12
2020-06-01 3.664588e+12
2020-07-01 three.662814e+12
Freq: MS, dtype: float64
# the ' pandas.DataFrame ' here is merely there to make Jupyter render a Markdown table that looks amend than the raw ' print ' output.
pandas.DataFrame(Statistics_Table(dataset1 = df).loc[["Investment forecasts (monthly pace data)",
"Investment fitted values' real errors (monthly step data)"]]["Mean of Accented Values"])
Mean of Absolute Values | |
Investment forecasts (monthly step information) | iii.66E+12 |
Investment fitted values' real errors (monthly step information) | 7.88E+09 |
U.s.A.'south Government Investment using the HW method
Hot_Winters_Method(proper name = "Government Investment")
Authorities Investment forecasts:
2020-05-01 3.866815e+12
2020-06-01 3.876213e+12
2020-07-01 3.885344e+12
Freq: MS, dtype: float64
U.S.A.'s Net Exports of Appurtenances and Services using the HW method
Hot_Winters_Method(proper name = "Net Exports", negative_accounting = True)
df with Holt-Winters estimates
Consumption (monthly data) | Investment (quarterly information) | Investment (monthly step data) | Authorities Investment (quarterly information) | Government Investment (monthly step data) | Cyberspace Exports (quarterly data) | Net Exports (monthly step data) | Gdp Component Sum (quarterly data) | GDP Component Sum (monthly step data) | GDP (every quarter) | Gross domestic product (monthly footstep data) | Investment fitted values (monthly step data) | Investment forecasts (monthly step data) | Investment fitted values' real errors (monthly step data) | Government Investment fitted values (monthly step information) | Government Investment forecasts (monthly footstep data) | Government Investment fitted values' real errors (monthly step data) | Net Exports (monthly step data) positive | Cyberspace Exports fitted values (monthly step data) | Net Exports forecasts (monthly step data) | Internet Exports fitted values' existent errors (monthly step data) | |
01/02/1950 | NaN | 4.47E+10 | 4.47E+10 | 4.90E+x | iv.90E+10 | 2.20E+09 | 2.20E+09 | NaN | NaN | ii.81E+11 | 2.81E+eleven | iv.47E+x | NaN | 1.53E-05 | 4.87E+10 | NaN | -2.13E+08 | 8.08E+11 | two.20E+09 | NaN | six.10E-04 |
01/03/1950 | NaN | NaN | 4.47E+10 | NaN | iv.90E+10 | NaN | 2.20E+09 | NaN | NaN | NaN | ii.81E+11 | 4.47E+10 | NaN | 1.53E-05 | 4.90E+10 | NaN | 7.02E+07 | 8.08E+11 | 2.20E+09 | NaN | 6.10E-04 |
01/04/1950 | NaN | NaN | iv.47E+10 | NaN | 4.90E+x | NaN | 2.20E+09 | NaN | NaN | NaN | 2.81E+11 | 4.47E+10 | NaN | one.53E-05 | four.91E+x | NaN | one.92E+08 | 8.08E+11 | ii.20E+09 | NaN | 6.10E-04 |
01/05/1950 | NaN | 4.95E+10 | iv.95E+x | 4.96E+10 | iv.96E+10 | 1.64E+09 | ane.64E+09 | NaN | NaN | 2.90E+xi | two.90E+11 | four.47E+10 | NaN | -4.73E+09 | iv.92E+x | NaN | -four.68E+08 | 8.07E+xi | 2.20E+09 | NaN | 5.60E+08 |
01/06/1950 | NaN | NaN | iv.95E+10 | NaN | 4.96E+10 | NaN | i.64E+09 | NaN | NaN | NaN | 2.90E+11 | iv.84E+10 | NaN | -1.10E+09 | iv.96E+10 | NaN | -3.65E+07 | viii.07E+xi | i.68E+09 | NaN | three.43E+07 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
01/03/2020 | 1.39E+thirteen | NaN | 3.67E+12 | NaN | 3.85E+12 | NaN | -v.26E+11 | NaN | 2.09E+13 | NaN | 2.15E+13 | 3.67E+12 | NaN | 3.05E+09 | 3.85E+12 | NaN | 2.84E+09 | 2.79E+11 | -v.25E+eleven | NaN | 8.10E+08 |
01/04/2020 | ane.20E+thirteen | NaN | 3.67E+12 | NaN | three.85E+12 | NaN | -5.26E+11 | NaN | 1.90E+13 | NaN | 2.15E+13 | three.67E+12 | NaN | -1.43E+09 | 3.86E+12 | NaN | 1.34E+10 | 2.79E+11 | -5.18E+eleven | NaN | 8.11E+09 |
01/05/2020 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | iii.67E+12 | NaN | NaN | 3.87E+12 | NaN | NaN | NaN | -5.20E+11 | NaN |
01/06/2020 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 3.66E+12 | NaN | NaN | 3.88E+12 | NaN | NaN | NaN | -five.18E+11 | NaN |
01/07/2020 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | three.66E+12 | NaN | NaN | iii.89E+12 | NaN | NaN | NaN | -5.16E+eleven | NaN |
Backtesting our Method
The Python function defined in the cell below returns the In-Sample Recursive Prediction values of ' data ' using the Holt-Winters exponential smoother Plus it so provides forecasts for 1 Out-Of-Sample period (thus the acronym 'ISRPHWPOOOF'):
def ISRPHWPOOOF(data_set, dataset_name, start, result_name, enforce_cap = Fake, cap = one.1):
""" ISRPHWPOOOF Version 3.0:
data_set (pandas dataset): dataframe where the data is stored
dataset_name (str): Our data is likely to be in a pandas dataframe with dates for
indexes in social club to alleviate any appointment sinking bug. Every bit a result, this line allows
the user to specify the column within such a dataset to use.
beginning (str): The commencement of our in-sample recursive prediction window. eastward.g.: "1990-01-01".
This value can be changed.
enforce_cap (bool): Set to False by default.
cap (int/float): Gear up to ' 1.one ' by default.
"""
# The following for loop volition throw errors informing the states that the unspecified Holt-Winters
# Exponential Smoother parameters will be chosen by the default
# ' statsmodels.tsa.holtwinters.ExponentialSmoothing ' optimal ones. This is preferable and
# doesn't need to exist stated for each iteration in the loop.
warnings.simplefilter("ignore")
# We create an empty list (toget appended/populated) for our dataset's forecast using the
# Holt-Winters exponential smoother and to exist populated by our forecasts (in- or out-of-sample)
data_model_in_sample_plus_one_forecast, value, index = [], [], []
# the ' len(...) ' function hither returns the number of rows in our dataset from our starting engagement till its end.
for i in range(0,len(data_set[dataset_name].loc[pandas.Timestamp(starting time):].dropna())):
# This line deffines ' start_plus_i ' as our starting date plus i months
start_plus_i = str(datetime.datetime.strptime(start, "%Y-%m-%d") + dateutil.relativedelta.relativedelta(months=+i))[:10]
HWESi = statsmodels.tsa.holtwinters.ExponentialSmoothing(data_set[dataset_name].dropna().loc[:pandas.Timestamp(start_plus_i)],
trend = 'add',
seasonal_periods = 12,
damped = Truthful).fit(use_boxcox = True).forecast(1)
# This outputs a forecast for 1 period ahead (whether in-sample or out of sample). Since we start at i = 0, this line provides a HW forecast for i at ane;
# similarly, at the last i (say T), it provides the offset and merely out-of-sample forecast (where i = T+1).
data_model_in_sample_plus_one_forecast.append(HWESi)
try:
# Sometimes the H-W model comes up with extreme estimates, a cap can account for that:
if enforce_cap == Truthful:
if bladder(str(HWESi)[14:-25]) > cap:
value.append(float(str(HWESi)[14:-25]))
else:
value.append(numpy.nan) # If the ratio
else:
value.suspend(bladder(str(HWESi)[14:-25]))
except:
# This adds NaN (Not a Number) to the list ' values ' if there is no value to add together.
# The statsmodels.tsa.api.ExponentialSmoothing function sometimes (rarely) outputs NaNs.
value.append(numpy.nan)
finally:
# This adds our indecies (dates) to the list ' index '
index.append(str(HWESi)[:10])
# We desire our programme to permit usa know of warnings from now on; they were only disabled for the for loop above.
warnings.simplefilter("default")
return pandas.DataFrame(data = value, index = alphabetize, columns = [result_name])
We volition dorsum-test our models from January 1990
Backtesting our Method with Investment data
# Model:
Investment_model_in_sample_plus_one_forecast = ISRPHWPOOOF(data_set = df,
dataset_name = "Investment (monthly step data)",
outset = get-go,
result_name = "Investment model in sample plus 1 forecast")
df = pandas.merge(df, Investment_model_in_sample_plus_one_forecast,
how = "outer", left_index = True, right_index = True)
# Model'southward errors:
Investment_model_in_sample_plus_one_forecast_error = pandas.DataFrame(df["Investment (monthly pace data)"] - df["Investment model in sample plus one forecast"],
columns = ["Investment model in sample plus one forecast error"])
df = pandas.merge(df, Investment_model_in_sample_plus_one_forecast_error.dropna(),
how = "outer", left_index = Truthful, right_index = True)
Plot1ax(title = "Investment component of United states Gross domestic product", datarange = [start,-1], ylabel = "Today's $",
dataset = df, datasubset = ["Investment (monthly footstep data)", "Investment model in sample plus 1 forecast"])
In the graph to a higher place, we put ourselves in the shoes of an analyst who only has quarterly Investment data. She/He uses the latest quarterly releases of Investment information which spans from 1950 (in our case) to last quarter (final calendar month at the earliest). She/He and so uses the HW model to compute a forecast for the current period (calendar month) - in yellowish in the graph in a higher place.
Backtesting our Method with Authorities Investment data
# Model:
Government_Investment_model_in_sample_plus_one_forecast = ISRPHWPOOOF(data_set = df,
dataset_name = "Regime Investment (monthly step data)",
start = start,
result_name = "Regime Investment model in sample plus one forecast")
df = pandas.merge(df, Government_Investment_model_in_sample_plus_one_forecast,
how = "outer", left_index = Truthful, right_index = Truthful)
# Model'south errors:
Government_Investment_model_in_sample_plus_one_forecast_error = pandas.DataFrame(df["Government Investment (monthly step information)"] - df["Regime Investment model in sample plus one forecast"],
columns = ["Authorities Investment model in sample plus one forecast error"])
df = pandas.merge(df, Government_Investment_model_in_sample_plus_one_forecast_error.dropna(),
how = "outer", left_index = True, right_index = Truthful)
Plot1ax(title = "Government Investment component of United states of america Gdp", datarange = [start,-1], ylabel = "Today'southward $",
dataset = df, datasubset = ["Regime Investment (monthly step data)",
"Government Investment model in sample plus one forecast"])
Backtesting our Method with Net Exports data
# Model:
Net_Exports_model_in_sample_plus_one_forecast = ISRPHWPOOOF(data_set = df,
dataset_name = "Net Exports (monthly step data) positive",
start = start,
result_name = "Net Exports model in sample plus i forecast")
Net_Exports_min_p1 = numpy.absolute(pandas.DataFrame.min(df["Net Exports (monthly pace data)"])) + 1
df = pandas.merge(df, Net_Exports_model_in_sample_plus_one_forecast - Net_Exports_min_p1,
how = "outer", left_index = True, right_index = True)
# Model's errors:
Net_Exports_model_in_sample_plus_one_forecast_error = pandas.DataFrame(df["Net Exports (monthly step data)"] - df["Net Exports model in sample plus one forecast"],
columns = ["Net Exports model in sample plus 1 forecast mistake"])
df = pandas.merge(df, Net_Exports_model_in_sample_plus_one_forecast_error.dropna(),
how = "outer", left_index = True, right_index = True)
Plot1ax(title = "Cyberspace Exports component of Usa GDP", datarange = [start,-i], ylabel = "Today'south $",
dataset = df, datasubset = ["Net Exports (monthly step data)",
"Internet Exports model in sample plus 1 forecast"])
G.D.P. Montly Estimates
df["Computed Gdp"] = df["Consumption (monthly data)"] + df["Investment model in sample plus one forecast"] + df["Government Investment model in sample plus one forecast"] + df["Net Exports model in sample plus one forecast"]
Plot1ax(title = "U.s.a. GDP versus Computed US GDP figures using the HW model", datarange = [start,-1], ylabel = "Today'due south $",
dataset = df, datasubset = ["Computed GDP", "Gdp (monthly stride data)"])
Conclusion
It is possible to approximate monthly The states GDP figures using the HW model to a good degree of accuracy. The final forecast even predictable the autumn in Gdp caused by COVID-19 (in 2020) before official figures were released. Such estimates can non only exist done via an Expenditure Approach but besides an Income Approach; a mixture of the 2 would be an interesting report.
Annotation that it is possible to utilise this method to compute future monthly GDP forecasts.
References:
Mitchell, Smith, Weale, Wright, and Salazar (2005): James Mitchell, Richard J. Smith, Martin R. Weale, Stephen Wright, Eduardo 50. Salazar, An Indicator of Monthly GDP and an Early on Estimate of Quarterly GDP Growth, The Economic Journal, Volume 115, Issue 501, Feb 2005, Pages F108–F129, https://doi.org/10.1111/j.0013-0133.2005.00974.x
C. C. Holt (1957) Forecasting seasonals and trends past exponentially weighted moving averages, ONR Enquiry Memorandum, Carnegie Found of Engineering.
P. R. Winters (1960). Forecasting sales past exponentially weighted moving averages. Management Science
Source: https://developers.refinitiv.com/en/article-catalog/article/estimating-monthly-gdp-via-the-expenditure-approach-and-the-holt-winters-model
0 Response to "An Error Occured While Uploading the File Please Try Again Gdp"
Post a Comment