Recession Warning Traffic Light
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © BarefootJoey

// ██████████████████████████████████████████████████████████████████████
// █▄─▄─▀██▀▄─██▄─▄▄▀█▄─▄▄─█▄─▄▄─█─▄▄─█─▄▄─█─▄─▄─███▄─▄█─▄▄─█▄─▄▄─█▄─█─▄█
// ██─▄─▀██─▀─███─▄─▄██─▄█▀██─▄███─██─█─██─███─███─▄█─██─██─██─▄█▀██▄─▄██
// █▄▄▄▄██▄▄█▄▄█▄▄█▄▄█▄▄▄▄▄█▄▄▄███▄▄▄▄█▄▄▄▄██▄▄▄██▄▄▄███▄▄▄▄█▄▄▄▄▄██▄▄▄██

//@version=5
indicator('Recession Warning Traffic Light')

// Groups
grfr = "Federal Reserve"
gryc = "Yield Curve"
grm2 = "Money Supply"
grsp = "Stock Market"
grpm = "Precious Metals"
grle = "Leading Economic Indicator"
grw  = "Recession Warning"

// BarefootJoey's indicator('Moving Average Growth Rate', precision=4) // (Daily Updates)
sp500 = request.security('SPX', "W", close)
psma_length = 16 //input(16, title='Price SMA Length', group=grsp)
sustainable = input.float(2, title='Sustainable Growth Rate', group=grsp)
current_ma = ta.sma(sp500, psma_length)
previous_ma = current_ma[1]
delta = current_ma - previous_ma
growthrate = delta / previous_ma
growthrate_percentage = growthrate * 100
bau2 =  growthrate_percentage < sustainable and growthrate_percentage >= 0
heating_up2 = growthrate_percentage >= sustainable 
warning2 = growthrate_percentage < 0
plot_color2 = bau2 ? color.green : heating_up2 ? color.orange : warning2 ? color.red : color.gray

// US 3m/10y Inversion (Daily Updates)
us3m = request.security('US03MY', "D", close)
us10y = request.security('US10Y', "D", close)
us10y3m = (us10y - us3m) * 100
us10y3m_col = us10y3m>0?color.green:us10y3m<0?color.red:na
us10y3m_col2 = us10y3m>0?color.green:us10y3m<0?color.red:color.gray

// M2 Money Supply (Monthly Updates)
m2sl = request.security('M2SL', "D", close)
// M2 Trend State
var m2state = 0
if m2sl>m2sl[1]
    m2state := 1
    m2state
if m2sl<m2sl[1]
    m2state := -1
    m2state
m2state := m2state
m2sl_col = m2state==1?color.green:m2state==-1?color.red:na

// Federal Reserve GDP/Growth
sustainable2 = input.float(2.5, "Sustainable Growth", minval=0, group=grfr)
i_input = input.symbol("GDPC1", title="Growth Ticker", group=grfr) //, tooltip="You may get errors if your chart is set to a different timeframe/ticker than 1d CPILFESL")
tickeri = request.security(i_input, "D", close)
// GDP Trend State
var gdpstate = 0
if tickeri>tickeri[1]
    gdpstate := 1
    gdpstate
if tickeri<tickeri[1]
    gdpstate := -1
    gdpstate
gdpstate := gdpstate
gdp_col = gdpstate==1?color.green:gdpstate==-1?color.red:na

// BarefootJoey's indicator('Precious Metal Ratios')
f_security(_symbol, _res, _src) =>
    request.security(_symbol, _res, _src)
goldpr = f_security('TVC:GOLD', "W", close) // D, W, or M depending on noise level desired
rhodpr = f_security('LSE:XRH0', "W", close) // D, W, or M depending on noise level desired
pmfinal = rhodpr / goldpr
pmfinaltxt_col = pmfinal < pmfinal[1] ? color.green : pmfinal > pmfinal[1] ? color.red : color.gray
// PM Trend State
var pmstate = 0
if pmfinal < pmfinal[1]
    pmstate := 1
    pmstate
if pmfinal > pmfinal[1]
    pmstate := -1
    pmstate
pmstate := pmstate
pm_col = pmstate==1?color.green:pmstate==-1?color.red:na

// Leading Ecnomic Data of Choice
i_input2 = input.symbol("UNRATE", title="Leading Economic Indicator", group=grle, tooltip="Baskets of leading economic indicators, as collections, reflect overall growth or contraction of economic activity. These indicators include measures of level and growth in productivity, employment, housing, consumer confidence, industrial purchasing confidence, and much more.")
tickeri2 = request.security(i_input2, "D", close)
// LE Trend State
var lestate = 0
if tickeri2<tickeri2[1] 
    lestate := 1
    lestate
