//@version=6 // ============================================================================ // M2 Nowcast / Net-Liquidity Lead // Know M2's DIRECTION before the lagged monthly M2 print, via faster-releasing // leads (weekly M2, Fed net liquidity, H.8 bank deposits) — all normalized so // different-scale series compare, and each time-offsettable so you can slide a // lead forward to see it front-run the monthly M2 line. // // WHY EACH SERIES LEADS M2 (all confirmed to resolve as FRED:): // • Weekly M2 (FRED:WM2NS) — near-real-time M2, weekly-ending-Monday obs. // The H.6 release is only PUBLISHED monthly (since 2021-02-23), so the // series STEPS (flat then jumps) — but it still lands the M2 level ~3 wks // before the headline monthly print. This IS M2, just fresher-dated. // • Monthly M2 (FRED:M2SL) — the seasonally-adjusted headline being front-run. // Monthly, released 4th Tuesday for the PRIOR month (~3-4 wk lag). Plotted // faint as the reference the leads are trying to predict. // • Net Liquidity = WALCL − TGA − RRP — the macro-liquidity driver. Fed total // assets minus Treasury cash minus reverse-repo drains = money actually in // the system. Weekly (Thu H.4.1) + daily RRP, so it moves well ahead of M2. // • H.8 deposits (FRED:DPSACBW027SBOG) — commercial-bank deposits are ~80-90% // of M2 and are created when banks lend, so the weekly H.8 print (Wed-dated, // released Fri) effectively PRE-ANNOUNCES the monthly M2 by ~2-3 weeks. // // UNIT SCALING — the #1 correctness risk (verified magnitudes 2026-06-24/30): // M2 (WM2NS/M2SL) ...... BILLIONS (WM2NS ~23,062.9 = $23.06T) -> as-is // WALCL ................ MILLIONS (6,735,645 = ~$6.74T) -> /1000 -> billions // TGA (WDTGAL/WTREGEN) . MILLIONS (~918,696 = ~$919B) -> /1000 -> billions // RRPONTSYD ............ BILLIONS (26.900 = ~$26.9B) -> as-is (billions) // DPSACBW027SBOG ....... BILLIONS (~$18T level prints ~18,000) -> as-is // Everything below is normalized to $ BILLIONS. NEVER infer scale from // TradingView (it shows generic 'USD') — these are confirmed on the FRED pages. // // HONEST LABEL: this is a NOWCAST, not a guarantee. Leads front-run M2 but do // not perfectly predict it; the up/down read is a probabilistic direction cue. // Note also that request.security reads CURRENT (revised) values, so a backtest // read is look-ahead-biased vs. what was known in real time — fine for a macro // overlay, don't wire it into an automated signal. // ============================================================================ indicator("M2 Nowcast / Net-Liquidity Lead", shorttitle="M2 Nowcast", overlay=false, precision=2) // ── Data sources (editable — defaults are the verified FRED tickers) ────────── gS = "Data sources (FRED)" wm2Sym = input.symbol("FRED:WM2NS", "Weekly M2 (NSA)", group=gS, tooltip="Near-real-time M2, weekly-ending-Monday. Published monthly (H.6) so it steps. Leads the monthly print ~3 weeks. BILLIONS.") m2slSym = input.symbol("FRED:M2SL", "Monthly M2 (SA, reference)", group=gS, tooltip="The seasonally-adjusted headline M2 being front-run. Monthly, ~3-4 wk lag. BILLIONS. Plotted faint.") walclSym= input.symbol("FRED:WALCL", "Fed balance sheet (WALCL)", group=gS, tooltip="Fed total assets, weekly Wednesday level, released Thu H.4.1. MILLIONS on FRED — divided by 1000 here.") tgaSym = input.symbol("FRED:WDTGAL", "Treasury General Account (TGA)",group=gS, tooltip="Treasury cash. WDTGAL = Wednesday level (matches WALCL basis); swap to FRED:WTREGEN for week-average. MILLIONS — /1000 here.") rrpSym = input.symbol("FRED:RRPONTSYD", "Overnight reverse repo (RRP)", group=gS, tooltip="ON RRP drain, DAILY. BILLIONS on FRED — used as-is (already billions). Do NOT x1000 this AND treat TGA as billions; only RRP is billions among the liquidity terms.") depSym = input.symbol("FRED:DPSACBW027SBOG", "H.8 bank deposits (SA)", group=gS, tooltip="Commercial-bank deposits ~80-90% of M2, weekly Wed-dated (H.8, released Fri). Leads M2 ~2-3 weeks. BILLIONS.") // ── Series show toggles ─────────────────────────────────────────────────────── gShow = "Show series" showWM2 = input.bool(true, "Weekly M2 (WM2NS) — leads ~3wk", group=gShow) showM2 = input.bool(true, "Monthly M2 (M2SL) — the reference", group=gShow) showNL = input.bool(true, "Net Liquidity (WALCL−TGA−RRP)", group=gShow) showDep = input.bool(true, "H.8 deposits (leads ~2-3wk)", group=gShow) // ── Time offset (slide leads forward so they align with / lead monthly M2) ───── gO = "Time offset (lead / lag)" offBars = input.int(0, "Offset LEADS by N bars (+ shifts them forward => they LEAD M2)", group=gO, tooltip="Shifts the three lead series (weekly M2, net liquidity, deposits) forward/back in time so you can line them up against — or ahead of — the lagging monthly M2 line. On a weekly chart, try +2 to +4 to visualize the typical release lead.") // ── Normalization (so billions-M2 and a net-liq line compare on one axis) ────── gN = "Normalize" normMode = input.string("Z-score", "Normalize", options=["Z-score", "% from start", "Raw"], group=gN, tooltip="Z-score = standardized (comparable shapes regardless of scale). % from start = growth vs the first observation. Raw = untouched values (only sensible if all are already the same magnitude).") normLen = input.int(104, "Z-score / slope lookback (bars)", minval=10, group=gN, tooltip="Lookback for the z-score mean/stdev AND for the ROC growth term. 104 ≈ 2 years of weekly bars. Use a weekly or daily chart.") // ── Nowcast direction read ──────────────────────────────────────────────────── gD = "Nowcast direction" slopeLen = input.int(8, "Direction slope lookback (bars)", minval=1, group=gD, tooltip="Bars over which the composite lead's slope (ROC) is measured for the up/down read. ~8 weekly bars ≈ 2 months.") useComposite = input.bool(true, "Composite (net-liq + deposits) drives the read", group=gD, tooltip="ON: average the net-liquidity and H.8-deposits growth for a steadier direction cue. OFF: use net liquidity alone.") showBg = input.bool(true, "Shade background GREEN=up / RED=down", group=gD) // ── Pull series (no look-ahead bias); scale each to $ BILLIONS ───────────────── wm2 = request.security(wm2Sym, timeframe.period, close, lookahead=barmerge.lookahead_off) // BILLIONS as-is m2sl = request.security(m2slSym, timeframe.period, close, lookahead=barmerge.lookahead_off) // BILLIONS as-is walcl = request.security(walclSym, timeframe.period, close, lookahead=barmerge.lookahead_off) // MILLIONS tga = request.security(tgaSym, timeframe.period, close, lookahead=barmerge.lookahead_off) // MILLIONS rrp = request.security(rrpSym, timeframe.period, close, lookahead=barmerge.lookahead_off) // BILLIONS dep = request.security(depSym, timeframe.period, close, lookahead=barmerge.lookahead_off) // BILLIONS as-is // NET LIQUIDITY in $ billions: // WALCL(millions)/1000 − TGA(millions)/1000 − RRP(already billions) // i.e. (WALCL − TGA)/1000 − RRP. This keeps every term in billions to match M2. netliq = walcl / 1000.0 - tga / 1000.0 - rrp // ── First non-na values = bases for %-from-start normalization ───────────────── var float bWm2 = na, var float bM2 = na, var float bNL = na, var float bDep = na if na(bWm2) and not na(wm2) bWm2 := wm2 if na(bM2) and not na(m2sl) bM2 := m2sl if na(bNL) and not na(netliq) bNL := netliq if na(bDep) and not na(dep) bDep := dep // ── Normalize helper ────────────────────────────────────────────────────────── normalize(s, baseV) => r = s if normMode == "Z-score" mu = ta.sma(s, normLen) sd = ta.stdev(s, normLen) r := sd != 0 ? (s - mu) / sd : 0.0 else if normMode == "% from start" r := (not na(baseV) and baseV != 0) ? (s / baseV - 1.0) * 100.0 : na r nWm2 = normalize(wm2, bWm2) nM2 = normalize(m2sl, bM2) nNL = normalize(netliq, bNL) nDep = normalize(dep, bDep) // ── Nowcast direction: slope of the fast leads => "M2 pointing up / down" ────── nlG = ta.roc(netliq, slopeLen) // net-liquidity growth (the leading driver) depG = ta.roc(dep, slopeLen) // deposits growth (the bulk of M2) dirRaw = useComposite ? (nlG + depG) / 2.0 : nlG nowUp = dirRaw > 0 dirColor = nowUp ? color.new(color.green, 0) : color.new(color.red, 0) // ── Plots ───────────────────────────────────────────────────────────────────── // Reference: the lagging monthly M2 being front-run (faint, no offset). plot(showM2 ? nM2 : na, "Monthly M2 (M2SL, reference)", color=color.new(color.gray, 55), linewidth=1) // The three leads — offsettable so they can be slid forward to lead M2. plot(showWM2 ? nWm2 : na, "Weekly M2 (WM2NS)", color=color.new(color.blue, 0), linewidth=2, offset=offBars) plot(showNL ? nNL : na, "Net Liquidity", color=color.new(color.orange, 0), linewidth=2, offset=offBars) plot(showDep ? nDep : na, "H.8 deposits", color=color.new(color.teal, 0), linewidth=2, offset=offBars) // Nowcast direction row + background: GREEN when leads rising (M2 likely UP), // RED when falling (M2 likely DOWN). Honest nowcast — a direction cue, not a call. bgcolor(showBg ? color.new(nowUp ? color.green : color.red, 88) : na, title="Nowcast up/down shade") plotshape(dirRaw, "Nowcast direction dot", style=shape.circle, location=location.bottom, color=dirColor, size=size.tiny) hline(0, "zero (normalized)", color=color.new(color.gray, 70))