The system behind the trades

How Wave Works

Wave is an AI-driven paper-trading system on a single $100K bankroll. Every number below is sourced from the live database at render time — no marketing copy, no hand-waving.

Last updated: 2026-06-20
01

What Wave Is

An AI bot paper-trading crypto on one $100K bankroll. Public, observable, killswitched end-to-end.

Wave is a 24/7 scoring engine that watches the top ~50 crypto perp pairs by volume, scores each candidate across ~8 components, then opens paper trades when the score clears both a regime gate and an execution gate. The trades are real-time against real Binance prices, but the money is paper — no capital deployed until the system proves a 90-day positive edge over BTC buy-and-hold.

Single bankroll, not two. Longs, shorts, and the moonbag accumulation sleeve all share one $100K pool (Spec 2589 architecture). Anything that talks about "$200K combined" is a bug — the integrity audit catches that string in Telegram and report files automatically.

Right now (live from lib/crypto/equity.js):

  • Equity: $96415.89 (-3.58% MTM / 0.91% realized)
  • Closed trades all-time: 219122 in the v3 cohort (post-rebuild)
  • Open positions: 1+ longs · 0 shorts (see /wave for live counts)
  • Cash available: $50906 · Invested: $50000 (50% deployed)
02

Scoring Engine

8 components feed total_score. Each has a status — live, degraded, partial, or disabled. The badges below pull from the same DB keys the /wave dashboard reads.

Pillar status — live from <pillar>_pillar_status settings keys, written by the integrity audit every 30 min:

LIVE
Chart
Multi-TF technicals, patterns, bearish setups
LIVE
News
RSS sentiment per symbol
LIVE
Narrative
Sector rotation tailwind
LIVE
On-Chain
DefiLlama TVL momentum (DeFi tokens only)
LIVE
Smart Money
Creators + whale signals — currently disabled
LIVE
Narrative Alert
Scout v2 alerts — currently disabled
LIVE
Derivatives
Funding, OI, perpetual flows

Per-component breakdown:

L1live
Chart score (0-3)
Multi-TF TA: RSI, MACD, EMA stack, BBs, ADX, ATR, Ichimoku, Keltner, TTM Squeeze on 1h/4h/1d alignment plus pattern detection
L2degraded
News score (0-3)
RSS feeds + sentiment. Coverage gap on Binance long-tail perps — symbols not in mainstream feeds score zero by absence
L3live
Narrative score (0-2)
Sector rotation tailwind — AI, DeFi, RWA, DePIN, gaming, L1s, modular
L4partial
On-chain score (0-1.5)
DefiLlama TVL momentum. N/A (null) for non-DeFi symbols — TVL coverage is ~57 protocol slugs; recent signals overlap only ~6
L5live
Derivatives score (0-2)
Binance funding rate APR + OI delta. Calibrated for bear-trend setups (funding ≥50% APR only 0.4% of universe in flat markets — fires when it matters)
L6live
Bearish patterns (0-3)
NEW (Spec 2599 Phase 2): double top, head & shoulders, bear flag, rising wedge, bearish structure, descending triangle, Wyckoff upthrust
D1disabled
Smart Money score (0-2)
Disabled May 17 — variance 0.07 over 14 days (creators-x + creators-youtube data feeds starved). Re-enable via smart_money_enabled=1; under review. Creators and whale-based, not the same as the new Nansen netflow capture layer (C1)
D2retired
Narrative Alert (0-2)
Retired May 17 — variance 0.07 over 14 days, Scout v2 alerts pipeline not firing. Detector parked (no wired killswitch); would need a rebuilt alerts feed before re-scoring
C1capture-only
Smart Money Netflow (Nansen) (weight 0)
Nansen smart-money net inflows and outflows per token (ETH, SOL, Base), captured every 3h. Weight 0 by design, recording predictive value vs 24h and 72h outcomes before it influences any trade. The first review window has passed; it remains weight 0. Distinct from the disabled creators-based D1
C2capture-only
altFINS Signals (weight 0)
altFINS technical signals feed: a 7-day net bullish or bearish read per token, captured every 4h into crypto_external_signals. Weight 0 by design, recording predictive value against forward outcomes before it influences any trade. Distinct, third-party TA confirmation alongside our own multi-timeframe chart engine.
C3capture-only
LunarCrush Sentiment (weight 0)
LunarCrush social sentiment (0 to 100) with deep mid-cap coverage, captured every 4h into crypto_external_signals. Directly targets the news blind spot, since headline news skews large-cap while Wave trades mid-cap movers. Weight 0, measure first.
C4live
Dense 1-minute OHLCV (Binance) (data foundation)
NEW (June 11): true 1-minute open/high/low/close bars across the ~67-symbol universe (Binance spot, perp fallback), ~3.2M bars seeded back to May 7, into crypto_ohlcv_1m. Replaces the old 4-hour close-only history so backtests and stop replays see the actual intra-bar high/low instead of being blind between marks. Powers stop-aware replay and real volatility estimation.
C5capture-only
Open Interest + Implied Vol (Deribit DVOL) (weight 0)
NEW (June 11): Binance perp open interest + Deribit DVOL implied-vol index into crypto_open_interest / crypto_implied_vol. Leading regime signals (OI flush, IV draining off a spike) to lead the 14-day-return regime gate that lagged the June bottom by ~10 days.
C6capture-only
Cross-exchange Derivatives (Coinglass) (weight 0)
NEW (June 11): aggregated open interest, OI-weighted funding, and long/short account ratio across ALL exchanges (not just Binance) into crypto_coinglass_derivs. Cleaner regime + squeeze read than any single venue.
C7capture-only
On-chain Exchange Flows (CryptoQuant) (weight 0)
NEW (June 11): BTC + ETH exchange netflow, daily, into crypto_onchain_flows. Negative netflow = coins leaving exchanges = accumulation. The one long-side component with measured forward edge so far. Weight 0, measure first.

Strip-dead-features setting. When score_strip_dead_features=1 (current state), the Smart Money and Narrative Alert contributions are forced to zero in total_score regardless of what the per-symbol scorer returned. Re-enable cleanly by flipping their individual *_enabled flags AND the strip-dead setting back to 0.

onchain_score is null for non-DeFi tokens as of Spec 2599 Phase 1#3 — distinguishes "no DefiLlama mapping" (N/A) from "mapped but scored 0" (real signal). Eliminates phantom-zero dilution in total_score.

03

Measurement & Self-Audit Layer

How Wave checks its own work: measure first, weight later, no curve-fitting.

Several capture-only systems exist purely to tell us whether Wave is making the right calls. None of them touch a live score. They record what happened, what we skipped, and what we are watching, so a decision to add weight later is backed by data instead of a hunch.

Rejected-Candidate Ledger
Every blocked candidate is recorded with the exact reason it was rejected and what the coin did next over 24h and 72h. If our filters are turning away eventual winners, the ledger shows it. Table: crypto_rejected_candidates.
Missed-Rally Detector
Flags when an established major ran without us, recording the rally size and the reason we stayed flat or short. It targets systematic blind spots rather than one-off misses. Scans every 4h. Table: crypto_missed_rallies.
Smart-Money Capture (Nansen)
Smart-money net flows per token are recorded at weight 0, validating predictive value against real outcomes before the signal earns any trust. Captured every 3h. Tokens outside our trade universe are now priced by contract address via DexScreener at capture time, so forward-return evaluation works. Table: crypto_smartmoney_flows.
altFINS Signals
Third-party technical signals captured at weight 0 every 4h, a 7-day net bullish or bearish read per token, validated against real outcomes before it earns any trust. Table: crypto_external_signals (source altfins).
LunarCrush Sentiment
Social sentiment 0 to 100 with deep mid-cap coverage, captured at weight 0 every 4h. Closes the news blind spot since mainstream news skews large-cap while Wave trades mid-cap movers. Table: crypto_external_signals (source lunarcrush).

The discipline is deliberate: a new signal records its read with zero influence, we compare it against what actually happened, and only then do we consider giving it weight. The first review window has passed and every captured source still sits at weight 0 — none has yet earned a live weight.

04

Two Execution Gates

Score-emit threshold + regime-execution floor. Decoupled per side (Spec 2598).

Every candidate passes through two independent gates. A signal can be EMITTED (score ≥ threshold) but still BLOCKED from execution by the regime floor. The two were coupled until Spec 2598 — shorts now have their own execution floor so a chart-only short setup can fire in flat tape without lowering the long-side defensive floor.

risk_on
Sizing0.85×
Score floor4
BTC > 50d EMA AND 14d return > +5%. Sizing dampened from 1.0× pending n≥30 v3 data
neutral
Sizing0.7×
Score floor5 longs · 4 shorts
Default. Long-side keeps 5-floor; short-side decoupled to 4 (Spec 2598 — chart-only shorts can fire in sideways tape)
caution
Sizing0.5×
Score floor6
BTC ≤ 50d EMA OR 14d ≤ -5%
risk_off
Sizing0× longs · short-only
Score floor7
14d return ≤ -10%. New longs blocked; shorts continue

Gate 1 — score-emit threshold: shorts_min_score_after_3_trades=3 (default 4 pre-shorts-pilot). Anything below this never even enters as a signal candidate.

Gate 2 — regime execution floor: long-side reads min_score_neutral=5, short-side reads shorts_min_execution_score=4 (Spec 2598 decoupling). Both havestrict_floor_enforcement kill-switch.

Plus per-trade vetoes: cluster cap, day-of-week filter, funding-APR veto, onchain-zero veto, gap-through guard. Any one of these short-circuits an otherwise-qualifying signal.

05

Risk Management

Killswitched at every level. Deployment cap, sizing tiers, stops, ratchets.

Every rule below has a settings-key killswitch. Flipping it to 0 takes effect on the next scan tick — no redeploy.

Position sizingshorts_position_size_pct / tier × conviction × regime
Per-trade ≤5% of the unified $100K bankroll. Conviction multiplier ×0.5 for score-4 fallback entries (Spec 2585).
Deployment capmax_deployed_capital_pct=0.80
Total invested ≤ 80% of $100K — applies to combined longs + shorts (Spec 2589 unified pool). NOT 200K.
Slot capsmax_open_trades_hard_ceiling / shorts_max_open_trades_hard_ceiling
Long ceiling 40, short ceiling 25. Slot-count, not dollar-based.
ATR stopsatr_stops_enabled / atr_tp1_mult / atr_tp2_mult
TP1 at 1× ATR, TP2 at 2× ATR. Hard stop at entry × (1 - atr_stop_pct). Gap-through guard closes if breach >0.5× stop distance.
Break-even ratchetalways-on (Spec 2550)
Once TP2 hits, stop ratchets to entry — never gives back a winning trade.
Near-stop alertsnear_stop_alerts_enabled
Every 15min walks open positions; posts to the Silas Crypto group when any trade is within 1% of stop with 4h dedup.
Funding APR veto (longs)long_funding_veto_enabled, range -50% to 0%
Blocks longs when funding ∈ [-50%, 0%] — consensus shorts already positioned (Spec 2571). Score ≥8 overrides.
Onchain=0 veto (longs)long_onchain_zero_veto_enabled
Blocks longs when symbol IS in DefiLlama mapping AND TVL momentum is zero (Spec 2572). Now skipped for non-DeFi symbols (null, not 0).
Day-of-week filterday_of_week_filter_enabled
Blocks Sun all day + Sat afternoon entries. Spec 2573 audit: weekday 48% WR / +$818 vs weekend 20% WR / -$1,084 over 48 trades.
Cluster capcorrelation_cap_enabled, max_per_cluster=3
Max 3 trades per correlation cluster (AI, L1, etc) to prevent pile-on.
06

Audit Visibility

37 checks every 30 min. equity.js locked as the only P&L source. Pre-commit hook enforces it.

The system catches its own bugs before David eyeballs them. Each audit run cross-checks every live API endpoint, every snapshot table, every score-feature variance against lib/crypto/equity.js(the canonical truth). Dedup state machine prevents repeat alerts inside a 4-hour cooldown.

1. Number consistency
7 checks
Cross-checks /api/wave/stats, /shorts/stats, /winning-pulse, /combined/stats against equity.js — drift > $1 or > 0.05pp = FAIL
2. Architectural premise
4 checks
No "$200K" / "200K combined" in Telegram + audit files; no settings.*bankroll_usd other than the canonical bankroll_usd; unified_bankroll_v2 readable
3. Data plausibility
7 checks
Benchmark drift vs equity.js; day-over-day equity moves; deployment cap; position concentration; signal freshness
4. Data correctness
8 checks
6 score-feature variance checks (DEAD/DEGRADED/LIVE pillar status writeback); display-pair guard (realized + mtm both present)
5. Cron liveness
2 checks
consecutive_failures ≥ 3; stale crons past 2× expected interval (Tier-1 auto-fix: pm2 restart with 3/24h cooldown)
6. Entry cadence
6 checks
Per-side daily entries vs 7d avg (long + short); math identities to the cent (STARTING + closed + open == mtmEquity)
7. Scanner output yield
2 checks
wave-scan + wave-shorts-scan signal-to-candidate ratio; < 0.05% threshold flags starvation

Run-history table: every wave/crypto cron writes a row to crypto_cron_runs via the shared tripwire helper. Status, duration, output_summary_json, error_message. 30-day retention. Replaces pm2-log-grepping with a queryable history.

P&L canonical source rule (Spec 2599 Phase 8): every $/% number that gets shown or spoken to David comes from lib/crypto/equity.js. scripts/check-pnl-canonical.sh +.git/hooks/pre-commit fail any commit that introduces inline equity math outside the canonical writers.

Tier-1 auto-fix: snapshot drift > $1K vs equity.js auto-repairs the row; stale crons with last_success_at > 2×expected_interval auto-restart via pm2. Cooldown 3/24h per fix-type, 10/24h global cap. Killswitch integrity_audit_autofix_enabled.

07

Cohorts & Tuning

Pre-rebuild trades stay in the DB but don't feed weight tuning. v3 cohort starts now.

crypto_paper_trades.cohort column added by Spec 2599 Phase 9. All trades before the rebuild ship are tagged pre_rebuild; new trades opened by either scanner now writecohort='v3'. This is NOT data deletion — pre-rebuild trades are still queried for all-time lifetime numbers, but they don't feed Phase 2 weight tuning.

Phase 2 trigger: when cohort='v3' AND status='closed' count reaches n ≥ 30 AND every scoring feature has been alive for the full window, the daily audit auto-proposes re-weights via crypto_audit_proposals (Tier 2 — Silas review, no auto-apply).

Recap audio explicitly distinguishes the two scopes: "Lifetime, all trades: -$1939 over 71 trades" (canonical, equity.js) AND "V3-era cohort: -$X over 122 trades" (subset, labeled). No more pre-rebuild numbers wearing the word "Lifetime."

Current v3 cohort count: 122 closed trades (target n ≥ 30 to unlock Phase 2 tuning).

08

Daily Rhythm

When each cron runs and what it produces.

06:00 PT
wave-daily-audit
Full performance audit + Tier-1 auto-fix layer. Markdown report + MP3 transcript. Telegram digest currently muted per operator flag.
07:00 PT
wave-morning-recap
Friendly check-in audio.
08:00 PT
wave-morning-health
Single one-line DM: equity, pillar status, cron health, audit summary. Replaces noisy state-change spam.
17:00 PT
crypto-daily-recap
Evening recap MP3 + Telegram audio. All numbers sourced from equity.js per Spec 2597.
every 15min
wave-scan
Long-side scoring on top-50 by volume. Output → crypto_signals.
every 15min
wave-shorts-scan
Short-side scoring with bearish patterns. Output → crypto_signals + paper shorts.
every 15min
wave-near-stop-alerts
Walks open positions; posts to the Silas Crypto group when any trade is within 1% of stop.
every 30min
wave-system-integrity-audit
37 checks across 7 categories. Auto-fix benchmark drift + stale-cron restart. Pillar status writeback.
every 4h
wave-defillama-ingest
DefiLlama TVL ingestion across ~57 mapped protocol slugs.

Telegram cadence: morning health DM at 08:00 PT is the canonical "is Wave OK?" digest. Integrity audit Telegram currently muted per operator flag (integrity_audit_telegram_enabled=0) — runs silently, writes reports, alerts when flipped back on. Audit MP3s land at /recaps/<date>-audit.mp3 regardless.

09

Safety Rails

Killswitched rails layered on top of the scoring engine. Each is independent; flipping its DB key reverts to pre-rail behavior.

The original rebuild on 2026-05-17 added 13 rails over one day. Specs #2826 and #2827 layered another ten on top through May 21 / May 22 — portfolio drawdown breaker, BTC flash breaker, counterfactual shadow replay, wiring drift audit, BTC tape filter, counter-trend guard, daily loss cap, funding entry-gate, news weight set to zero, and the inverse-side shadow loop. Each row shows what it does, why it exists (with backing data where the case was empirical), and the exact DB key to flip if a rail needs to be disabled. Cohort marking is active throughout — pre-rebuild and v3 trades are tagged separately so post-rebuild metrics don't get muddied by legacy data.

