- What it is: Autonomous Cloudflare Worker that scans upcoming earnings, enriches with volatility and sentiment analysis, and delivers a newsletter via Resend.
- Why it matters: Retail options traders receive quantitative stats, AI commentary, and strategies every weekday morning.
- Performance: Yahoo Finance optimized architecture, sub-200ms quotes, 100% reliability, 69/69 passing tests.
- Subscribe: options-insight.ravishankars.com.
- What it is: Options Insight gives retail traders an edge by automatically analyzing upcoming earnings, enriching them with volatility and sentiment data, and delivering a powerful, easy-to-read newsletter to your inbox every morning.
- Why it matters: Retail options traders get institutional-style prep without the manual grindβquantitative stats, AI commentary, and playbook-ready strategies arrive every weekday morning.
- Performance: Yahoo Finance optimized architecture delivering sub-200ms quotes with 100% reliability and 69/69 passing tests.
- Subscribe: Preview the latest briefing and join the list at options-insight.ravishankars.com.
Options Insight automates the manual options workflow into a deterministic pipeline: scan > filter > analyze > narrate > publish. Traders get consistent, reviewable context.
- Market Radar: Finnhub earnings calendar filtered to curated universe (
src/config.js) and 1β45 day lookahead. - Data-Driven Prescreening: Revenue-based scoring prioritizes high-liquidity opportunities (18β8 symbols, 55% reduction).
- Yahoo Finance Primary: High-performance data provider, sub-200ms quotes, historical data, smart caching.
- Quant Analysis:
simplified-data.jscalculates volatility, RSI, price ranges, and scores opportunities. - Batch AI Analysis: Single Google Gemini API call processes all opportunities (5β1 calls, 80% time reduction).
- Professional Delivery: React Email template, Resend broadcast, unsubscribe handling.
- Primary Data Source: Yahoo Finance (free, reliable, fast)
- Quote Performance: 67-255ms average
- Historical Data: 60-day volatility calculations
- Caching: 5-minute TTL for bulk ops
- Rate Limiting: 500ms delays
- Success Rate: 100% Yahoo Finance reliability
- Fallback Usage: <1% (Finnhub rarely needed)
- Real Data Coverage: 100%
- Test Coverage: 69/69 tests passing, 95%+ core coverage
flowchart TD
classDef data fill:#F3E2D5,stroke:#B45F4D,stroke-width:1px,color:#3A3A3A
classDef worker fill:#FDFDFD,stroke:#E4C590,stroke-width:1.6px,color:#3A3A3A
classDef delivery fill:#DDBEA9,stroke:#B45F4D,stroke-width:1px,color:#3A3A3A
classDef touch fill:#FAF6F0,stroke:#B45F4D,stroke-width:1px,color:#3A3A3A
F["π
Finnhub<br/>Earnings Calendar"]:::data
Y["π Yahoo Finance<br/>Quotes & Historical Data<br/>(Primary - 100% reliable)"]:::data
FH["πΌ Finnhub<br/>Quote Fallback<br/>(Rare usage)"]:::data
G["π§ Google Gemini<br/>Narrative AI"]:::data
U["π€ Retail Trader<br/>Subscriber Persona"]:::touch
Signup["π Signup Page<br/>Cloudflare Pages"]:::touch
S["β± Scheduler & API<br/>(src/index.js)"]:::worker
Sub["π‘ Subscribe Endpoint<br/>(POST /subscribe)"]:::worker
P["π Opportunity Scan<br/>(src/finnhub.js)"]:::worker
V["π Volatility Analysis<br/>(src/simplified-data.js)<br/>β‘ Cached & Optimized"]:::worker
Q["β
Quality Gates<br/>(validateAnalysis)"]:::worker
T["π Email Composer<br/>(src/email-template.js)"]:::worker
Audience["π Resend Audience<br/>Contacts"]:::delivery
R["βοΈ Resend Broadcast"]:::delivery
L["π₯ Subscriber Inbox"]:::delivery
Unsub["πͺ One-click Unsubscribe<br/>Resend-managed"]:::delivery
F --> P
Y --> V
FH -.-> V
P --> V --> Q --> T --> R --> L --> Unsub --> Audience
G --> Q
S --> P
S --> R
U --> Signup --> Sub --> Audience
Traders sign up via Cloudflare Pages, POST to /subscribe, join the Resend audience, and receive daily research with unsubscribe managed by Resend.
Performance Highlights:
- Yahoo Finance: Sub-200ms, 100% reliability
- Smart Caching: 5-min TTL
- Graceful Fallbacks: Finnhub backup
- Real Data: Historical volatility from market data
| Layer | Service | Purpose | Performance Notes |
|---|---|---|---|
| Market Events | Finnhub | Earnings calendar & VIX quote | Free tier 60 calls/min; configured via FINNHUB_API_KEY |
| Primary Data | Yahoo Finance | Quotes & historical volatility | 100% reliable, sub-200ms response, no API limits |
| Fallback Data | Finnhub | Quote backup | <1% usage rate; automatic failover |
| AI Narrative | Google Gemini | Sentiment, strategy articulation | Model: gemini-pro-latest; validated before inclusion |
| Delivery | Resend | Broadcast the React Email digest | Audience ID stored in secrets |
| Compute | Cloudflare Workers | Cron trigger, API endpoints, pipeline orchestration | Runs at 08:00 UTC weekdays (see wrangler.toml) |
- Yahoo Finance Primary: 67-255ms average quote response time
- Smart Caching: 5-minute TTL reduces redundant API calls by ~80%
- Rate Optimization: 500ms delays = 58% faster bulk processing
- Real Data Focus: 100% historical volatility from actual market data (no estimates needed)
- Scan Universe:
getEarningsOpportunitiespulls 45 days, filters tickers, scores timing/liquidity. - Data-Driven Prescreening:
calculatePrescreenScoreuses revenue estimates and timing to rank opportunities. - Yahoo Finance Volatility:
SimplifiedDataProviderfetches quotes and volatility for top-ranked symbols, cached. - Quality Gate:
volatilityScore+validateAnalysisthresholds filter low-info names. - Batch AI Analysis: Single Gemini API call processes all qualified opportunities simultaneously.
- Rendering & Send:
EmailTemplaterenders,sendEmailDigestsends via Resend.
Emoji-prefixed logs at each stage; see make test-full-run for transcript.
Node.js 20+ required.
npm installCreate .env for CLI and Make targets:
FINNHUB_API_KEY=your_finnhub_key
GEMINI_API_KEY=your_gemini_key
RESEND_API_KEY=your_resend_key
AUDIENCE_ID=your_resend_audience_id
TRIGGER_AUTH_SECRET=your_shared_secret
SUMMARY_EMAIL_RECIPIENT=********@gmail.com
# SIGNUP_ALLOWED_ORIGINS=https://options-insight.pages.dev,https://yourdomain.com
# SUMMARY_EMAIL_FROM=alerts@ravishankars.comRate-limit performance
- Yahoo Finance: No API limits, sub-200ms response times, 100% reliability
- Smart Caching: 5-minute TTL reduces API calls by ~80% during bulk operations
- Finnhub: 60 calls/min free tierβample for daily earnings scans
- Optimized Delays: 500ms between requests = 58% faster processing
- Gemini: Quotas vary by account; failures default to skipping analysis so email still sends
make test-finnhub # Earnings scan
make test-yahoo # Quote + volatility pipeline
make test-email # Render newsletter previewmake preview-email
open email-preview.html| Scenario | Command | Description |
|---|---|---|
| End-to-end smoke | make test-full-run |
Simulates scheduler + delivery locally |
| Component drill-down | make test-<component> |
Finnhub, Yahoo, volatility, Gemini, email, scoring |
| Cron dev server | make dev |
Boots Wrangler with endpoints |
| Force a run | curl http://localhost:8787/cdn-cgi/handler/scheduled |
Mimics cron event |
| Manual trigger | curl -X POST -H "x-trigger-secret: $TRIGGER_AUTH_SECRET" https://.../trigger |
Requires secret header |
| Review run summary | Automatic | Status email to SUMMARY_EMAIL_RECIPIENT |
| Public signup form | pages/ |
Static site posts to /subscribe |
Emoji logs announce each stage; Yahoo Finance successes show response times, Finnhub fallbacks are marked.
The system operates within Cloudflare Worker limits to ensure reliable production performance:
| Constraint | Free Tier | Paid Tier | Impact on System |
|---|---|---|---|
| CPU Time | 10ms per request | 5 minutes per request | Newsletter pipeline requires paid tier for AI processing |
| Subrequests | 50 per request | 1,000 per request | Data-driven prescreening keeps requests under limits |
| Duration | No hard limit | No hard limit | Pipeline completes in ~30 seconds |
| Memory | 128 MB | 128 MB | Sufficient for current operations |
| Daily Requests | 100,000 | No limit | Cron schedule uses minimal quota |
Key Design Decisions:
- Prescreening Logic: Revenue-based filtering reduces API calls to stay within subrequest limits
- Batch Processing: Single Gemini API call minimizes both subrequests and CPU time
- Smart Caching: 5-minute TTL reduces redundant calls during development/testing
Reference: Cloudflare Workers Platform Limits
-
Push secrets:
make push-secrets
-
Deploy:
make deploy
-
Verify:
make verify-deployment
-
Manual trigger:
make trigger-production
GET /healthβ Liveness probeGET /statusβ API key inventory (masked)POST /triggerβ Run pipeline (requiresx-trigger-secret)POST /subscribeβ CORS-protected signup (acceptsSIGNUP_ALLOWED_ORIGINS)
High test coverage with unit and integration tests.
npm test
npm run test:coverage
npm run test:watch
npm run test:ui# Individual component tests
make test-finnhub # Earnings calendar data
make test-yahoo # Volatility analysis with Yahoo Finance
make test-gemini # AI analysis generation
make test-email # Newsletter rendering
make preview-email # Local newsletter preview
# Integration tests
make test-full-run # End-to-end pipeline80%+ coverage for lines, functions, branches, statements. Reports uploaded to Codecov.
- Performance Attribution: Track realized vs. forecast volatility and POP accuracy.
- Indicator Deepening: Expand technical signals (ADX, ATR, skew).
- Risk Guardrails: Position sizing heuristics, capital at risk warnings.
- Human-in-the-loop: Optional review queue.
- Portfolio Memory: Persist recommendations for analytics.
See contributing guide for setup, standards, and review. Browse good first issue or open a discussion.
CI checks: PRs run Wrangler dry-run compile (Node.js 20). Ensure
npx wrangler deploy --dry-runsucceeds before pushing.
Report sensitive findings via private security advisory or contact the maintainer. Acknowledge within 72 hours.
Licensed under MIT License. Contributions are covered by the same license.
- Outputs are educational research, not investment advice.
- Options carry risk; confirm assumptions independently.
- Source code is openβpreserve explanatory logging.
- Product Requirements Document
src/β Component implementations (finnhub.js,simplified-data.js,gemini.js,email-template.js)
