{"slug":"falling-wedge-pattern","qid":"recent_wedges","label":"recent_wedges","post_title":"falling-wedge-pattern","post_url":"/blog/lang/pcm/falling-wedge-pattern#q-recent_wedges","columns":["signal_date","signal_label","ticker","five_day_fall_pct","fwd_20_pct"],"rows":[{"signal_date":"2026-01-05","signal_label":"Jan 5, 2026","ticker":"PG","five_day_fall_pct":3.02,"fwd_20_pct":10.65},{"signal_date":"2026-01-05","signal_label":"Jan 5, 2026","ticker":"MCD","five_day_fall_pct":3.48,"fwd_20_pct":6.54},{"signal_date":"2026-01-06","signal_label":"Jan 6, 2026","ticker":"PEP","five_day_fall_pct":3.66,"fwd_20_pct":19.59},{"signal_date":"2026-03-09","signal_label":"Mar 9, 2026","ticker":"NKE","five_day_fall_pct":7.34,"fwd_20_pct":-24.48},{"signal_date":"2026-04-28","signal_label":"Apr 28, 2026","ticker":"HD","five_day_fall_pct":4.32,"fwd_20_pct":-3.41},{"signal_date":"2026-04-29","signal_label":"Apr 29, 2026","ticker":"HD","five_day_fall_pct":4.92,"fwd_20_pct":-0.5},{"signal_date":"2026-05-11","signal_label":"May 11, 2026","ticker":"T","five_day_fall_pct":4.71,"fwd_20_pct":-8.69},{"signal_date":"2026-07-24","signal_label":"Jul 24, 2026","ticker":"AMZN","five_day_fall_pct":6.12,"fwd_20_pct":11.43},{"signal_date":"2026-08-12","signal_label":"Aug 12, 2026","ticker":"NKE","five_day_fall_pct":4.57,"fwd_20_pct":-9.6},{"signal_date":"2026-08-20","signal_label":"Aug 20, 2026","ticker":"INTC","five_day_fall_pct":11.89,"fwd_20_pct":17.88},{"signal_date":"2026-08-31","signal_label":"Aug 31, 2026","ticker":"GS","five_day_fall_pct":1,"fwd_20_pct":-10.69},{"signal_date":"2026-09-01","signal_label":"Sep 1, 2026","ticker":"HD","five_day_fall_pct":5.36,"fwd_20_pct":-11.03}],"shape":"series","sql":"WITH\nbars AS (\n    SELECT\n        ticker,\n        date,\n        toFloat64(high)  AS hi,\n        toFloat64(low)   AS lo,\n        toFloat64(close) AS px\n    FROM global_markets.stocks_daily_aggs\n    WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','META','TSLA','AVGO','JPM','BAC','WFC','GS','KO','PEP','PG','JNJ','PFE','MRK','XOM','CVX','WMT','HD','MCD','NKE','CSCO','INTC','IBM','T','VZ','DIS')\n      AND date >= '2010-01-04'\n      AND date <= '2026-09-30'\n),\nsplit_dates AS (\n    SELECT\n        ticker,\n        groupArray(execution_date) AS split_days\n    FROM\n    (\n        SELECT ticker, execution_date\n        FROM global_markets.stocks_splits\n        WHERE execution_date >= '2009-10-01'\n        GROUP BY ticker, execution_date\n    )\n    GROUP BY ticker\n),\nstepped AS (\n    SELECT\n        ticker,\n        date,\n        px,\n        hi - lo AS rng,\n        if(hi < lagInFrame(hi, 1) OVER w AND lo < lagInFrame(lo, 1) OVER w, 1, 0) AS lower_both\n    FROM bars\n    WINDOW w AS (PARTITION BY ticker ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)\n),\nfeat AS (\n    SELECT\n        ticker,\n        date,\n        px,\n        sum(lower_both) OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)  AS wedge_streak,\n        avg(rng)        OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)  AS rng5,\n        groupArray(rng) OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 64 PRECEDING AND 5 PRECEDING) AS prior_rng,\n        lagInFrame(px, 5)   OVER wf AS px_back5,\n        leadInFrame(px, 5)  OVER wf AS px_fwd5,\n        leadInFrame(px, 10) OVER wf AS px_fwd10,\n        leadInFrame(px, 20) OVER wf AS px_fwd20\n    FROM stepped\n    WINDOW wf AS (PARTITION BY ticker ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)\n),\nscored AS (\n    SELECT\n        f.ticker   AS ticker,\n        f.date     AS date,\n        f.px       AS px,\n        f.px_back5 AS px_back5,\n        f.px_fwd20 AS px_fwd20,\n        if(f.wedge_streak = 4 AND f.rng5 < arraySort(f.prior_rng)[15], 1, 0) AS is_wedge\n    FROM feat AS f\n    LEFT JOIN split_dates AS s ON s.ticker = f.ticker\n    WHERE length(f.prior_rng) = 60\n      AND f.px_back5 > 0\n      AND f.px_fwd5  > 0\n      AND f.px_fwd10 > 0\n      AND f.px_fwd20 > 0\n      AND NOT arrayExists(d -> (d >= f.date - 10) AND (d <= f.date + 32), s.split_days)\n)\nSELECT\n    signal_date,\n    signal_label,\n    ticker,\n    five_day_fall_pct,\n    fwd_20_pct\nFROM\n(\n    SELECT\n        toString(date)                           AS signal_date,\n        formatDateTime(date, '%b %e, %Y')        AS signal_label,\n        ticker,\n        round(abs(100 * (px / px_back5 - 1)), 2) AS five_day_fall_pct,\n        round(100 * (px_fwd20 / px - 1), 2)      AS fwd_20_pct\n    FROM scored\n    WHERE is_wedge = 1\n    ORDER BY date DESC\n    LIMIT 12\n)\nORDER BY signal_date ASC","computed_at":"2026-10-06T15:38:26.463782+00:00","elapsed":0.007691536}