Oracle3
Open-source trading engine and MCP server for prediction markets. Fee-aware no-arbitrage trading across related contracts, live on Kalshi, Polymarket and Solana or on paper.
Every stock in plain English, every move with a reason. No finance degree, no jargon, no guessing.
Translation pending
FinanceTypeScript · JavaScriptGitHub @DavidHasselhoeOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
A stock research and portfolio web app for beginner-to-intermediate investors. Live market data, AI-powered insights, crypto & commodity support, SEC filing analysis, investing education, and social features — all in one place, with a free tier and a Stripe-powered Pro subscription.Read the full README ↗A stock research and portfolio web app for beginner-to-intermediate investors. Live market data, AI-powered insights, crypto & commodity support, SEC filing analysis, investing education, and social features — all in one place, with a free tier and a Stripe-powered Pro subscription.
account_tier in Supabase), self-serve checkout and billing portalTermTooltip renders plain-language labels for beginners, full finance terms for advanced| Area | Technology |
|---|---|
| Framework | Next.js 16 (App Router), React 19 |
| Language | TypeScript (strict mode) |
| Styling | Tailwind CSS 4 |
| Database & Auth | Supabase — Postgres, Auth, Storage |
| Client data | TanStack Query v5 |
| Validation | Zod |
| UI | Radix UI / shadcn-ui, Framer Motion, Lucide icons, cmdk |
| Charts | Lightweight Charts (TradingView — price charts), Recharts (financials), D3 + d3-sankey (Sankey diagram) |
| AI — chat | Vercel AI SDK + Anthropic Claude |
| AI — analysis |
Primary market data: TwelveData (quotes, candles, stats, financials, earnings, logos)
News & fallbacks: Finnhub
SEC filings: EDGAR direct
Company logos: Logo.dev + TwelveData, persisted in Supabase Storage
| Source | Used for |
|---|---|
| TwelveData | Real-time & historical quotes, candles, statistics, financials, earnings, technical indicators, logos, symbol search |
| Finnhub | Market news, fallback quotes |
| SEC EDGAR | 10-K, 10-Q, 20-F, 8-K filing ingestion |
| Anthropic Claude | Bull chat, "Why Today?" price explanations, Daily Brief, AI Deep Dive reports, Bull's Weekly Pick, Academy content |
| Resend | Morning alert email, verification and billing email |
| SnapTrade | Brokerage OAuth + live holdings sync |
| Stripe | Pro subscription billing |
| Upstash | Redis for API rate limiting and market data caching; QStash for the hourly user-alerts schedule |
| Supabase | User accounts, holdings, watchlists, theses, daily briefs, Academy progress, company index |
| Discord | Changelog announcements, ops/cron alerts (internal webhooks) |
| Instagram Graph API | Automated content pipeline (earnings calendar and results, earnings deep dives, market movers, Weekly Pick scoreboard); publishes automatically and confirms in Discord |
npm install
Create .env.local in the project root. ENV_SETUP.md has the full variable list.
Required for core functionality:
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
ANTHROPIC_API_KEY # Every AI feature (Claude)
TWELVE_DATA_API_KEY # Primary market data
Optional / production:
FINNHUB_API_KEY # News + quote fallbacks
RESEND_API_KEY # Email notifications
CRON_SECRET # Protect cron endpoints
LOGO_DEV_KEY # Company logos
NEXT_PUBLIC_APP_URL # Used in email links
SNAPTRADE_CLIENT_ID # Brokerage OAuth
SNAPTRADE_CONSUMER_KEY
UPSTASH_REDIS_REST_URL # Rate limiting / caching
UPSTASH_REDIS_REST_TOKEN
STRIPE_SECRET_KEY # Pro subscription billing
STRIPE_WEBHOOK_SECRET
STRIPE_PRICE_PRO_MONTHLY
STRIPE_PRICE_PRO_ANNUAL
DISCORD_CHANGELOG_WEBHOOK_URL # Discord announcements
DISCORD_INSTAGRAM_WEBHOOK_URL
INSTAGRAM_APP_ID # Automated Instagram content pipeline
INSTAGRAM_APP_SECRET
INSTAGRAM_ACCESS_TOKEN
INSTAGRAM_USER_ID
See ENV_SETUP.md for the complete, current list.
Apply Supabase migrations:
npx supabase db push
npm run dev
Open http://localhost:3000.
BullPen/
├── app/
│ ├── api/ # 100+ API route handlers
│ ├── stock/[ticker]/ # Stock detail page
│ ├── asset/[slug]/ # Universal crypto/commodity page (BTC-USD, XAU-USD)
│ ├── etf/[ticker]/ # ETF page
│ ├── holdings/ # Portfolio dashboard
│ ├── watchlist/ # Watchlist
│ ├── tools/ # AI, screener, compare, filings, calendar, heatmap, deep-dive, …
│ ├── academy/ # Courses, daily challenges, leaderboard
│ ├── picks/ # Bull's Weekly Pick archive
│ ├── pricing/, upgrade/ # Pro subscription pages
│ ├── dashboard/ # Post-login landing dashboard
│ ├── notifications/ # In-app notification center
│ ├── share/[id]/ # Public shareable cards (no auth required)
│ ├── admin/ # Internal-only: AI cost tracking, feedback
│ ├── social/, users/ # Community features
│ └── (auth, onboarding, brokerage-callback routes)
├── components/ # React components (organised by domain)
│ ├── asset/ # Crypto/commodity cards and stats
│ ├── stock/ # Stock-specific components
│ ├── holdings/ # Portfolio components
│ ├── discover/ # Homepage widgets
│ ├── academy/ # Course cards, challenge cards
│ ├── billing/ # Pricing, checkout, entitlements UI
│ ├── deep-dive/ # AI Deep Dive lens picker and report blocks
│ ├── picks/ # Weekly Pick hero and history
│ ├── watchlist/
│ ├── ai/ # AI chat panel
│ ├── i18n/ # Language switcher
│ └── ui/ # Shared design system
├── hooks/ # Shared React hooks
├── lib/
│ ├── ai/ # Agent, system prompt, tool definitions; deep-dive/ and picks/ subpipelines
│ ├── assets/ # Asset type utilities (slugToSymbol, inferAssetType)
│ ├── billing/ # Stripe checkout, tiers, quotas, AI cost logging
│ ├── finance/ # Health score, signals, glossary
│ ├── twelvedata/ # TwelveData API client
│ ├── supabase/ # Typed Supabase clients
│ ├── security/ # Rate limiting, input validation
│ ├── currency/ # FX conversion
│ ├── i18n/ # Locale config + AI translation pipeline
│ ├── discord/ # Ops webhook posting
│ ├── instagram/ # Automated content generation/rendering
│ ├── shares/ # Public share-link generation
│ ├── onboarding/ # Post-signup flow state
│ └── ingestion/ # SEC filing ingestion pipeline
├── scripts/ # One-off CLI utilities
└── supabase/migrations/ # SQL migrations
| Script | Description |
|---|---|
npm run dev | Development server (localhost:3000) |
npm run build | Production build |
npm run lint | ESLint (primary code-quality gate) |
npm run i18n:translate -- --ns=<ns> | AI-translate new keys in a namespace (review the diff: it can reorder or rewrite other keys) |
npm run i18n:pseudo | Regenerate the qa pseudo-locale |
npm run test-cron-coverage | Check every cron route has a scheduler and vice versa |
npm run test-no-truncated-text | Fail on AI-written text cut off without a Show more |
npm run trigger-cron | Manually fire the daily brief cron |
npm run trigger-alerts | Manually fire the user-alerts cron |
npm run trigger-instagram-earnings | Manually fire the Instagram content-generation cron |
npm run instagram-publish | Publish a staged Instagram carousel |
npm run test-credit-budget | Test the shared TwelveData credit-budget guard |
npm run test-trends | Test trend detection |
npm run verify-picks-math | Sanity-check Bull's Weekly Pick performance calculations |
npm run set-gold-tier | Set a user's account_tier directly (admin utility) |
npm run post-changelog-discord | Announce a new changelog entry in Discord |
Many more one-off scripts (logo backfills, locale tooling, email/webhook smoke tests) live in scripts/ — see package.json for the full list.
Split across three schedulers. Every cron route requires the CRON_SECRET bearer header, whoever triggers it. The full table with schedules and reasons lives in docs/agent/scheduled-work.md; run npm run test-cron-coverage after touching any of them.
| Scheduler | Used for | Examples |
|---|---|---|
Vercel cron (vercel.json) | Jobs that run at most once a day | Daily Brief (06:30 UTC), Weekly Pick (Mon 06:30), morning alert email (08:30), earnings/dividend/price-move notifications, economic calendar sync, Academy content, Instagram posts |
| Upstash QStash | Sub-daily, time-sensitive jobs | User price/metric alerts, hourly through market hours |
GitHub Actions (.github/workflows/cron-*.yml) | Hours-long batch loops paced under the TwelveData rate limit, and jobs that commit to git | Market data and financials prefetch, calendar prefetch, screener refresh, search index refresh, index constituent sync |
Trigger manually with npm run trigger-cron (daily brief) or npm run trigger-alerts (user alerts).
main → production; push to preview → stable preview URLvercel.json's ignoreCommand decides which commits build: main always builds; Dependabot branches and changelog-only commits (docs(changelog)…) are skipped, which keeps deployment storage down.
Proprietary.
| Anthropic SDK — Claude (Why Today?, Daily Brief, Deep Dive, Bull's Weekly Pick, Academy) |
| Billing | Stripe — Pro subscription checkout, billing portal, webhooks |
| Resend |
| Rate limiting & cache | Upstash Redis |
| Brokerage OAuth | SnapTrade TypeScript SDK |
| i18n | i18next, react-i18next — 7 locales |
| Analytics | Vercel Analytics, Speed Insights |
| Ops notifications | Discord webhooks (changelog announcements, cron/error alerts) |