One $100K bankroll
What: Wave is one bot with one $100K balance. Longs and shorts share the pool.
Why: Spec 2589 eliminated the phantom $200K combined framing; David said "we put both longs and shorts into one 100K, not 200."
bankroll_usd=100000, unified_bankroll_v2=1
Side-specific execution floors
What: Longs require score ≥ 5; shorts require score ≥ 4.
Why: Empirical edge differs by side. Decoupled per Spec 2598.
min_score_neutral=5, shorts_min_execution_score=4 (now 5 post-evening fixes)
Conviction step bands
What: Position size scales with score in steps, not a continuous curve. score ≥ 7 → 1.5×; 5–6 → 1.0×; < 5 → 0.5×.
Why: The old (score/4)^1.5 curve overdosed score-5 entries at 1.4× and was inconsistent across long/short. Step bands match David’s stated risk shape.
conviction_sizing_enabled=1, conviction_mult_hi=1.5, conviction_mult_mid=1.0, conviction_mult_lo=0.5
Vol-adaptive sizing
What: Baseline 4% ATR. Low-vol setups size up to 1.5×, high-vol size down to 0.5×. Clamped [0.5×, 1.5×]. Both scanners.
Why: A 2% ATR and 8% ATR setup at the same conviction carry very different real risk; the base chain previously treated them identically.
vol_adaptive_sizing_enabled=1, vol_adaptive_baseline_atr=0.04
48h symbol cooldown
What: Side-aware. After any close on the same side at worse than -2%, that symbol cannot re-enter on that side for 48 hours.
Why: Blocks revenge re-entries. Backing: ZEC took 3 long losses (-$491), AI took 4 (-$159), both within tight windows.
symbol_cooldown_enabled=1, symbol_cooldown_hours_after_loss=48, symbol_cooldown_min_loss_pct=-2.0
Long tier filter (dolphin + shark only)
What: Longs only enter on dolphin or shark tier coins.
Why: Minnow + whale tiers lost -$635 across 11 trades; dolphin + shark were net positive.
long_tier_filter_enabled=1, long_allowed_tiers=dolphin,shark
Short exposure cap 40%
What: Blocks new short entries when total short side would exceed 40% of bankroll. Warns at 35%. Existing positions grandfathered.
Why: Today’s book is 99% short at entry — one BTC squeeze and the pool is gone. Prevents future concentration.
short_exposure_cap_enabled=1, short_exposure_cap_pct=40, short_exposure_warn_pct=35
Cluster-$ correlation cap 25%
What: Blocks new entries that would push any correlation cluster (BTC-major, ETH-DeFi, SOL-eco, etc.) past 25% of bankroll.
Why: Layers a $-based cap on top of the existing count cap. Catches concentration even when no single cluster has 3 positions.
correlation_cap_enabled=1, correlation_max_cluster_pct=0.25
24h no-progress flush
What: If a trade hasn’t made +1.5% progress toward TP1 within 24 hours, force-exit at current price instead of tightening and bleeding.
Why: The 24–48h hold band was 17.6% WR / -$1,593 across 17 trades — the biggest single bleed on the long book. First production save: TRUMP flushed at -3.3% at 16:45 PT May 17.
early_no_progress_flush_enabled=1, early_no_progress_min_pct=1.5
Late hold tighten
What: One-way ratchet on longs older than 60 hours: tightens stop, never loosens.
Why: Spec 61 #3 evidence: 1–3 day holds had 33% WR and lost -$722 net. The ratchet prevents the late-bleed pattern.
late_hold_tighten_enabled=1, late_hold_tighten_h60_pct=6.0, h72_pct=3.0, h84_pct=2.0
Regime sizing
What: BTC 50d EMA + 14d return classifies risk_on / neutral / caution / risk_off. Sizing multiplies by 0.85× / 0.5× / 0.4× / 0.25×.
Why: Macro context modulates how aggressive position sizing should be. Under review May 24 — risk_on H2 produced 15.4% WR / -$1,031.
regime_enabled=1; per-regime overrides: neutral_size_multiplier=0.5, caution_size_multiplier=0.4, risk_off_size_multiplier=0.25
News-spike escalation
What: Score-(floor-1) signals with news_score=3 AND most-recent matched news ≤ 30 min old can enter at the lowered threshold.
Why: Catches the +7.97% news-driven win bucket (TRUMP, BTC, ETH on news=3). Without timing, the system was treating fresh and stale news identically.
news_spike_escalation_enabled=1, news_spike_window_min=30
Real-money pre-flight guard
What: Settings API physically refuses real_money_enabled=1 until a 10-item checklist passes. Currently paper-only.
Why: Eliminates the failure mode where a stray dashboard flip, cron, or operator could accidentally turn live trading on. The checklist itself is the real-money project.
real_money_pre_flight_passed=0 (must reach 1 before real_money_enabled can flip)
Portfolio drawdown breaker
What: Halts ALL new entries when MTM equity drops more than drawdown_breaker_pct (default 12%) below the rolling 14-day peak. Releases automatically when equity recovers above the threshold.
Why: Caps total damage during a regime shift before per-trade stops can fully express. Inspired by the prop-trading "daily drawdown" rule that pulls the operator off the desk.
drawdown_breaker_enabled=1, drawdown_breaker_pct=0.12
BTC flash breaker
What: Blocks new long entries when BTC drops ≥4% in 4 hours OR ≥8% in 24 hours. Auto-releases when the move cools.
Why: On BTC flash crashes the whole alt complex moves together. Pausing longs for the duration is cheaper than opening into the cascade.
btc_flash_breaker_enabled=1, btc_4h_drop_pct=-0.04, btc_24h_drop_pct=-0.08
Counterfactual shadow replay
What: Every scan window also replays the trade the would-have-been opposite ruleset would have produced. Logged to crypto_shadow_trades for offline comparison; never affects live PnL.
Why: Tells us, with real data, whether our entry edge actually beats the simplest counterfactual (inverse / loose / tight / trail-only / scalp / long-hold variants).
shadow_replay_enabled=1, 6 variants live (live/loose/tight/longhold/trailonly/scalp)
Wiring drift audit (9_settings_hygiene)
What: Audit category 9 walks every key in crypto_wave_settings and FAILs if it has no consumer in code AND no unwired_legacy tag. Forces every new setting to be either wired or explicitly deferred.
Why: Spec 2822 wiring sweep found 8 of 13 supposedly-active killswitches were no-ops. The drift detector prevents that from happening again.
wiring_status column on crypto_wave_settings (consumer | unwired_legacy | NULL)
BTC tape + range filter
What: Blocks long entries when BTC is making a fresh 24h low (entry percentile <20). Blocks short entries when BTC is making a fresh 24h high (>80). Both sides record the entry percentile at fill.
Why: Diagnostic on 116 closed trades showed entries clustered near unfavorable extremes — fading the dominant tape direction. Stopping that bleed alone closes ~30% of the cumulative loss.
tape_filter_enabled=1, range_filter_min_pct=20, range_filter_max_pct=80
Counter-trend guard
What: Refuses long entries while BTC 4h return is < -2% (no catching falling knives). Refuses short entries while BTC 4h return is > +2%.
Why: On the 3-day-hold cohort that lost -$5,169, 62% of entries were against the prevailing BTC 4h direction. This rail explicitly says "do not fight the tape".
counter_trend_guard_enabled=1, counter_trend_btc_4h_threshold=0.02
Daily loss cap
What: Walks the day's realized PnL each scan; if cumulative loss exceeds daily_loss_cap_usd (default $2,000) the scanner stops opening new positions until 00:00 PT.
Why: On three of the worst days in history a single bad regime printed -$1,800 to -$2,400. The cap turns "ride it out" into "stop digging" automatically.
daily_loss_cap_enabled=1, daily_loss_cap_usd=2000
Funding entry-gate
What: Records funding APR at entry on every paper trade. Blocks short entries when funding APR is already below -funding_entry_gate_apr_short (default 15%) — the move has already paid out.
Why: Highest-loss shorts in history were entered AFTER funding had already gone deeply negative. Treats funding as a leading indicator, not just a filter.
funding_entry_gate_enabled=1, funding_entry_gate_apr_short=15
News weight set to zero
What: news_weight forced to 0 in the scoring chain — news no longer contributes to total_score. Pillar still tracked + logged for forensics.
Why: Post-mortem on 24h-hold losses showed news_score=3 entries lost -$1,107 vs +$48 for news_score=0 trades. The signal was correlated with retail FOMO tops.
news_weight=0 (was 1.5)
Inverse-side shadow loop
What: For every live trade the system opens, it also writes a shadow trade in the OPPOSITE direction with the same sizing + rules. Settles independently in crypto_shadow_trades.
Why: If the inverse cohort beats live by a margin > the round-trip costs, that's the strongest possible signal that entry direction (not exit rules) is the leak.
inverse_shadow_enabled=1
Chop killswitch (proactive)
What: Blocks ALL new entries (long + short) when regime is caution/risk_off AND 14d realized P&L < -$500 AND last 10 closed trades WR < 40%. All three must hold.
Why: May 24 forensic: the inverse-shadow cohort lost 96.5% of trades in the recent bleed period. That's empirical proof the market was paying nobody. The right response is to stop trading, not to switch sides. Proactive replacement for the reactive stop-bleed pattern.
chop_killswitch_enabled=1, chop_killswitch_regimes=caution,risk_off, chop_killswitch_drawdown_usd=-500, chop_killswitch_min_wr_pct=40
Per-symbol 7d loss cool-down
What: After any losing exit on (symbol, side), block new (symbol, side) entries for 7 days. Distinct from the 48h cool-down above (this catches single-loss re-fires within a week).
Why: Recent bleed dominated by re-traded losers: ZEC ×3 = -$491, SIREN ×3 = -$542, BNB ×2 = -$423. The 48h cool-down only catches -2%+ losses; this catches everything.
symbol_loss_cooldown_enabled=1, symbol_loss_cooldown_days=7
Drawdown-aware sizing
What: When trailing 14d realized P&L < -$500, multiply final position size by 0.5×. Layered on top of all other sizing modifiers.
Why: P4 bleed period had avg position size $3,639 vs P1 era $2,132. Bot was sizing UP into a -$2,803 bleed - classic human discipline failure that a bot should not replicate.
drawdown_sizing_enabled=1, drawdown_sizing_threshold_usd=-500, drawdown_sizing_mult=0.5
48h chop-zone close
What: Force-close longs that have been held >=48 hours and are still sitting in the +/- 2% P&L band.
Why: The 24-72h hold bucket is historically the killer (5W/26L, -$3,929). Trades that survive past 24h either close fast with momentum or ride the trail past 72h. The middle zone bleeds.
chop_zone_close_enabled=1, chop_zone_close_hours=48, chop_zone_close_band_pct=2
Ladder-add for high-conviction repeats
What: When a fresh signal scores >= 7 on a symbol we already hold AND the existing position is in profit, allow a SECOND tranche. Cap at 2 tranches per symbol.
Why: The 1-position-per-symbol cap blocked 66 entries in 14d. Of 6 high-score (>=6) signals we ignored because we already held that symbol, 4 of 5 (where data exists) would have won. Also positions the bot to pyramid into winners in bull markets.
ladder_add_enabled=1, ladder_add_min_score=7, ladder_add_max_tranches=2, ladder_add_require_profit=1
Regime-adaptive trail
What: Trail stop distance and arming threshold are now per-regime. risk_on: loose (10% trail, 8% arm) so winners can run. neutral: medium (5%/5%, the prior flat default). caution/risk_off: tight (3%/3%) so chop doesn't eat slow trades. Falls back to flat settings if a per-regime key is unset.
Why: Single-config trail was killing trending winners in bull (NEAR went +61% after we exited at +4.8% on May 6) and bleeding slow trades in chop. One trail can't serve both regimes.
trail_stop_pct_<regime>, trail_activate_at_pct_<regime>; e.g. trail_stop_pct_risk_on=0.10
Regime-adaptive leverage (bull-mode multiplier)
What: Position size multiplier driven by regime + recent WR. risk_on + WR >= 50%: 2.0×. risk_on + WR < 50%: 1.5×. neutral/caution/risk_off: 1.0×. Hard safety interlock: leverage stays at 1.0× whenever 14d realized P&L is negative - cannot amplify a losing book, period. Layered ON TOP of drawdown sizing (only activates when drawdown sizing is at 1.0×).
Why: For the bot to 2× buy-and-hold in a real bull, position sizes have to scale up when the tape is clear and we are winning. The interlock prevents the obvious failure mode (leveraging into a drawdown).
regime_leverage_enabled=1, regime_leverage_mult_risk_on=2.0, regime_leverage_mult_risk_on_cautious=1.5, regime_leverage_risk_on_wr_floor=50
Liq fade threshold $100k + 12h hold
What: wave-liquidation-fade now triggers on any (symbol, hour) cluster >= $100,000 in Bybit liquidations and holds shadow positions for up to 12 hours.
Why: May 24 backtest of 14d cascades at $100k threshold: 7 wins / 1 loss (88% WR) at 12h hold, +$362 hypothetical P&L at $1,500 per fade. Old threshold $500k caught only 1 of 8 winning setups; old 4h hold cut before reversion peaked.
liquidation_fade_threshold_usd=100000 (was 500000), liquidation_fade_max_hold_h=12 (was 4)
Shadow zero-hold tp_single_8 guard
What: Shadow trades require a minimum 60-second hold before any TP/stop fires. Without this, edge-case entries where the entry candle already contains the TP price registered as instant +8% wins.
Why: May 24 audit found 27 ghost rows (BANANAS31/ICP/TON) closing in <1 second at the entry candle's TP, inflating scalp/long v2 shadow P&L by +216% - pure noise contaminating promotion analytics.
60-second min hold hardcoded in crons/lib/shadow-trades.js
Symmetric shadow-fill slippage
What: The live shadow monitor (processShadowTrades) now applies exit slippage to EVERY fill via the canonical applySlippage() helper - take-profits pay the same realistic per-fill cost stops already paid. Unpriceable max-hold safety-closes record pnl_pct=NULL (honest unknown) instead of a fabricated 0%.
Why: May 29 review: the simulator booked TPs at the clean trigger price with zero slippage while stops gapped through realistically, rigging the model to flatter any take-profit-heavy variant (this is what made scalp look like a fake winner). NULL keeps fake break-evens out of WR/PnL/Sharpe.
slippage_model_enabled=1 (set 0 for exact prior fill math), slippage_atr_fraction_exit=0.25
Shadow-monitor liveness probe
What: The shadow monitor now runs on every scan even when the live long book is empty, and voids rows overdue past max_hold + 6h as monitor_gap_void (NULL pnl). wave-health-monitor DMs David when overdue-open shadows exceed the threshold - a market-independent signal that the monitor has stalled.
Why: May 26-29: a 0-open-longs early return silently skipped the shadow monitor for 3 days (943 rows froze open). pm2, the scan health check, and the numbers audit all stayed green because they watch the scan wrapper and number consistency, not shadow-output freshness.
shadow_monitor_gap_grace_h=6, shadow_monitor_stale_alert_count=50

