{
  "schema_version": "1.0",
  "signals": [
    {
      "id": "gap-up-above-20dma",
      "family": "gap",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The stock opened at least 2% above yesterday's close, on a day when it was already trading above its 20-day average price.",
      "definition": "open[t] / close[t-1] - 1 >= 0.02\nAND close[t-1] > sma(close, 20)[t-1]",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "gap_threshold": [
          0.016,
          0.018,
          0.02,
          0.022,
          0.024
        ],
        "ma_length": [
          16,
          18,
          20,
          22,
          24
        ]
      },
      "headline_parameters": {
        "gap_threshold": 0.02,
        "ma_length": 20
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "gap-down-below-20dma",
      "family": "gap",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The stock opened at least 2% below yesterday's close, on a day when it was already trading below its 20-day average price.",
      "definition": "open[t] / close[t-1] - 1 <= -0.02\nAND close[t-1] < sma(close, 20)[t-1]",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "gap_threshold": [
          0.016,
          0.018,
          0.02,
          0.022,
          0.024
        ],
        "ma_length": [
          16,
          18,
          20,
          22,
          24
        ]
      },
      "headline_parameters": {
        "gap_threshold": 0.02,
        "ma_length": 20
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "close-crosses-above-20dma",
      "family": "price-structure",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The stock closed back above its 20-day average price after having spent at least five of the previous ten sessions below it.",
      "definition": "close[t] > sma(close, 20)[t]\nAND close[t-1] <= sma(close, 20)[t-1]\nAND count(close < sma(close, 20) over t-10..t-1) >= 5",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "ma_length": [
          16,
          18,
          20,
          22,
          24
        ],
        "days_below": [
          3,
          4,
          5,
          6,
          7
        ]
      },
      "headline_parameters": {
        "ma_length": 20,
        "days_below": 5
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "new-60-day-high",
      "family": "price-structure",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The stock closed at its highest level in sixty sessions, on volume at least equal to its own twenty-day average.",
      "definition": "close[t] = max(close over t-59..t)\nAND volume[t] >= 1.0 * avg(volume, 20)[t]",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "lookback": [
          40,
          50,
          60,
          70,
          80
        ],
        "volume_ratio": [
          0.6,
          0.8,
          1.0,
          1.2,
          1.4
        ]
      },
      "headline_parameters": {
        "lookback": 60,
        "volume_ratio": 1.0
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "volume-spike-without-price-move",
      "family": "volume",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "Volume was at least three times the stock's own twenty-day average while the closing price barely moved \u2014 under 1% either way.",
      "definition": "volume[t] >= 3.0 * avg(volume, 20)[t]\nAND abs(close[t] / close[t-1] - 1) <= 0.01",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "volume_multiple": [
          2.0,
          2.5,
          3.0,
          3.5,
          4.0
        ],
        "move_cap": [
          0.005,
          0.0075,
          0.01,
          0.0125,
          0.015
        ]
      },
      "headline_parameters": {
        "volume_multiple": 3.0,
        "move_cap": 0.01
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "narrowest-range-in-seven-sessions",
      "family": "volatility",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The day's high-to-low range was the narrowest of the last seven sessions, and under 2% of the closing price.",
      "definition": "(high[t] - low[t]) / close[t] = min((high - low) / close over t-6..t)\nAND (high[t] - low[t]) / close[t] <= 0.02",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "lookback": [
          5,
          6,
          7,
          8,
          9
        ],
        "range_cap": [
          0.01,
          0.015,
          0.02,
          0.025,
          0.03
        ]
      },
      "headline_parameters": {
        "lookback": 7,
        "range_cap": 0.02
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "three-down-days-in-an-uptrend",
      "family": "price-structure",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The stock closed lower three sessions running while still trading above its fifty-day average price.",
      "definition": "close[t] < close[t-1] < close[t-2] < close[t-3]\nAND close[t] > sma(close, 50)[t]",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "streak": [
          1,
          2,
          3,
          4,
          5
        ],
        "ma_length": [
          40,
          45,
          50,
          55,
          60
        ]
      },
      "headline_parameters": {
        "streak": 3,
        "ma_length": 50
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "early-session-of-the-month",
      "family": "seasonality",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The third trading session of a calendar month, for a stock trading above its hundred-day average price.",
      "definition": "t is the third trading session of its calendar month (session_offset = 2)\nAND close[t] > sma(close, 100)[t]",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "session_offset": [
          0,
          1,
          2,
          3,
          4
        ],
        "ma_length": [
          20,
          50,
          100,
          150,
          200
        ]
      },
      "headline_parameters": {
        "session_offset": 2,
        "ma_length": 100
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed",
      "note": "Registered deliberately as the clearest demonstration of effective sample size on the site: a calendar condition fires on every eligible security on the same day, so a raw count in the hundreds of thousands collapses to roughly the number of distinct dates."
    },
    {
      "id": "market-wide-down-day",
      "family": "breadth",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "A session on which the median eligible security fell at least 2%, for a stock trading above its hundred-day average price.",
      "definition": "median(log return of all eligible securities)[t] <= -0.02\nAND close[t] > sma(close, 100)[t]",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "market_threshold": [
          -0.03,
          -0.025,
          -0.02,
          -0.015,
          -0.01
        ],
        "ma_length": [
          20,
          50,
          100,
          150,
          200
        ]
      },
      "headline_parameters": {
        "market_threshold": -0.02,
        "ma_length": 100
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "computed"
    },
    {
      "id": "post-earnings-announcement-drift",
      "family": "earnings-drift",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The sessions following a quarterly results announcement, split by whether the stock rose or fell on the announcement day itself.",
      "definition": "t = the first session after a quarterly results announcement\nAND sign(close[t] / close[t-1] - 1) determines the arm",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "reaction_threshold": [
          0.01,
          0.02,
          0.03,
          0.04,
          0.05
        ],
        "ma_length": [
          20,
          50,
          100,
          150,
          200
        ]
      },
      "headline_parameters": {
        "reaction_threshold": 0.03,
        "ma_length": 100
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20,
        60
      ],
      "status": "registered",
      "note": "NOT COMPUTED. It needs a point-in-time announcement date for every result between 2011 and 2026, stamped by filing date rather than period end. The daily bhavcopy carries no such field and no free public archive reconstructs it back to 2011. Registered rather than dropped, and it stays here unanswered until that dataset exists."
    },
    {
      "id": "raw-open-interest-change",
      "family": "volume",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "A single session's percentage change in a stock's futures open interest, split by direction.",
      "definition": "open_interest[t] / open_interest[t-1] - 1 crosses a declared threshold",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "oi_threshold": [
          0.05,
          0.075,
          0.1,
          0.125,
          0.15
        ],
        "ma_length": [
          20,
          50,
          100,
          150,
          200
        ]
      },
      "headline_parameters": {
        "oi_threshold": 0.1,
        "ma_length": 100
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "registered",
      "note": "NOT COMPUTED. It needs the derivatives bhavcopy rather than the cash one, and a futures-eligible point-in-time universe to go with it. Registered now, at the same time as everything else, so that whatever it eventually shows was declared before it was seen."
    },
    {
      "id": "index-reconstitution-entry",
      "family": "index-events",
      "version": 1,
      "registered": "2026-09-05",
      "plain_english": "The sessions around a security being added to a broad index at a scheduled reconstitution.",
      "definition": "t = the announcement session of an index inclusion",
      "measured_from": "open[t+1]",
      "parameter_grid": {
        "days_before_effective": [
          1,
          3,
          5,
          7,
          10
        ],
        "ma_length": [
          20,
          50,
          100,
          150,
          200
        ]
      },
      "headline_parameters": {
        "days_before_effective": 5,
        "ma_length": 100
      },
      "horizons": [
        1,
        3,
        5,
        10,
        20
      ],
      "status": "registered",
      "note": "NOT COMPUTED. It needs as-of index membership back to 2011. Today's constituent list cannot answer it \u2014 using it would be the reconstitution survivorship channel the method section warns about, measured instead of controlled for."
    }
  ]
}