Build a production-aware system that detects market conditions using CoinMarketCap API and decides when your trading strategies should be active.
Introduction
Most trading bots fail for one simple reason:
They keep trading when the market conditions are bad.
Execution is not the hard part. Timing is.
Markets shift between different states:
- Risk-On → momentum strategies work
- Risk-Off → capital preservation matters
- Altcoin Season → rotation into higher beta assets
- Bitcoin Dominance → defensive positioning
CoinMarketCap API allows you to detect these conditions programmatically.
In this guide, you’ll build a Market Timing Bot with CoinMarketCap API, where:
- CoinMarketCap API powers macro signals
- Your system classifies market conditions
- Other bots use this as a decision filter
System Architecture
CoinMarketCap API
├─ Fear & Greed
├─ Altcoin Season Index
├─ Quotes Latest
├─ Listings Latest
↓
Timing Engine
↓
Risk-On / Risk-Off / Neutral
↓
Strategy Control Layer
Project Setup
import os
import requests
import pandas as pd
CMC_API_KEY = os.getenv("CMC_API_KEY")
BASE_URL = "https://pro-api.coinmarketcap.com"
HEADERS = {
"Accept": "application/json",
"X-CMC_PRO_API_KEY": CMC_API_KEY,
}
Step 1: Fetch Fear & Greed Index
Endpoint
/v3/fear-and-greed/latest
def fetch_fear_greed():
url = f"{BASE_URL}/v3/fear-and-greed/latest"
r = requests.get(url, headers=HEADERS, timeout=10)
r.raise_for_status()
data = r.json()["data"]
return {
"value": data["value"],
"classification": data["value_classification"],
"update_time": data["update_time"]
}
Step 2: Fetch Altcoin Season Index
Endpoint
/v1/altcoin-season-index/latest
def fetch_altcoin_index():
url = f"{BASE_URL}/v1/altcoin-season-index/latest"
r = requests.get(url, headers=HEADERS, timeout=10)
r.raise_for_status()
data = r.json()["data"]
return data["altcoin_index"]
Step 3: Fetch Market Momentum (Quotes)
Endpoint
/v3/cryptocurrency/quotes/latest
def fetch_top_assets():
url = f"{BASE_URL}/v3/cryptocurrency/quotes/latest"
params = {
"id": "1,1027,5426" # BTC, ETH, SOL
}
r = requests.get(url, headers=HEADERS, params=params, timeout=10)
r.raise_for_status()
return r.json()["data"]
Important: Flatten quote -> USD
def extract_momentum(data):
results = {}
for asset_id, asset in data.items():
usd = asset["quote"]["USD"]
results[asset["symbol"]] = {
"percent_change_1h": usd["percent_change_1h"],
"percent_change_24h": usd["percent_change_24h"],
"volume_24h": usd["volume_24h"],
}
return results
Step 4: Market Breadth (Listings)
Endpoint
/v3/cryptocurrency/listings/latest
def fetch_market_breadth(limit=200):
url = f"{BASE_URL}/v3/cryptocurrency/listings/latest"
params = {
"limit": limit,
"sort": "market_cap"
}
r = requests.get(url, headers=HEADERS, params=params, timeout=10)
r.raise_for_status()
return r.json()["data"]
def calculate_breadth(data):
positives = 0
for asset in data:
change = asset["quote"]["USD"]["percent_change_24h"]
if change > 0:
positives += 1
return positives / len(data)
Step 5: Build Regime Score
def compute_regime(fg, alt_index, momentum, breadth):
try:
avg_momentum = sum([v["percent_change_24h"] for v in momentum.values()]) / len(momentum)
score = 0
score += fg * 0.3
score += alt_index * 0.25
score += avg_momentum * 0.25 # symmetric contribution
score += breadth * 100 * 0.2
if score > 70:
return "RISK_ON"
elif score < 40:
return "RISK_OFF"
else:
return "NEUTRAL"
except Exception:
return "UNKNOWN"
Step 6: Interpret Altcoin Season
def classify_altcoin_season(index):
if index > 75:
return "ALTCOIN_SEASON"
elif index < 25:
return "BITCOIN_SEASON"
else:
return "TRANSITION"
Step 7: Use Regime in Other Bots
regime = compute_regime(...)
if regime == "RISK_ON":
enable_strategies()
elif regime == "RISK_OFF":
reduce_exposure()
Step 8: Historical Backtesting
Endpoint
/v3/cryptocurrency/quotes/historical
⚠️ May require paid plan depending on depth.
Use to:
- validate regime transitions
- tune thresholds
- simulate strategy performance
Paid Endpoint Warning
Some endpoints may return:
HTTP 403 Forbidden
Error 1006: Plan Not Authorized
Examples:
- /v3/cryptocurrency/quotes/historical
- /v1/cryptocurrency/trending/gainers-losers
Fallback Strategy
If endpoints fail, continue with core signals:
# fallback regime inputs
use_fear_greed = True
use_alt_index = True
use_quotes = True
use_listings = True
Rate Limit Strategy
- Quotes/Listings → 60 seconds
- Fear & Greed → 15 minutes
- Altcoin Season → 15 minutes
Best practices:
- poll quotes every 30–60 seconds
- poll macro signals every 15 minutes
- cache results
- use exponential backoff for 429
Common Mistakes
- Ignoring quote → USD nesting
- Polling macro signals too frequently
- Not handling 403 errors
- Overweighting one signal
- No fallback logic
Final Thoughts
A trading system without timing is incomplete.
CoinMarketCap API allows you to turn market data into a decision layer.
This becomes the control system for every strategy you run.
Next Steps
- integrate timing into trading bots
- test scoring weights
- add logging and alerts
- combine with execution systems
Better timing leads to better results.
