Indicator · Pine Script v6 · Own pane

Recession Warning Traffic Light

by regalouisei· code credited to BarefootJoey

This indicator tracks macroeconomic and financial conditions to estimate recession risk across multiple market dimensions.

View on GitHub

GitHub stars2on the repository
Pine versionv6current
Lines of code196
Settings9inputs
LicenceNone statedfile: MPL-2.0
Last update8 months ago25 Feb 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

196 lines of Pine Script v6 from pinescript/editors_picks/recession-warning-traffic-light.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

recession-warning-traffic-light.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © BarefootJoey

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

//@version=6
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
show_prob = input.bool(true, 'Show Recession Probability?', group = grw)
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)
combined_col = rec_prob <= 20 ? color.green : rec_prob >= 80 ? color.red : color.gray
plot(show_prob ? rec_prob : na, color = combined_col, editable = false)
var label rp = na
if barstate.islast and show_prob
    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.gray, 50)
//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 = rec_prob > w_thresh ? 'Warning!' : 'No 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/USREC") // Recession data from Federal Reserve, not working as of Oct 2024
rec_src = request.security('FRED:JHDUSRGDPBR', 'D', close) // Recession data from Federal Reserve, thanks to @alphaXiom
//rec_src = input.symbol("USREC") // Recession data from Federal Reserve
rec_col = rec_src == 1 ? color.new(color.red, 0) : color.new(color.gray, 50) // 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 = rec_src == 1 ? 'Recession!' : 'No Recession', size = size.small, style = label.style_label_left, color = color.new(color.white, 100), textcolor = rec_col, tooltip = 'Actual Recessions as Indicated by The Federal Reserve')
    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])

// ------------------------------- Alerts ----------------------------------- // 
gra = '🔔 Alerts 🔔'
alert_freq = input.string(alert.freq_once_per_bar_close, 'Alert Frequency', options = [alert.freq_once_per_bar_close, alert.freq_once_per_bar, alert.freq_all], group = gra)
bar_update_alerts = input.bool(true, 'Trade updates each bar?', tooltip = 'Check this box to receive an alert with the current trade status every time the bar closes.', group = gra)
// Number of Decimals for Labels
pricedecimals = input.int(defval = 2, title = 'Number of Price Decimals', minval = 0, maxval = 10, group = gra)
truncateprice(number, pricedecimals) =>
    factor = math.pow(10, pricedecimals)
    int(number * factor) / factor

alert_update = 'Recession Warning Update\n' + '\n\'FRED/$USRECD\': ' + (rec_src == 1 ? 'Recession!' : 'Not Recession') + '\nRecession Probability: ' + str.tostring(rec_prob) + ' %' + '\n' + (rec_prob <= 20 ? 'Low Probability of Recession' : rec_prob >= w_thresh ? 'High Probability of Recession' : 'Elevated Probability of Recession') + '\n' + '\n---Indicators---' + '\nLead Indicator: ' + (lestate == 1 ? 'Ok' : lestate == -1 ? 'Warning' : ' Undetermined') + '\nM2 Money Supply: ' + (m2state == 1 ? 'Ok' : m2state == -1 ? 'Warning' : 'Undetermined') + '\nFederal Reserve: ' + (gdpstate == 1 ? 'Ok' : gdpstate == -1 ? 'Warning!' : 'Undetermined') + '\nYield Curve: ' + (us10y3m > 0 ? 'Ok' : us10y3m < 0 ? 'Warning' : 'Equal') + '\nStock Market: ' + (bau2 ? 'Ok' : heating_up2 ? 'Heating up!' : warning2 ? 'Warning!' : 'Undetermined') + '\nPrecious Metals: ' + (pmstate == 1 ? 'Ok' : pmstate == -1 ? 'Warning!' : 'Undetermined') + '\n\nLive Chart: https://www.tradingview.com/chart/EL3vihDV/' //www.tradingview.com/chart/EL3vihDV/"

if bar_update_alerts and rec_prob >= w_thresh
    alert(message = alert_update, freq = alert_freq)

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

Overview

Recession Warning Traffic Light requests external data for the S&P 500 moving average growth rate, US 10-year minus 3-month yield curve inversion, M2 money supply trends, real GDP growth, precious metal ratios, and unemployment figures. The script aggregates these components into a composite warning status displayed in a separate pane. Inputs allow customization of growth thresholds, economic tickers, and alert trigger levels for macro monitoring.

Details

Published by

regalouisei on GitHub

Code credit

BarefootJoey, as written in the script's header

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Screeners & dashboards, Moving averages, Trend

Markets

Indices, Stocks

Timeframes

H4 and above

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Sustainable Growth Ratefloat2sustainable
Sustainable Growthfloat2.5sustainable2
Growth TickersymbolGDPC1i_input
Leading Economic IndicatorsymbolUNRATEi_input2
Show Recession Probability?booltrueshow_prob
Warning Thresholdint50w_thresh
Alert Frequencystringalert.freq_once_per_bar_closealert_freq
Trade updates each bar?booltruebar_update_alerts
Number of Price Decimalsint2pricedecimals
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

218 stars

Multi-Timeframe Analysis Suite calculates trend direction and momentum conditions across five user-selected timeframes using moving averages, RSI, and Stochastic oscillators. It evaluates moving average slope and oscillator levels to compute trend alignment, m

Indicator v6 Screeners & dashboardsTrend
Updated 3 months ago · None stated GitHub repository of Multi-Timeframe Analysis Suite

KamaFama

by Mastaaa1987
141 stars

KamaFama is an indicator that translates a Freqtrade trading strategy into Pine Script for visualization. It combines Kaufman Adaptive Moving Average (KAMA), MAMA/FAMA calculations derived via Hilbert Transform, Williams %R, and correlation trend filters to ev

Indicator v6 Moving averagesOscillators & momentum
Updated 6 weeks ago · MIT GitHub repository of KamaFama
10 stars

This indicator combines SuperGuppy exponential moving average ribbons with SuperTrend pivot points in a separate pane screener. It classifies up to twenty assets as neutral, long, strong long, short, or strong short. Fast and slow EMA stacks define trend align

Indicator v4 TrendMoving averages
Updated 4 years ago · MIT GitHub repository of SuperGuppySTPPScreener
9 stars

This indicator functions as a multi-pair forex screener, drawing output in a separate pane. It fetches price data across major currency pairs using security functions based on a user-selected resolution timeframe. It processes these market feeds with short, me

Indicator v4 Screeners & dashboardsTrend Repaints
Updated 5 years ago · None stated GitHub repository of AG Screener (Phill_I Request)

MTF WaveTrend Opportunity Hunter calculates multi-timeframe momentum and confluence scores using WaveTrend across custom Regime, Setup, Trigger, and Context timeframes. It plots a net confluence score histogram, multi-layer heat ribbons, an RRG-style Rotation

Indicator v6 TrendOscillators & momentum
Updated yesterday · MIT GitHub repository of MTF WaveTrend Opportunity Hunter [WavesUnchained]

Snagprofit WMA

by dearvn
4 stars

Snagprofit WMA is a multi-timeframe trend indicator that calculates a 125-period Weighted Moving Average across the 1-minute, 5-minute, 15-minute, and 1-hour timeframes alongside a local 50-period Simple Moving Average. It identifies momentum signals when pric

Indicator v5 Moving averagesTrend Repaints
Updated 4 years ago · None stated GitHub repository of Snagprofit WMA

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers