What we’re actually doing
Each market day before the open, our engine reads roughly 20-30 high-volume, gap-up or gap-down stocks from a scanner universe. For each, it computes a composite score across 9 components, classifies the setup into a bucket, and records the score (along with the inputs that produced it) in an immutable ledger.
The public free feed publishes the highest-scoring LONG and the highest-scoring SHORT each morning. The paid feed (opening when we hit 30 verified trading days) publishes every qualifying signal in real time.
The 9 components
4 CORE components (all required for ELITE)
- Gap quality. The true premarket gap: (today’s open − previous close) / previous close. Sourced from the live equities streamer’s OPENPRICE field. We refuse to compute gap from stale closing-price data because it produces fake gaps (we found this bug and quarantined the offending data; see the audit doc).
- ATR expansion. Whether average true range is widening — the underlying volatility regime that lets gap continuations actually move.
- VWAP structure. Price location relative to the pre-market pivot. A 5% gap that opens far above its VWAP behaves very differently from one that fades back to it.
- Regime alignment. Macro tape: trend-up, trend-down, breakout, breakdown, vol-crush, vol-expansion. A LONG signal in a TREND_DOWN regime gets penalized.
5 ENHANCER components (boost confidence; absence does NOT lower score)
- Relative volume. Today’s volume vs. 20-day average, normalized by time-of-day fraction.
- Options flow alignment. Real-time flow from our flow engine; block trades, sweeps, aggressive prints — matched against the gap direction.
- Locate / short pressure. Hard-to-borrow status + locate fees + utilization — the squeeze fuel for shorts.
- Catalyst presence. News flag (earnings, FDA, macro print) tied to the symbol.
- Historical performance. Rolling win-rate of similar setups (gap-size bucket × direction × regime).
What “data-aware” means
Most signal systems penalize missing data. Ours doesn’t.
Missing components are excluded from the score normalization, not stuffed with a neutral fill value. A signal with 4 CORE components present and scoring high gets a high score — it doesn’t get artificially dragged down because the catalyst-news flag is missing.
Instead, we publish a separate data coverage percentage and a score confidence figure alongside every signal. You see exactly how much data went into the score, so you can decide whether to take it.
This was a meaningful change from how our system used to work; we documented the diff publicly in the methodology log.
Buckets
Every scored signal lands in one of four buckets:
- ELITE_GAP_LONG / ELITE_GAP_SHORT. Adjusted score ≥ 75, all 4 CORE components present, data coverage ≥ 50%, R:R ≥ 1.5, no hard exclusions. These are the highest-conviction picks.
- WATCHLIST. Strong score but missing one or more requirements above. Often these are pre-9:30 picks using PREMARKET_LAST proxy data; they upgrade to ELITE if the open confirms the gap.
- AVOID. Below the action threshold or has a hard exclusion (macro lockout, stale data, etc.). We don’t publish these to the free feed, but the daily summary includes the aggregate count + reason for transparency.
- INSUFFICIENT_DATA. Fewer than 2 of 4 CORE components present. Not scorable.
How verification works
Every signal we generate carries:
trade_id— deterministic from (date, symbol, direction).row_hash— SHA-256 of the row’s canonical JSON (excluding the hash itself).prev_hash— the previous row’srow_hash. Chains every row to every prior row.
Each row is committed to an append-only ledger file (signal_ledger.jsonl) and never modified after writing. Outcomes attach to signals via a separate, also-append-only file (outcome_ledger.jsonl) at least 60 minutes after the signal was committed — making lookahead computationally infeasible.
At 4:01 PM ET each market day, we compute the Merkle root of that day’s ledger rows and commit one line to a public GitHub repository, plus an OpenTimestamps proof anchored on the Bitcoin blockchain.
You can verify any claim we make about our track record yourself:
git clone https://github.com/eggheadengineer/gammapulse-public-roots cd gammapulse-public-roots ./verify.sh 2026-06-22 # any date
The script returns OK if our published root matches the recomputed root from the day’s details file. MISMATCH means we (or someone) modified the underlying data after publication. That would be the alarm condition. The chain breaks; we can’t hide it.
When the methodology changes
Each ledger row carries an engine_version and methodology_version tag. When we change how scoring works, the version bumps. Old rows keep their original scoring — we never re-score historical signals.
Every methodology change is announced publicly in our Discord #methodology-notes channel with: the previous version, the new version, what changed, why it changed, and the expected impact on signals.
The most recent change (2026-06-18) replaced the NEUTRAL-fill scoring with the data-aware scoring described above. The diff is in the public Git history.
What this isn’t
- It is not a stock recommendation. We score setups; you decide what to do.
- It is not a guarantee. Past performance does not predict future returns. The point of publishing every loss is to keep that fact in front of you.
- It is not personalized. The same signal goes to every subscriber at the same time. We don’t adjust for your account size, risk tolerance, or situation.
- It is not advice. We are publishers, not investment advisers. We never tell you to take a specific trade.