Skip to content

Analyst Ratings Dataset

Access Wall Street analyst ratings, price targets, and recommendation changes. Track consensus ratings and target price movements for systematic trading strategies.

The Analyst Ratings dataset provides:

  • Current Rating: Buy, hold, or sell recommendation
  • Price Target: Analyst’s target price (with historical changes)
  • Analyst Info: Firm name and rating type
  • Rating Changes: Upgrades, downgrades, and reiterations
  • Historical Data: Track rating changes over time
CoverageDetails
MarketsS&P 500, NASDAQ, NYSE
SourcesMajor investment banks and research firms
Update FrequencyDaily
Historical Data3+ years
RatingMeaningSignal
Strong BuyHighest conviction recommendationBullish
Buy / OutperformExpect stock to beat marketBullish
Hold / NeutralExpect market performanceNeutral
UnderperformExpect stock to lag marketBearish
SellRecommend sellingBearish

Note: The targetPrice field is a string that may show price changes (e.g., "$205 → $190").

from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
# Get analyst ratings as DataFrame
df = fb.analyst_ratings.ticker("S&P 500", "AAPL", as_dataframe=True)
print(df.head())

For complete code examples in Python, JavaScript, C++, Rust, and cURL, see the API Reference.

Scan for recent rating changes:

from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
def scan_rating_changes(tickers):
"""Find stocks with recent upgrades or downgrades"""
upgrades = []
downgrades = []
for ticker in tickers:
try:
ratings = fb.analyst_ratings.ticker("S&P 500", ticker)
for r in ratings["analystRatings"][:5]: # Last 5 ratings
if r["type"] == "Upgrade":
upgrades.append({
"ticker": ticker,
"institution": r["institution"],
"signal": r["signal"],
"targetPrice": r["targetPrice"],
"date": r["date"]
})
elif r["type"] == "Downgrade":
downgrades.append({
"ticker": ticker,
"institution": r["institution"],
"signal": r["signal"],
"targetPrice": r["targetPrice"],
"date": r["date"]
})
except Exception:
continue
return {"upgrades": upgrades, "downgrades": downgrades}
tickers = ["AAPL", "MSFT", "GOOGL", "AMZN", "NVDA", "META", "TSLA"]
changes = scan_rating_changes(tickers)
print("Recent Upgrades:")
for u in changes["upgrades"]:
print(f" {u['ticker']}: {u['institution']} -> {u['signal']} ({u['targetPrice']})")
print("\nRecent Downgrades:")
for d in changes["downgrades"]:
print(f" {d['ticker']}: {d['institution']} -> {d['signal']} ({d['targetPrice']})")

Calculate upside potential to consensus target:

import re
from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
def parse_target_price(target_str):
"""Parse target price string like '$205 → $190' and return the new target"""
if not target_str:
return None
# Match price patterns like $190, $205.50, etc.
prices = re.findall(r'\$?([\d,]+\.?\d*)', target_str.replace(',', ''))
if prices:
# Return the last price (new target) or only price
return float(prices[-1])
return None
def calculate_upside(market, ticker, current_price):
"""Calculate upside to analyst target"""
ratings = fb.analyst_ratings.ticker(market, ticker)
analyst_ratings = ratings.get("analystRatings", [])
if not analyst_ratings:
return None
# Parse target prices from string format
targets = []
for r in analyst_ratings:
target = parse_target_price(r.get("targetPrice"))
if target:
targets.append(target)
if not targets:
return None
avg_target = sum(targets) / len(targets)
upside = ((avg_target - current_price) / current_price) * 100
return {
"ticker": ticker,
"current_price": current_price,
"avg_target_price": round(avg_target, 2),
"upside_percent": round(upside, 2),
"num_analysts": len(targets)
}
# Example usage (you'd get current price from market data)
result = calculate_upside("S&P 500", "AAPL", 185.00)
if result:
print(f"{result['ticker']}: {result['upside_percent']}% upside to ${result['avg_target_price']}")

Track how analyst sentiment is changing over time:

from finbrain import FinBrainClient
fb = FinBrainClient(api_key="YOUR_API_KEY")
def analyze_rating_trend(market, ticker):
"""Analyze if analyst sentiment is improving or deteriorating"""
ratings = fb.analyst_ratings.ticker(market, ticker)
signal_scores = {
"Sell": 1, "Underperform": 2, "Hold": 3, "Neutral": 3,
"Buy": 4, "Outperform": 4, "Overweight": 4, "Strong Buy": 5
}
scores = []
for r in ratings["analystRatings"]:
score = signal_scores.get(r["signal"], 3)
scores.append({"date": r["date"], "score": score, "type": r["type"]})
if len(scores) < 2:
return "insufficient_data"
recent_avg = sum(s["score"] for s in scores[:5]) / min(5, len(scores))
older_avg = sum(s["score"] for s in scores[5:10]) / min(5, len(scores[5:10])) if len(scores) > 5 else recent_avg
if recent_avg > older_avg + 0.3:
return "improving"
elif recent_avg < older_avg - 0.3:
return "deteriorating"
else:
return "stable"
trend = analyze_rating_trend("S&P 500", "AAPL")
print(f"Analyst sentiment: {trend}")