{"slug":"market-structure-and-break-of-structure","qid":"bos_horizon","label":"bos_horizon","post_title":"market-structure-and-break-of-structure","post_url":"/blog/lang/th/market-structure-and-break-of-structure#q-bos_horizon","columns":["horizon_label","bos_events","continuation_pct","base_rate_pct","edge_pp","back_inside_pct"],"rows":[{"horizon_label":"1 วัน","bos_events":448,"continuation_pct":54.9,"base_rate_pct":53.3,"edge_pp":1.6,"back_inside_pct":21.7},{"horizon_label":"3 วัน","bos_events":448,"continuation_pct":59.2,"base_rate_pct":56,"edge_pp":3.2,"back_inside_pct":40.2},{"horizon_label":"5 วัน","bos_events":448,"continuation_pct":57.1,"base_rate_pct":56.6,"edge_pp":0.5,"back_inside_pct":49.1},{"horizon_label":"10 วัน","bos_events":448,"continuation_pct":56.9,"base_rate_pct":58.1,"edge_pp":-1.2,"back_inside_pct":62.5},{"horizon_label":"20 วัน","bos_events":448,"continuation_pct":60.7,"base_rate_pct":60.1,"edge_pp":0.6,"back_inside_pct":70.8}],"shape":"table","sql":"WITH\npx AS\n(\n    SELECT\n        ticker,\n        date,\n        toFloat64(high)  AS h,\n        toFloat64(close) AS c\n    FROM global_markets.stocks_daily_aggs\n    WHERE ticker IN ('AAPL', 'JPM', 'KO', 'MSFT', 'QQQ', 'SPY')\n      AND date >= '2021-01-01'\n      AND date <  '2026-09-01'\n),\nsorted AS\n(\n    SELECT\n        ticker,\n        arraySort(x -> x.1, groupArray((date, h, c))) AS bars\n    FROM px\n    GROUP BY ticker\n),\narrs AS\n(\n    SELECT\n        ticker,\n        arrayMap(x -> x.2, bars) AS highs,\n        arrayMap(x -> x.3, bars) AS closes\n    FROM sorted\n),\npivots AS\n(\n    SELECT\n        ticker,\n        highs,\n        closes,\n        arrayJoin(arrayFilter(i ->\n            (i > 3)\n            AND (i <= length(highs) - 3)\n            AND (highs[i] > arrayMax(arraySlice(highs, i - 3, 3)))\n            AND (highs[i] > arrayMax(arraySlice(highs, i + 1, 3))),\n            arrayEnumerate(highs))) AS pivot_i\n    FROM arrs\n),\nbreaks AS\n(\n    SELECT\n        ticker,\n        closes,\n        pivot_i,\n        highs[pivot_i] AS level,\n        pivot_i + 3 + arrayFirstIndex(x -> x > highs[pivot_i], arraySlice(closes, pivot_i + 4, 30)) AS break_i\n    FROM pivots\n    WHERE arrayFirstIndex(x -> x > highs[pivot_i], arraySlice(closes, pivot_i + 4, 30)) > 0\n),\nevents AS\n(\n    SELECT\n        ticker,\n        break_i,\n        argMax(level, pivot_i) AS level,\n        any(closes)            AS closes\n    FROM breaks\n    GROUP BY ticker, break_i\n),\nafter_bos AS\n(\n    SELECT\n        n,\n        count()                                                    AS bos_events,\n        round(100 * avg(closes[break_i + n] > closes[break_i]), 1) AS continuation_pct,\n        round(100 * avg(arrayMin(arraySlice(closes, break_i + 1, n)) < level), 1) AS back_inside_pct\n    FROM\n    (\n        SELECT\n            break_i,\n            level,\n            closes,\n            arrayJoin([1, 3, 5, 10, 20]) AS n\n        FROM events\n        WHERE break_i + 20 <= length(closes)\n    )\n    GROUP BY n\n),\nbase AS\n(\n    SELECT\n        n,\n        round(100 * avg(closes[t + n] > closes[t]), 1) AS base_rate_pct\n    FROM\n    (\n        SELECT\n            closes,\n            t,\n            arrayJoin([1, 3, 5, 10, 20]) AS n\n        FROM\n        (\n            SELECT\n                closes,\n                arrayJoin(arrayEnumerate(closes)) AS t\n            FROM arrs\n        )\n        WHERE t + 20 <= length(closes)\n    )\n    GROUP BY n\n)\nSELECT\n    concat(toString(a.n), ' วัน')                 AS horizon_label,\n    a.bos_events                                   AS bos_events,\n    a.continuation_pct                             AS continuation_pct,\n    b.base_rate_pct                                AS base_rate_pct,\n    round(a.continuation_pct - b.base_rate_pct, 1) AS edge_pp,\n    a.back_inside_pct                              AS back_inside_pct\nFROM after_bos AS a\nINNER JOIN base AS b ON b.n = a.n\nORDER BY a.n","computed_at":"2026-09-22T15:02:00.834167+00:00","elapsed":18.570478865}