Top — Opportunities
| # | Symbol | Name | Price | Open | Change | Volume | RVOL | Trades | Dir | Score | Conf | Rec | Exp Move | Mkt Cap | $100 Target | Rationale |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Loading opportunities... | ||||||||||||||||
Market MoversReal-time gainers, losers & most active from FMP
🟢 Top Gainers
🔴 Top Losers
🔥 Most Active
—
📈 Price History
📊 Price & Volume
🤖 AI Score & Signals
📋 Fundamentals
📐 Feature Readout
📐 CAN SLIM Analysis (N · L · M factors)
📊 Trade Activity Summary
✂️ Stock Split
👤 Insider Trades (90 days)
🏛️ Congress Trades (90 days)
🏦 Institutional Holdings (13F filings)
📰 Recent Documents & Catalysts
AlertsScore jumps, new catalysts, trading events
System OverviewPipeline health & data stats
SettingsYour dashboard filters — find the best opportunities
🤖 Signal Filters
📋 Stock Filters
📊 Volume & Momentum
📐 Technical Position
🛡️ Risk Gates
🔔 Notifications
My ProfileAccount details
👤 Personal Information
🔒 Change Password
📋 Account Info
Manage UsersAdmin only
Create New User
Edit User —
Auto TradingPaper Trading Engine Performance
📊 Open Positions
📋 Today's Trades
🚫 Today's Rejections
📈 Performance History
📝 Recent Alpaca Orders
WatchlistEvery ticker the engine is watching · scored + CAN SLIM-passed
Show raw prompt sent to AI
Trading InfoHow the auto-trading engine works
🏗️ Architecture Overview
The engine scans the entire US market every cycle, scores it on two independent paths (news-driven and price-driven), and executes paper trades through Alpaca. Scoring runs every ~2 minutes; the trading cycle every 3 minutes during market hours. A candidate must survive the scoring funnel and a chain of nine entry gates before any order is placed, and the last of those gates re-checks the setup against a live quote at the moment of execution.
📥 Entry Rules
News is not required. A stock qualifies on either path — an AI/news score, or price-and-volume action alone. In practice most trades come from Path 2 (market-driven), and roughly 95% of the scored universe has no news coverage at all.
To become a candidate a stock must clear the scoring funnel:
Candidates are ranked by score × (0.5 + confidence/2) × market_score × mover tier. Confidence modifies the ranking but cannot override a large score gap — a well-behaving stock with no news still outranks a weaker one that happens to be in the headlines.
Each candidate then passes nine entry gates in order, and the first failure stops it:
Execution: spread-aware limit at ask + small buffer; canceled if unfilled after the configured window (15s minimum) or if the ask runs away while pending. Partial fills are adopted and protected with a correctly-sized stop.
Note on rejections: a symbol is logged once per gate per day, so rejection counts on the Watchlist and Debug pages are distinct names, not attempts.
💰 Budget Controls
Loading…
🛑 Stop Loss & Trailing Stops
Initial Stop Loss: Every position gets a GTC (Good Till Cancelled) stop order immediately after fill, placed —. The stop distance matches the stock's volatility instead of shrinking as position size grows; the dollar risk is capped instead by limiting position size to Stop Loss Amount ÷ Stop Loss %. Stop persists across sessions until triggered or cancelled.
Breakeven Move: once a position's peak gain reaches —, the stop is raised to the entry price — a winner that fades exits at scratch instead of riding back down to a full stop-loss.
Profit Target: —
Trailing Stop (two-tier, time-aware):
Loading…
Overnight recovery: At each day's first cycle, the engine checks all open DB trades. If a stop order expired (e.g., due to a previous bug), it automatically re-places a fresh GTC stop at the original stop price.
🚨 Circuit Breakers
Circuit breakers are the last line of defence and work completely independently of scoring, gates and signals. They watch one thing only — actual account equity reported by Alpaca — and they override everything above them. A perfect setup on the best-scoring stock in the market will not be bought if a breaker is tripped.
Three separate drawdowns, measured against three different baselines:
Two response tiers, evaluated most-severe-first on every cycle:
How each one clears:
Live status:
Every breaker event writes a Critical alert to the portal Alerts page, and halts are also surfaced on the Debug page. Unlike most settings, these five thresholds live in appsettings / environment variables, not in the database — they are not editable from the Trade Settings page and changing them requires a redeploy.
🛡️ Risk Manager
Every trade proposal must pass the risk manager before execution. It has absolute veto power.
Rejected trades are logged with the reason. All trade entries, closures, and rejections also write to the portal Alerts page under Info/Warning severity.
📊 Data Pipeline
The scoring engine uses two equally weighted paths. A stock needs only one of them:
Where the data comes from — and how fresh it is:
Anything outside the real-time cap still uses the delayed stored bars, which is why the caps sit where the tradeable names are — the universe is ranked by dollar volume, not by how far a stock has already moved.
⏰ Daily Schedule
All three times above are set on the Trade Settings page. Current values are shown in the Budget Controls panel.
⚠️ Important Notes
• This is paper trading — no real money at risk. After 30 days of validated performance, the system can be switched to live trading.
• Position size is a request, not a guarantee. The per-trade risk cap (Stop Loss Amount ÷ Stop Loss %) overrides it. Raising position size without raising the stop amount changes nothing. The Budget Controls panel shows the effective size and the resulting maximum share price.
• News is optional, not required. Path 2 scores on price and volume alone and accounts for most trades. Confidence is lower for stocks without news by construction, so it only modifies the ranking — it cannot override a materially better score.
• Data freshness matters more than any single gate. The market-wide Polygon feed is 15-minute delayed on the current plan; real-time FMP bars are layered on top for scoring, gating and the final pre-order check. Anything beyond those caps is still evaluated on delayed data.
• Most live configuration (budget, stop loss, breakeven trigger, profit target, gate thresholds, entry window, flatten time) is edited on the Trade Settings page and stored in the app_config table — the engine reloads it every cycle, no restart needed. Exception: circuit-breaker thresholds and the core risk limits live in appsettings / environment variables and require a redeploy to change.
• Saving Trade Settings writes every field at once. Any setting the page does not display is written back at its code default, which can silently revert a value set elsewhere. If you change something by hand in the database, make sure the UI also exposes it.
• The engine is always long, never short. The correct response to high volatility is reducing allocation, not reversing direction.
• Every trade is logged in the trades database table with full audit trail: entry/exit prices, P&L, score at time of entry, stop loss adjustments, and exit reason.
• All significant engine events (entries, closures, EOD, errors, circuit breakers) are written to the portal Alerts page for persistent visibility beyond the DigitalOcean log stream.
Stock ScreenerReal-time anti-manipulation filters
Trade Settings Auto-trading engine parameters — changes apply within 3 minutes
💰 Budget & Sizing
🚦 Entry Gates
📈 Trailing Stop
📡 Path 2 — Market Scan Thresholds — pre-market watchlist + intraday momentum scan
uptrend_check_failed:<reason>.
vwap_check_failed:below_vwap.
ema_breakout_failed:*.
canslim_failed:c_fail|a_fail|s_fail|i_fail in the Rejections panel (highlighted purple).
ticker_fundamentals table must exist before CAN SLIM can be enabled. If you've just deployed the CAN SLIM build, click the button below to create it. Safe to call repeatedly (no-op if already exists).
features and scores tables are the main bloat sources — every scoring cycle writes one JSONB row per ticker to each. Defaults below are conservative for an active operator; tighten further if disk is constrained. Set any value to 0 to disable purge for that table. Tables NOT shown (trades, outcomes, tickers, fundamentals, users) are never purged — they're either small or contain irreplaceable P&L history.
RVOL × |change%| descending
Best conviction = highest relative volume AND biggest move.
System AlertsAPI errors, service health & operational issues
🔴 Active Issues
🔧 API Diagnostics
📋 Recent System Events
📊 Minute BarsPer-minute price, volume and trade count for one ticker, exactly as stored
🔎 Explain TickerEnter a symbol to see every gate it passed or failed, and why it was or was not bought
Leave Time blank and it explains the last snapshot inside your entry window. Set a time and it uses the last snapshot at or before it — what the engine actually had to work with at that instant, never a later one, since a future snapshot would explain a decision using data that did not exist yet.
🐛 DebugEngine state, scoring health & gate funnel — for diagnosing "why no trades"
⚙️ Engine Cycle Health
💰 Trading Status
🚧 Gate Funnel
🔬 Raw JSON
InformationUnderstanding AI signals & metrics
📊 Score (0–100)
The Score is a composite number from 0 to 100 that represents the overall strength of an AI-detected trading opportunity. Higher scores indicate stronger signals with more supporting evidence.
It combines three components:
🎯 Confidence (0–100%)
Confidence measures how reliable the score is — not how big the move will be, but how much you should trust the signal. A high score with low confidence means the signal is strong but uncertain.
Confidence is calculated from:
🧭 Direction
LONG indicates the AI expects the price to rise. SHORT indicates the AI expects the price to fall. Direction is determined by the sign of the raw score before taking its absolute value.
📏 Expected Move (basis points)
Estimated price movement in basis points (100bp = 1%). This is a heuristic based on catalyst impact, price velocity, and volume — not a prediction. Use it to gauge the magnitude of the opportunity, not as a price target.
💡 Recommendation
The Recommendation synthesizes Score, Confidence, Direction, and signal quality into a single actionable label. This is decision support — not investment advice.
Score ≥ 50, Confidence ≥ 35%, AI catalyst confirmed, volume spike confirms. Highest conviction signal.
Score ≥ 50, Confidence ≥ 35%, no contradictory signals. Strong but without volume confirmation.
Score ≥ 30, Confidence ≥ 20%. Solid signal with reasonable conviction.
Meets Buy criteria but contradictory signals present. Proceed with caution.
Score ≥ 15 but low confidence, no AI catalyst, or thin data. Higher risk.
Score too low or conflicting signals too strong to act on. Monitor for developments.
Short-side equivalents (Strong Short, Short, Speculative Short) use the same thresholds for bearish direction.
📡 All Data Points Tracked
Complete inventory of every data source, feature, and signal that feeds into opportunity scoring. Data flows through the pipeline: Sources → Ingestion → AI Analysis → Feature Engineering → Scoring → Ranking.
📈 Market Data (Real-Time)
Source: Tiingo + FMP • Refresh: every 60 seconds during market hours
| Last Price | Current traded price |
| Bid / Ask | Best bid and ask (when available) |
| OHLCV Bars | Open/High/Low/Close/Volume — 1m, 5m, 15m, 1h, daily |
| Volume | Current session volume |
| Avg Volume (30d) | 30-day average daily volume — basis for RVOL calculation |
| RVOL | Relative Volume = current vol ÷ avg vol. ≥2x = high conviction (green), 1–2x = elevated (yellow) |
| Trade Count | Number of individual trades (from Alpaca bars n field). Distinguishes real broad participation from a few large block trades |
| VWAP | Volume-Weighted Average Price — from Alpaca bars vw field. Price deviation from VWAP flags pumps or dumps |
| Day High / Low | Intraday high and low prices |
| Previous Close | Prior session closing price |
| Change / Change % | Dollar and percentage change from previous close |
| Market Cap | Total market capitalization |
| P/E Ratio | Price-to-earnings ratio (trailing) |
| 52-Week High / Low | Annual price range |
🌐 Ticker Universe (Reference)
Source: FMP Screener • Refresh: daily via Universe Seeder
| Symbol | Ticker symbol (e.g., AAPL) |
| Exchange | NYSE, NASDAQ, AMEX |
| Company Name | Full entity name |
| Sector / Industry | GICS sector and industry classification |
| Is Active | Whether ticker is currently tradeable |
🤖 AI Analysis (GPT-4.5) (Per Document)
Source: GPT-4.5 structured extraction • Trigger: each new document ingested
| Sentiment Score | -100 (extreme bearish) to +100 (extreme bullish) |
| Impact Level | 0–100 significance rating for intraday effect |
| Bullish Probability | 0.0–1.0 likelihood of upward movement |
| Bearish Probability | 0.0–1.0 likelihood of downward movement |
| AI Confidence | 0.0–1.0 model's certainty in its own assessment |
| Event Type | earnings, guidance, m&a, product, legal, macro, analyst, insider, layoffs, partnership, security_incident, regulatory, rumor, other |
| Time Sensitivity | immediate, intraday, or multi_day |
| Summary | ≤600 char AI-written explanation of the event |
| Key Drivers | Up to 10 short driver strings explaining the signal |
| Risk Flags | halt_risk, low_liquidity, source_unreliable, contradictory, pump_risk, legal_uncertainty |
| Tickers Mentioned | All symbols referenced in the document |
| Numbers Mentioned | Key figures (EPS, revenue, guidance) with context |
| Model Version | GPT model used (e.g., gpt-4.5) |
| Prompt Version | Versioned prompt template for reproducibility |
🔧 Computed Features (Per Scoring Cycle)
Computed every 1–5 minutes during market hours from raw data
| vol_spike_ratio | Current 15m volume / avg 15m volume (30d) — detects unusual activity |
| rvol | Relative volume = current session vol ÷ 30-day avg vol. Live version of vol_spike_ratio |
| trade_count | Number of individual trades from Alpaca bars. <100 on high volume = suspicious block trades |
| dollar_volume | price × volume — real capital involved. Screener requires ≥$1M for high-conviction entries |
| vwap | Volume-weighted average price from stored bars. Baseline for detecting artificial price moves |
| vwap_dev_pct | % deviation of current price from VWAP. >±5% without volume = pump/dump signal |
| price_velocity | (last_price − price_15m_ago) / price_15m_ago — momentum |
| atr_expansion | ATR_15m_today / ATR_15m_30d — volatility regime change |
| gap_pct | (premarket_open − prev_close) / prev_close — gap impact |
| news_density_60m | Count of documents in last 60 minutes — catalyst frequency |
| sentiment_weighted | avg(sentiment × impact) — AI-weighted signal strength |
| bull_bear_skew | bullish_prob − bearish_prob — directional tilt |
| impact_momentum | sum(impact_level last 60m) − prior 60m — catalyst acceleration |
| source_reliability | Weighted score by source type (SEC filings > news > social) |
| liquidity_score | Function of spread, volume, and price — risk gating |
📐 CAN SLIM Methodology (N · L · M factors implemented)
CAN SLIM is William O'Neil's growth stock methodology. It identifies stocks with strong fundamentals, institutional backing, and market leadership. This platform implements the three technical factors most relevant to intraday trading: N, L, and M.
IBD Rule: Buy stocks breaking out near their 52-week high, not extended laggards. Leaders typically break out from bases within 15% of their 52-week high.
| Score 100 | Within 5% of 52W high |
| Score 85 | Within 10% of 52W high |
| Score 70 | Within 15% — IBD threshold |
| Score 40 | Within 25% of 52W high |
| Score 0–20 | >35% below high — laggard |
IBD Rule: Buy the top 1–2 stocks in a strong industry group. An RS Rating of 80+ means the stock outperformed 80% of all stocks over the past 12 months.
| 80–100 | Leader — top 20% of universe |
| 60–79 | Average — mid-range performer |
| 0–59 | Laggard — avoid or short |
IBD Rule: Don't fight the market. 3 out of 4 stocks follow the general market trend. Only buy when the market is in a confirmed uptrend.
| ↑ Uptrend | SPY price ≥ 50-day MA |
| ↓ Downtrend | SPY price < 50-day MA |
📰 Documents & News (Textual Intelligence)
Source: Tiingo News API • Refresh: every 30–120 seconds
| Title | Headline text |
| Source | Vendor/publisher identifier |
| Source Type | news, ir, earnings, filing, social, internal |
| Published At | Original publication timestamp |
| Body Text | Full article/release content (cleaned) |
| Content Hash | SHA-256 for deduplication |
| URL | Link to original source |
| Language | Document language (default: en) |
👤 Insider Trades (SEC Form 4)
Source: FMP API • Refresh: every 15 minutes
| Reporting Name | Name of insider (officer, director, 10% owner) |
| Title / Role | CEO, CFO, Director, 10% Owner, etc. |
| Action | Buy (Acquisition) or Sell (Disposition) |
| Shares Transacted | Number of shares bought/sold |
| Price | Transaction price per share |
| Total Value | shares × price — dollar value of trade |
| Securities Owned | Post-transaction holding count |
| Transaction Date | When the trade occurred |
| Filing Date | When Form 4 was filed with SEC |
| SEC Filing URL | Link to original Form 4 filing |
🏛️ Congress Trades (STOCK Act)
Source: FMP API (Senate + House) • Refresh: every ~60 minutes
| Member Name | Full name of congress member |
| Chamber | Senate or House of Representatives |
| Office / District | State and district of the member |
| Transaction Type | purchase, sale, sale_partial, sale_full, exchange |
| Amount Range | e.g., "$1,001 – $15,000" (STOCK Act range format) |
| Estimated Value | Midpoint of reported range |
| Asset Description | Description of the security traded |
| Date Received | When disclosure was received by ethics office |
| Capital Gains >$200 | Whether trade had capital gains over $200 |
| Filing URL | Link to STOCK Act disclosure |
🏦 Institutional Holdings (SEC EDGAR 13F)
Source: SEC EDGAR — free, no API key • Refresh: every ~60 minutes
| Fund Name | Investment manager / fund name |
| CIK | SEC Central Index Key of the filer |
| Issuer Name | Name of held company (as filed) |
| CUSIP | 9-character security identifier |
| Title of Class | e.g., COM, COM CL A, CALL, PUT |
| Shares Held | Number of shares in position |
| Market Value ($) | Dollar value of position (post-2023: exact dollars) |
| Investment Discretion | SOLE, SHARED, or DEFINED |
| Put / Call | Options exposure indicator (when applicable) |
| Filing Date | When 13F was filed with SEC |
| Period of Report | Quarter-end date the filing covers |
| Accession Number | SEC filing identifier for audit trail |
Note: 13F filings are quarterly with ~45 day reporting lag.
✂️ Stock Splits (Detection & Penalty)
Source: FMP API • Refresh: every 2 hours • Window: ±90 days
| Symbol | Affected ticker |
| Split Date | Effective date of split |
| Ratio | e.g., 4:1, 10:1, 1:10 (reverse) |
| Forward / Reverse | Whether numerator > denominator |
| Days Since/Until | Age or countdown to split date |
🏆 Scoring Outputs (Per Ticker Per Cycle)
Generated every 1–5 minutes, stored in scores table
| Score | 0–100 composite opportunity strength |
| Confidence | 0.0–1.0 signal reliability |
| Direction | long or short |
| Expected Move (bp) | Estimated price movement in basis points |
| Horizon (minutes) | 30 (immediate), 120 (intraday), or 390 (full day) |
| Rationale | Human-readable explanation of the signal |
| Supporting Signals | List of evidence supporting the direction |
| Contradicting Signals | List of evidence opposing the direction |
| Recommendation | Strong Buy/Buy/Speculative/Watch/Short variants |
| Inputs Snapshot | All feature + document IDs for reproducibility |
📊 Outcomes & Calibration (Backtesting)
Labeled overnight for weight tuning • Stored in outcomes table
| Realized Move (bp) | Actual price movement over the predicted horizon |
| Max Adverse (bp) | Maximum adverse excursion (worst drawdown) |
| Max Favorable (bp) | Maximum favorable excursion (best peak) |
| Realized Horizon (min) | Actual time to peak move |
🛡️ Risk Filters (Hard Gates)
Applied before ranking — tickers failing these are excluded from scoring
| Min Dollar Volume | Minimum $ volume over last 20 minutes |
| Max Spread % | Maximum bid-ask spread percentage |
| Halt / SSR Detection | Trading halt or Short Sale Restriction active |
| Price Floor | Minimum price threshold (avoid penny stocks) |
| Blacklist | Manually excluded tickers |
🧠 Self-Learning Maps (Auto-Growing)
Mapping tables that improve automatically as data flows through the system
| CUSIP → Ticker | Maps 9-char CUSIPs from 13F filings to our symbols. Learned from each filing processed. |
| Issuer Name → Ticker | Maps 13F issuer names (e.g., "APPLE INC") to symbols. Uses 4-strategy fuzzy matching. |
| Company Aliases | Handles name variants by stripping suffixes (INC, CORP, LTD, etc.) and matching by prefix/contains. |
📋 Data Source Summary
| Source | Provider | Cost | Refresh | Data Type |
|---|---|---|---|---|
| Quotes & Bars | Tiingo + Alpaca | Included | 60 sec | Real-time prices, OHLCV bars |
| News | Tiingo + Alpaca | Included | 30–120 sec | Headlines + full text |
| Ticker Universe | Alpaca + FMP | Included | Daily | Active tradeable assets, seeding |
| Snapshots & Movers | Alpaca | Included | 60 sec | Latest trade, quote, minute bar |
| Profiles & Fundamentals | FMP | Included | Daily | Sector, P/E, market cap |
| Insider Trades | FMP | Included | 15 min | SEC Form 4 |
| Congress Trades | FMP | Included | ~60 min | STOCK Act (Senate + House) |
| Stock Splits | FMP | Included | 2 hours | Calendar ±90 days |
| Institutional 13F | SEC EDGAR | Free | ~60 min | 13F-HR holdings (XML) |
| AI Analysis | OpenAI GPT-4.5 | Per-token | Per document | Structured extraction |
