Commit Graph
39 Commits
Author SHA1 Message Date
momentum devandClaude Fable 5 b3a47d775d feat(019): discovery on its own thread + tuner heartbeat (honest stale alert)
Telemetry: discovery took 6-30s ON the single scheduler, freezing ingest/arm
so the trigger read stale bars — the real 'late edge detection'. Now discovery
runs on its own daemon thread with a dedicated DB connection; the watchlist it
mutates is a lock-guarded Watchlist (list-like drop-in, no torn reads); the
scheduler discover step auto-disables (single-writer). Loop is now 3 fast
threads (entries/exits/discovery) + slow scheduler for tolerant work.

Also: nightly_tune writes a heartbeat every run, so the boot alert distinguishes
'tuner not running' (real) from 'ran, no profitable ORB config, kept params'
(expected — the strategy has no edge). Kills the misleading Telegram alarm.
543 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 08:44:10 -05:00
momentum devandClaude Fable 5 a619a99f05 plans(019): move discovery off the scheduler — telemetry-proven 6-30s loop blocker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 08:33:49 -05:00
momentum devandClaude Fable 5 375973fe21 plans(018): sub-second exit thread — the last real execution-latency lever
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 22:05:33 -05:00
momentum devandClaude Fable 5 2fd0a860ad plans(017): lower-gap redesign REFUTED — no positive cell in gap x overhang grid
Sliced 2191 depth fires gap x overhang under real exit: lower-gap is WORST
(0-3% -0.831R), inverting the low-gap-edge hypothesis. Overhang helps a little
everywhere, nothing crosses zero. Exhaustive: 13 levers + regime + depth +
this grid = zero positive. No positive subpopulation in gap-ORB $2-20.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 21:13:26 -05:00
momentum devandClaude Fable 5 bdeb2ec4b4 plans(017): VERDICT — L2 depth is real but too weak; FAIL under real exit + random-gate null
Definitive test, n=2191 real deployed exit: ask-overhang separates +0.083R
(high -0.676 vs low -0.759, direction held sniff->scale = genuinely real) but
fails the random-gate null — it shrinks losses, never creates profit. Live
gap>=10% band n=13/74 = no signal. Same shape as regime gate on a negative-EV
base. 13 conversion levers + regime + depth tested, zero make it positive.
Real-money rec: NO. Depth edge argues for a broader-population redesign as
future research, not a live fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 18:00:07 -05:00
momentum devandClaude Fable 5 0da3ac0ff7 plans(017): honest status — signal real but modest (AUC 0.586), clean verdict backfilling
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 11:48:08 -05:00
momentum devandClaude Fable 5 b9828e5e06 plans(017) Phase 0: GO — ask-overhang-above-break separates winners AUC 0.80
First genuine selection signal in the project. 40 real fires, Databento
XNAS.ITCH book at each trigger: naive imbalance = noise (AUC 0.45/0.50), but
ask-size resting within 1% ABOVE the break separates winners at AUC 0.80
(winner median 0.276 vs loser 0.005; median split 27% vs 67% win). Inverted
from supply-trap intuition = absorption/fuel mechanism, invisible in OHLCV.
n=23 single-day sniff -> GO to Phase 1 recorder, not to trading. Cost: pennies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 09:26:50 -05:00
momentum devandClaude Fable 5 012bcd7b3b plans(017)+data: Databento L2 key verified live — Phase 0 is now a ~$0 same-day experiment
Cost-checked (no data spent): DATABENTO_API_KEY reaches XNAS.ITCH TotalView
10-level depth; every real gapper (EHGO/ATPC/MUD/LASE/AEON) covered at
$0.0001-0.0066/fire, full 20-fire sniff <$1 inside free credits. Catalogs
all 13 provisioned-but-unwired keys with a wire-on-demand triage (Databento
= game-changer; 4 news APIs = skip; rest redundant).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 09:06:33 -05:00
momentum devandClaude Fable 5 4f720fca4f plans(017): L2 order-book depth recorder — free-first, spend-gated, pre-registered
The one untested selection axis (order-book depth = the owner's 'size stacked
above the break' instinct). Staged so $0 is spent until a free sniff test +
recorder prove the signal exists and covers the universe; paid feed is an
explicit owner gate; the signal faces the same pre-registered bar + random-gate
null as every refuted lever before it touches the live entry. Honest ceiling
stated: a PASS nudges odds, is not an autonomous oracle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 08:57:06 -05:00
momentum devandClaude Fable 5 d4d1383e2c plans: mark queued defects fixed
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 20:57:56 -05:00
momentum devandClaude Fable 5 5bf089cdcc research: orderflow H1/H2/H4 verdicts — all refuted in substance; H2's formal PASS is a bar artifact
H2 exposed an adjudicator gap: on a -0.21R/fire baseline any keep-or-zero
gate zeroing ~44% of fires clears +0.05 mechanically; its own pre-registered
strata check inverts (choppy beats persistent within both gap buckets =
Simpson's). Queued: random-gate null for keep-or-zero bars. H3 accruing as
designed (n=29, skip-on-no-coverage working).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 19:24:47 -05:00
momentum devandClaude Fable 5 8fd0fc7921 plans(016): record first adjudication — FAIL on pre-registered bar (3% coverage; flagged fires outperformed)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 11:22:19 -05:00
momentum devandClaude Fable 5 d2114a7716 plans(016): DONE — merged f6999c7; backfill seeded
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:56:26 -05:00
momentum devandClaude Fable 5 d8d37700aa plans(016): EDGAR dilution enrichment — unbreak nightly refresh + pre-register filing-veto experiment
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:29:40 -05:00
momentum devandClaude Fable 5 92488b72bc youtube: YT_PLAYLIST_URLS — comma-separated playlists via env, synced at boot
One playlist per add-playlist CLI call made adding a second playlist a chore.
Now YT_PLAYLIST_URLS takes a comma-separated list of playlist URLs (list=
param extracted) or bare ids; the transcripts service seeds the playlists
table from it at boot (insert-if-missing — hand-set labels are never
clobbered), and `python -m youtube_claims.run sync-playlists` does the same
on demand. Documented in both compose files; 3 tests.

Also: queue the two executor-surfaced defects (OrderFilledEvent side,
/api/attribution env hardcode) + the flaky nightly regime build-features
step in the plans index; regime_features 07-16 backfilled supervised.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 09:14:22 -05:00
momentum devandClaude Fable 5 8feac6da81 plans(015): DONE — executed + review-approved first pass, awaiting merge
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 08:45:39 -05:00
momentum devandClaude Fable 5 822584e072 plans(014): DONE — executed + review-approved first pass, awaiting merge
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 07:38:01 -05:00
momentum devandClaude Fable 5 e224d82291 plans(013): DONE — executed + review-approved, awaiting merge
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 06:51:14 -05:00
momentum devandClaude Fable 5 2d65669308 plans(012): DONE — executed + review-approved on advisor/012-dashboard-order-limits, awaiting merge
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 06:12:29 -05:00
momentum devandClaude Fable 5 5f2cbc4909 plans(012): revise Step 3 after executor STOP — lifecycle events never carried limit/stop; enrich client-side via client_order_id join to d.orders
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 06:05:26 -05:00
momentum devandClaude Fable 5 33708ffe6a plans(012-015): dashboard visibility milestone — order limits, symbol charts, decision trace, /backtest replay
Owner-requested UI work, advisor-planned for executor handoff:
- 012: show working limit/stop/target prices on positions + order lifecycle,
  cut dead columns (order-id, approval Mode)
- 013: symbol drill-in — 24h candlestick + live buy/sell fill markers
  (TradingView Lightweight Charts v5.2, vendored, Apache-2.0)
- 014: live decision trace — surface entry_gate_evaluated receipts as a feed
  (value→threshold per gate) + chart reject markers
- 015: /backtest replay page — theoretical entries/exits over past sessions
  under CURRENT settings, assembled strictly from Experiment-OS primitives

All four are read-path only; zero live-loop surface.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 06:00:45 -05:00
momentum devandClaude Fable 5 43a3ace91d Regime gate: make the live gate actually decide (it shipped inert) + fix breadth_rvol units
The 07-15 live gate never made a real decision: live_session_favorable read
today's breadth_rvol from today's OWN setup_events rows, which only the
NIGHTLY labeler writes — always None intraday, fail-open every session (the
07-15 "validation block" was computed pre-guard on a zero-filled feature).
Worse, breadth_rvol was unit-corrupted: _session_context pooled all setup
versions and pm1 stores RAW cumulative premarket volume in relative_volume
(median ~261k) vs the ratio tracks (~0.8) — ~240/267 historical sessions'
breadth was actually median premarket volume, and plan 009's v1 RVOL fallback
was about to flip forward sessions to ratio units.

Fixes (TDD, 21 regime tests):
- breadth_rvol is now pm1-ONLY: median premarket volume — the dominant
  historical source, unit-consistent, and strictly pre-open knowable.
- _live_breadth_rvol recomputes today's pm1 fires IN MEMORY from premarket
  minute_bars (pure compute_premarket_setups, no insert); previous_close
  falls back to the latest prior daily close when today's daily_bars row is
  absent intraday (else the gap basis silently flips to the premarket open).
- _regime_reject: verdicts before 9:50 ET are PROVISIONAL (re-scored ~5 min;
  ingest lag can truncate the premarket frame) and the first verdict at/after
  9:50 is FINAL even when None — caps the scorer at a handful of runs/day
  instead of ~78 on quiet days (hot-path stall guard). Throttle arithmetic
  moved inside the fail-open try (naive/aware mixing must not escape).
- Live fit excludes breadth_rvol-NULL training rows (zero-fill taught a
  "zero premarket volume" class the serve path can never produce).

Prod re-validation on the cleaned feature (regime_features rebuilt, scores
rewritten): regime_meta_v1 fire-weighted expR_delta +0.0570 (pre-registered
bar +0.05, n=2058, PASS — the contaminated +0.0965 was inflated), keeps 37%;
recent-80-session delta +0.149R/session (always −0.141 → gated +0.008).
First genuine live verdict 2026-07-16: UNFAVORABLE (pm breadth 612,819).
Known accepted skew: live scaled-IEX volumes vs nightly SIP tape — the
meta_live-vs-EOD comparison is the standing forward measure.

Also backfilled the missed 07-15 nightly job supervised (SIP refetch, 50 v1
+ 6 pm1 setups, SPY/QQQ ingest, regime row) — plan 009's accrual clock is
unbroken.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 14:00:07 -05:00
momentum devandClaude Opus 4.8 9082144d43 Regime gate: record live-gating (paper) in plans index
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 14:12:36 -05:00
momentum devandClaude Opus 4.8 9e7752c1fa Regime gate: fire-weighted harness PASS (meta_v1 +0.0965R, positive on live population)
Both regime experiments PASS pre-registered bars over the 2041 v1-population
fires — first PASS of the milestone. meta_v1 gated expR +0.0117R/fire (from
-0.085R baseline). Adjudicated live via the admin /api/regime/run pipeline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 14:30:11 -04:00
momentum devandClaude Opus 4.8 691cb9592a Regime gate: record prod backtest verdict in plans index
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 14:06:44 -04:00
momentum devandClaude Opus 4.8 092d6072e8 Regime gate (plan 011): deploy-wire the shadow pipeline + on-demand admin trigger + prod backtest
The session-level metalabel P(our ORB profits today) — the one lever that
survives out-of-sample. Backtested on 266 prod sessions (walk-forward):

  trade-always (trained subset): -0.111R/session, 36% hit
  meta_v1 GATED (trades best ~32% of days): -0.004R/session, 48% hit
  delta +0.107R in-sample, +0.128R OOS (recent 80 sessions), improves across folds

It does NOT make the bot profitable — it takes a bleeding strategy to roughly
flat by sitting out the worst ~2/3 of sessions. threshold_v1 rule gates too
little to matter; meta_v1 (walk-forward GBM) is the signal. Leaky full-fit
(+0.61R) >> walk-forward confirms the discipline was load-bearing; the OOS
holding is the evidence the +0.078R is real, not look-ahead.

Changes:
- research/regime.py: batch minute-bar load per session (64k per-fire round-trips
  -> ~266 queries; fixed a >5min build to ~3min) + incremental label pass (skip
  already-labeled sessions; --rebuild forces full). Nightly cost now ~one new day.
- docker-compose.yml + truenas-compose.yml: scheduler runs build-features + score
  (both models) before `experiments run`, nightly. ALL-SHADOW — does NOT gate live
  trading (that stays owner-gated Step 5).
- admin_api.py + admin.html: POST /api/regime/run (detached) + GET /api/regime/status
  + a Run/Status button — the panel had no way to trigger this.
- plans/011 + docs/research/regime_notes.md (6-book distillation) + plans 008/009 docs.

Prod state (shadow, rollback = DROP regime_features/regime_scores + DELETE
experiments WHERE id LIKE 'regime%'): 266 feature rows, 532 scores, 2 experiments
registered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 14:05:34 -04:00
momentum devandClaude Fable 5 1da168da45 plans(010): NO-GO — premarket entry is a paper-fill mirage (-1.3R @ realistic thin-book spread)
Step 1 measured: pm1+fat-tail expR -0.50R@0.5% fill -> -1.27R@1% (realistic) ->
-2.74R@2%, vs ORB -0.11R. The 22-min fat tail can't outrun the 1-2% premarket
spread. Every entry lever this session (gap bands + premarket) is negative after
honest fills; the gated ORB is least-bad. Keep TRIGGER_GAP_MAX=35.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:05:55 -04:00
momentum devandClaude Fable 5 6b6cde53db plans(010): premarket shadow-entry — harness-gated, fill-honest, never live until proven
The one unexplored setup (premarket/pm1). Step-1 go/no-go: does pm1 + the
validated fat-tail exit beat the ORB AFTER honest thin-book fills (real
spread_pct, fat premarket adverse)? If not, STOP — premarket is a paper-fill
mirage. Shadow-first; TRADING_SESSION_ONLY stays ON; no live order until a
forward shadow edge survives realistic slippage (owner-gated).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 09:39:06 -04:00
momentum devandClaude Fable 5 7a28eafeff plans(008): RVOL adds nothing beyond VWAP (0.526->0.535, noise) — VWAP is the whole story
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 21:12:26 -04:00
momentum devandClaude Fable 5 2abbf35257 plans(008): correct verdict — v1-scoped AUC 0.641 is real but is the VWAP gate already run
The 0.514 was the liq1-dominated mix. Scoped to live v1: CV AUC 0.641, driven
~entirely by above_vwap_flag (above-VWAP +1R 35.4% vs below 12.7%, 2.8x). The
bot already enforces above-VWAP; residual within that population = 0.526 ≈ noise.
No new alpha in current features; revisit after 009 fills rvol/context/catalyst.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 21:06:45 -04:00
momentum devandClaude Fable 5 1755f1f416 plans(009): status -> code DONE, awaiting supervised rebuild+probe
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:37:07 -04:00
momentum devandClaude Fable 5 e2b3c1ceae operator-plane: headless smoke + effective-config panel + ledger + unpin ruff
Step 6: tests/smoke_dashboard_headless.py renders the real page in a headless
browser and fails on any JS console/pageerror (standalone script, not
pytest-collected; CI non-blocking first). admin_api gains GET /api/config/effective
(per-key masked value + source: overrides.env vs compose, missing .env.example
keys flagged as drift) + an admin.html table (values XSS-escaped). dashboard.html
gains the Experiment Ledger panel reading the plan-006 verdicts from the snapshot
(empty-state until the tables exist). Removes the last CI ruff per-file pin
(api/main.py:F821) now that os/hmac are imported; scoped ruff is green unpinned.
Marks plan 007 DONE in plans/README.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 00:36:00 -04:00
momentum devandClaude Fable 5 f62ed646dc plans: 006 experiment-os -> DONE
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 23:53:20 -04:00
momentum devandClaude Fable 5 24c7330e58 plans: 005 entry-path unification -> DONE
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 23:26:26 -04:00
momentum devandClaude Fable 5 124d816cb9 plans: 004 learning flywheel -> DONE
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 22:49:58 -04:00
momentum devandClaude Fable 5 23b3d01a00 money-path: nightly cage-count reconcile (broker vs event store) + schedule it
Plan 003 step 5 (completes plan 003). research/eod_reconcile.py diffs broker
truth (open positions, today's live orders) against event-store truth (today's
submits/fills/closes) and emits a loud eod_reconcile event + Telegram alert on
any drift — the duplicate-resting-order-after-restart class (2026-07-06) caught
automatically instead of by hand. Read-only (reports, never auto-fixes). Wired
into both scheduler blocks after premarket_eval. Pure diff core is unit-tested.

Suite: 373 passed (+22 plan-003 tests), 15 fail = WSL-loopback dashboard only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 22:29:00 -04:00
momentum devandClaude Fable 5 af8137dfd7 delete: dead DDL (10 tables), dead projections, pinned dead code; README/pyproject prune
pg_schema.sql: drop CREATE TABLE for 10 zero-reference tables (operator DROP
list in plans/002-deletions.log — production tables untouched until run).
projections.py: remove 4 zero-consumer query functions.
Clear all 'plan 002' ruff pins from the CI gate (files now F-clean);
api/main.py:F821 pin remains for plan 007. README repo-map/test-count fixed;
pydantic-settings removed (zero imports). Full receipts: plans/002-deletions.log

Suite: 351 passed (16 schwab/dead-module tests removed), 15 failures = the
known WSL-loopback dashboard set only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 21:09:35 -04:00
momentum devandClaude Fable 5 0cb74c4c3b plans: 001 production safety rails -> DONE
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:43:24 -04:00
momentum devandClaude Fable 5 653f13a7d9 milestone 2026-07: plans 001-007 + ideation artifacts + architecture diagrams
Recon (8 clusters) -> ideation (48->14->7, all verified) -> plans, cold-read
verified by 8 fresh-context reviewers, 33 plan defects fixed pre-execution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:28:07 -04:00