Commit graph

119 commits

Author SHA1 Message Date
886dbaec86 feat(api): /api/meet-kevin/backtest/* routes
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
2026-05-24 01:10:34 +00:00
db103df9b1 feat(kevin_bridge): service entrypoint with concrete wiring
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Wires the dependency-injected KevinBridge to concrete Redis cursor +
DB session factory + AlpacaBroker (or stub when creds missing). Includes
TradeSignalPublisher (Pydantic -> dict for the redis stream) and
SIGINT/SIGTERM graceful shutdown. Adds is_asset_tradable + get_latest_price
to AlpacaBroker so the bridge can query asset metadata.
2026-05-24 01:06:18 +00:00
cff2564428 feat(kevin_bridge): exit-scan daily job + cursor + audit writer
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
2026-05-24 01:03:53 +00:00
a417cae77b feat(kevin_bridge): blocklist + daily risk counters
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
2026-05-24 01:01:54 +00:00
3347847e38 feat(kevin_bridge): multi-mention aggregator with capped conviction boost
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
2026-05-24 01:01:02 +00:00
adbd7f3c65 feat(kevin_bridge): main orchestrator with dependency injection
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
Composable: cursor/aggregator/strategy/publisher/audit_writer/broker
all injected. Master kill-switch (kevin_enable_trading=false) routes to
audit-only path. Cursor advances ONLY after XADD succeeds (race fix).
Concrete collaborators wired in subsequent tasks.

Also extends TradeSignal + SignalDirection.EXIT with the optional
fields Kevin paths need (strategy_id, target_dollars, stop_loss_pct,
take_profit_pct).
2026-05-24 00:59:56 +00:00
cd75c4ab7e feat(backtester): extend compute_metrics with alpha/beta/winners/best
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
In-place extension (no fork). Existing tests still pass; new fields are
optional and None when no benchmark is supplied.
2026-05-24 00:57:42 +00:00
23ce45a4f2 feat(kevin): mention-driven backtest mini-engine
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
Walks mentions chronologically, T+1 entry, time-based exit per
KevinStrategy. Reuses backtester/metrics::compute_metrics for headline
numbers. KevinPriceLoader fronts market_data + Alpaca.
2026-05-24 00:56:57 +00:00
7dcce5ea0e feat(kevin): KevinStrategy standalone decision logic
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Stateless: mention + account_state -> KevinDecision. Conviction-weighted
sizing, time_horizon-derived hold periods, hard per-ticker cap. The
bridge and the backtest mini-engine both call evaluate_mention so
behaviour cannot drift.
2026-05-24 00:51:31 +00:00
c4e92b580e feat(kevin): alembic migration for v2 trading tables
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
3 new tables + seeds the 'kevin' row in strategies with a pinned UUID
constant so Trade.strategy_id can be joined back to the strategy across
live + backtest paths.
2026-05-24 00:50:00 +00:00
4d40536da7 feat(kevin): SA models for bridge audit + backtest persistence
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
3 tables (kevin_signal_bridge_state, kevin_backtest_runs,
kevin_backtest_trades) all UUID-keyed for consistency with Trade/Position.
KEVIN_STRATEGY_UUID constant pinned for FK joins from Trade.strategy_id.
2026-05-24 00:49:52 +00:00
6636054742 feat(dashboard): /meet-kevin/strategy page wired
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
Strategy.tsx composes 6-up metrics header, StrategyVsBenchmarkCurve
equity chart, TickerScorecardTable and BacktestRunHistory. Selecting a
backtest run replaces the chart with that run's equity curve. Run
Backtest button fires POST and polls for completion.
App.tsx: +route /meet-kevin/strategy.
Layout.tsx: +sidebar entry 'MK Strategy' under Meet Kevin group.
2026-05-24 00:48:27 +00:00
5f5529ef09 feat(dashboard): 3 components for the strategy page
TickerScorecardTable: bridge-status badges (WOULD-TRADE/HOLDING/etc),
conviction bar, unrealised P&L, manual-close button.
BacktestRunHistory: sortable run list with return/sharpe/alpha columns,
row click selects a run for detail view.
StrategyVsBenchmarkCurve: dual lightweight-charts line (strategy blue,
SPY dashed grey) with legend.
2026-05-24 00:48:22 +00:00
90cf21521f feat(dashboard): TS types + API client for strategy + backtest
BacktestRun, BacktestRunDetail, StrategyTicker, StrategyEquityCurve,
StrategyPerformance types added to meetKevin.ts. New meetKevinStrategy.ts
with 8 axios methods covering the backtest run/list/get/latest and
strategy tickers/equity-curve/performance/close endpoints.
2026-05-24 00:48:16 +00:00
9d752aa0a2 feat(kevin): KevinDecision + KevinAccountState schemas
Some checks failed
ci/woodpecker/push/woodpecker Pipeline was canceled
Standalone schemas (no BaseStrategy coupling) used by both the live
signal bridge and the backtest mini-engine.
2026-05-24 00:44:57 +00:00
c83f13625b add Meet Kevin v2 implementation plan (3 phases, 22 tasks)
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Maps the design doc (commit 280f807) to bite-sized tasks. Phase 1 ships
strategy + backtest + bridge in audit-only mode; Phase 2 extends
OrderRequest/AlpacaBroker for BRACKET orders, extends RiskManager, and
flips the kill-switch; Phase 3 ships the paper-account UI page.

Each task has Test → Run-and-fail → Implement → Run-and-pass → Commit
steps with concrete code in every step. Implementer can pick up any
task without prior session context.
2026-05-24 00:40:20 +00:00
280f807236 add Meet Kevin v2 paper-trading + backtest + UI design
Synthesizes work of two parallel architect agents (strategy +
paper-trading rules / backtest + UI surface) and the subsequent
challenger review. Resolves 11 issues the challenger raised:

- KevinStrategy is standalone, not BaseStrategy subclass (signature
  mismatch — BaseStrategy.evaluate is bar-driven, Kevin is event-driven)
- backtester/kevin_backtest.py as parallel mention-driven mini-engine,
  not a fake adapter onto BacktestEngine
- AlpacaBroker BRACKET support specified (OrderRequest schema + broker
  _build_order_request extensions)
- Filtering paper-account trades via strategy_id FK (the actual field;
  Trade.strategy_name doesn't exist) — migration seeds a 'kevin' row
- Cursor advance race fixed (XADD success → cursor advance)
- Daily counter mechanics specified (Redis INCR + audit dedupe)
- kevin_signal_bridge_state table added to data model (3 new tables now)
- All PKs UUID for consistency with Trade/Position
- StrategyVsBenchmarkCurve.tsx promoted from contingent to definitely-new
- 'avoid' policy split into AVOID_CLOSES_LONGS + AVOID_BLOCKS_DAYS knobs
- Phasing collapsed A+B into Phase 1 (ticker scorecard needs bridge
  audit rows to render WOULD-TRADE badges)
2026-05-23 10:04:04 +00:00
ed2195d879 feat(meet-kevin): throttle inter-video LLM calls (30s) to stay under Anthropic RPM
First production run hit Anthropic's per-account rate_limit_error (429) trying
to burn through 16 backfill videos in seconds. The SDK's built-in retry can't
recover because the rate limit window resets slower than the 3 retry attempts.

Added meet_kevin_inter_video_sleep_seconds (default 30s) to PipelineDeps and
main's _process_pending_videos loop. 16 backfill videos now take ~8 min (16 * 30s
sleeps + ~30s per LLM call) instead of bursting into the rate limit.
2026-05-22 20:25:19 +00:00
3402ba0e7f fix(docker): drop sentiment extras from runtime image
sentiment-analyzer service is disabled in the K8s revival (removed from
the workers Pod spec). Its torch+transformers dependency adds ~2GB to
the image with no runtime benefit. Tests still install it via the
.[dev] extras for the test step.

Image size: ~3GB -> ~1GB.
2026-05-22 20:15:06 +00:00
31047e6fd2 ci: include meet_kevin extras in test step (yt-dlp, feedparser, anthropic, httpx) 2026-05-22 20:00:59 +00:00
8a1d03a967 refactor(meet-kevin): switch LLM back to native Anthropic SDK with OAuth bearer
Previous refactor (89f01ad) moved to OpenRouter because no sk-ant-api-* key
was found in Vault. Turns out claude-agent-service-spare-{1,2} hold
sk-ant-oat01-* OAuth tokens (108 chars, scope user:inference, 1-year TTL,
minted via 'claude setup-token' — see memory id=832).

These tokens work with the Anthropic SDK via the auth_token= constructor
argument (routes to Authorization: Bearer ... instead of x-api-key: ...).
They consume the Enterprise Claude subscription quota rather than
per-call billing, so the OpenRouter zero-credit problem goes away.

- llm_analyzer.py: revert OpenAI client to AsyncAnthropic; tool-use API
  + cache_control restored
- config.py: openrouter_api_key -> anthropic_oauth_token; model slug
  reverted from anthropic/claude-sonnet-4.5 -> claude-sonnet-4-5
- main.py: AsyncOpenAI -> AsyncAnthropic(auth_token=...), drop OpenRouter
  attribution headers
- pyproject: openai>=1.50 -> anthropic>=0.40 in meet_kevin extras
- tests: mocks ported back to messages.create + tool_use blocks
2026-05-22 19:24:40 +00:00
4f4d365652 fix(docker): add ffmpeg + nodejs for yt-dlp YouTube extraction
yt-dlp requires:
- ffmpeg for sub-conversion (--convert-subs srt) and any format mux
- A JS runtime for YouTube player decryption (deno or node)

Without these, every caption extraction attempt in the meet-kevin-watcher
container fails with 'ffmpeg not found' + 'No supported JavaScript runtime
could be found'. Adding both to the runtime stage of Dockerfile.service.

Size impact: ~50 MB.
2026-05-22 14:03:22 +00:00
89f01ad9c0 refactor(meet-kevin): switch LLM analyzer to OpenRouter via OpenAI SDK
User's Vault has openrouter_api_key but no direct sk-ant-* Anthropic key.
OpenRouter passes through Claude Sonnet 4.6 (~3% markup over Anthropic
list pricing) and matches the existing gpt_mini_endpoint pattern used
by recruiter-responder.

- Replace anthropic.AsyncAnthropic with openai.AsyncOpenAI + base_url
- Convert Anthropic tool-use API to OpenAI function-calling
- System prompt unchanged (analyst instructions are model-agnostic)
- Drop cache_control (not in OpenAI API); revisit later if cost matters
- Model slug: anthropic/claude-sonnet-4.5 (OpenRouter's current Claude tier)
- Pricing: $3.10/M input, $15.50/M output (OpenRouter pass-through)
- Config field anthropic_api_key -> openrouter_api_key
- pyproject extras: anthropic>=0.40 -> openai>=1.50

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 09:52:55 +00:00
3c20c8c12c feat: add meet_kevin extras (yt-dlp, feedparser, anthropic) 2026-05-21 20:16:09 +00:00
7b81980c66 fix(meet-kevin): API smoke-test bugs from Task 17 QA
Three issues caught during end-to-end manual QA against docker-compose:

1. SAEnum field columns serialized to Python enum NAMES ('DISCOVERED')
   but the DB enum had VALUES ('discovered'). Added `values_callable`
   to all 5 SAEnum() declarations in shared/models/meet_kevin.py so they
   emit values, matching the migration's enum literals.

2. /dashboard's "last 7 days" / "last 14 days" filters used
   `func.cast("7 days", type_=None)` which produced NullType DDL.
   Replaced with `text("now() - interval '7 days'")`.

3. /dashboard's outlook trend query repeated `func.date_trunc("day", col)`
   in SELECT, GROUP BY and ORDER BY — Postgres treats each as a separate
   parameterized expression. Hoisted into a single `day_trunc` variable
   so all three clauses reference the same SQL fragment.

All 11 /api/meet-kevin/* endpoints now return valid JSON against a
docker-compose Postgres seeded with one analyzed video + NVDA mention.
2026-05-21 20:15:08 +00:00
01856bab9f feat(dashboard): wire Meet Kevin routes + sidebar entry 2026-05-21 20:08:08 +00:00
6bcb6637a8 feat(dashboard): Meet Kevin stocks list + per-ticker drill-down 2026-05-21 20:07:01 +00:00
9ce0e44929 feat(dashboard): Meet Kevin video detail page (tabs + iframe + deep-links) 2026-05-21 20:05:14 +00:00
625c22b833 feat(dashboard): Meet Kevin videos feed page 2026-05-21 20:03:23 +00:00
d4a1ca870e feat(dashboard): Meet Kevin home page 2026-05-21 20:01:53 +00:00
a4d75e37c4 feat(dashboard): reusable Meet Kevin components (ActionChip, ConvictionBar, YouTubeEmbed) 2026-05-21 19:58:36 +00:00
83b18b43cf revert: keep original dashboard tsconfig (Task 10 didn't need to change it) 2026-05-21 19:57:30 +00:00
cafcaad502 feat(dashboard): Meet Kevin TypeScript types + API client 2026-05-21 19:56:13 +00:00
bfa7a503da feat(api): /api/meet-kevin/* routes (11 endpoints) 2026-05-21 19:53:16 +00:00
8f5ee8f1c3 feat(meet-kevin): pipeline orchestrator + service main loop
Implements Task 8 of the Meet Kevin revival plan.

- pipeline.py: PipelineDeps dataclass (frozen, DI-friendly), process_one_video
  state machine (discovered→captioned→analyzed with retry/cost-cap logic),
  and daily_cost_used() SQL helper.
- main.py: async run() entry point with RSS poll loop, per-video pipeline
  processing, OTEL counters, SIGTERM/SIGINT shutdown, httpx client lifecycle,
  and clean Anthropic/DB teardown.
- tests: 5 pipeline unit tests (happy path, no captions, cost cap, retry
  increment, failed-after-3-retries) all passing; full watcher suite 56/56.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 19:48:43 +00:00
8309556c00 feat(meet-kevin): Claude Sonnet 4.6 LLM analyzer (tool-use forcing + prompt cache)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 19:44:57 +00:00
145f7dbec5 feat(meet-kevin): caption extractor via yt-dlp
- Implement CaptionResult frozen dataclass for structured caption data
- Add parse_srt() to parse SubRip format with flexible timestamp handling
- Add extract_captions() async function using yt-dlp subprocess wrapper
- Prefer manual captions over auto-generated; clean up SRT files after parsing
- Add 16 comprehensive tests covering edge cases (empty input, malformed SRT,
  timestamp variations, language extraction, manual vs auto selection)
- Type-safe implementation with full mypy --strict compliance
- Add sample.srt fixture with 3 segments mentioning NVDA for test reference
2026-05-21 19:40:52 +00:00
8ce3ede09c feat(meet-kevin): RSS poller for YouTube uploads 2026-05-21 19:36:22 +00:00
8edcb070ed feat: scaffold meet_kevin_watcher service + config 2026-05-21 19:33:04 +00:00
61adf63c7d feat: add Alembic migration for Meet Kevin tables 2026-05-21 19:31:21 +00:00
a49e46f787 fix(models): drop dead __table_args__ + use func.now() for server defaults 2026-05-21 19:26:42 +00:00
8ed2e70e8f feat: add Meet Kevin SQLAlchemy models (5 tables) 2026-05-21 19:19:33 +00:00
8a412e6ae9 fix(schemas): use enum types as field types + enforce symbol length
- Replace all Literal[...] type annotations with corresponding enum classes
  (TickerAction, TimeHorizon, MarketOutlook, VideoStatus, TranscriptSource)
  for MeetKevinTickerMention, MeetKevinAnalysis, and API response models
  (VideoSummary, VideoDetail, StockMention, StockSummary, TimelineBucket)
- Add min_length=1, max_length=10 validation to MeetKevinTickerMention.symbol
- Split test_conviction_edge_cases into two separate boundary tests
- Strengthen test_valid_ticker_mention with assertions for all 6 fields
- Trim no-information docstrings from TranscriptSegment, StockTimeline
- All 60 schema tests pass
2026-05-21 19:15:59 +00:00
75534de71b feat: add Meet Kevin pydantic schemas (analysis + API shapes) 2026-05-21 19:06:04 +00:00
8f616e6487 add Meet Kevin revival implementation plan
22-task plan across 6 phases (data layer, watcher service stages,
API gateway, dashboard, container/deps, K8s revival). Each task
includes TDD checkboxes, file paths, acceptance criteria, and
commit commands. References the design doc (ab382af) for schemas,
prompts, and the Terraform diff.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 19:01:24 +00:00
ab382af3f5 add Meet Kevin revival design document
Design for reviving the trading-bot K8s stack with a new Meet Kevin
YouTube watcher pipeline. v1 scope: poll RSS every 3h, extract
captions via yt-dlp, run transcript through Claude Sonnet 4.6 for
structured per-ticker recommendations and market outlook, surface
in a new ticker-centric UI under /meet-kevin/*. Bot integration
(signal_generator) and auto-trading deferred to v2.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 18:42:46 +00:00
Viktor Barzin
072ea015fd
ci: retrigger build 2026-03-15 22:53:07 +00:00
Viktor Barzin
59d2e634c8
[ci] rebuild 2026-02-28 23:00:48 +00:00
Viktor Barzin
02d6f717a5
[ci] rebuild after agent restart
Some checks are pending
ci/woodpecker/push/woodpecker Pipeline is running
2026-02-28 15:10:08 +00:00
Viktor Barzin
b64b15e737
[ci] rebuild
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2026-02-28 14:47:20 +00:00