if tickeri2>tickeri2[1] 
    lestate := -1
    lestate
lestate := lestate
le_col = lestate==1?color.green:lestate==-1?color.red:na

// All bullish/bearish
bgbull_col = gdpstate==1 and us10y3m>0 and m2state==1 and (bau2 or heating_up2) and pmstate==1 and lestate==1 ? color.new(color.green,80) : na
bgbear_col = gdpstate==-1 and us10y3m<0 and m2state==-1 and warning2 and pmstate==-1 and lestate==-1 ? color.new(color.red,80) : na
combined_col = gdpstate==1 and us10y3m>0 and m2state==1 and (bau2 or heating_up2) and pmstate==1 and lestate==1 ? color.new(color.green,0) : gdpstate==-1 and us10y3m<0 and m2state==-1 and warning2 and pmstate==-1 and lestate==-1 ? color.new(color.red,0) : color.gray

// Recession probability
rec_prob = (lestate==1?0:lestate==-1?20:10) + (pmstate==1?0:pmstate==-1?20:10) + (gdpstate==1?0:gdpstate==-1?20:10) + (m2state==1?0:m2state==-1?20:10) + (us10y3m>0?0:us10y3m<0?20:10) + (bau2?0:heating_up2?10:warning2?20:0)
plot(rec_prob, color=combined_col)
var label rp = na
if barstate.islast
    rp := label.new(bar_index, y=rec_prob, text=str.tostring(rec_prob)+"%", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(combined_col,0), tooltip="Recession Probability")
    label.delete(rp[1])

// Recession Warnings
w_thresh = input.int(50, "Warning Threshold", minval=0, maxval=100, group=grw)
warning = rec_prob>w_thresh?color.orange:color.new(color.orange,100)
//warning_bg = rec_prob>w_thresh?color.orange:na
plot(-10, "Recession Warning", color=warning, linewidth=4)
var label w = na
if barstate.islast
    w := label.new(bar_index, y=-10, text="Warning!", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=warning, tooltip="Recession Probability above " + str.tostring(w_thresh) + "%")
    label.delete(w[1])

// Actual Recessions
rec_src = request.quandl("FRED/USRECD") // Recession data from Federal Reserve
rec_col = rec_src == 1 ? color.new(color.red,0) : color.new(color.red,100)  // if value is 1, call True (means there is a recession)
plot(-5, "Actual Recession", color=rec_col, linewidth=4)
var label ar = na
if barstate.islast
    ar := label.new(bar_index, y=-5, text="Recession!", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=rec_col, tooltip="S&P 500 Growth Rate (4 Month)")
    label.delete(ar[1])

// Traffic Light Plots
// Stock Market Growth
plot(-35, "Stock Market", color=plot_color2, linewidth=4)
var label gr = na
if barstate.islast
    gr := label.new(bar_index, y=-35, text="Stock Market", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(plot_color2,0), tooltip="S&P 500 Growth Rate (4 Month)")
    label.delete(gr[1])

// Treasury Yield Curve Inversion
plot(-30, "Yield Curve", color=us10y3m_col, linewidth=4)
var label inv = na
if barstate.islast
    inv := label.new(bar_index, y=-30, text="Yield Curve", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(us10y3m_col2,0), tooltip="US 10y/3m Yield Curve Inversion")
    label.delete(inv[1])

// M2 Money Supply
plot(-20, "Money Supply", color=m2sl_col, linewidth=4)
var label m2 = na
if barstate.islast
    m2 := label.new(bar_index, y=-20, text="Money Supply", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(m2sl_col,0), tooltip="M2 Money Supply")
    label.delete(m2[1])

// Federal Reserve, Growth/GDP
plot(-25, "Federal Reserve", color=gdp_col, linewidth=4)
var label fr = na
if barstate.islast
    fr := label.new(bar_index, y=-25, text="Federal Reserve", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(gdp_col,0), tooltip="Economic Growth (GDP)")
    label.delete(fr[1])

// Precious Metals
plot(-40, "Precious Metals", color=pm_col, linewidth=4)
var label pm = na
if barstate.islast
    pm := label.new(bar_index, y=-40, text="Precious Metals", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(pmfinaltxt_col,0), tooltip="Rhodium:Gold Ratio")
    label.delete(pm[1])

// Leading Economic Indicator
plot(-15, "Lead Econ Indicator", color=le_col, linewidth=4)
var label le = na
if barstate.islast
    le := label.new(bar_index, y=-15, text="Lead Indicator", size=size.small, style=label.style_label_left, color=color.new(color.white,100), textcolor=color.new(le_col,0), tooltip=syminfo.ticker(i_input2))
    label.delete(le[1])

// EoS made w/ ❤ by @BarefootJoey ✌💗📈