analyze
Perform technical analysis on cryptocurrencies using RSI, SMA, volatility, z-score, and trend direction to generate actionable trading signals.
Instructions
Technical analysis for any crypto: RSI, SMA, volatility, z-score, trend direction. Actionable signals included.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| symbol | Yes | Crypto symbol | |
| days | No | Lookback period in days (default: 30) |
Implementation Reference
- index.js:335-338 (handler)The tool handler for 'analyze' within MCPMarketServer.handleToolCall. It fetches candlestick data and passes it to the technicalAnalysis function.
case 'analyze': { const candles = await getCryptoCandles(args.symbol, '1h', args.days || 30); return technicalAnalysis(candles); } - index.js:166-225 (helper)The helper function `technicalAnalysis` that performs the actual RSI, SMA, volatility, and z-score calculations.
function technicalAnalysis(candles) { const closes = candles.map(c => c.close); const n = closes.length; if (n < 14) return { error: 'Need at least 14 candles for analysis' }; // SMA const sma20 = closes.slice(-20).reduce((a, b) => a + b, 0) / Math.min(20, n); const sma50 = n >= 50 ? closes.slice(-50).reduce((a, b) => a + b, 0) / 50 : null; // RSI (14-period) let gains = 0, losses = 0; for (let i = n - 14; i < n; i++) { const diff = closes[i] - closes[i - 1]; if (diff > 0) gains += diff; else losses -= diff; } const avgGain = gains / 14; const avgLoss = losses / 14; const rs = avgLoss === 0 ? 100 : avgGain / avgLoss; const rsi = 100 - (100 / (1 + rs)); // Volatility const returns = []; for (let i = 1; i < n; i++) { returns.push(Math.log(closes[i] / closes[i - 1])); } const mean = returns.reduce((a, b) => a + b, 0) / returns.length; const variance = returns.reduce((a, b) => a + (b - mean) ** 2, 0) / returns.length; const volatility = Math.sqrt(variance); // Z-score const allMean = closes.reduce((a, b) => a + b, 0) / n; const std = Math.sqrt(closes.reduce((a, b) => a + (b - allMean) ** 2, 0) / n); const zscore = std > 0 ? (closes[n - 1] - allMean) / std : 0; // Trend const recent = closes.slice(-5); const older = closes.slice(-10, -5); const recentAvg = recent.reduce((a, b) => a + b, 0) / recent.length; const olderAvg = older.length > 0 ? older.reduce((a, b) => a + b, 0) / older.length : recentAvg; const current = closes[n - 1]; return { current_price: current, sma_20: Math.round(sma20 * 100) / 100, sma_50: sma50 ? Math.round(sma50 * 100) / 100 : 'insufficient data', rsi_14: Math.round(rsi * 100) / 100, rsi_signal: rsi > 70 ? 'OVERBOUGHT' : rsi < 30 ? 'OVERSOLD' : 'NEUTRAL', volatility: Math.round(volatility * 10000) / 10000, volatility_annualized: Math.round(volatility * Math.sqrt(365 * 24) * 10000) / 100 + '%', zscore: Math.round(zscore * 100) / 100, zscore_signal: zscore > 2 ? 'EXTENDED HIGH' : zscore < -2 ? 'EXTENDED LOW' : 'NORMAL', trend: recentAvg > olderAvg * 1.01 ? 'UPTREND' : recentAvg < olderAvg * 0.99 ? 'DOWNTREND' : 'SIDEWAYS', price_vs_sma20: current > sma20 ? 'ABOVE' : 'BELOW', high: Math.max(...closes), low: Math.min(...closes), range_pct: ((Math.max(...closes) - Math.min(...closes)) / Math.min(...closes) * 100).toFixed(2) + '%', }; } - index.js:288-298 (registration)Registration of the 'analyze' tool in the getToolDefinitions method.
name: 'analyze', description: 'Technical analysis for any crypto: RSI, SMA, volatility, z-score, trend direction. Actionable signals included.', inputSchema: { type: 'object', properties: { symbol: { type: 'string', description: 'Crypto symbol' }, days: { type: 'number', description: 'Lookback period in days (default: 30)' } }, required: ['symbol'] } },