Watchdog retune (May 31): liveness, near-miss, and dead-scoring monitoring. A quiet day no longer triggers false alarms now that the score floor is 6; alerts fire only on a stalled scanner or genuinely dead scoring.

10

Pattern Detection

Bullish + bearish chart-pattern detectors. Aggregator fires on the highest-confidence detection per scan; score folds into total_score via the per-side killswitches.

All detectors live in lib/crypto/patterns.js. The aggregators (detectBullishPatterns, detectBearishPatterns) return the top confidence match plus a 0–3 score that scales into total_score. Killswitches: bullish_pattern_enabled=1, bearish_pattern_enabled=1.

Bullish (longs) — 8 detectors
  • Double bottom
  • Inverse head & shoulders
  • Bull flag
  • Cup & handle
  • Descending wedge
  • Ascending triangle
  • Symmetric triangle (bullish)
  • Wyckoff spring
Bearish (shorts) — 7 detectors
  • Double top
  • Head & shoulders
  • Bear flag
  • Rising wedge
  • Bearish structure (LH/LL)
  • Descending triangle
  • Wyckoff upthrust

Cohort marking is active — pre-rebuild and v3 trades are tracked separately so the detectors' post-rebuild contribution can be measured without legacy contamination.

11

Strategy Suite (Spec #2828, May 22)

New data feeds, shadow strategies, and sizing helpers shipped as one batch. Most ship in shadow or default-OFF until 7 days of forward data prove the edge.

The diagnostic on the first 116 trades showed that exits work (trail stop is +$6,985) but the entry direction is the leak. The May 22 batch attacks both sides of that problem: new data feeds (BTC dominance, liquidations, funding extremes, event calendar) give the scanners context they didn't have before; new shadow strategies (liquidation fade, Kelly sizing, bankroll compounding, slippage-modelled backtest, pre-listing watchlist) run alongside the live system without affecting real PnL until the data says they earned the upgrade.

Data feeds (always on)

BTC dominance + total market cap· hourly · live
Pulls BTC.D, ETH.D, and total crypto market cap from CoinGecko /global into crypto_market_metrics. Feeds the regime-aware filters and the morning health DM.
crypto-market-metrics-snapshot cron, btc_dominance_filter_enabled=1
Liquidation feed· realtime · live
Long-running pm2 process subscribed to Bybit v5 allLiquidation WS across 30 perp pairs. One row per real liquidation event into crypto_liquidations. (Binance Futures WS is geo-blocked from this VPS even though their REST works — Bybit is the working alternative.)
crypto-liquidation-ws pm2 app, LIQ_WS_MIN_USD=1000 floor
Funding-carry scout· every 30 min · live (digest only)
Detects symbols with |funding APR| ≥ funding_carry_min_apr (15%) and logs them. Daily Telegram digest at 14:00 UTC lists current carry opportunities.
wave-funding-carry-scout cron, funding_carry_scout_enabled=1, funding_carry_min_apr=15
Token-unlock calendar· daily · live
Daily fetch of upcoming token-unlock cliffs from DeFiLlama's free emissions datasets. Intersects our tradeable universe (coingecko_id) with DeFiLlama protocol slugs, sums the market-impacting tokens per unlock date (excludes non-circulating moves), and writes pct-of-supply into crypto_unlock_warnings. Replaced the old token.unlocks.app scrape, which became an un-scrapeable JS shell and had written nothing since 2026-05-19.
wave-unlock-defillama cron (14:00 UTC), unlock_feed_enabled=1, unlock_feed_horizon_days=60
Event calendar block· live, 18 events seeded · live
crypto_event_calendar seeded with 2026 FOMC meetings (6), CPI releases (9), and BTC/ETH quarterly options expiries through Dec. Every entry checks the upcoming-events window and refuses if within block_window_hours.
event_calendar_filter_enabled=1, 18 events seeded
Focus universe gate· always · off by default
When enabled, restricts entries to the curated crypto_universe_focus list (BTC, ETH, SOL, etc.). Shrinks the universe to where we have real edge.
universe_focus_enabled=0 (opt-in)

Shadow strategies + sizing helpers

Liquidation fade· shadow
Aggregates 1h liquidation $-volume per symbol+side; when it crosses the $100K threshold, opens a SHADOW trade in the OPPOSITE direction (the fade), every 5 min. Lives in crypto_shadow_trades with variant_code=liq_fade; never affects real PnL until 7d of forward data proves edge. Both sides now mark to the perp feed: short fades and (as of May 29) long fades price against crypto_short_price_cache, the same feed their entry liquidation price came from - previously long fades carried no coingecko_id and could only expire unpriced.
wave-liquidation-fade cron (*/5), liquidation_fade_enabled=1, liquidation_fade_live_enabled=0, liquidation_fade_threshold_usd=100000
Kelly Criterion sizing· off by default
Per side (now wired on BOTH longs and shorts), computes f = (WR × payoff − 1) / payoff over the last 30 closed trades and clamps to [0, kelly_max_fraction=0.25]. When ON, sizes down trades that exceed the Kelly bet; never sizes UP.
kelly_sizing_enabled=0, kelly_min_lookback_trades=30, kelly_max_fraction=0.25
Bankroll compounding· off by default
Daily at PT midnight (08:00 UTC), rolls bankroll_usd to current MTM equity. Future trade sizes scale with realized + open PnL. Logs to crypto_bankroll_compound_log.
wave-bankroll-compound cron, compound_bankroll_enabled=0
Slippage-modelled backtest· live
replayTrade() in lib/crypto/backtest-engine.js now applies entry-side slippage when ruleset.slippage.enabled. Counterfactual replay cron reads slippage_model_enabled and passes the slippage option through to every variant — replays now produce real-fill-adjusted PnL.
slippage_model_enabled=1, slippage_atr_fraction_entry=0.5, slippage_atr_fraction_exit=0.25
Funding-extreme long trigger· live
When funding APR drops to ≤ -20% (deeply negative — shorts paying longs), wave-scan treats the signal as a squeeze setup: bypasses the funding-veto AND lowers the score floor by 1 point. Symmetric to news-spike escalation.
funding_extreme_long_enabled=1, funding_extreme_long_min_apr=-20
Funding-extreme reversal (crowded-trade fade)· shadow
Every 30 min, reads Binance perp funding. Extreme positive APR (≥ +50%) means longs are paying shorts - crowded longs - so it opens a SHADOW SHORT (the fade); extreme negative APR (≤ -25%) means crowded shorts, so it opens a SHADOW LONG. Filters out stock-tokenized perps that have no coingecko id, and de-conflicts against the live book. Lives in crypto_shadow_trades with variant_code=funding_fade. Because these symbols sit outside the actively-priced spot universe, the cron marks each open position to the perp markPrice in crypto_short_price_cache every run, so held trades stay priceable after funding normalises. Never affects real PnL until 7d of forward data proves edge.
wave-funding-fade cron (*/30), funding_fade_enabled=1, funding_fade_live_enabled=0, funding_fade_short_min_apr=50, funding_fade_long_max_apr=-25
Token-unlock shorts· shadow
Hourly, reads the unlock calendar and opens a SHADOW SHORT when a tracked token has an unlock of at least unlock_short_min_pct_supply (1% of supply) within the next unlock_short_entry_lead_days (7), holding through the event - the thesis being that fresh supply hitting the market is downward pressure. De-conflicts against the live book. Like funding-fade, these symbols sit outside the active spot universe, so entries and held positions are priced and kept alive from the Binance perp markPrice in crypto_short_price_cache. variant_code=unlock_short; never affects real PnL until proven.
wave-unlock-short cron (hourly), unlock_short_enabled=1, unlock_short_live_enabled=0, unlock_short_min_pct_supply=1.0, unlock_short_entry_lead_days=7
Pre-event positioning· shadow
Hourly cron walks crypto_event_calendar for events 6-24h ahead and opens a SHADOW position per the category bias table: FOMC=short BTC, ETF/options-expiry=short the underlying, listing/hard_fork=long. Live mode killswitched until 7d of positive shadow PnL.
wave-event-positioning cron, event_positioning_enabled=1
Pre-listing front-run· shadow
Two-cron pipeline. crypto-listing-scraper pulls Coinbase RSS + Binance news + KuCoin announcements hourly into crypto_listing_watchlist. wave-listing-front-run opens a SHADOW LONG on any pending symbol it can resolve to a coingecko_id (wider stop -8%, TP +30%, 96h hold).
crypto-listing-scraper + wave-listing-front-run crons, listing_front_run_enabled=1
Funding cash-and-carry pairs· shadow
Two-cron pipeline. wave-carry-entry (every 30 min) opens paired long-spot + short-perp positions when funding APR ≥ +20% and the candidate resolves to a real crypto coingecko_id (filters out stock-tokenized perps). wave-carry-settle (hourly) accrues funding income, MTM both legs, closes when funding flips, time stop hits, or legs diverge >4%. New crypto_carry_positions + crypto_carry_settlements tables. Live mode (real exchange orders) gated until pipeline is built.
wave-carry-entry + wave-carry-settle crons, carry_entry_enabled=1, carry_live_enabled=0
Automated promotion check· live
Daily cron compares every shadow variant (live/loose/tight/longhold/trailonly/scalp/liq_fade/event_pre/listing_front/inverse) to the live cohort baseline over 30d. When sample n≥30 AND winrate-lift ≥5pp AND payoff ≥1.1× live AND ΔPnL ≥$500 AND sharpe ≥0.12, writes a PROMOTE recommendation to crypto_promotion_recommendations and DMs David with the breakdown. Never auto-flips killswitches.
wave-shadow-promotion-check cron, shadow_promotion_check_enabled=1, runs 14:15 UTC daily
Market-neutral long/short book· shadow (NEW June 11)
Dollar-neutral cross-sectional book: long the strongest-momentum liquid coins, short the weakest, net ~zero to BTC, so it harvests the long-minus-short SPREAD regardless of market direction. The structural answer to "we are always on the wrong side" - a bouncing market does not hurt it. Backtested over 35d of dense 1m data: positive gross spread, Sharpe ~1.1, and correlation to BTC of 0.08 (essentially uncorrelated). Runs forward daily into crypto_mn_shadow to gather out-of-sample evidence across regimes. No live path.
crypto-market-neutral-shadow cron (14:45 UTC), market_neutral_shadow_enabled=1, mn_liquid_top_n=30
Bull-turn readiness monitor· live (readout)
Computes the real long re-enable signal every 6h - BTC vs its 50d EMA (the hard gate that held the line on the June 8 fakeout), market breadth (% of the universe above its own 20d SMA), bottom_score, and the basing sub-state - and the PHASE: 0 frozen / 1 leaders-early / 2 broad turn. So longs unfreeze on a confirmed broad turn, not the lagging 14-day-return gate or a BTC-only bounce. Currently Phase 0. Readout only; the live long re-enable stays a manual, evidence-gated step.
crypto-bull-turn-monitor cron, bull_turn_require_btc_above_ema50=1, min_breadth20_pct=50
Bull-market long playbook· shadow (NEW June 11)
Runs the four bull-market long levers forward in paper so the long engine is battle-tested at the turn: SELECTION (leaders-only early, then cross-sectional momentum, onchain accumulation tilt), SIZING (ramp pilot 0.5x to full on confirmed breadth), EXITS (run-the-winners: a wide 15% trail - matched shadow data shows trail exits beat the live exits by +2 to +4pp/trade on longs), TIMING (phase-gated, flat until the turn). Plus an aggressive bottom-catch A/B that buys leaders at bottom-confirmation before the EMA reclaim, to measure if catching bounces early pays net.
crypto-bull-long-shadow cron, bull_long_shadow_enabled=1, bull_long_aggressive_enabled=1, bull_long_trail_pct=0.15
Automatic exposure governor· live (NEW June 11)
Writes auto_short_exposure_mult each hour from price-action + recent performance (NOT the lagging regime), and the short scanner scales live size by it - so the book throttles itself automatically: near-flat in a basing chop (where shorts bleed) and at the turn (longs lead), full size in a clean downtrend, self-correcting as the regime changes. No manual switch-flipping. Currently 0.25x (BTC basing ~4.5% off its 14d low).
crypto-exposure-governor cron (hourly), auto_exposure_governor_enabled=1
Shadow promote/retire lifecycle· live (NEW June 11)
Complements the promotion check above for the new shadow tables (market-neutral, bull-long, bull-turn). Asymmetric automation: AUTO-RETIRES a clearly-bleeding shadow past a large sample (disables its killswitch - risk down, safe to automate) but only RECOMMENDS promotions (risk up needs a human nod). real_money_enabled is never auto-flipped.
crypto-shadow-promotion-eval cron, shadow_promotion_eval_enabled=1

The full strategy plan that motivated this batch lives at /root/cc-summaries/2026-05-22-boostio-10x-strategy-plan.md. Promotion criterion across the board: ≥30 closed shadow trades with WR + payoff that beats the live cohort by more than the round-trip cost. Until then, the live book runs on the existing engine and the new strategies record themselves into crypto_shadow_trades + their per-strategy log tables.

12

Research & Data Foundation (June 18)

A day spent on data quality, not new trading behavior: a research engine, the survivor-bias fix, and a validated dead-coin universe. Every item here is capture-only at weight 0 — none of it touches live scoring, sizing, entries, exits, leverage or orders.

Research engine, honest outcome. We stood up a full historical-cycle research pass and an analog engine that finds past look-alikes for the current tape, framed around a "Master Trader OS" idea of keeping signal research strictly separate from execution. The honest result: these are context and risk tools, not a proven buy/sell edge. They help us reason about where we are in a cycle; they do not place trades.

We did not wire a fake edge. We swept a portfolio simulator plus position-sizing, exit, veto and entry variants, each tested out-of-sample against a plain fixed-fractional baseline. None beat the baseline out-of-sample, so we wired exactly none of them into live trading. The discipline is the point — we do not ship a strategy change just because it looked good in-sample.

What we actually built — all capture-only research data quality:

Funding-rate history + keep-fresh cron· capture-only
Backfilled the full per-settlement funding history for the perp universe (~643K rows back to 2019), with APR normalized by each contract's REAL funding interval rather than a blanket 8-hour assumption — so carry, basis and net-of-cost research finally has an honest time series. A keep-fresh cron tops it up after each settlement.
Smart-money contrast lanes + resolver cron· weight 0
The Nansen capture was inflow-only, so it had no control group. It now records inflow vs outflow/distribution vs a near-zero NEUTRAL control, adds 7-day and 30-day outcomes with a BTC benchmark and excess-of-beta, and a resolver cron maps each token to liquidity and a canonical coin id. Stays weight 0 until out-of-sample validation.
Market concentration + leadership· regime/context
Daily breadth, top-5/10 return-and-volume concentration and leadership rotation, plus TRUE top-1/5/10 market-cap concentration and an HHI on the hourly market snapshot. Pure regime context — never a buy/sell signal.
Forward point-in-time universe· survivor-bias fix
Snapshots the investable top-250 every day going forward, so future backtests see the universe as it actually was, not as it looks today. The structural fix for survivor bias — the trap of only studying the coins that survived.
Asset-lifecycle enrichment (CoinGecko)· data quality
Enriches the asset-lifecycle table from CoinGecko (categories + identifiers) so each tracked asset carries the metadata needed to classify and validate it.
Forward delisting / dead-coin events· forward-only
A disappearance schema + daily cron records coins leaving (or re-entering) the universe as forward delisting evidence. Forward-only by design: it accrues going forward and is never back-dated.
CMC inactive / untracked map· ingested
Ingested CoinMarketCap's authenticated inactive + untracked map — 28,888 dead/inactive coins, of which 24,173 carry a platform + contract address — as the raw dead-coin universe to bridge and verify against CoinGecko.
Contract-bridge drain + asset-class classifier· guardrail
A low-rate drain bridges CMC rows to CoinGecko by contract address, and a classifier blocks tokenized stocks, ETFs, funds and Ondo / real-world-asset wrappers so they can never pollute the crypto dead-coin set.
Medium-bridge validation· validated
Contract-level validation of the medium-confidence bridges caught real false positives (vendor id mismatches), so only contract-proven rows were upgraded — mismatches were left untouched, never silently rewritten.
Gated lifecycle promotion· lifecycle
Contract-proven dead coins were promoted into the asset-lifecycle table as delisted behind an exact gate (11 first, then 18 more). Final state: 274 lifecycle rows, 29 delisted. Dates and market cap stay unknown/null because CMC does not provide exact delist dates — we refuse to invent them.
Daily-OHLCV coverage backfill + keep-fresh guard· data quality
The daily OHLC history was missing for many traded symbols, so reconstruction research covered only ~30 of 75 closed longs — and that subset was positively biased (the off-coverage trades were the big losers). We backfilled 31 previously-uncovered symbols (ZEC, ICP, TIA, HBAR, ETC, TAO, ONDO, JUP, PENDLE, IMX, STRK, WIF and more) from the existing Binance source (11,131 rows; 92 to 123 symbols) and added a keep-fresh guard so a one-time backfill can never silently freeze. No scoring/sizing/entry change.
Clean-space breakout, honestly de-biased· capture-only
Once the backfill closed the coverage gap, the clean-space/breakout edge that looked strong on the biased subset (+$585 / 70% win on 10 trades) largely collapsed on the full set (+$111 / 53% win on 17). The direction survives but the magnitude was mostly a coverage artifact — so it stays weight 0 and is not promoted. We would rather kill our own result than wire a fake edge.

What did not change. No trading, scoring, sizing, entry, exit, leverage, order or real-money setting was touched. The delisting/dead-coin events table stays forward-only, and anything merely medium-confidence, conflicting, not-found, unverifiable or tokenized is not promoted — only contract-proven crypto graduates into the lifecycle.

13

Intentionally Not Here Yet

The honest list of what's NOT in this version, and why.

Wave ships in phases. Below is everything that someone might reasonably assume is part of a "real trader" stack but is deliberately deferred — with the reason for each, so nothing surprises you later.

Real money (live capital)
Gate: 90 consecutive days beating BTC buy-and-hold on v3 cohort. Currently zero v3 trades; Phase 2 tuning requires n≥30 first.
Pitchforks / trendline drawing
Pivot-point selection needs its own design + backtest. Naive line-fitting overfits noise.
Elliott Wave
Subjective by design. No widely-accepted automated detector. Permanently deferred.
Volume Profile usage (L)
BUILT (POC/VAH/VAL in patterns.js, vp_quality_score slot) but TESTED & REFUTED: net-of-cost OOS backtest (2026-06) was −1.4% out-of-sample, −6.7% in BTC uptrends — in-sample only, collapses OOS. Stays weight 0; an answered question, not a gap.
Higher-TF bias (M)
computeHtfBiasScore() built + ~600d history backfilled; htf_bias_enabled=0. (Note: htf_bias_score IS consumed live today by the context-confirmation gate.) Low priority — largely a trend re-encode; untested OOS.
Funding × price-action (O)
BUILT (funding_pa_score slot) but TESTED & REFUTED: −4.1% net-of-cost OOS. Would have replaced the funding-veto; stays weight 0.
FVG / order blocks (P)
BUILT (detectFvg() populates fvg_score) but TESTED & REFUTED: −5.7% OOS / −16.1% in BTC uptrends. Stays weight 0.
Wyckoff Spring (Q)
detectWyckoffEvent() built; the bearish upthrust is LIVE, but the bullish Spring (longs) was TESTED & REFUTED (−2.0% OOS / −11.6% in uptrends) and stays gated at weight 0.
Stablecoin dry-powder / SSR
NEW (2026-06): wave-stablecoin-supply captures DeFiLlama stablecoin supply (deep, 8.6yr). VALIDATED POSITIVE — rising supply / low SSR → higher forward BTC (HIGH-growth quintile +7.1% vs −2.7%). Capture-only at weight 0; best candidate to wire as a soft regime/context input after forward OOS.
Cross-venue funding dispersion
NEW (2026-06): wave-cross-venue-funding captures Binance/Bybit/Hyperliquid funding (cadence-normalized to APR). Liquid majors carry a real spread (~10-23% APR) BUT the sign is unstable — Hyperliquid was hotter than Binance at launch and has already flipped colder, so the spread may be regime-noise not a structural edge. Capture-only; validating persistence on the liquid subset before any trade path.
External signal stack (TVL/smart-money/social)
altFINS + LunarCrush + Nansen + DeFiLlama-TVL captured at weight 0. Only TVL-contrarian holds up (orthogonal to price reversal, IC −0.165 t−3.17); smart-money is directionally-right but underpowered; altFINS/social are noise. Re-validate as the capture window matures before any weight.
14

Roadmap

Triggers, not dates. Wave ships when the data says it's ready.

Phase 2
Trigger: n ≥ 30 v3 trades + all features alive
Auto-tune scoring weights from v3-cohort outcomes. The walk-forward optimizer (wave-optimizer-sweep/promote) is BUILT and runs PROPOSE-ONLY — David approves every promotion; crypto_audit_auto_fixes tracks per-setting changes. Still gated on v3 trade count.
Phase 3
In progress (2026-06)
Macro / on-chain data expansion — DELIVERED so far (capture-only, validating forward): stablecoin "dry-powder" supply (DefiLlama beyond DeFi, validated 8.6yr — rising supply / low SSR → higher forward BTC), cross-venue funding dispersion (Binance/Bybit/Hyperliquid), TVL-contrarian (orthogonal to price, confirmed), deep BTC-dominance history. Still open: Glassnode net-flows; real per-coin historical market-caps (now unlocked via the CoinGecko Analyst plan).
Phase 4
Re-scoped (the TA detectors were refuted)
ORIGINAL plan (wire Volume-Profile + HTF-bias + CME-gaps + Wyckoff-Spring + FVG into scoring) is RETIRED: all were backtested net-of-cost OOS (2026-06) and collapse (VP −6.7%, FVG −16.1%, Funding×PA −4.1%, Wyckoff-Spring −11.6% in BTC uptrends). They stay weight 0 — answered, not pending. NEW Phase 4: graduate the VALIDATED orthogonal/macro signals (dry-powder, TVL-contrarian) to a non-zero context/regime weight after forward OOS confirmation.
Phase 5
After 90d positive alpha on v3
Live capital via Coinbase API. Same scoring, real money, kill-switch on drawdown. Honest status: the SHORT-side scalp book is the live edge; the long book is net-negative & regime-gated, and carry is regime-contingent — so the 90d-positive-alpha gate is not close on directional longs.

No fixed dates. The roadmap moves when the data does — n ≥ 30 v3 trades unlocks Phase 2, not a calendar. If a phase needs more time, it gets more time. If it ships earlier, it ships earlier. Either way the morning health DM tells David where we are.

15

Moonbag Accumulation

A signal-driven, buy-and-hold sleeve for the bottom zone. Not a stop-managed trade: it accumulates deep-value coins and holds them through the cycle.

Wave's trade book is built for momentum: it enters on a score, manages a stop, and exits. That is the wrong tool for a different job, which is accumulating coins you believe in near a cycle bottom and holding them for the move up. The moonbag sleeve is that second tool. It is part of Wave, funded from the same one $100K bankroll, but its bags follow different rules: no hard stop, no take-profit ladder, no time-based exit, and a deeper drawdown tolerance. The momentum manager skips them, so the two styles share one bankroll without interfering. Every bag is a real, tagged Wave long, so it counts in the bankroll's equity and shows up, marked, in the Open Trades table.

How the picks are chosen

The basket is the top Scout candidates by score: deep below all-time high, scored on value, quality, structure, narrative and entry. Every position is tagged with why it is held: the moonbag hold-type (longer hold, higher drawdown tolerance), the signal source (Scout), the score at entry, the live current score, and the percent below ATH. So you can always see at a glance which holdings are patient bags and exactly why each was picked.

The list stays current, not frozen. Scores refresh every run, and a candidate only stays eligible if it still meets the moonbag score bar AND was re-scored recently. A high score that has gone stale (not re-scanned in days) is excluded, so the sleeve holds today's high-scorers, not last week's. Picks that are not on Binance are priced live via CoinGecko, so the best Scout signals are not left out just because they sit off our main exchange feed.

How it accumulates

Built for a no-leverage, hold-the-cycle style: no tight stop, no time-based exit. It deploys a first tranche now, then adds on weakness (pre-planned dip tranches below the entry reference) so being early lowers the average cost, and adds one more tranche when Bitcoin reclaims its rising 50-day average (the trend-turn confirmation). It caps total deployment to keep dry powder in reserve and posts every add to the crypto channel. Nothing is auto-sold: a bag that decays below the bar is flagged for review, and the decision to take profit stays manual.

Paper only, real money off, killswitched (accumulation_enabled). The bags are first-class Wave longs in crypto_paper_trades tagged cohort=moonbag, so they count in the one bankroll's equity and appear, tagged, in the Open Trades table under the Moonbag filter. They sit alongside the on-chain bottom score that reads real MVRV, SOPR, NUPL, realized price and exchange reserves plus a weighted read of Blockchain Backer's posts.

16

Changelog

What changed and when. The "Last updated" date above is derived from this list, so the page can never quietly drift out of date.

2026-06-20 · Daily-OHLCV coverage backfill, an honest clean-space downgrade, a survivor candidate registry, and a full self-audit pass
  • Daily-OHLCV coverage backfill: the daily OHLC history was missing for many traded symbols, so reconstruction-based research only covered ~30 of 75 closed longs — and that covered set was positively biased (the off-coverage trades were the big losers). We backfilled the daily history for 31 previously-uncovered symbols (ZEC, ICP, TIA, HBAR, ETC, TAO, ONDO, JUP, PENDLE, IMX, STRK, WIF and more) from the existing Binance source — 11,131 rows, the table went from 92 to 123 symbols — and added a keep-fresh guard so a one-time backfill can never silently freeze. Data-quality only; no scoring/sizing/entry change.
  • Clean-space breakout, honestly de-biased: once the coverage gap closed, the clean-space/breakout edge that looked strong on the biased subset (+$585 / 70% win on 10 trades) largely collapsed on the full set (+$111 / 53% win on 17). The direction survives but the magnitude was mostly a coverage artifact, so the feature stays capture-only at weight 0 and is NOT promoted. We would rather kill our own pretty result than wire a fake edge.
  • Survivor candidate registry + promotion cockpit: every promotion candidate from the recent research chain is now recorded in a machine- and human-readable registry (15 candidates today — implemented-default-off, capture-only, needs-data, analytics-only, rejected) and surfaced read-only on a promotion cockpit, so the exact status, evidence and next-proof of each idea is visible and cannot quietly drift.
  • Default-off research wiring: a long coil-veto guard (the most PnL-predictive single component in testing) is wired into the long scanner but ships provably inert — its setting does not exist, so it never fires — pending forward proof. The conviction-flatten idea was rejected after a toggle-accurate replay flipped its apparent edge negative. Net-directional exposure capture runs capture-only. None of these touch live behavior.
  • Full self-audit pass: an 8-track, 26-agent read-only audit swept the engine, backtest/PnL canon, data ingestion, the signal stack, shadow strategies, cron/infra health and the database. It confirmed the core discipline holds end-to-end (real money off, signals capture-only at weight 0, optimizer propose-only with a hard blocklist) and found a set of paper-only correctness/hygiene defects — the high-value ones now fixed: the backfilled OHLCV symbols are kept fresh, a false "scanner silent" watchdog alert is gated on real scanner liveness, shadow killswitches no longer strand open positions, promotion recommendations require a credible baseline before flagging PROMOTE, and short targets can no longer be stored as impossible negative prices.
  • Multi-cycle validation harness + an honest result: we built a read-only backtest harness that validates candidate edges across the cycle data we already hold (123 alts 2023-2026; BTC/ETH on-chain to 2013), reusing the canonical fill math, net-of-cost, out-of-sample, and survivorship-free (it even includes coins that delisted/collapsed in-window, like the OM crash). A 3-agent adversarial review confirmed the engine has no look-ahead and faithful fill math. The verdict was humbling and useful: the naive directional long edges (trend, breakout, cross-sectional momentum) do NOT clear cost once tested rigorously - the apparent winners were survivorship mirages. We would rather our own tool kill a fake edge than risk money on it.
  • On-chain cycle valuation dial (capture-only): the same study found a real, multi-cycle edge - on-chain valuation (MVRV/NUPL) times the cycle at the extremes (BTC NUPL<0 historically +64% over 180d at an 82% hit rate; it marked the 2018 and 2022 bottoms and the 2021 top). A new daily cron now records the BTC+ETH valuation zone, percentile and a suggested long-size multiplier - read by nothing, recorded forward to prove itself before it ever earns a live weight. As of today it reads early/accumulation (ETH below its realized price), not euphoria.
  • Deferred-detector audit: corrected the "Intentionally Not Here Yet" list. Two items had quietly SHIPPED — the realtime Binance liquidation websocket now runs as a live pm2 process (the 5-min poll was retired), and the CME-gap scanner is populated and scheduled. The rest (Volume Profile, higher-TF bias, funding×price-action, FVG, Wyckoff Spring) are built into the scanner with score slots but their killswitches are OFF (weight 0) — now under a net-of-cost out-of-sample backtest; only the survivors graduate, capture-only first.
  • Discipline unchanged: everything here is paper, capture-only or research wiring at weight 0. Real money stays off, no live scoring/sizing/entry/exit/leverage/order change, and every new idea proves itself forward before it can earn a live path.
2026-06-18 · Survivor-bias groundwork + deeper capture: funding history, smart-money contrast lanes, concentration, and a delisted/dead-coin universe
  • Real funding-rate history: we backfilled the full per-settlement funding history for the perp universe (about 643K rows back to 2019, with APR normalized by each contract’s real funding interval) instead of only a threshold event log, so carry, basis and net-of-cost research finally has a real time series. A keep-fresh job tops it up after each settlement. Capture-only.
  • Smart-money contrast lanes: the Nansen capture was inflow-only, so it had no control group and "does smart money predict returns" was untestable. It now records inflow vs outflow/distribution vs a near-zero neutral control, adds 7-day and 30-day outcomes with a BTC benchmark and excess-of-beta, and resolves liquidity plus a canonical coin id per token. Still weight 0.
  • Market concentration and leadership: a daily breadth + top-5/10 return-and-volume concentration + leadership-rotation read, plus true top-1/5/10 market-cap concentration and an HHI on the hourly market snapshot. Pure regime/context, never a buy/sell signal.
  • The big one - correcting survivor bias: our local history only contained coins that survived to today, so every backtest over-credited winners. We now (a) snapshot the point-in-time investable universe daily going forward, (b) detect coins leaving or re-entering it as forward delisting evidence, and (c) ingested a vendor dead-coin universe (about 29K inactive/delisted coins from CoinMarketCap) bridged to CoinGecko ids and contract-verified. Tokenized stocks and ETFs (Ondo and Reserve wrappers) are explicitly classified out so they never pollute the crypto dead-coin set. Behind an exact promotion gate, 29 contract-proven dead coins (11, then 18 more) are now recorded as delisted in the asset-lifecycle table (274 lifecycle rows total, 29 delisted); dates and market cap stay null because CMC supplies no exact delist dates.
  • Discipline unchanged: every item here is capture-only research data-quality at weight 0. None of it touches scoring, sizing, entries, exits, leverage, orders or real money. Dead and delisted assets are staged and validated before anything is trusted; the honest point-in-time universe accrues forward and the deep historical dead-coin set stays provisional until validated.
2026-06-16 · Moonbag folded into the one Wave bankroll, and a unified, filterable trade book
  • The moonbag accumulation sleeve is now part of Wave, not a separate pool. The bags are first-class Wave longs (tagged cohort=moonbag) drawn from the same one $100K bankroll, so they count in the canonical equity and the dry-powder math instead of living in a second book. They still follow hold-the-cycle rules: no hard stop, no take-profit ladder, no time exit, deeper drawdown tolerance, and the momentum manager leaves them alone.
  • Unified, filterable Open Trades: every position is now tagged by side (long/short), strategy (momentum/moonbag) and source (Scout), and the trade table has filter chips for each. The moonbag bags show inline, marked, with their score and "hold" in place of stop/TP/time. This is the groundwork for letting members filter and mirror exactly the slices they want.
2026-06-15 · On-chain bottom layer, a Blockchain Backer read, and a Scout-driven moonbag accumulation sleeve
  • Real on-chain bottom metrics: we now ingest MVRV, adjusted SOPR, NUPL, realized price and exchange reserves from CryptoQuant (about a year of daily history backfilled), so the system can finally measure the things a real bottom-caller measures instead of price heuristics. A v2 bottom score is computed alongside the live one from that on-chain data plus a heavily weighted read of Blockchain Backer, whose full Substack posts are now ingested. It currently reads higher than the old score, driven by exchange supply-shock and his bottom call. All shadow: it does not change live behavior.
  • Moonbag accumulation sleeve (paper, hold-the-cycle): a buy-and-hold sleeve separate from the trade book, for accumulating deep-value coins near a cycle bottom with no leverage and no tight stop. The basket is the top Scout picks (deep below all-time high), each tagged with why it is held (moonbag hold-type, Scout source, score, thesis, percent below ATH). Scores refresh every run and stale or below-bar names drop off, so it holds current high-scorers, not frozen ones. Picks not on Binance are priced live via CoinGecko. It deploys a first tranche, adds on dips, and adds again when Bitcoin reclaims its rising 50-day average, keeping dry powder in reserve. Real money off, killswitched.
  • Bottom-mode shadow longs: a shadow long behavior that holds longer with a looser stop when the bottom score is high and sustained, to forward-test the patient-at-a-bottom thesis. Off by default, no live path.
  • Discipline unchanged: everything above is paper and shadow-first, real money stays off, and the new scores and sleeves prove themselves forward before anything earns a live path.
2026-06-11 · Wrong-side audit, a dense data foundation, and a market-neutral shadow book
  • Why the book felt like constant losses: an 11-agent audit found it was not bleeding (roughly flat) but mis-timed. The book was short-only and the market based around June 6, so we kept shorting bounces. The cause is regime timing: risk_off flips on a sub -10% trailing 14-day return, which stays pinned for about 10 days after a crash while the drop rolls off the window, long after price bottomed. We reverted the June 6 short-loosening so we stop taking low-quality bounce shorts; a full-history replay confirmed the fix, matching the audit number to the dollar.
  • Basing sub-state (behind a flag, replay-validated): a no-lookahead detector (distance from the trailing low, bottom-score confirm, 3-day momentum) flags a base about 9 days before the lagging gate flips, so we throttle shorts into a base instead of fighting it. Off by default until forward evidence confirms it.
  • New data foundation: we were on 4-hour, close-only prices, so every backtest was blind between marks. We now ingest true 1-minute OHLC bars across the universe (about 3 million backfilled), open interest, Deribit implied volatility (DVOL), cross-exchange derivatives via Coinglass (aggregated OI, funding, long-short ratio), and on-chain exchange flows via CryptoQuant. This gives stop-aware backtests and real volatility for the first time.
  • Market-neutral direction: one-sided directional bets are why a bouncing market can hurt us at all. A dollar-neutral long/short book (long the strong, short the weak, net zero to BTC) backtested over 35 days with a positive gross spread, Sharpe near 1.1, and correlation to BTC of 0.08 - essentially uncorrelated. It now runs forward as a paper shadow book to prove out across regimes. No live path, no real money.
  • Discipline unchanged: everything is paper, real money stays off, and the new strategy runs in shadow until out-of-sample evidence earns it a live path. We rejected the tempting overfits (flip to longs, promote the inverse cohort, lower the long floor) because the data did not robustly support them.
2026-06-01 · Homepage Signal Feed Layer section
  • The homepage now surfaces the connected data stack that was already documented here: smart-money, social, technical, DEX pricing, market data, TVL, and narrative feeds. It is a visibility change, not a new integration.
  • Copy stays honest: these sources are captured and validated first. New sources start capture-only at weight 0 until out-of-sample edge is proven, so nothing shown there drives live trades yet.
2026-06-01 · Short-side profit-protection guard
  • When a short moves meaningfully in our favor before TP1, Wave can now tighten the stop or arm a pre-TP trail instead of leaving the gain unprotected. Defaults are conservative: protect once a short is up about 5%, lock at least a small profit, and arm a pre-TP trail rather than waiting for a TP row that may be missing or too wide.
  • No-TP risk decay: if a short has been held for several hours and never moved meaningfully in our favor, Wave tightens its stop to cut the bleed. Forced close stays off by default. It tightens risk first, it does not auto-exit.
  • Short side only. Long-side exits, entry score floors, and real-money settings are unchanged.
2026-06-01 · External data layer expanded: altFINS signals, LunarCrush sentiment, DexScreener pricing, 4h cadence
  • altFINS technical signals (capture-only, weight 0): the altFINS signals-feed is now pulled into crypto_external_signals. It contributes a 7-day net bullish or bearish read per token. Like everything new, it is recorded at zero weight and does not touch any score, sizing or entry yet.
  • LunarCrush social sentiment (capture-only, weight 0): LunarCrush sentiment (0 to 100) is now captured for our universe with deep mid-cap coverage. This directly addresses the news and sentiment blind spot, since headline news skews toward large caps while Wave trades mid-cap movers. A single bulk call keeps it inside the provider rate limit. Zero weight, measure first.
  • DexScreener pricing for smart-money capture: Nansen surfaces tokens outside our trade universe, so their capture price used to be missing. We now price those tokens by contract address via DexScreener at capture time, so forward-return evaluation of smart-money flows is finally possible. Forward only: older rows captured before the fix stay unpriced.
  • Cadence and coverage: the external-signals pull moved from once daily to every 4 hours, and the orchestrator now ingests every configured provider together each cycle (Nansen, altFINS, LunarCrush). It stays inside provider quotas at this cadence.
  • Top Accumulation feed: a smart-money net-inflow leaderboard now posts to our internal crypto channel every 4 hours. It is observational only, capture-only at weight 0.
  • Discipline unchanged: every one of these is recorded with zero influence on trades. They graduate to non-zero weight only after out-of-sample validation shows they predict forward returns. No curve-fitting.
2026-05-31 · Capture-only data layer: Nansen smart money, reject ledger, missed-rally, watchdog retune
  • Nansen smart-money netflow capture: smart-money net inflows and outflows per token (Ethereum, Solana, Base) are pulled every 3h into crypto_smartmoney_flows. This is capture-only at weight 0, it does not touch any score, sizing or entry yet. We are measuring whether smart-money accumulation predicts 24h and 72h forward returns before giving it any weight. This is a new signal, separate from the old disabled creators-based Smart Money pillar.
  • Rejected-candidate ledger: every blocked candidate is now recorded in crypto_rejected_candidates with the exact reason (below score floor, symbol cooldown, tier filter, exposure caps) plus its 24h and 72h forward return. If our filters are blocking eventual winners, the data will show it. 450 rows on day one.
  • Missed-rally detector: crypto_missed_rallies scans every 4h and logs when an established major (market cap over $300M) rallies 8% or more while Wave was flat or short, along with the reason we did not go long. It targets the systematic blind-spot class such as the HBAR and XLM miss.
  • Watchdog retune: the old raw "zero trades today equals alert" logic was retired (it false-alarmed now that a score floor of 6 means fewer trades by design) in favor of scanner-liveness, near-miss context, and a dead-scoring detector that fires only when something is genuinely wrong.
  • Discipline: measure first, weight later. The new signals are recorded with zero influence; the first review window has now passed and every captured source still sits at weight 0 — none has yet earned a live weight. No curve-fitting.
2026-05-31 · Monitoring rebuild + content refresh
  • Every cron now heartbeats on success, intentional-skip AND failure (crons/lib/cron-health.js). The skip path updates last-run, so a healthy-but-skipping cron is no longer mistaken for dead.
  • New liveness + correctness watchdog judges crons by last-run vs expected interval (a correct skip stays fresh), checks output freshness, self-heals once, and escalates with the real error.
  • Read-only cron-health board added at /dashboard/crypto/health. Removed the superseded liquidation poller (the Binance websocket has carried liquidations since).
2026-05-30 · Coil scoring v3 + regime fixes + self-optimizer
  • Coil scoring v3: "buy the coil before the spring, fade the obvious rocket." Bullish divergence, squeeze, volume and 4h-momentum boost the score; multi-timeframe-aligned, high-ADX, high-ATR and extended-weekly setups are penalized.
  • Score-6 quality floor: candidates below a 6 do not execute, killing the low-conviction churn.
  • Regime fixes: stopped shorting into caution regimes and unblocked longs that were being over-gated.
  • On-chain pillar weighted at 1.75. Self-optimizer (champion/challenger walk-forward) runs daily and only promotes a challenger after an out-of-sample gate. Still 100% paper.
  • Short-side scanner now captures the full TA snapshot + coil_score on every short, so a validated coil-short formula can be built on labeled data.
2026-05-17 · Original how-it-works rebuild
  • First public version of this page: 13 rails over one day documenting the scoring engine, gates and risk model.

See it live

Every trade, every signal, every regime change — happening right now.

Open the Wave Dashboard →