A full-stack options flow intelligence platform with a Bloomberg terminal-style dashboard. Scans 300+ tickers daily for unusual activity, scores each alert with a composite Flow Score, and surfaces high-conviction signals with full context — Greeks, IV rank, earnings proximity, repeat accumulation, and macro futures.
Dashboard — Live Flow Feed
Alert Detail — Greeks, Chart, News
- EOD options scan — pulls full options chains for 300+ tickers via Tradier after market close
- Flow Score (0–100) — composite conviction score weighted by premium, vol/OI ratio, IV rank, order type, and repeat count
- Sweep / Block / Split classification — order type tagged and filterable on every alert
- Repeat flow detection — same strike/expiry appearing within 3 days flagged with accumulation count
- IV Rank — tells you if the buyer paid historically cheap or expensive implied volatility
- Full Greeks — delta, gamma, vega, theta from Tradier or computed via Black-Scholes
- Earnings calendar — days-to-earnings on every alert; ⚡ EARNINGS THIS WEEK strip on dashboard
- Real-time Supabase subscription — new alerts appear instantly via Postgres Realtime without polling
- LIVE / HISTORY toggle — switch between today's feed and 7D / 30D / 90D lookback
- Ticker aggregation — per-ticker summary bar with total premium and alert count
- Multi-interval price charts — 6 intervals (1m to 1D) with candlestick, line, area views
- Market news feed — recent news per ticker alongside every alert
- Filter bar — filter by contract type, ticker, order type, and minimum Flow Score
- Keyboard navigation — ↑↓ navigate rows, Enter expand detail, R refresh, / search
- Unlimited alerts (free tier capped at 50/day)
- All candle intervals + extended price history
- Custom alert rules — set conditions on premium, score, order type, DTE, tickers, and more
- Email notifications — triggered after each pipeline run with 60-minute cooldown per rule
- Auth — Supabase Auth with email/password, forgot password, email verification
- Subscriptions — Stripe Checkout + Billing Portal, webhooks for lifecycle events
- Manual trigger —
POST /api/ingestto run the pipeline on demand - Smart startup — auto-runs pipeline on boot if no data found within the last 2 days
- Duplicate-safe upsert — pipeline deduplicates contracts by
(trade_date, contract_ticker)before DB write
| Layer | Technology |
|---|---|
| Backend API | FastAPI + Uvicorn |
| Scheduling | APScheduler (9:00 AM ET + 4:30 PM ET) |
| Options data | Tradier (free developer account) |
| Price charts | Tradier /markets/history + /markets/timesales |
| Database | Supabase (PostgreSQL + Realtime) |
| Auth | Supabase Auth |
| Billing | Stripe |
| Resend | |
| Frontend | Next.js 15 + React 19 |
| Styling | Tailwind CSS v4 |
| Logging | Loguru |
- Python 3.11+
- Node.js 18+
- Supabase project
- Tradier developer account (free — options data)
- Stripe account (for billing)
- Anthropic API key
- Resend API key (optional — for email notifications)
git clone https://github.com/your-username/flowhawk.git
cd flowhawk
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Fill in your keyscd dashboard
npm install
# Create .env.local with your Supabase keys
echo 'NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co' >> .env.local
echo 'NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key' >> .env.local
echo 'NEXT_PUBLIC_API_URL=http://localhost:8000' >> .env.localRun the full schema in your Supabase → SQL Editor:
# Copy and paste the contents of supabase_schema.sql and run it# Tradier — free developer account at https://developer.tradier.com
# Sandbox URL works for developer tokens; use https://api.tradier.com/v1 for live accounts
TRADIER_ACCESS_TOKEN=your_tradier_token
TRADIER_BASE_URL=https://sandbox.tradier.com/v1
# Anthropic
ANTHROPIC_API_KEY=your_key
# Supabase
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_KEY=your_service_role_key
SUPABASE_JWT_SECRET=your_jwt_secret
# Stripe
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_ID=price_...
# Email notifications (optional)
RESEND_API_KEY=re_...
FROM_EMAIL=alerts@yourdomain.com
# Deployment
FRONTEND_URL=https://your-app.vercel.app
ALLOWED_ORIGINS=https://your-app.vercel.app
# Ingestion filters
MIN_PREMIUM=100000 # Minimum total premium ($)
MIN_VOL_OI_RATIO=2.0 # Minimum volume / open interest ratio
MIN_VOLUME=50 # Minimum contract volume
MIN_DTE=7 # Minimum days to expiration
MAX_DTE=90 # Maximum days to expiration
RUN_ON_STARTUP=false # Force pipeline run on every bootNEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
NEXT_PUBLIC_API_URL=http://localhost:8000# Backend (terminal 1)
source venv/bin/activate
uvicorn main:app --reload --port 8000
# Frontend (terminal 2)
cd dashboard
npm run dev- Backend:
http://localhost:8000 - Dashboard:
http://localhost:3000 - API docs:
http://localhost:8000/docs
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/api/flow-alerts |
Latest alerts (filters: trade_date, ticker, contract_type, order_type, min_flow_score, limit) |
GET |
/api/flow-history |
Historical alerts by date range (params: days, ticker, min_premium, limit) |
GET |
/api/ticker/{symbol} |
Price candles + stats (param: interval) |
GET |
/api/ticker/{symbol}/news |
Recent news articles |
POST |
/api/ingest |
Manually trigger ingestion pipeline |
GET |
/api/alert-rules |
List user alert rules (auth required) |
POST |
/api/alert-rules |
Create alert rule (auth required) |
PATCH |
/api/alert-rules/{id} |
Update alert rule (auth required) |
DELETE |
/api/alert-rules/{id} |
Delete alert rule (auth required) |
flowhawk/
├── ingestion/
│ ├── config.py # Settings + 300-ticker universe
│ ├── models.py # Pydantic data models
│ ├── market_data.py # Tradier/Polygon/yfinance data client
│ ├── filters.py # Threshold filtering logic
│ ├── scoring.py # Flow Score calculation
│ ├── greeks.py # Black-Scholes Greeks
│ ├── alert_rules.py # Rule evaluation + Resend email
│ ├── database.py # Supabase read/write/upsert
│ └── pipeline.py # Full ingestion orchestration
├── dashboard/
│ └── src/
│ ├── app/
│ │ ├── page.tsx # Landing page
│ │ ├── dashboard/page.tsx # Main dashboard
│ │ ├── dashboard/rules/page.tsx # Alert rules (pro)
│ │ ├── login/ # Auth pages
│ │ ├── signup/
│ │ └── pricing/
│ ├── components/
│ │ ├── FlowTable.tsx
│ │ ├── AlertDetail.tsx
│ │ ├── FilterBar.tsx
│ │ ├── StatsBar.tsx
│ │ ├── TickerAggregation.tsx
│ │ ├── FuturesBar.tsx
│ │ ├── MarketClock.tsx
│ │ ├── RuleBuilder.tsx
│ │ └── RuleList.tsx
│ ├── hooks/
│ │ ├── useRealtimeAlerts.ts # Supabase Realtime subscription
│ │ ├── useKeyboardNav.ts
│ │ └── useTier.ts
│ ├── contexts/
│ │ └── AuthContext.tsx
│ └── lib/
│ ├── api.ts # Typed API client
│ ├── types.ts # TypeScript interfaces
│ ├── supabase.ts # Supabase client singleton
│ └── utils.ts # Formatting helpers
├── auth.py # JWT auth middleware
├── main.py # FastAPI app + scheduler + routes
├── supabase_schema.sql # Full database schema
├── requirements.txt
└── .env.example
- Import repo at vercel.com, set root directory to
dashboard - Add env vars:
NEXT_PUBLIC_SUPABASE_URL=... NEXT_PUBLIC_SUPABASE_ANON_KEY=... NEXT_PUBLIC_API_URL=https://your-backend.onrender.com
- Import repo at render.com, set root directory to
/ - Start command:
uvicorn main:app --host 0.0.0.0 --port $PORT - Add all
.envvariables in the Environment tab
MIT License — see LICENSE for details.
Not financial advice. FlowHawk surfaces data for informational purposes only.

