feat(enrichment): automatic trade context enrichment MVP - #12
Open
omerElezra wants to merge 8 commits into
Open
Conversation
Given a completed trade's broker data, compute objective post-trade metrics and store them separately from raw executions: - lib/domain/enrichment.ts: pure enrichTradeContext(trade, provider) — basic result, planned R/R + actual R, stock technicals at entry (MA20/50/200, returns, volume, ATR14), SPY+QQQ market bias, MFE/MAE journey with exit efficiency, and a dataQuality section (missing inputs, missing market data, assumptions, warnings). Never invents data: null/UNKNOWN when inputs or candles are unavailable. - DailyBarProvider interface with a default adapter over the existing Yahoo/Polygon getCandles dispatch (lib/marketdata/daily-provider.ts). - trade_context_enrichment table (migration 009, JSONB payload keyed by symbol+entry_time like trade_journal) + upsert/fetch queries. - GET/POST /api/v1/trades/[tradeId]/enrichment: POST computes from the grouped trade + journal plan (stop/target) and upserts; closed trades only. - Trade detail page: "Trade Context" card with Compute/Recompute button rendering all sections, with — / UNKNOWN for missing data. - First unit-test infra in the repo: vitest (npm test), 19 tests covering long/short P&L, R/R, missing-stop behavior, MA alignment, market bias, MFE/MAE and exit efficiency via a fake bar provider. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Stock context now uses MA20/50/150 (user trades the daily timeframe; MA150 is the long-trend reference) — alignment, above/distance fields renamed accordingly; schema_version bumped to 2. - Market context gains VIX at entry: last close before the entry day, 5d change, and a LOW/NORMAL/ELEVATED/EXTREME regime (<15/<20/<30/30+). VIX is display-only context — market bias stays SPY+QQQ. - ^VIX daily bars come from Cboe's free history CSV (new lib/marketdata/cboe-vix.ts): Yahoo blocks datacenter IPs and Polygon gates indices behind a paid plan (free tier returns 403). Polygon ticker mapping for ^-prefixed indices (I:VIX) added anyway for keys with an indices plan. - Card renders the new MA150 labels and VIX level/regime/5d change, tolerating v1 rows (missing fields render as dashes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Redesign the trade journal to only ask for subjective inputs and derive the rest from measured data. Auto-suggested values are flagged with an "auto" chip and stay fully editable; a user edit drops the flag. - Market Read section pre-fills from the trade's enrichment: recent trend (MA alignment), volume vs trend (relative volume thresholds 2.5x/1.1x/0.9x), MA relation chips (above/below MA20 & MA150, plus "Overextended" when >7% from MA20). Prefill runs once, only into empty fields, and never overwrites saved journal values. - Risk amount ($) auto-computes live as |entry - stop| x qty while the stop is typed; manual override wins permanently. - Exit reason suggests "Hit Stop"/"Hit Target" when the actual exit landed within 1.5% of (or beyond) the planned level. - Candle pattern, open gaps and support/res/fib move into a collapsed "More (optional)" section (auto-opens when they hold saved values). - Footer shows how many fields are auto-filled pending review; saving still requires an explicit click so suggestions are never persisted unseen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…itable scoring rules New /entry-check page that forces a deliberate pre-entry decision: - computePreEntryContext reuses the enrichment section calculators as-of any timestamp (empty = live "now" check, past = retrospective practice incl. a "what happened after" 5/10/20d forward outcome with stop/target first-hit) - transparent rule-based score: user-editable scoring_rules (AND of typed predicates over a curated fact catalog, no black box), 7 seeded defaults, fired/skipped breakdown always shown; unified Entry confirmation question (confirmation vs anticipation/FOMO) shared with the journal - trade_plans table (migration 010): full check saved with frozen score breakdown, status planned/entered/skipped/expired, editable in place via full-form loading (each plan is a single row, PATCH recomputes the score) - copy-paste AI coach prompt built from the full context/checklist/score/ outcome, with clipboard fallback modal; lazy return-since-plan chip - shared journal form controls + Hebrew hover-help extracted for reuse Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ver help - trade journal form now uses the extracted form-controls/journal-presets; "Entry reason" unified with entry-check into the Entry confirmation question (discipline dimension only — setups stay in Technical setup, incl. new MA Support Bounce / Fibonacci Retracement / Bouncing on MA150); sections renamed to match entry-check (Setup & Plan, Chart Details) - Hebrew hover explanations on every question, option chip and section, on the Trade Context card metrics and on the dashboard/analytics KPI cards - notes and custom-value inputs auto-detect Hebrew (dir="auto") Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parses scripts/migrations/*.sql and fails when code and schema drift: columns read/written must exist, migrated-but-untouched columns are flagged as redundant unless whitelisted, upsert conflict keys need a matching UNIQUE constraint, the scoring_rules seed must parse, pass validateRule and stay identical to DEFAULT_RULES, and migration numbering must be gapless. CLAUDE.md documents the repo-root-mounted test command and requires running the suite for any DB-touching change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Verified with knip + manual grep: - delete the orphaned /api/v1/metrics/performance endpoint and lib/domain/performance.ts (no client callers — FastAPI-port leftover), their types (PerformanceReport, HoldingTimeStats), the unused kpi-row component, the unused autoInterval helper and the unused SSR supabase client; drop unused @radix-ui/react-separator and react-tooltip deps - unexport symbols only used inside their own module Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Merged
4 tasks
feat(entry-check): pre-entry check page with saved trade plans and editable scoring rules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Automatic Trade Context Enrichment: given a completed trade's raw broker data, compute the essential objective post-trade metrics and store them separately from executions.
enrichTradeContext(trade, provider)infrontend/lib/domain/enrichment.ts(pure, provider injected, unit-testable):nullwhen the stop is missing or invalidmarketSupportiveForTrade(long↔bullish, short↔bearish)missingInputs,missingMarketData,assumptions,warningsDailyBarProviderwith a default adapter over the existing Yahoo/PolygongetCandlesdispatch; another source can be plugged in without touching the domain logic.trade_context_enrichmenttable (migration 009, applied to Supabase): JSONB payload keyed by(symbol, entry_time)liketrade_journal; raw broker data stays untouched.POST /api/v1/trades/[tradeId]/enrichmentcomputes from the grouped trade + journal plan (stop/target) and upserts;GETreturns the stored row. Closed trades only.—/UNKNOWNbadges.npm test), 19 tests covering long/short P&L, R/R, missing-stop behavior, MA alignment, market bias, MFE/MAE, and exit efficiency via a fake bar provider.Design rules
No recommendations, no predictions, no invented data — anything not derivable from inputs is
null/UNKNOWNand reported indataQuality. Indicators use daily closes strictly before the entry day; MFE/MAE come from daily highs/lows (recorded as assumptions).Reviewer notes
UNKNOWNwith amissingMarketDatanote suggestingPOLYGON_API_KEY; broker-derived metrics compute regardless.planned_stop_loss/planned_target_priceare not in IBKR data — they come from the journal when filled in; R metrics arenullotherwise.(avgExit − avgEntry) × qtyminus commission per spec, which can differ slightly from the group's brokerrealized_pnl-basednetPnl.🤖 Generated with Claude Code