{"slug":"stochastic-oscillator-explained","qid":"signal_frequency","label":"signal_frequency","post_title":"stochastic-oscillator-explained","post_url":"/blog/lang/th/stochastic-oscillator-explained#q-signal_frequency","columns":["year","cross_down_80_count","cross_up_20_count"],"rows":[{"year":2016,"cross_down_80_count":231,"cross_up_20_count":140},{"year":2017,"cross_down_80_count":206,"cross_up_20_count":134},{"year":2018,"cross_down_80_count":212,"cross_up_20_count":163},{"year":2019,"cross_down_80_count":260,"cross_up_20_count":119},{"year":2020,"cross_down_80_count":236,"cross_up_20_count":155},{"year":2021,"cross_down_80_count":219,"cross_up_20_count":154},{"year":2022,"cross_down_80_count":212,"cross_up_20_count":200},{"year":2023,"cross_down_80_count":234,"cross_up_20_count":159},{"year":2024,"cross_down_80_count":244,"cross_up_20_count":151},{"year":2025,"cross_down_80_count":223,"cross_up_20_count":168},{"year":2026,"cross_down_80_count":117,"cross_up_20_count":112}],"shape":"ranking","sql":"WITH\n    bars AS (\n        SELECT\n            ticker,\n            date,\n            argMax(toFloat64(close), _ingest_time) AS close,\n            argMax(toFloat64(high),  _ingest_time) AS high,\n            argMax(toFloat64(low),   _ingest_time) AS low\n        FROM global_markets.stocks_daily_aggs\n        WHERE ticker IN ('AAPL','MSFT','NVDA','AMZN','GOOGL','META','JPM','JNJ','XOM','PG','KO','WMT','HD','UNH','CVX','PEP','MRK','CSCO','ORCL','MCD')\n          AND date >= '2015-01-01'\n          AND date <  '2026-09-01'\n        GROUP BY ticker, date\n    ),\n    ranges AS (\n        SELECT\n            ticker, date, close,\n            count()   OVER w14 AS n14,\n            max(high) OVER w14 AS hh14,\n            min(low)  OVER w14 AS ll14\n        FROM bars\n        WINDOW w14 AS (PARTITION BY ticker ORDER BY date ROWS BETWEEN 13 PRECEDING AND CURRENT ROW)\n    ),\n    fast AS (\n        SELECT\n            ticker, date, close,\n            if(hh14 > ll14, 100 * (close - ll14) / (hh14 - ll14), 50) AS k_fast\n        FROM ranges\n        WHERE n14 = 14\n    ),\n    slow AS (\n        SELECT\n            ticker, date, close,\n            avg(k_fast) OVER w3 AS k_slow,\n            count()     OVER w3 AS n3\n        FROM fast\n        WINDOW w3 AS (PARTITION BY ticker ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)\n    ),\n    fwd AS (\n        SELECT\n            ticker, date, close, k_slow,\n            lagInFrame(k_slow, 1)  OVER wl AS k_prev,\n            leadInFrame(close, 20) OVER wf AS c20\n        FROM slow\n        WHERE n3 = 3\n        WINDOW\n            wl AS (PARTITION BY ticker ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW),\n            wf AS (PARTITION BY ticker ORDER BY date ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)\n    )\nSELECT\n    toYear(date)                                        AS year,\n    countIf((k_prev >= 80) AND (k_slow < 80))           AS cross_down_80_count,\n    countIf((k_prev <= 20) AND (k_slow > 20))           AS cross_up_20_count\nFROM fwd\nWHERE date >= '2016-01-01'\n  AND c20 > 0\nGROUP BY year\nORDER BY year","computed_at":"2026-09-28T15:44:32.731765+00:00","elapsed":0.031611532}