STRASMORE/EXPLORE 2,170 QUERIES

Stocks at 52-week lows, ordered by year-to-date return

Answered against 22 years of US equities and 12 years of US options data and published with the query that produced it. This result is stored as of 2026-08-25, from Stocks at 52-Week Highs and Lows.

as of ranking 9×3read in context →
Stocks at 52-week lows, ordered by year-to-date return — 9 rows by 3 columns, computed from US exchange, SIP and OPRA data.
tickercloseytd_return_pct
TTD13.27-65
APP298.59-55.7
QXO13.41-30.5
NRG111.78-29.8
TLN305.54-18.5
VST135.66-15.9
LHX262.83-10.5
DKS179.33-9.4
CMS68.42-2.2
Rows × columns
9 × 3
Computed
Completeness
No missing values
Source
US exchange, SIP and OPRA market data
Licence
Strasmore terms · free, no signup
Formats
JSON · CSV · the SQL below

What each column holds

Column definitions for Stocks at 52-week lows, ordered by year-to-date return, derived from the stored result.
ColumnTypeRangeNotes
ticker text 9 distinct values (APP, CMS, DKS…)
close number 13.27 to 305.54 US dollars
ytd_return_pct number -65 to -2.2 percent

Computed from Strasmore's warehouse of US exchange, SIP and OPRA market data. Equity prices are delayed; options greeks and implied volatility are end-of-day. This result is stored, not recomputed on load — it is exactly the numbers that were returned on , and the query below is what returned them.

the exact SQL behind every number
WITH universe AS (
    SELECT ticker
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE window_start >= now() - INTERVAL 20 DAY
      AND toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York')) >= 570
      AND toHour(toTimeZone(window_start, 'America/New_York')) * 60 + toMinute(toTimeZone(window_start, 'America/New_York')) < 960
      AND ticker IN (SELECT arrayJoin(tickers) FROM global_markets.stocks_income_statements
                     WHERE period_end >= today() - 400)
      AND ticker NOT IN ('SPCX','KORU','SOXL','SOXS','TQQQ','SQQQ','NVDL','NVDS','NVD','TSLL','TSLQ','TSLZ','SPXL','SPXS','UPRO','SPXU','LABU','LABD','FAS','FAZ','TNA','TZA','YINN','YANG','UDOW','SDOW','BOIL','KOLD','UCO','SCO','USD','SSO','SDS','QLD','QID','ERX','ERY','DRN','DRV','CURE','SOXY','MUU','SNXX','UVXY','SVXY','UVIX','SVIX','BULZ','WEBL','WEBS','DPST','DRIP','GUSH','AGQ','ZSL','BITX','ETHU','MSTX','MSTU','CONL','DUST','JNUG','JDST','NUGT')
      AND ticker NOT IN (SELECT ticker FROM global_markets.stocks_splits
                         WHERE execution_date BETWEEN today() - 460 AND today())
    GROUP BY ticker
    HAVING sum(toFloat64(close) * toFloat64(volume)) >= 2000000000
),
last_session AS (
    SELECT max(date) AS d FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY' AND date >= today() - 12 AND date < today()
),
daily AS (
    SELECT ticker, date AS dt, toFloat64(close) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE date < today()
      AND ticker IN (SELECT ticker FROM universe)
      AND date > (SELECT d FROM last_session) - 365
),
ranged AS (
    SELECT ticker,
           argMax(c, dt) AS last_close,
           max(c) AS hi,
           min(c) AS lo,
           argMaxIf(c, dt, dt <= toDate('2025-12-31')) AS base_close,
           count() AS n_sessions,
           min(dt) AS first_dt,
           max(dt) AS last_dt
    FROM daily
    GROUP BY ticker
    HAVING n_sessions >= 200
       AND countIf(dt <= toDate('2025-12-31')) > 0
       AND last_dt = (SELECT d FROM last_session)
       AND first_dt <= (SELECT d FROM last_session) - 350
)
SELECT ticker,
       round(last_close, 2) AS close,
       round((last_close / base_close - 1) * 100, 1) AS ytd_return_pct
FROM ranged
WHERE last_close <= lo * 1.01
ORDER BY ytd_return_pct ASC, ticker ASC
LIMIT 12

Run your own version of this

The same 22 years of US equities and 12 years of options data are queryable in SQL or plain English. A free account runs 100 queries a day and takes no card.

More from this analysisStocks at 52-Week Highs and Lows
Stocks at 52-week highs, ordered by year-to-date return ranking 12×3 How far the whole screen sits below its 52-week high ranking 6×4 Where five broad-market ETFs sit inside their own 52-week range ranking 5×4 New 52-week highs against new lows, daily, over the past six weeks series 31×4 Annualized volatility vs total return, 25 large caps, calmest to wildest (~2 years) ranking 25×3 When headlines actually land: article counts by ET clock hour, July 2026 ranking 24×4 See all 2,170 queries →