NYC
skills/smithery/ai/crypto-data

crypto-data

SKILL.md

Crypto Data Skill

Free crypto market data using public APIs. No paid MCP server required.

API Sources

Data Source Rate Limit Auth
Fear & Greed Index Alternative.me Unlimited None
Trending Coins CoinGecko 10-30/min Optional
Market Data CoinGecko 10-30/min Optional
Coin Prices CoinGecko 10-30/min Optional

Fear & Greed Index

From Alternative.me (always free, no auth):

async function get_fear_greed_index() {
  // Fetch from Alternative.me (free, no rate limit)
  const response = await fetch('https://api.alternative.me/fng/')
  const data = await response.json()

  // Response format:
  // {
  //   "data": [{
  //     "value": "25",
  //     "value_classification": "Extreme Fear",
  //     "timestamp": "1706745600",
  //     "time_until_update": "43200"
  //   }]
  // }

  const fng = data.data[0]
  return {
    value: parseInt(fng.value),                    // 0-100
    classification: fng.value_classification,       // "Extreme Fear", "Fear", "Neutral", "Greed", "Extreme Greed"
    timestamp: parseInt(fng.timestamp) * 1000,     // Unix ms
    next_update_in: parseInt(fng.time_until_update) // Seconds
  }
}

// Historical Fear & Greed (last N days)
async function get_fear_greed_history(days = 30) {
  const response = await fetch(`https://api.alternative.me/fng/?limit=${days}`)
  const data = await response.json()

  return data.data.map(d => ({
    value: parseInt(d.value),
    classification: d.value_classification,
    date: new Date(parseInt(d.timestamp) * 1000).toISOString().slice(0, 10)
  }))
}

Classification Thresholds

Value Classification Trading Signal
0-24 Extreme Fear Strong Buy (contrarian)
25-44 Fear Buy
45-55 Neutral Hold
56-75 Greed Sell
76-100 Extreme Greed Strong Sell (contrarian)

Trending Coins

From CoinGecko (free tier):

async function get_trending_coins() {
  // CoinGecko free API (no auth, 10-30 calls/min)
  const response = await fetch('https://api.coingecko.com/api/v3/search/trending')
  const data = await response.json()

  // Response contains top 15 trending coins
  return data.coins.map(c => ({
    id: c.item.id,                    // "bitcoin"
    symbol: c.item.symbol,            // "BTC"
    name: c.item.name,                // "Bitcoin"
    market_cap_rank: c.item.market_cap_rank,
    price_btc: c.item.price_btc,
    score: c.item.score               // Trending score (0 = most trending)
  }))
}

Market Data (Top Coins)

async function get_market_data(vs_currency = 'usd', per_page = 100) {
  const url = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=${vs_currency}&order=market_cap_desc&per_page=${per_page}&page=1&sparkline=false&price_change_percentage=1h,24h,7d`

  const response = await fetch(url)
  const data = await response.json()

  return data.map(coin => ({
    id: coin.id,
    symbol: coin.symbol.toUpperCase(),
    name: coin.name,
    current_price: coin.current_price,
    market_cap: coin.market_cap,
    market_cap_rank: coin.market_cap_rank,
    total_volume: coin.total_volume,
    high_24h: coin.high_24h,
    low_24h: coin.low_24h,
    price_change_24h: coin.price_change_percentage_24h,
    price_change_7d: coin.price_change_percentage_7d_in_currency,
    ath: coin.ath,
    ath_change_percentage: coin.ath_change_percentage
  }))
}

Simple Price Query

async function get_coin_prices(coin_ids, vs_currencies = 'usd') {
  // coin_ids: comma-separated, e.g., "bitcoin,ethereum,solana"
  const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coin_ids}&vs_currencies=${vs_currencies}&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true`

  const response = await fetch(url)
  return await response.json()

  // Response:
  // {
  //   "bitcoin": {
  //     "usd": 67187.34,
  //     "usd_market_cap": 1317802988326.25,
  //     "usd_24h_vol": 28000000000,
  //     "usd_24h_change": 3.64
  //   },
  //   "ethereum": { ... }
  // }
}

Global Market Data

async function get_global_market_data() {
  const response = await fetch('https://api.coingecko.com/api/v3/global')
  const data = await response.json()

  return {
    total_market_cap_usd: data.data.total_market_cap.usd,
    total_volume_24h_usd: data.data.total_volume.usd,
    btc_dominance: data.data.market_cap_percentage.btc,
    eth_dominance: data.data.market_cap_percentage.eth,
    active_cryptocurrencies: data.data.active_cryptocurrencies,
    market_cap_change_24h: data.data.market_cap_change_percentage_24h_usd
  }
}

Coin ID Mapping

Common Hyperliquid symbols to CoinGecko IDs:

