STRASMORE/EXPLORE 2,401 QUERIES 22Y EQUITIES · 12Y OPTIONS

2,401 answered market questions

every one with its exact SQL, its result and the date it was computed · free, no signup

What Happens When the Yield Curve Un-Inverts
Which leg did the work: 2-year and 10-year moves over the 91 days before each crossingtable · 2026-09-19 · 7×9 SPY's change from the crossing-day close, 3, 6 and 12 months after each un-inversiontable · 2026-09-19 · 2×5 The 2s10s spread by month, full historyseries · 2026-09-19 · 604×5Preview: a 16-point series, ending lower. The 2s10s over the trailing six months, with the 2-year and 10-year moves that produced itseries · 2026-09-19 · 26×8Preview: a 16-point series, ending higher. Every 2s10s un-inversion: the crossing and the spread 3, 6 and 12 months latertable · 2026-09-19 · 7×8
Which leg did the work: 2-year and 10-year moves over the 91 days before each crossing

Which leg did the work: 2-year and 10-year moves over the 91 days before each crossing

most recentas of table 7×9read in context →
Which leg did the work: 2-year and 10-year moves over the 91 days before each crossing — 7 rows by 9 columns, computed from US exchange, SIP and OPRA data.
episodecrossed_ony2_91d_beforey2_at_crossy10_91d_beforey10_at_crossy2_change_bpy10_change_bpsteepener_type
May 19801980-05-0212.0410.0411.2910.24-200-105bull steepener (2-year fell most)
Oct 19811981-10-2815.7615.4214.6115.44-3483bear steepener (10-year rose most)
Jul 19821982-07-1914.1813.5213.6613.68-662bull steepener (2-year fell most)
Jun 19891989-06-309.738.089.38.1-165-120bull steepener (2-year fell most)
Dec 20002000-12-2765.15.835.11-90-72bull steepener (2-year fell most)
Mar 20072007-03-214.714.514.64.53-20-7bull steepener (2-year fell most)
Sep 20242024-09-044.723.764.293.77-96-52bull steepener (2-year fell most)
the exact SQL behind every number
WITH
daily AS
(
    SELECT
        date,
        dateDiff('day', toDate('1970-01-01'), date)   AS dnum,
        ifNull(toFloat64(max(yield_2_year)), 0.)      AS y2,
        ifNull(toFloat64(max(yield_10_year)), 0.)     AS y10,
        y10 - y2                                      AS spread
    FROM global_markets.treasury_yields
    WHERE yield_2_year > 0 AND yield_10_year > 0
    GROUP BY date
),
scored AS
(
    SELECT
        date, dnum, y2, y10, spread,
        count()         OVER (ORDER BY date ROWS BETWEEN 60 PRECEDING AND 1 PRECEDING) AS rows_prior,
        sum(spread < 0) OVER (ORDER BY date ROWS BETWEEN 60 PRECEDING AND 1 PRECEDING) AS neg_prior,
        sum(spread > 0) OVER (ORDER BY date ROWS BETWEEN CURRENT ROW AND 20 FOLLOWING) AS pos_next
    FROM daily
),
candidates AS
(
    SELECT
        date, dnum, y2, y10, spread,
        lagInFrame(dnum, 1, toInt64(-100000)) OVER (ORDER BY dnum ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS prev_dnum
    FROM scored
    WHERE spread > 0 AND rows_prior = 60 AND neg_prior >= 35 AND pos_next >= 19
),
episodes AS
(
    SELECT date AS cross_date, y2, y10, spread
    FROM candidates
    WHERE dnum - prev_dnum > 180
      AND date <= today() - 380
)
SELECT
    episode,
    crossed_on,
    y2_91d_before,
    y2_at_cross,
    y10_91d_before,
    y10_at_cross,
    y2_change_bp,
    y10_change_bp,
    multiIf(
        y2_change_bp < 0 AND abs(y2_change_bp) >= abs(y10_change_bp), 'bull steepener (2-year fell most)',
        y10_change_bp > 0 AND abs(y10_change_bp) > abs(y2_change_bp), 'bear steepener (10-year rose most)',
        'mixed'
    ) AS steepener_type
FROM
(
    SELECT
        formatDateTime(e.cross_date, '%b %Y')                                       AS episode,
        toString(toDate(e.cross_date))                                              AS crossed_on,
        round(argMinIf(d.y2, d.date, d.date >= addDays(e.cross_date, -91)), 2)      AS y2_91d_before,
        round(any(e.y2), 2)                                                         AS y2_at_cross,
        round(argMinIf(d.y10, d.date, d.date >= addDays(e.cross_date, -91)), 2)     AS y10_91d_before,
        round(any(e.y10), 2)                                                        AS y10_at_cross,
        round((any(e.y2)  - argMinIf(d.y2,  d.date, d.date >= addDays(e.cross_date, -91))) * 100) AS y2_change_bp,
        round((any(e.y10) - argMinIf(d.y10, d.date, d.date >= addDays(e.cross_date, -91))) * 100) AS y10_change_bp
    FROM episodes AS e
    CROSS JOIN daily AS d
    WHERE d.date BETWEEN addDays(e.cross_date, -100) AND e.cross_date
    GROUP BY e.cross_date
)
ORDER BY crossed_on
$