{"slug":"double-top-pattern-follow-through","qid":"after_break_vs_baseline","label":"after_break_vs_baseline","post_title":"double-top-pattern-follow-through","post_url":"/blog/lang/th/double-top-pattern-follow-through#q-after_break_vs_baseline","columns":["horizon_label","after_break_pct","baseline_pct","signal_count"],"rows":[{"horizon_label":"5 วันทำการ","after_break_pct":0.01,"baseline_pct":0.45,"signal_count":87},{"horizon_label":"10 วันทำการ","after_break_pct":1.5,"baseline_pct":0.83,"signal_count":87},{"horizon_label":"20 วันทำการ","after_break_pct":0.98,"baseline_pct":1.66,"signal_count":87},{"horizon_label":"60 วันทำการ","after_break_pct":6.71,"baseline_pct":4.46,"signal_count":87}],"shape":"ranking","sql":"WITH\npx AS (\n    SELECT ticker, date,\n           toFloat64(argMax(high, _ingest_time))  AS h,\n           toFloat64(argMax(low, _ingest_time))   AS l,\n           toFloat64(argMax(close, _ingest_time)) AS c\n    FROM global_markets.stocks_daily_aggs\n    WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','META','JPM','JNJ','KO','XOM')\n      AND date >= '2015-01-01' AND date < today()\n    GROUP BY ticker, date),\nsplits AS (\n    SELECT ticker, groupArray(execution_date) AS split_dates\n    FROM global_markets.stocks_splits\n    WHERE execution_date >= '2014-01-01'\n    GROUP BY ticker),\npivots AS (\n    SELECT ticker, date, h, l, c,\n           toUInt8(h = max(h) OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 10 PRECEDING AND 10 FOLLOWING)) AS is_peak\n    FROM px),\nframed AS (\n    SELECT ticker, date, h, is_peak,\n           groupArray(h)       OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 60 PRECEDING AND CURRENT ROW) AS h_back,\n           groupArray(l)       OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 60 PRECEDING AND CURRENT ROW) AS l_back,\n           groupArray(is_peak) OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 60 PRECEDING AND CURRENT ROW) AS p_back,\n           groupArray(c)       OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN CURRENT ROW AND 90 FOLLOWING) AS c_fwd,\n           groupArray(date)    OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN CURRENT ROW AND 90 FOLLOWING) AS d_fwd\n    FROM pivots),\npaired AS (\n    SELECT ticker, date AS peak2_date, h AS peak2_high, h_back, l_back, c_fwd, d_fwd,\n           arrayFirst(g -> (p_back[61 - g] = 1)\n                       AND (abs((h_back[61 - g] / h) - 1) <= 0.03)\n                       AND (arrayMin(arraySlice(l_back, 61 - g, g + 1)) <= (0.95 * least(h_back[61 - g], h))),\n                      range(15, 61)) AS gap\n    FROM framed\n    WHERE is_peak = 1 AND length(l_back) = 61 AND length(c_fwd) = 91),\nnecked AS (\n    SELECT ticker, peak2_date, gap,\n           arrayMin(arraySlice(l_back, 61 - gap, gap + 1)) AS neckline,\n           c_fwd, d_fwd\n    FROM (\n        SELECT p.ticker AS ticker, p.peak2_date AS peak2_date,\n               p.l_back AS l_back, p.c_fwd AS c_fwd, p.d_fwd AS d_fwd,\n               p.gap AS gap, s.split_dates AS split_dates\n        FROM paired AS p\n        LEFT JOIN splits AS s ON p.ticker = s.ticker)\n    WHERE gap > 0\n      AND arrayCount(d -> (d >= (peak2_date - 150)) AND (d <= (peak2_date + 180)), split_dates) = 0),\nconfirmed AS (\n    SELECT ticker, d_fwd[k_rel + 11] AS confirm_date\n    FROM (SELECT *, arrayFirstIndex(x -> x < neckline, arraySlice(c_fwd, 12, 20)) AS k_rel FROM necked)\n    WHERE k_rel > 0\n    ORDER BY ticker, confirm_date\n    LIMIT 1 BY ticker, confirm_date),\nuniverse AS (\n    SELECT f.c_fwd AS c_fwd, s.hit AS is_signal\n    FROM framed AS f\n    LEFT JOIN (SELECT ticker, confirm_date, toUInt8(1) AS hit FROM confirmed GROUP BY ticker, confirm_date) AS s\n           ON f.ticker = s.ticker AND f.date = s.confirm_date\n    WHERE length(f.c_fwd) = 91)\nSELECT\n    concat(toString(hz), ' วันทำการ')                      AS horizon_label,\n    round(quantileExactIf(0.5)(ret_pct, is_signal = 1), 2) AS after_break_pct,\n    round(quantileExactIf(0.5)(ret_pct, is_signal = 0), 2) AS baseline_pct,\n    countIf(is_signal = 1)                                 AS signal_count\nFROM (\n    SELECT hz, is_signal, 100 * ((c_fwd[hz + 1] / c_fwd[1]) - 1) AS ret_pct\n    FROM (SELECT c_fwd, is_signal, arrayJoin([5, 10, 20, 60]) AS hz FROM universe))\nGROUP BY hz\nHAVING countIf(is_signal = 1) > 0\nORDER BY hz","computed_at":"2026-09-28T15:44:18.606439+00:00","elapsed":136.821229852}