from IPython.display import Markdown
import pandas as pd
from tulip.core.collection import TulipCollection
from tulip.data.bloomberg import BloombergClient as bb
from tulip.data.haver import HaverClient as hc
from tulip.plots import plot_area, plot_lines
from tulip.data.gs import GSClient as gs
import pycountry
from tulip.analysis.country_related.analytics import summarize_gs_eco_fct
ISO_2 = "CA"
pyctry = pycountry.countries.get(alpha_2=ISO_2)
gs_eco_fct = gs.get_eco_forecast(geographyId=ISO_2)
gs_summary = summarize_gs_eco_fct(gs_eco_fct)
gs_summary = gs_summary[~gs_summary.index.str.contains("ngdp")].to_frame().T
gs_summary.style.set_caption(f"Goldman {pyctry.name} Economic Forecasts").format(
precision=2
)Current Activity Indicator (Goldman)¶
cai_series_soft_vs_hard = gs.get_CAI_series(
geographyId=ISO_2,
metricName=[
"CAI_HEADLINE",
"CAI_CONTRIBUTION_TYPE_HARD",
"CAI_CONTRIBUTION_TYPE_SOFT",
],
startDate="1980-01-01",
)
cai_series_soft_vs_hard = cai_series_soft_vs_hard.set_index("metricName", append=True)[
"metricValue"
].unstack("metricName")
cai_series_soft_vs_hard.columns = ["Hard", "Soft", "Headline"]
cai_plot = plot_lines(
cai_series_soft_vs_hard,
show_0=True,
title=f"<b>{pyctry.name} Current Activity Indicator</b> Updated: {pd.Timestamp.today().strftime('%Y-%m-%d')}",
years_limit=4,
)
cai_plotIFSD Nowcast¶
IFSD was founded in 2016 by Kevin Page, Canada’s first Parliamentary Budget Officer. IFSD is both a non-profit, Canadian think-tank and a global advisory practice
ifs_nowcast = bb.get_series("IFSDCAST Index")
ifs_nowcast.plot(years_limit=2, tick_suffix="%")Retail Sales¶
retail_sales = bb.get_series("CARSCHNG Index")
retail_sales.info.title = "Retail Sales MoM"
retail_sales.plot(years_limit=2, tick_suffix="%")PMIs¶
pmi = {
"MPMICASA Index": "S&P Manufacturing PMI",
"MPMICACA Index": "S&P Composite PMI",
"IVEYSA Index": "Ivey PMI",
}
pmi_collection = bb.create_collection(list(pmi.keys()))
for i, k in enumerate(pmi.values()):
pmi_collection[i].info.title = k
pmi_collection.dashboard.table()
pmi_collection.dashboard.plots(hlines=50)real_gdp_yoy = hc.get_series("V6E05783@CANADA")
real_gdp_yoy.ts = real_gdp_yoy.ts.pct_change(4)
real_gdp_yoy.plot(show_0=True, tick_format="0.0%")GDP Detail¶
growth_stats = {
"Real GDP": "yryr%(V6E05752@CANADA)", # Canada: Real Gross Domestic Product at Market Prices
"Fixed Investment": "yryr%(V6E05732@CANADA)", # Canada: GDP: Gross Fixed Capital Formation
"Inventories": "V6E05741@CANADA", # Canada: GDP: Investment in Inventories
"Consumption": "yryr%(V6E05723@CANADA)", # Canada: GDP: Final Consumption Expenditure
"Exports": "yryr%(V6E05745@CANADA)", # Canada: GDP: Exports of Goods and Services
"Imports": "yryr%(V6E05748@CANADA)", # Canada: GDP: Imports of Goods and Services
}
growth_stats_collection = []
for k, v in growth_stats.items():
growth_stats_collection.append(hc.get_series(v))
growth_stats_collection = TulipCollection(growth_stats_collection)
growth_stats_collection["yryr%(V6E05748@CANADA)"].good_is = -1
growth_stats_collection.dashboard.table()
growth_stats_collection.dashboard.plots(show_0=True)Nominal GDP¶
# Nominal GDP Growth
hc.get_series("yryr%(V6E05783@CANADA)").plot(show_0=True) # Nominal GDP GrowthPrices¶
prices = {
"CPI-Trim": "V1M85715@CANADA",
"CPI-Median": "V1M85714@CANADA",
"CPI-Common": "V1M85713@CANADA",
"CPI YoY": "n156cy@g10",
"Wages YoY": "canewcl@CANADA",
"Inflation Expectations 1Y": "CANVXI1@CANADA", # CSCE
"Wage Growth Expectations 1Y": "CANVXW1@CANADA",
}
prices_collection = []
for k, v in prices.items():
prices_collection.append(hc.get_series(v))
prices_collection = TulipCollection(prices_collection)
prices_collection.dashboard.table()prices_df = prices_collection.df
prices_df.columns = list(prices.keys())
fig = plot_lines(
prices_df.iloc[:, :3],
years_limit=5,
title="<b>Core Inflation Measures</b> (Preferred by the BoC)",
tick_suffix="%",
)
fig.add_hline(2, line_width=1, annotation_text="Target") # , annotation="Target")fig = plot_lines(
prices_df.iloc[:, -3:].ffill(),
years_limit=5,
title="<b>Inflation Surveys</b>",
tick_suffix="%",
)
fig.add_hline(2, line_width=1, annotation_text="Target") # , annotation="Target")business_outlook_survey_prices_dict = {
"Below 1 percent": "B156IE1@CANADA",
"1 to 2 percent": "B156IE2@CANADA",
"2 to 3 percent": "B156IE3@CANADA",
"Above 3 percent": "B156IE4@CANADA",
"No response": "B156IE5@CANADA",
}
business_outlook_survey_prices = []
for k, v in business_outlook_survey_prices_dict.items():
business_outlook_survey_prices.append(hc.get_series(v))
business_outlook_survey_prices = TulipCollection(business_outlook_survey_prices)
business_outlook_survey_prices.dashboard.table()bos_prices = business_outlook_survey_prices.df
bos_prices.columns = list(business_outlook_survey_prices_dict.keys())
# Define custom colors for each category
colors = {
"Above 3 percent": "red",
"2 to 3 percent": "coral",
"1 to 2 percent": "lightgreen",
"Below 1 percent": "green",
"No response": "gray",
}
fig = plot_area(
bos_prices,
title="<b>Business Outlook Survey - Inflation Expectations</b>",
tick_suffix="%",
logo=False,
)
for trace in fig.data:
if trace.name in colors:
trace.line.color = colors[trace.name]
fig.show()Other faster, idiosyncratic price data points available in Canada
weekly_price = {
"Commodity Price Index": "P156CP@INTWKLY",
"Commodity Price Index Ex Energy": "P156CPX@INTWKLY",
"Gasoline Price": "P156GRT@INTWKLY",
"Pork Prices": "P156HGV@INTWKLY",
}
weekly_price_collection = []
for k, v in weekly_price.items():
weekly_price_collection.append(hc.get_series(v))
weekly_price_collection = TulipCollection(weekly_price_collection)
weekly_price_collection.dashboard.table()
Employment¶
# Employment metrics
employment = {
"EI Claims": "E156CEA@INTWKLY", # Canada: Employment Insurance: Claims Established
"EI Recipients": "E156ATA@INTWKLY", # Canada: Employment Insurance: Active Recipients
"Job Loss Probability": "CANVXJL@CANADA", # Canada: Consumer Expectations Survey: Prob of Losing Job
}
employment_collection = []
for k, v in employment.items():
employment_collection.append(hc.get_series(v))
employment_collection = TulipCollection(employment_collection)
employment_collection.good_is = {
"E156CEA@INTWKLY": -1, # Lower claims is good
"E156ATA@INTWKLY": -1, # Lower recipients is good
"CANVXJL@CANADA": -1, # Lower probability of job loss is good
}
employment_collection.dashboard.table()
employment_collection.dashboard.plots()Output Gap¶
output_gap = hc.get_series("B156IGAP@CANADA")
output_gap.plot(show_0=True, tick_suffix="%")weekly_price_collection.dashboard.plots(years_limit=3)Trade¶
trade_stats = {
"Current Account Balance % GDP": "s156bcpg@g10",
}
trade_collection = []
for k, v in trade_stats.items():
trade_collection.append(hc.get_series(v))
trade_collection = TulipCollection(trade_collection)
trade_collection.dashboard.table()trade_collection.dashboard.plots(show_0=True)Surveys¶
surveys = {
"Business Barometer 3M": "CFO3@CANADA", # Canada: Business Barometer Index: 3 Month Outlook
"Business Barometer 1Y": "CFAA@CANADA", # Business Barometer Index: Canada
"Policy Uncertainty": "CEPUIN@CANADA", # Canada: News-Based Policy Uncertainty Index
}
surveys_collection = []
for k, v in surveys.items():
surveys_collection.append(hc.get_series(v))
surveys_collection = TulipCollection(surveys_collection)
surveys_collection.good_is = {
"CFO3@CANADA": 1, # Higher business confidence is good
"CFAA@CANADA": 1, # Higher business confidence is good
"CEPUIN@CANADA": -1, # Lower uncertainty is good
}
surveys_collection.dashboard.table()
surveys_collection.dashboard.plots(years_limit=3, hlines=[50, 50])Credit Creation¶
debt_stats = {
"Non-Financial Debt % GDP": "S156zdnp@g10",
"Household Debt to Disposable Income": "S156zdhi@g10",
"Household Debt % GDP": "S156zdhp@g10",
}
debt_collection = []
for k, v in debt_stats.items():
debt_collection.append(hc.get_series(v))
debt_collection = TulipCollection(debt_collection)
debt_collection.dashboard.table()
debt_collection.dashboard.plots()Budget¶
government_finance = {
"Public Debt": "N156FDP@G10", # Canada: Business Barometer Index: 3 Month Outlook
"Govt Budget Surplus/Deficit": "H156FGBP@G10", # Business Barometer Index: Canada
}
government_finance_collection = []
for k, v in government_finance.items():
government_finance_collection.append(hc.get_series(v))
government_finance_collection = TulipCollection(government_finance_collection)
government_finance_collection.dashboard.table()government_finance_collection.dashboard.plots()Asset Pricing¶
# Asset Piricing
# Yields and Stockfrom tulip_mania.notebook_related import notebook_updated
notebook_updated()