The stock doesn't move on what actually happened — it moves on whether it beat expectations. OpenClaw pulls live Wall Street consensus estimates and tracks when analysts quietly revise them up or down.
Before a company reports, dozens of Wall Street analysts publish their own predictions for revenue and earnings per share (EPS). The "consensus" is the average of all those predictions. This is the number the market is priced around. A company can grow revenue 20% and the stock still drops — if analysts expected 25% growth. It's all relative to expectations.
Here's how the market reacts:
The consensus estimate is the baseline. Everything is measured relative to it. Miss by a penny, and you can see a 5% sell-off. Beat by a penny, and a 5% rally. The actual growth rate matters far less than whether you met expectations.
This is the advanced insight — learn it well. When analysts revise their estimates up before a report, it often means they have informal intelligence that things are going well. When they revise down, the opposite. Tracking revision direction in the 30 days before a report is a well-known signal among professional traders.
Example: If Apple had 15 analysts covering it, and 12 of them raised their EPS estimate in the last 30 days, that's bullish momentum going into the report. The direction and concentration of revisions often predicts the stock's reaction more accurately than the earnings surprise itself.
Pro Tip: Revisions made in the 2 weeks before earnings are especially valuable. Near-term revisions suggest the analyst has seen something material. A late upward revision from 3+ analysts is a strong bullish signal.
Why? Because analysts don't revise lightly. Each revision represents a call to their trading desk, their fund clients, their reputation. If multiple analysts are revising up together, it's not random noise — it's a coordinated signal that fundamentals are improving.
| Without OpenClaw | With OpenClaw |
|---|---|
| Manually check analyst pages for each stock | Script pulls estimates for your full watchlist automatically |
| No revision history. Can't see what changed. | Compares current vs 30-days-ago estimates. Tracks every change. |
| No automated alerts. You miss signals. | Flags significant revisions. Flags when +5% consensus change detected. |
| Data trapped in browser tabs | Logs all estimates to CSV. Build strategies on top of historical data. |
| No dashboard. Can't see trends across 30+ stocks. | Central log. Compare revision patterns across your entire watchlist. |
OpenClaw does the heavy lifting. You get data. You make decisions.
Here's the config file that tells OpenClaw what to track and how to alert you:
watchlist:
tickers: [AAPL, MSFT, NVDA, AMZN, GOOGL]
estimates:
track_revisions: true
revision_window_days: 30
flag_revision_pct: 5.0 # flag if estimate moved ±5% or more
sources: ["yfinance"]
alerts:
email: "you@example.com"
daily_digest: true
tickers — List of stock symbols to monitor. Add as many as you want.track_revisions — Set to true to enable revision tracking (comparing current estimates to prior runs).revision_window_days — How far back to look for revisions. 30 days is standard for earnings season signals.flag_revision_pct — Threshold for flagging. If an EPS estimate moves ±5% or more, the script flags it as "SIGNIFICANT". Adjust to suit your sensitivity.sources — Data source. "yfinance" is free and works well for consensus data.email — Where daily digest alerts go. Optional but highly recommended.daily_digest — If true, you get one email per day summarizing all revisions and significant changes across your watchlist.Here's the complete, heavily commented script that pulls estimates and tracks revisions:
"""
earnings_estimates.py — OpenClaw Earnings Estimates Tracker
Pulls EPS and revenue consensus estimates for your watchlist.
Flags significant analyst revisions in the configured window.
"""
import yaml
import yfinance as yf
import pandas as pd
from datetime import datetime
# ── Load config ────────────────────────────────────────────────────────────
with open("earnings-config.yaml") as f:
cfg = yaml.safe_load(f)
tickers = cfg["watchlist"]["tickers"]
flag_pct = cfg["estimates"].get("flag_revision_pct", 5.0)
# ── Fetch estimates for each ticker ───────────────────────────────────────
print("📊 EARNINGS ESTIMATES — YOUR WATCHLIST")
print("=" * 60)
results = []
for ticker in tickers:
stock = yf.Ticker(ticker)
try:
# Get analyst earnings estimates (quarterly)
estimates = stock.earnings_estimate
revenue = stock.revenue_estimate
if estimates is None:
print(f" {ticker}: No estimate data available")
continue
# Current quarter estimates
current_q = estimates.iloc[0] if not estimates.empty else None
if current_q is not None:
eps_est = current_q.get("avg", "N/A")
eps_low = current_q.get("low", "N/A")
eps_high = current_q.get("high", "N/A")
num_analysts = current_q.get("numberOfAnalysts", "N/A")
# Revenue estimate (if available)
rev_est = "N/A"
if revenue is not None and not revenue.empty:
rev_row = revenue.iloc[0]
rev_est = rev_row.get("avg", "N/A")
print(f"\n {ticker}")
print(f" EPS Estimate: ${eps_est}")
print(f" Range: ${eps_low} – ${eps_high}")
print(f" Revenue Estimate: {rev_est}")
print(f" # Analysts: {num_analysts}")
results.append({
"Ticker": ticker,
"EPS Estimate": eps_est,
"EPS Low": eps_low,
"EPS High": eps_high,
"Revenue Est": rev_est,
"Analysts": num_analysts,
"Fetched": datetime.today().strftime("%Y-%m-%d"),
})
except Exception as e:
print(f" {ticker}: Error — {e}")
# ── Check for revision signals (compare to prior log if it exists) ─────────
print("\n\n🔍 REVISION CHECK")
print("=" * 60)
try:
prior = pd.read_csv("data/estimates_log.csv")
prior_latest = prior.groupby("Ticker").last().reset_index()
for r in results:
prior_row = prior_latest[prior_latest["Ticker"] == r["Ticker"]]
if prior_row.empty:
print(f" {r['Ticker']}: No prior data for comparison (first run)")
continue
prior_eps = prior_row["EPS Estimate"].values[0]
curr_eps = r["EPS Estimate"]
try:
change_pct = ((float(curr_eps) - float(prior_eps)) / abs(float(prior_eps))) * 100
direction = "⬆️ UP" if change_pct > 0 else "⬇️ DOWN"
flag = " ⚠️ SIGNIFICANT" if abs(change_pct) >= flag_pct else ""
print(f" {r['Ticker']}: {direction} {abs(change_pct):.1f}%{flag}")
except:
print(f" {r['Ticker']}: Could not compute revision")
except FileNotFoundError:
print(" No prior log found — this is your first run. Baseline saved.")
# ── Save to CSV ────────────────────────────────────────────────────────────
if results:
df = pd.DataFrame(results)
df.to_csv("data/estimates_log.csv", mode="a", header=not pd.io.common.file_exists("data/estimates_log.csv"), index=False)
print("\n💾 Saved to data/estimates_log.csv")
Run this weekly (before earnings week) to track revision momentum. The longer your CSV log, the more patterns you'll spot.
Here's what you see when you run the script:
In this example:
Check your email inbox for the daily digest. You're ready to trade on this intelligence.
Use these signals to interpret estimate data and spot trading opportunities:
If analysts predict EPS between $1.20 and $2.00 for the same quarter, there's massive disagreement. This high uncertainty usually means the stock will move more on the actual report. Set alerts for wide ranges.
When you see +5%, +8%, +10% revisions, insiders may be leaking guidance to favored analysts. This is illegal but happens. The point: upward revisions are often early signals of outperformance.
Revisions made 30 days before earnings are old news. Revisions made 7–14 days before are hot. The closer to the report date, the more material the revision. A 3+ analyst upward revision 10 days before earnings is a strong buy signal.
Downward revisions are less common and more serious. When they happen, the consensus is shrinking. This precedes missed earnings and stock drops. Watch for a pattern of multiple downward revisions — that's your exit signal.
A stock covered by 50+ analysts has a tighter consensus. One analyst's revision doesn't move the needle. A stock covered by 5 analysts can swing wildly on a single revision. Pay attention to analyst count.
You don't want to run this manually every week. Set it on a schedule. Here's the cron command to run the script every Monday at 7 AM (before market open, so you see revisions before the week's earnings):
# Run weekly on Monday mornings to track revision trends
0 7 * * 1 cd /path/to/openclaw && python earnings_estimates.py
0 — minute (0 = top of the hour)7 — hour (7 AM in 24-hour format)* — day of month (any)* — month (any)1 — day of week (1 = Monday)cd /path/to/openclaw && python earnings_estimates.py — command to runReplace /path/to/openclaw with your actual directory path. You can also add > /tmp/earnings.log 2>&1 at the end to capture output for debugging.
If you prefer a daily check (more responsive to last-minute revisions), change the cron to:
0 7 * * * cd /path/to/openclaw && python earnings_estimates.py
The last * instead of 1 means "every day" instead of "Monday only". You'll get daily alerts, which is more sensitive but also more noise.