Mastering the MCP Gateway — 58 data types, custom screening DSL, auto-adaptive regime detection, and the complete data backbone of your automated trading system.
The Model Context Protocol (MCP) is an open standard created by Anthropic that lets AI models interact with external tools and data sources through a unified interface. Think of it as a USB-C port for AI — one standardized connection that works with any compatible service.
The architecture follows a client-server model:
MCP servers are declared in your Claude Code settings. The DailyTickers Gateway connects via stdio transport:
{
"mcpServers": {
"dailytickers": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-dailytickers"],
"env": {
"MW_API_KEY": "your-api-key",
"MW_ENDPOINT": "https://gateway.dailytickers.com"
}
},
"market-alerts": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-market-alerts"],
"env": {
"ALERTS_DB": "/path/to/alerts.db"
}
}
}
}
Once configured, Claude Code automatically discovers all available tools at startup. You can verify with:
$ claude --mcp-debug
MCP Server: dailytickers (connected)
Tools: 15 available
- GetMarketOverview
- QueryData
- GetInstruments
- RunAutoScreener
- RunScreener
- CalculateOptionsGreeks
- AnalyzeOptionsStrategy
- LLMAnalysis
- GetReferentialData
- GetVersion
- GetHealth
- GetWorkflows
- StartWorkflow
- CheckJobStatus
- ListJobs
MCP Server: market-alerts (connected)
Tools: 7 available
- create_alert
- list_alerts
- update_alert
- delete_alert
- pause_alert
- snooze_alert
- get_alert_status
MCP tools are discoverable at runtime. Claude Code reads the tool schemas and understands what each tool does, what parameters it accepts, and what it returns. You don't need to write any integration code — just configure the server and Claude Code handles the rest.
When Claude Code calls an MCP tool, here's what happens under the hood:
{
"method": "tools/call",
"params": {
"name": "QueryData",
"arguments": {
"symbols": ["AAPL", "MSFT", "GOOGL"],
"types": "quote,technicals,sentiment_overall",
"period": "1y"
}
}
}
{
"content": [
{
"type": "text",
"text": "{\"AAPL\": {\"quote\": {\"price\": 187.44, \"change\": 2.31, ...}, ...}}"
}
]
}
The response is always a JSON object with the requested data types nested under each symbol. Claude Code parses this automatically and uses the data for analysis.
The DailyTickers MCP Gateway is a comprehensive financial data service exposing 15 tools. Here's the complete catalog with use cases:
Returns a complete market snapshot: all major indices, commodities, crypto, rates, VIX, dollar index, market regime, sentiment indicators, and top news. This is your morning briefing in one call.
GetMarketOverview({ depth: "deep" })
// Returns:
{
"regime": "EARLY_RISK_OFF",
"vix": 23.75,
"dxy": 103.42,
"indices": {
"SPY": { "price": 559.23, "change": -1.2, "rsi14": 38.5 },
"QQQ": { "price": 472.10, "change": -1.8, "rsi14": 35.2 },
...
},
"commodities": { "GLD": ..., "SLV": ..., "USO": ... },
"crypto": { "BTC-USD": ..., "ETH-USD": ..., "SOL-USD": ... },
"rates": { "US10Y": 4.32, "US2Y": 4.15, "spread": 0.17 },
"sentiment": { "fear_greed": 28, "put_call_ratio": 1.15, ... },
"news": [ ... top 20 market-moving headlines ... ]
}
The Swiss Army knife of market data. Query any combination of 58 data types for any list of symbols. This is the tool you'll use most.
QueryData({
symbols: ["NVDA", "AMD", "AVGO"],
types: "quote,bars_daily,technicals,sentiment_overall,financials",
period: "1y"
})
Comprehensive analysis of a single symbol. Returns everything: quote, technicals, fundamentals, earnings, holders, sentiment, news, support/resistance, volume profile, trading signals, analyst actions, insider transactions. One call, complete picture.
GetInstruments({ symbols: ["AAPL"] })
// Returns 50-100KB of structured data per symbol
Automatically detects the current market regime and runs regime-appropriate screening strategies. Adjusts strategy weights based on VIX, breadth, momentum, and other regime indicators.
Run custom screening queries using the DailyTickers DSL. Full control over conditions, universe, and sorting. This is how you build strategy-specific screens.
Calculate Black-Scholes Greeks for any option contract. Supports custom volatility inputs and SABR model.
Analyze multi-leg options strategies: spreads, straddles, iron condors, butterflies. Returns P&L diagram, max profit/loss, breakeven points, and Greeks.
Send data to a DeepSeek model for additional AI perspective. Useful for narrative analysis, pattern recognition, and cross-referencing your own analysis with a different AI model.
Reference data: symbol lists, sector classifications, index constituents, ETF holdings. Essential for building universes and sector analysis.
QueryData is the workhorse of the Gateway. It accepts a list of symbols and a comma-separated list of data types. Here's the complete reference organized by category:
| Type | Description | Key Fields |
|---|---|---|
quote | Current quote with bid/ask/volume | price, change, changePercent, volume, avgVolume, marketCap, pe, eps |
bars_daily | Daily OHLCV bars (default 1 year) | date, open, high, low, close, volume |
bars_intraday | Intraday bars (5min/15min/1h) | timestamp, open, high, low, close, volume |
bars_weekly | Weekly OHLCV bars | date, open, high, low, close, volume |
QueryData({
symbols: ["AAPL"],
types: "quote,bars_daily",
period: "6m"
})
// quote response:
{
"price": 187.44,
"previousClose": 185.13,
"change": 2.31,
"changePercent": 1.25,
"volume": 58234100,
"avgVolume": 52100000,
"marketCap": 2890000000000,
"pe": 31.2,
"eps": 6.01,
"52wHigh": 199.62,
"52wLow": 164.08,
"beta": 1.24
}
// bars_daily response (last 5 bars):
[
{ "date": "2026-03-05", "open": 185.50, "high": 188.20, "low": 184.90, "close": 187.44, "volume": 58234100 },
{ "date": "2026-03-04", "open": 184.20, "high": 186.10, "low": 183.75, "close": 185.13, "volume": 49876000 },
...
]
| Type | Description | Key Fields |
|---|---|---|
technicals | RSI, MACD, Bollinger, EMAs, SMA, ATR | rsi14, macd, macdSignal, macdHistogram, ema20, ema50, ema200, sma20, sma50, sma200, atr14, bbUpper, bbLower, bbWidth |
support_resistance | Key S/R levels with strength scores | supports[], resistances[] with price, strength, touches |
volume_profile | Volume at price distribution | poc (point of control), valueAreaHigh, valueAreaLow, nodes[] |
trading_signals | Aggregated buy/sell signals | summary (buy/sell/hold), signals[] with name, action, value |
QueryData({
symbols: ["NVDA"],
types: "technicals,support_resistance,trading_signals"
})
// technicals:
{
"rsi14": 42.3,
"macd": -2.15,
"macdSignal": -1.87,
"macdHistogram": -0.28,
"ema20": 875.50,
"ema50": 890.20,
"ema200": 820.10,
"atr14": 18.75,
"bbUpper": 920.30,
"bbLower": 830.70,
"bbWidth": 10.2
}
// support_resistance:
{
"supports": [
{ "price": 840.00, "strength": 0.92, "touches": 4 },
{ "price": 815.50, "strength": 0.85, "touches": 3 }
],
"resistances": [
{ "price": 900.00, "strength": 0.88, "touches": 5 },
{ "price": 930.00, "strength": 0.78, "touches": 2 }
]
}
// trading_signals:
{
"summary": "SELL",
"signals": [
{ "name": "RSI(14)", "action": "sell", "value": 42.3 },
{ "name": "MACD(12,26)", "action": "sell", "value": -2.15 },
{ "name": "EMA(20)", "action": "sell", "value": "below" },
{ "name": "Bollinger", "action": "neutral", "value": "mid" },
{ "name": "Volume", "action": "buy", "value": "above_avg" }
]
}
| Type | Description | Key Fields |
|---|---|---|
financials | Income statement, balance sheet, cash flow | revenue, netIncome, grossMargin, operatingMargin, freeCashFlow, totalDebt, currentRatio |
earnings_quarterly | Quarterly EPS vs estimates | date, epsActual, epsEstimate, surprise, revenueActual, revenueEstimate |
stats | Key statistics and ratios | pe, forwardPE, peg, ps, pb, evEbitda, roe, roa, debtEquity, currentRatio |
holders | Top institutional holders | holders[] with name, shares, percentHeld, changeShares |
| Type | Description | Key Fields |
|---|---|---|
sentiment_overall | Aggregated sentiment score | score (-1 to 1), bullPercent, bearPercent, volume, trending |
sentiment_stocktwits | StockTwits-specific sentiment | bullish, bearish, messages_24h, watchers, trending |
sentiment_reddit | Reddit/WSB sentiment | mentions_24h, sentiment, subreddits[], topPosts[] |
news | Recent news articles | articles[] with title, source, date, sentiment, url |
analyst_actions | Analyst upgrades/downgrades | actions[] with firm, action, priceTarget, date |
| Type | Description | Key Fields |
|---|---|---|
short_interest | Short interest data | shortPercent, shortRatio, shortShares, daysTocover |
ctb | Cost to borrow (current) | fee, available, lastUpdate |
ctb_history | CTB over time | history[] with date, fee, available |
ftd_threshold | Failure to deliver data | ftd[] with date, quantity, price |
insider_transactions | Insider buys and sells | transactions[] with name, title, type, shares, price, date |
institutional_holders | 13F filings data | holders[] with name, shares, value, changePercent |
sec_filings | Recent SEC filings | filings[] with type, date, description, url |
| Type | Description | Key Fields |
|---|---|---|
options_chain | Full options chain by expiry | calls[], puts[] with strike, bid, ask, volume, oi, iv, greeks |
unusual_options | Unusual options activity | trades[] with type, strike, expiry, volume, oi, premium, sentiment |
Request only the data types you need. Each type adds to response time and payload size. For a quick scan, quote,technicals is sufficient. Save financials,earnings_quarterly,holders for deep dives on final candidates.
QueryData supports up to 50 symbols per call. This is critical for efficient scanning:
// Stage 1: Quick scan of 30 candidates
QueryData({
symbols: ["CF","CHRD","AMPX","MEOH","PAA","TTE","EWG","EWJ",
"XLE","GLD","AAPL","NVDA","AMD","MSFT","GOOGL",
"META","AMZN","TSLA","JPM","GS","BAC","XOM","CVX",
"LLY","UNH","PFE","COST","WMT","HD","CAT"],
types: "quote,technicals"
})
// Stage 2: Deep dive on top 10
QueryData({
symbols: ["CF","CHRD","AMPX","MEOH","PAA","TTE","EWG","EWJ","XLE","GLD"],
types: "quote,technicals,sentiment_overall,insider_transactions,financials,
support_resistance,trading_signals,news"
})
The RunScreener tool accepts custom conditions written in a domain-specific language (DSL). This DSL lets you express complex screening criteria in a single line of readable code.
| Category | Fields |
|---|---|
| Price | close, open, high, low, prevClose |
| Volume | vol, avgVol, relVol |
| Momentum | rsi14, macd, macdSignal, macdHist |
| Trend | ema20, ema50, ema200, sma20, sma50, sma200 |
| Volatility | atr14, bbWidth, bbUpper, bbLower |
| Fundamentals | pe, forwardPE, ps, marketCap, eps |
| Short | shortPercent, shortRatio, daysTocover |
| Function | Description | Example |
|---|---|---|
sma(field, period) | Simple moving average | close > sma(close, 200) |
ema(field, period) | Exponential moving average | close > ema(close, 50) |
std(field, period) | Standard deviation | close < sma(close,20) - 2*std(close,20) |
max(field, period) | Period maximum | close == max(close, 52w) |
min(field, period) | Period minimum | close > min(close, 52w) * 1.1 |
change(field, period) | Percentage change | change(close, 5d) > 5 |
rank(field) | Percentile rank in universe | rank(relVol) > 90 |
| Operator | Description | Example |
|---|---|---|
>, <, >=, <= | Comparison | rsi14 < 30 |
==, != | Equality | sector == "Technology" |
&& | AND (all conditions must be true) | rsi14 < 30 && vol > avgVol * 2 |
|| | OR (any condition can be true) | rsi14 < 25 || macd < -2 |
crosses_above | Crossed above (today) | close crosses_above ema(close,50) |
crosses_below | Crossed below (today) | macd crosses_below macdSignal |
rsi14 < 30 && vol > sma(vol,20) * 2 && close > sma(close,200) && macdHist > 0
Stocks that are oversold (RSI below 30) with volume confirmation (2x average), still in a long-term uptrend (above 200-day SMA), and showing early momentum reversal (MACD histogram turning positive). These are high-probability mean reversion setups.
close > max(high, 20d) && vol > avgVol * 1.5 && rsi14 > 55 && rsi14 < 75 && close > ema(close,50)
Stocks breaking out above their 20-day high on above-average volume, with RSI in the sweet spot (strong but not overbought), and above the 50 EMA. These are continuation setups with momentum confirmation.
bbWidth < 5 && atr14 < sma(atr14,20) * 0.7 && vol < avgVol * 0.6 && close > sma(close,200)
Stocks in a tight consolidation (narrow Bollinger Bands, low ATR, low volume) above the 200 SMA. These often precede explosive moves. The direction of the breakout determines the trade.
close > ema(close,20) && ema(close,20) > ema(close,50) && ema(close,50) > ema(close,200) && rsi14 > 50 && change(close,5d) > 0
sector == "Utilities" || sector == "Consumer Staples" || symbol IN ("GLD","SLV","TLT","SH","SQQQ") && rsi14 < 65 && change(close,5d) > 0
pe < 15 && forwardPE < pe && change(close,3m) < -15 && insider_net_buying_90d > 0
RunScreener({
conditions: "rsi14 < 30 && vol > sma(vol,20) * 2 && close > sma(close,200)",
universe: "SP500", // SP500, NASDAQ100, RUSSELL2000, ALL_US, custom list
sort: "rsi14 ASC", // Sort oversold first
limit: 20 // Top 20 results
})
// Response:
{
"count": 7,
"regime": "EARLY_RISK_OFF",
"results": [
{
"symbol": "CF",
"name": "CF Industries Holdings",
"price": 78.50,
"change": -3.2,
"rsi14": 22.1,
"volume": 8500000,
"avgVolume": 3200000,
"relVol": 2.66,
"sma200": 72.30,
"sector": "Materials",
"marketCap": 15200000000,
"score": 87
},
...
]
}
You can screen specific symbols instead of a predefined universe:
RunScreener({
conditions: "rsi14 < 35 && close > ema(close,50)",
symbols: ["VGK","EWG","EWQ","EWU","SAP","ASML","BBVA","TTE","SIE",
"EWJ","EWY","EWH","FXI","MCHI"],
sort: "rsi14 ASC",
limit: 10
})
The AutoScreener is the crown jewel of the Gateway. It automatically detects the current market regime and adjusts its screening strategies accordingly.
| Regime | VIX Range | Breadth | Dominant Strategy | Hedge % |
|---|---|---|---|---|
| RISK ON | < 16 | > 60% | Momentum, Breakout | 0% |
| NEUTRAL | 16-22 | 40-60% | Balanced (all strategies) | 10% |
| EARLY RISK-OFF | 22-30 | 30-40% | Oversold bounce, Safe haven | 20% |
| RISK OFF | > 30 | < 30% | Shorts, Hedges, Cash | 40%+ |
| RECOVERY | Falling from >25 | Rising | Oversold leaders, Sector rotation | 10% |
The AutoScreener uses a composite of 7 indicators to determine the regime:
function detectRegime(marketData) {
const signals = {
vix: marketData.vix, // VIX level
vixTrend: marketData.vix_5d_change, // VIX direction
breadth: marketData.advanceDeclineRatio, // NYSE A/D ratio
putCall: marketData.putCallRatio, // Options P/C ratio
spyRsi: marketData.spy_rsi14, // SPY RSI
dxy: marketData.dxy_5d_change, // Dollar strength
yieldCurve: marketData.us10y - marketData.us2y // Yield spread
};
let score = 0; // -100 (full risk-off) to +100 (full risk-on)
// VIX contribution (weight: 25%)
if (signals.vix < 16) score += 25;
else if (signals.vix < 22) score += 10;
else if (signals.vix < 30) score -= 15;
else score -= 25;
// VIX trend (weight: 10%)
if (signals.vixTrend < -2) score += 10; // VIX falling = bullish
else if (signals.vixTrend > 3) score -= 10;
// Breadth (weight: 25%)
if (signals.breadth > 2.0) score += 25;
else if (signals.breadth > 1.0) score += 10;
else if (signals.breadth < 0.5) score -= 25;
else score -= 10;
// Put/Call (weight: 15%)
if (signals.putCall > 1.2) score -= 15; // Fear = bearish
else if (signals.putCall < 0.7) score += 15;
// SPY RSI (weight: 10%)
if (signals.spyRsi > 65) score += 10;
else if (signals.spyRsi < 35) score -= 10;
// Dollar (weight: 10%)
if (signals.dxy > 1.5) score -= 10; // Strong dollar = risk-off
else if (signals.dxy < -1.0) score += 10;
// Yield curve (weight: 5%)
if (signals.yieldCurve < 0) score -= 5; // Inverted = warning
else score += 5;
// Map score to regime
if (score > 40) return "RISK_ON";
if (score > 10) return "NEUTRAL";
if (score > -20) return "EARLY_RISK_OFF";
if (score <= -20) {
if (signals.vixTrend < -3) return "RECOVERY";
return "RISK_OFF";
}
}
| Strategy | Risk-On | Neutral | Early Risk-Off | Risk-Off | Recovery |
|---|---|---|---|---|---|
| Momentum Breakout | 35% | 25% | 10% | 0% | 20% |
| Trend Following | 25% | 25% | 15% | 5% | 15% |
| Oversold Bounce | 15% | 20% | 30% | 15% | 35% |
| Volatility Squeeze | 15% | 15% | 10% | 5% | 15% |
| Value + Insiders | 10% | 15% | 15% | 15% | 15% |
| Safe Haven / Short | 0% | 0% | 20% | 60% | 0% |
RunAutoScreener()
// Response:
{
"regime": "EARLY_RISK_OFF",
"regimeScore": -12,
"indicators": {
"vix": 23.75,
"vixTrend": +2.1,
"breadth": 0.75,
"putCall": 1.05,
"spyRsi": 38.5,
"dxy": +0.8,
"yieldSpread": 0.17
},
"strategyWeights": {
"momentum_breakout": 0.10,
"trend_following": 0.15,
"oversold_bounce": 0.30,
"volatility_squeeze": 0.10,
"value_insiders": 0.15,
"safe_haven": 0.20
},
"candidates": [
{ "symbol": "CF", "strategy": "oversold_bounce", "score": 92, ... },
{ "symbol": "GLD", "strategy": "safe_haven", "score": 88, ... },
{ "symbol": "TTE", "strategy": "value_insiders", "score": 87, ... },
...
],
"totalCandidates": 47,
"timestamp": "2026-03-05T23:00:00Z"
}
A momentum breakout strategy that works beautifully in a bull market can lose money fast in a risk-off environment. The AutoScreener prevents this by automatically shifting to defensive strategies when conditions deteriorate. During the March 2026 early risk-off environment (VIX 23.75), it allocated 30% to oversold bounce and 20% to safe haven — exactly the right response.
Here's the complete 5-step workflow that combines multiple MCP calls into a production-grade market scanner. This is exactly what runs every weekday at 23:00 via the automated pipeline.
# Market Regime Assessment
## Instructions
1. Call `GetMarketOverview` with depth "deep"
2. Extract: VIX, SPY RSI, DXY change, breadth, put/call ratio
3. Determine the regime: RISK_ON, NEUTRAL, EARLY_RISK_OFF, RISK_OFF, RECOVERY
4. Output the regime and the strategy weight matrix
## Expected Output
```json
{
"regime": "EARLY_RISK_OFF",
"strategyWeights": { ... },
"keyIndicators": { ... },
"narrative": "Brief market context..."
}
```
# Multi-Strategy Scanner
## Instructions
Run 6 screens in parallel:
1. RunAutoScreener — Get regime-adapted candidates (limit 50)
2. RunScreener — Oversold bounce on SP500:
`rsi14 < 30 && vol > sma(vol,20) * 2 && close > sma(close,200)`
3. RunScreener — Momentum breakout on SP500:
`close > max(high, 20d) && vol > avgVol * 1.5 && rsi14 > 55 && rsi14 < 75`
4. RunScreener — Volatility squeeze on SP500:
`bbWidth < 5 && atr14 < sma(atr14,20) * 0.7 && close > sma(close,200)`
5. RunScreener — EU/APAC (custom symbols):
`rsi14 < 40 && close > ema(close,50)`
symbols: VGK, EWG, EWQ, EWU, SAP, ASML, EWJ, EWY, EWH, FXI
6. RunScreener — Sector ETFs:
`change(close,5d) > 2 && vol > avgVol * 1.2`
symbols: XLF, XLE, XLK, XLV, XLI, GLD, SLV, TLT, ARKK, ICLN
Merge all results, deduplicate by symbol, keep top 30 by score.
## Anti-Duplicate Check
Read last 3 scanner articles. At least 70% of selected symbols must be NEW
(not in last 3 scans). If not, replace repeats with next-best candidates.
# Deep Analysis for Scanner Candidates
## Instructions
For the top 30 candidates from Step 2, run:
QueryData({
symbols: [top 30 tickers],
types: "quote,technicals,support_resistance,trading_signals,
sentiment_overall,insider_transactions,financials,news"
})
## Validation (P0 — Critical)
For EACH candidate:
- Verify entry price is within 10% of current spot price
- If entry zone > 10% from spot → REJECT (stale data)
- Verify volume is not 0 (halted stocks)
- Verify market cap > $500M (no penny stocks)
## Output
Structured data per candidate for the scoring engine.
This is covered in detail in Part 3: The Analysis Engine. Each candidate is scored across 6 dimensions:
# Final Selection — Top 10 A+ Setups
## Selection Criteria
From scored candidates:
1. Composite score >= 85 (A+ threshold)
2. No layer below 60 (no red flags)
3. Technical confluence >= 3 signals
4. Diversification: min 5 US + 2 EU + 1 APAC + 2 ETF
## In Risk-Off/Early Risk-Off regimes:
- Minimum 20% defensive setups (GLD, TLT, SH, SQQQ, safe-haven ETFs)
## For each selected setup, compute:
- Entry zone: current price or key level (support, EMA pullback)
- Stop loss: below nearest support or 1.5x ATR
- TP1: first resistance or +1R
- TP2: second resistance or +2R
- R/R ratio: must be >= 1.5
## A++ Selection (Top 3)
From the 10 A+ setups, select the 3 with:
- Highest composite score
- Highest technical confluence
- Best R/R ratio
- Most unique (not in recent scans)
These go to the priority Discord channel.
## Output Format
For each setup: ticker, name, strategy, score, entry, stop, TP1, TP2,
R/R, thesis (3 sentences), confirmations (4), invalidations (4),
timing notes, sector/geo badge.
All 5 steps are orchestrated by a single instruction in your project's CLAUDE.md file. When Claude Code receives "scan du jour", it executes all steps automatically:
### "Scanner" / "Scan du jour"
1. Read ALL retrospectives (scanner/retrospective/YYYYMMDD/)
- Extract hit rates by strategy
- Adjust strategy weights accordingly
2. Read last 3 scans for anti-duplicate filter
3. RunAutoScreener — detect regime + get candidates
4. RunScreener x3 (oversold, momentum, breakout)
5. RunScreener EU/APAC + sector ETFs
6. QueryData deep analysis for all candidates
7. Multi-layer scoring (6 dimensions)
8. Select top 10 A+ with diversification constraints
9. Generate HTML article in scanner/YYYYMMDD/
10. Index with add_card.js
11. Git commit & push (auto-deploy)
12. Post top 3 A++ to Discord
The entire pipeline is defined declaratively in CLAUDE.md. Claude Code reads the instructions and orchestrates the MCP calls, data processing, HTML generation, indexing, and deployment. There is zero application code to maintain — the AI is the application.
The Gateway handles rate limiting internally, but here are practical guidelines:
| Data Type | Update Frequency | Delay |
|---|---|---|
| quote | Real-time (market hours) | < 1 second |
| bars_intraday | Every bar close | 1-2 seconds |
| bars_daily | After market close | ~30 minutes |
| technicals | With bars_daily | ~30 minutes |
| financials | After earnings release | 1-24 hours |
| sentiment_stocktwits | Every 15 minutes | 15 minutes |
| insider_transactions | After SEC filing | 1-2 days |
| short_interest | Bi-monthly (FINRA) | 10 business days |
If the scanner runs at 23:00 but uses closing data from 16:00, after-hours moves can invalidate setups. Always validate entry prices against current quote before posting alerts. Reject if >10% drift.
EU/APAC stocks traded as ADRs (e.g., SAP, ASML) have full data. But ETFs like EWG or FXI may lack sentiment data. Handle gracefully: if sentiment_overall is null, use sector-level sentiment as a proxy.
Running scans on Sunday will return Friday's closing data for equities. Crypto is 24/7. Always check quote.lastUpdate timestamp and note data age in the output.
// In your CLAUDE.md or skill file:
When calling MCP tools, follow this error handling pattern:
1. If GetMarketOverview fails → retry once after 5 seconds
If still fails → use cached regime from yesterday's scan
2. If RunScreener returns 0 results → loosen conditions by 10%
Example: rsi14 < 30 → rsi14 < 35
3. If QueryData returns partial data (some symbols missing) →
continue with available data, note missing symbols in output
4. If GetInstruments fails for a candidate →
use QueryData fallback (less data but still usable)
5. Never generate setups without fresh quote validation
Now that you can pull any market data in real-time, it's time to build the AI Analysis Engine that scores setups across 6 dimensions to identify A++ quality trades.