A fully automated stock analysis engine that monitors markets 24/7, scores every tracked stock across 8 independent analysis modules, and delivers precision alerts when a high-probability investment opportunity is detected.
StockOpportunity runs as two independent processes — an analysis engine and a live dashboard — working together around the clock.
AAPL · MSFT · GOOGL · AMZN · NVDA · META · BRK.B · JPM · V · JNJ
Easily extended — add any ticker to the Stocks table.
When a stock crosses the 75/100 threshold, an HTML email is delivered instantly via SendGrid — including the score, confidence, and the top signals that triggered the alert.
The Scheduler is a .NET Worker Service powered by Quartz.NET. It runs two jobs that together keep the data fresh and the scores current — six times per day.
Fetches 1 year of daily OHLCV data every run. Free, no key required.
Quarterly income, balance sheet, cash flow, and ratios. Refreshed weekly (saves API quota).
Fetches last 10 headlines per stock. Only new articles are sent to OpenAI for sentiment scoring (−1.0 to +1.0). Duplicate headlines are skipped automatically.
Form 4 filings from the last 90 days. Refreshed weekly. Classifies each filing as BUY or SELL.
Starts 30 minutes after Job 1 so fresh data is already in the database.
Each module reads from the database and returns a score (0–100) with signals.
The Score Engine combines all module scores into a single final score (0–100).
Every module result and the final opportunity score are persisted for the dashboard.
Sends an HTML email via SendGrid with the score, confidence, and top signals.
When the Scheduler starts, Data Ingestion fires immediately and Analysis fires 2 minutes later — so the system is fully operational within minutes of launch without waiting for the next scheduled window.
Every module runs independently, returns a score from 0 to 100, a confidence level, and a list of human-readable signals that explain the score. Modules never crash the system — a data failure returns a neutral 50 with low confidence.
After all 8 modules run, the Score Engine combines their scores into a single opportunity score using a weighted average formula.
Final Score = Σ ( module_score × weight ) ÷ Σ ( weights )
Example:
FinancialHealth 82 × 0.25 = 20.5
Valuation 61 × 0.20 = 12.2
Momentum 74 × 0.20 = 14.8
Sentiment 65 × 0.10 = 6.5
Institutional 70 × 0.10 = 7.0
Leadership 50 × 0.10 = 5.0 ← stub, neutral
Macro 50 × 0.05 = 2.5 ← stub, neutral
Moat 50 × 0.01 = 0.5 ← stub, signals only
─────────────────────────────────────
Final Score = 69.0 / 1.01 ≈ 68.3
Each module returns a confidence level (0–100%) alongside its score. Modules with more historical data report higher confidence (e.g. Momentum needs 200 days of prices for 95% confidence). If fewer than 5 modules contributed real data, the overall confidence is penalised proportionally.
The engine extracts the 5 most meaningful human-readable signals from the highest-scoring modules. These appear in the BUY alert email and on the dashboard — giving a clear, plain-English reason why the opportunity was flagged.
Only BUY recommendations trigger an email alert. All scores are saved to the database and visible on the dashboard regardless of threshold.
Five external data sources feed the system. All API keys are stored securely in configuration — never in code. All clients use automatic retry with exponential backoff if a request fails.
| Source | Data Provided | Cost | Frequency |
|---|---|---|---|
| Yahoo Finance | Daily OHLCV prices (1 year history) | Free | Every run (6×/day) |
| Financial Modeling Prep | Income statements, balance sheet, cash flow, P/E, P/S, EV/EBITDA | Paid plan | Once per week per stock |
| Polygon.io | News headlines (last 10 articles per stock) | Free tier | Every run (6×/day) |
| OpenAI (gpt-4o-mini) | Sentiment score (−1.0 to +1.0) per news headline | Usage-based | Only for new articles (~$0.002/stock/day) |
| SEC EDGAR | Form 4 insider transactions (buys & sells, last 90 days) | Free | Once per week per stock |
Every API call is wrapped in Polly retry logic — 3 attempts with 2s / 4s / 8s exponential backoff. A failed data source never crashes a run.
300ms pause between stocks, 150ms pause between SEC XML fetches. FMP and SEC data is cached weekly to stay well within free-tier quotas.
News articles are deduplicated by title + date — OpenAI is only called for articles not already in the database, minimising token costs.
A Blazor Server web application provides a real-time read-only view of all scores, signals, and alerts. Three pages cover the full picture.
Top 50 stocks ranked by latest score. Summary cards showing BUY / WATCH / IGNORE counts. Score badges, confidence bars, and the top signal per stock at a glance.
Full breakdown for a single stock: KPI cards, all top signals, per-module score bars with individual signals, and a 30-day score history table.
All BUY alerts from the last 30 days with score, signals, and email delivery status. Clicking a row navigates to the full stock detail page.
All data is stored in a SQL Server database. 8 tables cover everything from raw market data through to scored results and sent alerts.
| Table | Purpose | Written By |
|---|---|---|
| Stocks | Universe of tracked stocks — Symbol, Name, Sector, Exchange | Manual / seed |
| Prices | Daily OHLCV snapshots from Yahoo Finance | DataIngestionJob |
| Financials | Quarterly fundamentals — revenue, net income, EBITDA, debt, FCF, ratios | DataIngestionJob |
| NewsArticles | Headlines from Polygon.io with OpenAI sentiment score (−1.0 to +1.0) | DataIngestionJob |
| InsiderTransactions | SEC Form 4 filings — insider buys and sells with share count and price | DataIngestionJob |
| ModuleResults | Per-module score, confidence, and signals after each analysis run | DailyAnalysisJob |
| OpportunityScores | Final aggregated score per stock per run, with recommendation and top signals | DailyAnalysisJob |
| Alerts | Every triggered BUY alert with email and Telegram delivery status | DailyAnalysisJob |
Purpose-built in C# .NET 8 for reliability, performance, and easy extension.
Language & runtime
Data persistence
Lightweight SQL ORM
Job scheduling
Retry & resilience
Email delivery
Real-time dashboard
NLP sentiment
The system is production-ready today. Planned enhancements will increase scoring depth and accessibility.