const COINGECKO_IDS = {
  'BTC': 'bitcoin',
  'ETH': 'ethereum',
  'SOL': 'solana',
  'AVAX': 'avalanche-2',
  'MATIC': 'matic-network',
  'ARB': 'arbitrum',
  'OP': 'optimism',
  'LINK': 'chainlink',
  'UNI': 'uniswap',
  'AAVE': 'aave',
  'DOGE': 'dogecoin',
  'SHIB': 'shiba-inu',
  'PEPE': 'pepe',
  'WIF': 'dogwifcoin',
  'BONK': 'bonk',
  'SUI': 'sui',
  'APT': 'aptos',
  'SEI': 'sei-network',
  'INJ': 'injective-protocol',
  'TIA': 'celestia',
  'JUP': 'jupiter-exchange-solana',
  'ONDO': 'ondo-finance',
  'RENDER': 'render-token',
  'FET': 'fetch-ai',
  'NEAR': 'near',
  'ATOM': 'cosmos',
  'DOT': 'polkadot',
  'ADA': 'cardano',
  'XRP': 'ripple',
  'LTC': 'litecoin',
  'BCH': 'bitcoin-cash'
}

function get_coingecko_id(symbol) {
  return COINGECKO_IDS[symbol.toUpperCase()] || symbol.toLowerCase()
}

Combined Sentiment Function

For trading agents, combine Fear & Greed with market data:

async function get_market_sentiment() {
  // Parallel fetch for efficiency
  const [fng, global_data, trending] = await Promise.all([
    get_fear_greed_index(),
    get_global_market_data(),
    get_trending_coins()
  ])

  // Calculate composite sentiment
  let sentiment_score = 50  // Neutral base

  // Fear & Greed contribution (40%)
  if (fng.value <= 25) sentiment_score += 20       // Extreme fear = bullish
  else if (fng.value <= 40) sentiment_score += 10
  else if (fng.value >= 75) sentiment_score -= 20  // Extreme greed = bearish
  else if (fng.value >= 60) sentiment_score -= 10

  // Market trend contribution (30%)
  if (global_data.market_cap_change_24h > 3) sentiment_score += 15
  else if (global_data.market_cap_change_24h > 1) sentiment_score += 8
  else if (global_data.market_cap_change_24h < -3) sentiment_score -= 15
  else if (global_data.market_cap_change_24h < -1) sentiment_score -= 8

  // BTC dominance contribution (30%) - rising = risk-off, falling = risk-on
  // (Handled separately based on trading strategy)

  return {
    fear_greed: fng,
    global: global_data,
    trending: trending.slice(0, 5),
    sentiment_score: Math.max(0, Math.min(100, sentiment_score)),
    direction: sentiment_score >= 60 ? 'BULLISH' : sentiment_score <= 40 ? 'BEARISH' : 'NEUTRAL'
  }
}

Rate Limit Handling

// Simple rate limiter for CoinGecko
const RATE_LIMIT = {
  calls: 0,
  reset_time: Date.now() + 60000,
  max_calls: 25  // Stay under 30/min limit
}

async function rate_limited_fetch(url) {
  // Reset counter every minute
  if (Date.now() > RATE_LIMIT.reset_time) {
    RATE_LIMIT.calls = 0
    RATE_LIMIT.reset_time = Date.now() + 60000
  }

  // Check limit
  if (RATE_LIMIT.calls >= RATE_LIMIT.max_calls) {
    const wait = RATE_LIMIT.reset_time - Date.now()
    await new Promise(r => setTimeout(r, wait))
    RATE_LIMIT.calls = 0
    RATE_LIMIT.reset_time = Date.now() + 60000
  }

  RATE_LIMIT.calls++
  return fetch(url)
}

Error Handling

async function safe_fetch(url, default_value = null) {
  try {
    const response = await fetch(url)
    if (!response.ok) {
      if (response.status === 429) {
        // Rate limited - wait and retry
        await new Promise(r => setTimeout(r, 60000))
        return safe_fetch(url, default_value)
      }
      throw new Error(`HTTP ${response.status}`)
    }
    return await response.json()
  } catch (error) {
    console.error(`Fetch error: ${error.message}`)
    return default_value
  }
}

Usage in Trading Agent

// In your scan loop:
async function get_sentiment_for_trade(coin, chat_id) {
  // Get Fear & Greed (free, unlimited)
  const fng = await get_fear_greed_index()

  // Get coin-specific data
  const coin_id = get_coingecko_id(coin)
  const price_data = await get_coin_prices(coin_id)

  // Get global context
  const global_data = await get_global_market_data()

  return {
    fear_greed: fng.value,
    fear_greed_signal: fng.value <= 30 ? 'BUY' : fng.value >= 70 ? 'SELL' : 'NEUTRAL',
    coin_24h_change: price_data[coin_id]?.usd_24h_change || 0,
    market_24h_change: global_data.market_cap_change_24h,
    btc_dominance: global_data.btc_dominance
  }
}
Weekly Installs
1
Repository
smithery/ai
First Seen
11 days ago
Security Audits
Installed on
claude-code1