News & Sentiment (wraquant.news)¶
The news module provides 17 functions for news sentiment analysis, corporate event monitoring, and SEC filings retrieval – the data layer for event-driven and sentiment-based quant strategies.
Three areas of coverage:
Sentiment analysis (
sentimentsubmodule) – Score news headlines using a built-in Loughran-McDonald-inspired keyword lexicon, or optionally VADER/TextBlob. Build sentiment time series with recency weighting, and generate discrete trading signals from aggregate sentiment.Corporate events (
eventssubmodule) – Earnings calendar and surprise analysis (PEAD), dividend history and payout trends, insider transaction activity (net buy/sell ratios), and institutional ownership tracking with quarterly changes.SEC filings (
filingssubmodule) – Search and retrieve 10-K, 10-Q, 8-K, and other filing types. Convenience functions for annual reports, quarterly reports, and material events.
All functions use the FMP (Financial Modeling Prep) API for data. Requires
the market-data extra and an FMP_API_KEY environment variable.
Quick Example¶
from wraquant.news import news_sentiment, earnings_history, recent_filings
# Aggregate sentiment for a ticker
sentiment = news_sentiment("AAPL")
print(f"Sentiment: {sentiment['aggregate_sentiment']:.2f}")
print(f"Articles analyzed: {sentiment['n_articles']}")
# Earnings history with surprise analysis
earnings = earnings_history("AAPL")
print(earnings[["date", "eps_actual", "eps_estimate", "surprise_pct"]].head())
# Recent SEC filings
filings = recent_filings("AAPL", limit=5)
print(filings[["date", "type", "title"]])
Sentiment Pipeline¶
The sentiment module implements a four-step pipeline:
Fetch – Pull headlines/articles via
FMPClientScore – Assign each headline a score in [-1, +1]
Aggregate – Combine scores with recency weighting
Signal – Convert the aggregate into a discrete trading signal
from wraquant.news import (
sentiment_score,
sentiment_timeseries,
sentiment_signal,
news_impact,
)
# Score individual headlines
score = sentiment_score("Apple beats earnings expectations, raises guidance")
print(f"Score: {score:.2f}") # Positive
# Sentiment time series (daily aggregate scores)
ts = sentiment_timeseries("AAPL", days=90)
print(ts.tail()) # pd.Series with date index
# Generate a trading signal from sentiment
signal = sentiment_signal("AAPL", threshold=0.3)
print(f"Signal: {signal['signal']}") # 1 (bullish), 0, or -1 (bearish)
# Measure news impact on price
impact = news_impact("AAPL", event_date="2025-01-30")
print(f"1-day return: {impact['return_1d']:.2%}")
Event-Driven Analysis¶
from wraquant.news import (
earnings_calendar,
earnings_surprises,
upcoming_earnings,
dividend_history,
insider_activity,
institutional_ownership,
)
# Earnings calendar for a date range
calendar = earnings_calendar(from_date="2025-04-01", to_date="2025-04-30")
print(f"Earnings reports this month: {len(calendar)}")
# Earnings surprises (beat/miss history)
surprises = earnings_surprises("AAPL")
avg_surprise = surprises["surprise_pct"].mean()
print(f"Average surprise: {avg_surprise:.1%}")
# Upcoming earnings for a ticker
upcoming = upcoming_earnings("TSLA")
# Dividend history
dividends = dividend_history("JNJ")
print(f"Current yield: {dividends['current_yield']:.2%}")
# Insider activity
insiders = insider_activity("AAPL")
print(f"Net insider sentiment: {insiders['net_sentiment']}")
# Institutional ownership
holders = institutional_ownership("AAPL")
print(holders[["holder", "shares", "pct_held"]].head(10))
SEC Filings¶
from wraquant.news import (
recent_filings,
annual_reports,
quarterly_reports,
material_events,
filing_search,
)
# Recent filings of any type
filings = recent_filings("AAPL", limit=10)
# Filter by filing type
annuals = annual_reports("MSFT", limit=3) # 10-K filings
quarterlies = quarterly_reports("MSFT", limit=4) # 10-Q filings
events = material_events("MSFT", limit=5) # 8-K filings
# Search filings with keywords
results = filing_search("AAPL", query="risk factors", filing_type="10-K")
See also
Fundamental Analysis (wraquant.fundamental) – Financial ratios and valuation models
Risk Analysis – Using news signals in risk analysis
Machine Learning (wraquant.ml) – News sentiment as ML features
Data (wraquant.data) – Data fetching and cleaning
API Reference¶
News, sentiment, and event-driven analysis.
FMP-backed module for news sentiment scoring, earnings analysis, insider trading activity, dividend history, SEC filings, and institutional ownership tracking.
- Modules:
sentiment: News sentiment scoring, timeseries, and signal generation events: Earnings, dividends, insider trades, institutional holders filings: SEC filings (10-K, 10-Q, 8-K) search and retrieval
Example
>>> from wraquant.news import news_sentiment, earnings_history
>>> sentiment = news_sentiment("AAPL")
>>> print(f"Sentiment: {sentiment['aggregate_sentiment']:.2f}")
>>> earnings = earnings_history("AAPL")
- news_sentiment(symbol, limit=50, *, engine='auto', half_life_days=7.0, include_press_releases=True)[source]¶
Analyze sentiment of recent news for a stock.
Fetches recent news headlines (and optionally press releases) from FMP, scores each headline using the specified sentiment engine, and computes aggregate statistics including recency-weighted sentiment and trend direction.
The recency weighting uses exponential decay so that recent articles contribute more to the aggregate than older ones. The trend is determined by comparing first-half vs. second-half sentiment to detect whether coverage is improving or deteriorating.
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"AAPL").limit (
int, default:50) – Maximum number of news articles to fetch. Higher values give a more robust sentiment estimate but include older news.engine (
str, default:'auto') – Sentiment scoring engine."auto"tries VADER, then TextBlob, then falls back to the built-in keyword scorer. Options:"auto","keyword","vader","textblob".half_life_days (
float, default:7.0) – Half-life for recency weighting in days. Default of 7 means a one-week-old article gets half the weight of today’s article.include_press_releases (
bool, default:True) – If True, also fetch press releases and include them in the analysis.
- Returns:
symbol (str) – Ticker symbol.
engine (str) – Sentiment engine used.
article_count (int) – Total number of articles scored.
articles (list[dict]) – List of dicts, each with keys
title,date,source,sentiment,url.aggregate (dict) – Aggregate statistics: - mean (float) – Simple mean sentiment. - weighted_mean (float) – Recency-weighted mean. - median (float) – Median sentiment. - std (float) – Standard deviation of scores. - bullish_pct (float) – Fraction of positive articles. - bearish_pct (float) – Fraction of negative articles. - neutral_pct (float) – Fraction of neutral articles.
trend (str) –
"improving","deteriorating", or"stable"based on first-half vs. second-half comparison.trend_delta (float) – Second-half mean minus first-half mean.
news_volume (str) –
"high","medium", or"low"based on article count relative to limit.
- Return type:
Example
>>> from wraquant.news.sentiment import news_sentiment >>> result = news_sentiment("AAPL", limit=30) >>> print(f"Weighted sentiment: {result['aggregate']['weighted_mean']:.3f}") >>> print(f"Trend: {result['trend']}")
Notes
Reference: Tetlock (2007). “Giving Content to Investor Sentiment.” The Journal of Finance, 62(3), 1139-1168.
See also
sentiment_timeseries: Build a daily time series of sentiment. sentiment_signal: Convert sentiment to a trading signal.
- sentiment_timeseries(symbol, days=90, *, engine='auto', resample='D')[source]¶
Build a daily (or custom frequency) sentiment time series.
Fetches up to
daysworth of news for a symbol, scores each article, and resamples into a regular time series by averaging sentiment within each period. Missing days are forward-filled so the series can be used directly alongside price data.- Parameters:
symbol (
str) – Ticker symbol (e.g.,"MSFT").days (
int, default:90) – Number of calendar days of history to request. FMP may return fewer articles than this span covers.engine (
str, default:'auto') – Sentiment scoring engine (seenews_sentiment).resample (
str, default:'D') – Pandas resample frequency string."D"for daily,"W"for weekly,"B"for business days.
- Return type:
- Returns:
pd.Series with a DatetimeIndex and sentiment scores averaged per period. Index name is
"date", series name is"sentiment".
Example
>>> from wraquant.news.sentiment import sentiment_timeseries >>> ts = sentiment_timeseries("TSLA", days=30) >>> print(ts.tail())
See also
news_sentiment: Detailed sentiment analysis for a single snapshot. sentiment_signal: Convert the time series to a signal.
- sentiment_signal(symbol, threshold=0.3, *, engine='auto', half_life_days=7.0)[source]¶
Generate a discrete sentiment-based trading signal for a stock.
Fetches recent news, computes the recency-weighted aggregate sentiment, and classifies it as bullish, bearish, or neutral based on the threshold.
The signal logic is: -
weighted_mean > threshold=>"bullish"-weighted_mean < -threshold=>"bearish"- Otherwise =>"neutral"- Parameters:
symbol (
str) – Ticker symbol (e.g.,"GOOG").threshold (
float, default:0.3) – Absolute threshold for signal classification. Lower values produce more signals (more sensitive); higher values filter out weak sentiment. Default of 0.3 is moderately conservative.engine (
str, default:'auto') – Sentiment scoring engine (seenews_sentiment).half_life_days (
float, default:7.0) – Half-life for recency weighting (seenews_sentiment).
- Return type:
- Returns:
One of
"bullish","bearish", or"neutral".
Example
>>> from wraquant.news.sentiment import sentiment_signal >>> signal = sentiment_signal("NVDA", threshold=0.2) >>> print(f"Sentiment signal: {signal}")
See also
news_sentiment: Full sentiment analysis with article-level detail. sentiment_timeseries: Historical sentiment time series.
- sentiment_score(texts, *, engine='auto')[source]¶
Score text passages on a numeric sentiment scale.
Scores arbitrary text using the specified sentiment engine. This is the low-level scoring function; for news-specific analysis with data fetching and aggregation, use
news_sentimentinstead.- Parameters:
- Returns:
scores (list[float]) – Sentiment score for each text, in the range [-1.0, 1.0].
mean_score (float) – Mean sentiment across all texts.
engine (str) – Name of the engine used.
- Return type:
Example
>>> result = sentiment_score("Stock rallied on strong earnings") >>> print(f"Score: {result['scores'][0]:.3f}") >>> print(f"Engine: {result['engine']}")
See also
news_sentiment: Full news sentiment pipeline with data fetching. sentiment_signal: Discrete signal from sentiment.
- news_impact(returns, event_dates, window=5)[source]¶
Measure the impact of news events on returns using event study.
Delegates to
wraquant.causal.treatment.event_studyto compute cumulative abnormal returns (CARs) around each event date.- When to use:
Use news impact analysis to quantify whether specific news events (earnings releases, FDA approvals, geopolitical shocks) have a statistically significant effect on returns.
- Parameters:
returns (
Series) – Return series with a DatetimeIndex.event_dates (
list|DatetimeIndex) – List of event dates to study.window (
int, default:5) – Number of periods before and after each event to include in the analysis window.
- Returns:
car (float) – Mean cumulative abnormal return across all events.
event_results – Detailed event study output from
wraquant.causal.treatment.event_study.
- Return type:
Example
>>> import pandas as pd, numpy as np >>> rng = np.random.default_rng(42) >>> dates = pd.bdate_range("2023-01-01", periods=252) >>> rets = pd.Series(rng.normal(0.0005, 0.01, 252), index=dates) >>> events = [dates[50], dates[150]] >>> result = news_impact(rets, events, window=5)
See also
wraquant.causal.treatment.event_study: Underlying event study. earnings_surprise: Earnings-specific impact metric.
- earnings_calendar(from_date=None, to_date=None)[source]¶
Fetch the earnings calendar for a date range.
Returns a DataFrame of upcoming and recent earnings announcements across all symbols. Useful for screening the market for event-driven opportunities and avoiding earnings risk in existing positions.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
date (str) – Earnings date.
eps_estimated (float) – Consensus EPS estimate.
eps_actual (float) – Actual EPS (NaN if not yet reported).
revenue_estimated (float) – Consensus revenue estimate.
revenue_actual (float) – Actual revenue (NaN if not yet reported).
time (str) –
"bmo"(before market open),"amc"(after market close), or"--".
- Return type:
Example
>>> from wraquant.news.events import earnings_calendar >>> cal = earnings_calendar("2024-01-15", "2024-01-19") >>> print(cal[["symbol", "date", "eps_estimated"]].head())
See also
earnings_surprises: Historical beat/miss data for a single stock. upcoming_earnings: Next earnings date for a specific symbol.
- earnings_surprises(symbol, limit=20)[source]¶
Fetch historical earnings surprises for a stock.
Returns actual vs. estimated EPS for each earnings report, with the standardized surprise computed as
(actual - estimate) / |estimate|. This is the raw data behind the PEAD (post-earnings announcement drift) anomaly.- Mathematical formulation:
SUE_t = (EPS_actual - EPS_estimate) / |EPS_estimate|
- Parameters:
- Returns:
date (str) – Earnings announcement date.
actual (float) – Actual reported EPS.
estimate (float) – Consensus analyst estimate.
surprise (float) – Standardized surprise.
surprise_pct (float) – Surprise as a percentage.
beat (bool) – True if actual exceeded estimate.
- Return type:
Example
>>> from wraquant.news.events import earnings_surprises >>> df = earnings_surprises("MSFT", limit=8) >>> print(df[["date", "actual", "estimate", "surprise_pct", "beat"]])
Notes
Reference: Bernard & Thomas (1989). “Post-Earnings-Announcement Drift: Delayed Price Response or Risk Premium?” Journal of Accounting Research, 27, 1-36.
See also
earnings_history: Extended analysis including PEAD metrics. upcoming_earnings: Next expected earnings date.
- upcoming_earnings(symbol)[source]¶
Get the next expected earnings date and consensus estimate.
Combines earnings calendar lookup with analyst estimates to provide a quick snapshot of the upcoming earnings event for a symbol.
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"AMZN").- Returns:
symbol (str) – Ticker symbol.
next_date (str | None) – Next expected earnings date, or None if not scheduled.
eps_estimate (float | None) – Consensus EPS estimate.
revenue_estimate (float | None) – Consensus revenue estimate.
days_until (int | None) – Calendar days until earnings.
time (str | None) –
"bmo"or"amc"if known.
- Return type:
Example
>>> from wraquant.news.events import upcoming_earnings >>> info = upcoming_earnings("GOOG") >>> if info["next_date"]: ... print(f"Earnings on {info['next_date']} " ... f"({info['days_until']} days away)")
See also
earnings_calendar: Full market-wide calendar. earnings_surprises: Historical beat/miss data.
- earnings_history(symbol, limit=20)[source]¶
Comprehensive earnings history with beat/miss analysis and PEAD.
Builds on
earnings_surprisesto provide aggregate statistics about a company’s earnings track record, including beat rate, average surprise magnitude, consistency, and post-earnings announcement drift (PEAD) metrics.The PEAD analysis measures whether the stock price continues to drift in the direction of the surprise after the announcement, which is one of the most robust and well-documented anomalies in finance.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
quarters_analyzed (int) – Number of quarters in the analysis.
surprises (pd.DataFrame) – Raw earnings surprise data (same format as
earnings_surprises).beat_rate (float) – Fraction of quarters where actual exceeded estimate.
miss_rate (float) – Fraction of quarters where actual was below estimate.
avg_surprise (float) – Mean standardized surprise.
avg_beat_magnitude (float) – Mean surprise when beating.
avg_miss_magnitude (float) – Mean surprise when missing.
surprise_std (float) – Standard deviation of surprises (measures consistency).
streak (dict) – Current streak info: - type (str) –
"beat"or"miss". - length (int) – Number of consecutive beats/misses.pead_signal (str) –
"strong_beat","moderate_beat","neutral","moderate_miss", or"strong_miss"based on the most recent surprise.
- Return type:
Example
>>> from wraquant.news.events import earnings_history >>> hist = earnings_history("AAPL", limit=12) >>> print(f"Beat rate: {hist['beat_rate']:.0%}") >>> print(f"Avg surprise: {hist['avg_surprise']:.2%}") >>> print(f"Current streak: {hist['streak']}")
Notes
Reference: Ball & Brown (1968). “An Empirical Evaluation of Accounting Income Numbers.” Journal of Accounting Research, 6(2), 159-178.
See also
earnings_surprises: Raw surprise data. upcoming_earnings: Next earnings date.
- dividend_history(symbol, limit=40)[source]¶
Analyze dividend history including yield, growth, and payout ratio.
Fetches historical dividend data and computes metrics relevant to dividend-focused strategies: yield trends, dividend growth rates, and consistency of payments. Dividend growth is a strong predictor of total return for income-oriented portfolios.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
dividends (pd.DataFrame) – Historical dividend data with columns:
date,dividend,yield_pct(if price available).total_dividends (int) – Number of dividend payments.
current_annual_dividend (float) – Estimated annual dividend based on most recent payment.
dividend_growth_rate (float) – Compound annual growth rate of dividends (if sufficient history).
consecutive_payments (int) – Count of consecutive periods with a dividend payment.
is_grower (bool) – True if the dividend has grown year-over-year in each of the last 3 periods.
- Return type:
Example
>>> from wraquant.news.events import dividend_history >>> div = dividend_history("KO", limit=20) >>> print(f"Annual dividend: ${div['current_annual_dividend']:.2f}") >>> print(f"Growth rate: {div['dividend_growth_rate']:.1%}")
See also
earnings_history: Earnings-based fundamental analysis.
- insider_activity(symbol, limit=100)[source]¶
Analyze insider buying and selling activity.
Insider transactions are among the most informative signals in equity markets. Insiders (officers, directors, 10%+ owners) must file SEC Form 4 within two business days of a transaction. Aggregate insider buying is a stronger signal than selling, because insiders may sell for many reasons (diversification, liquidity) but typically buy only when they expect appreciation.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
transactions (pd.DataFrame) – Raw transaction data with columns:
date,insider,transaction_type,shares,price,value.total_transactions (int) – Number of transactions.
buy_count (int) – Number of purchase transactions.
sell_count (int) – Number of sale transactions.
buy_sell_ratio (float) – Ratio of buys to sells (>1 is bullish). Returns
infif no sells.net_shares (int) – Net shares bought minus sold.
net_value (float) – Net dollar value of insider trades.
notable_trades (list[dict]) – Transactions above $1M.
signal (str) –
"bullish"if net buying is significant,"bearish"if net selling is significant,"neutral"otherwise.
- Return type:
Example
>>> from wraquant.news.events import insider_activity >>> insiders = insider_activity("AAPL") >>> print(f"Buy/sell ratio: {insiders['buy_sell_ratio']:.2f}") >>> print(f"Net value: ${insiders['net_value']:,.0f}") >>> print(f"Signal: {insiders['signal']}")
Notes
Reference: Lakonishok & Lee (2001). “Are Insider Trades Informative?” The Review of Financial Studies, 14(1), 79-111.
See also
institutional_ownership: Institutional holder analysis. earnings_history: Fundamental event analysis.
- institutional_ownership(symbol)[source]¶
Analyze institutional ownership and recent changes.
Institutional investors (mutual funds, hedge funds, pension funds) hold the majority of US equity market capitalization. Changes in institutional ownership can signal informed conviction: increasing ownership by smart-money managers is a moderately bullish signal.
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"TSLA").- Returns:
symbol (str) – Ticker symbol.
holders (pd.DataFrame) – Top institutional holders with columns:
holder,shares,date_reported,change,change_pct.total_institutional_holders (int) – Count of institutional holders.
total_shares_held (int) – Total shares held by institutions.
top_holder (str | None) – Name of the largest holder.
net_change (str) –
"increasing","decreasing", or"stable"based on aggregate position changes.concentration (float) – Herfindahl index of ownership concentration among top holders (higher = more concentrated).
- Return type:
Example
>>> from wraquant.news.events import institutional_ownership >>> inst = institutional_ownership("AAPL") >>> print(f"Top holder: {inst['top_holder']}") >>> print(f"Net change: {inst['net_change']}") >>> print(inst["holders"].head())
See also
insider_activity: Corporate insider transaction analysis.
- recent_filings(symbol, form_type=None, limit=20, *, fmp_client=None)[source]¶
Fetch recent SEC filings for a company.
Returns a DataFrame of SEC filings sorted by date (most recent first). Optionally filter by form type to focus on specific filing categories.
- When to use:
Use this as the primary entry point for SEC filing retrieval. For specific filing types, prefer the convenience wrappers
annual_reports(),quarterly_reports(), ormaterial_events(). Use this function directly when you need filings of a specific type not covered by the convenience functions (e.g., Form 4 insider transactions, 13F institutional holdings, S-1 registration statements).
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"AAPL").form_type (
str|None, default:None) – SEC form type to filter by (e.g.,"10-K","10-Q","8-K","4","13F"). IfNone, returns all filing types.limit (
int, default:20) – Maximum number of filings to return.fmp_client (
Any|None, default:None) – Optional pre-configuredFMPClientinstance. IfNone, a default client is created.
- Returns:
date (str) – Filing date.
type (str) – SEC form type.
title (str) – Filing title/description.
url (str) – Link to the filing on SEC EDGAR.
cik (str) – SEC Central Index Key.
- Return type:
Example
>>> from wraquant.news.filings import recent_filings >>> filings = recent_filings("MSFT", form_type="10-K", limit=5) >>> print(filings[["date", "type", "title"]])
See also
annual_reports: Shortcut for 10-K filings. quarterly_reports: Shortcut for 10-Q filings. material_events: Shortcut for 8-K filings. filing_search: Text search across filings.
- annual_reports(symbol, limit=5, *, fmp_client=None)[source]¶
Fetch 10-K annual report filings for a company.
Convenience wrapper around
recent_filings()that filters for 10-K filings only. Annual reports are the most comprehensive disclosure and include audited financial statements, MD&A (management discussion and analysis), risk factors, and more.- When to use:
Use this to find annual report filing dates and links for fundamental analysis. Annual reports are required reading before making investment decisions – they contain the audited financials, risk disclosures, and management’s own assessment of the business.
- Parameters:
- Returns:
date,type,title,url,cik. Sorted by date descending.- Return type:
Example
>>> from wraquant.news.filings import annual_reports >>> reports = annual_reports("AMZN", limit=3) >>> print(reports[["date", "title"]])
See also
quarterly_reports: 10-Q filings. material_events: 8-K filings. recent_filings: All filing types.
- quarterly_reports(symbol, limit=10, *, fmp_client=None)[source]¶
Fetch 10-Q quarterly report filings for a company.
Convenience wrapper around
recent_filings()that filters for 10-Q filings only. Quarterly reports provide interim financial statements and updated risk disclosures between annual reports.- When to use:
Use this to track intra-year financial trends. Quarterly reports are especially important for companies undergoing rapid change (turnarounds, market share shifts, cost restructuring) where waiting for the annual report would miss critical inflection points.
- Parameters:
- Returns:
date,type,title,url,cik. Sorted by date descending.- Return type:
Example
>>> from wraquant.news.filings import quarterly_reports >>> reports = quarterly_reports("META", limit=4) >>> print(reports[["date", "title"]])
See also
annual_reports: 10-K filings. material_events: 8-K filings. recent_filings: All filing types.
- material_events(symbol, limit=20, *, fmp_client=None)[source]¶
Fetch 8-K current report filings for a company.
8-K filings disclose material events that shareholders should know about between regular SEC reporting periods. These include:
Entry into or termination of a material agreement
Bankruptcy or receivership
Departure or appointment of officers/directors
Changes in fiscal year
Amendments to articles of incorporation
Material impairments
Unregistered sales of equity securities
Changes in certifying accountant
- When to use:
For event-driven strategies, 8-K filings are the most actionable filing type because they signal discrete, potentially price-moving corporate actions. Monitor 8-K filings for activist targets, M&A candidates, and companies undergoing management transitions.
- Parameters:
- Returns:
date,type,title,url,cik. Sorted by date descending.- Return type:
Example
>>> from wraquant.news.filings import material_events >>> events = material_events("GM", limit=10) >>> print(events[["date", "title"]])
See also
annual_reports: 10-K filings. quarterly_reports: 10-Q filings. recent_filings: All filing types.
- filing_search(query=None, from_date=None, to_date=None, *, limit=50, fmp_client=None)[source]¶
Search SEC filings by keyword and/or date range.
Performs a text search over filing titles and descriptions to find filings related to a specific topic (e.g.,
"merger","restatement","executive departure").This performs client-side filtering on bulk filing data, so it works best with a focused symbol-level query. For market-wide filing searches, use the SEC EDGAR full-text search API directly.
- When to use:
Use this to find specific filings when you know what topic you are looking for but not the exact form type or date. For example, searching for “merger” filings to identify M&A activity, or “restatement” to flag accounting issues. The query supports a
SYMBOL:keywordsyntax for targeted searches.
- Parameters:
query (
str|None, default:None) – Search query string. Matched case-insensitively against filing titles. Supports a"SYMBOL:keyword"syntax (e.g.,"AAPL:merger"). If only a symbol is provided (no":"), returns all filings for that symbol.from_date (
str|date|None, default:None) – Start date filter (inclusive). Accepts"YYYY-MM-DD"string ordatetime.dateobject.to_date (
str|date|None, default:None) – End date filter (inclusive).limit (
int, default:50) – Maximum number of results to return.fmp_client (
Any|None, default:None) – Optional pre-configuredFMPClientinstance. IfNone, a default client is created.
- Returns:
date,type,title,url,cik,symbol.- Return type:
Example
>>> from wraquant.news.filings import filing_search >>> results = filing_search("TSLA:merger", limit=10) >>> print(results[["date", "type", "title"]].head()) >>> results = filing_search( ... "AAPL:executive", ... from_date="2023-01-01", ... to_date="2023-12-31", ... )
See also
recent_filings: Browse filings by symbol and type. material_events: 8-K filings for material corporate events.
Sentiment¶
Sentiment analysis and news-based signal generation.
Provides functions for scoring news sentiment, building sentiment time series,
and generating discrete trading signals from textual data. Uses FMP as the
primary news data source and includes a built-in keyword-based sentiment
scorer that requires no NLP dependencies. When textblob or vaderSentiment
are installed, those engines can be used for higher-quality scoring.
The sentiment pipeline is:
Fetch – Pull headlines/articles via
FMPClient.Score – Assign each headline a score in [-1, +1].
Aggregate – Combine scores with recency weighting.
Signal – Convert the aggregate into a discrete trading signal.
References
Tetlock (2007), “Giving Content to Investor Sentiment”
Loughran & McDonald (2011), “When Is a Liability Not a Liability?”
Hutto & Gilbert (2014), “VADER: A Parsimonious Rule-based Model for Sentiment Analysis of Social Media Text”
- news_sentiment(symbol, limit=50, *, engine='auto', half_life_days=7.0, include_press_releases=True)[source]¶
Analyze sentiment of recent news for a stock.
Fetches recent news headlines (and optionally press releases) from FMP, scores each headline using the specified sentiment engine, and computes aggregate statistics including recency-weighted sentiment and trend direction.
The recency weighting uses exponential decay so that recent articles contribute more to the aggregate than older ones. The trend is determined by comparing first-half vs. second-half sentiment to detect whether coverage is improving or deteriorating.
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"AAPL").limit (
int, default:50) – Maximum number of news articles to fetch. Higher values give a more robust sentiment estimate but include older news.engine (
str, default:'auto') – Sentiment scoring engine."auto"tries VADER, then TextBlob, then falls back to the built-in keyword scorer. Options:"auto","keyword","vader","textblob".half_life_days (
float, default:7.0) – Half-life for recency weighting in days. Default of 7 means a one-week-old article gets half the weight of today’s article.include_press_releases (
bool, default:True) – If True, also fetch press releases and include them in the analysis.
- Returns:
symbol (str) – Ticker symbol.
engine (str) – Sentiment engine used.
article_count (int) – Total number of articles scored.
articles (list[dict]) – List of dicts, each with keys
title,date,source,sentiment,url.aggregate (dict) – Aggregate statistics: - mean (float) – Simple mean sentiment. - weighted_mean (float) – Recency-weighted mean. - median (float) – Median sentiment. - std (float) – Standard deviation of scores. - bullish_pct (float) – Fraction of positive articles. - bearish_pct (float) – Fraction of negative articles. - neutral_pct (float) – Fraction of neutral articles.
trend (str) –
"improving","deteriorating", or"stable"based on first-half vs. second-half comparison.trend_delta (float) – Second-half mean minus first-half mean.
news_volume (str) –
"high","medium", or"low"based on article count relative to limit.
- Return type:
Example
>>> from wraquant.news.sentiment import news_sentiment >>> result = news_sentiment("AAPL", limit=30) >>> print(f"Weighted sentiment: {result['aggregate']['weighted_mean']:.3f}") >>> print(f"Trend: {result['trend']}")
Notes
Reference: Tetlock (2007). “Giving Content to Investor Sentiment.” The Journal of Finance, 62(3), 1139-1168.
See also
sentiment_timeseries: Build a daily time series of sentiment. sentiment_signal: Convert sentiment to a trading signal.
- sentiment_timeseries(symbol, days=90, *, engine='auto', resample='D')[source]¶
Build a daily (or custom frequency) sentiment time series.
Fetches up to
daysworth of news for a symbol, scores each article, and resamples into a regular time series by averaging sentiment within each period. Missing days are forward-filled so the series can be used directly alongside price data.- Parameters:
symbol (
str) – Ticker symbol (e.g.,"MSFT").days (
int, default:90) – Number of calendar days of history to request. FMP may return fewer articles than this span covers.engine (
str, default:'auto') – Sentiment scoring engine (seenews_sentiment).resample (
str, default:'D') – Pandas resample frequency string."D"for daily,"W"for weekly,"B"for business days.
- Return type:
- Returns:
pd.Series with a DatetimeIndex and sentiment scores averaged per period. Index name is
"date", series name is"sentiment".
Example
>>> from wraquant.news.sentiment import sentiment_timeseries >>> ts = sentiment_timeseries("TSLA", days=30) >>> print(ts.tail())
See also
news_sentiment: Detailed sentiment analysis for a single snapshot. sentiment_signal: Convert the time series to a signal.
- sentiment_signal(symbol, threshold=0.3, *, engine='auto', half_life_days=7.0)[source]¶
Generate a discrete sentiment-based trading signal for a stock.
Fetches recent news, computes the recency-weighted aggregate sentiment, and classifies it as bullish, bearish, or neutral based on the threshold.
The signal logic is: -
weighted_mean > threshold=>"bullish"-weighted_mean < -threshold=>"bearish"- Otherwise =>"neutral"- Parameters:
symbol (
str) – Ticker symbol (e.g.,"GOOG").threshold (
float, default:0.3) – Absolute threshold for signal classification. Lower values produce more signals (more sensitive); higher values filter out weak sentiment. Default of 0.3 is moderately conservative.engine (
str, default:'auto') – Sentiment scoring engine (seenews_sentiment).half_life_days (
float, default:7.0) – Half-life for recency weighting (seenews_sentiment).
- Return type:
- Returns:
One of
"bullish","bearish", or"neutral".
Example
>>> from wraquant.news.sentiment import sentiment_signal >>> signal = sentiment_signal("NVDA", threshold=0.2) >>> print(f"Sentiment signal: {signal}")
See also
news_sentiment: Full sentiment analysis with article-level detail. sentiment_timeseries: Historical sentiment time series.
- sentiment_score(texts, *, engine='auto')[source]¶
Score text passages on a numeric sentiment scale.
Scores arbitrary text using the specified sentiment engine. This is the low-level scoring function; for news-specific analysis with data fetching and aggregation, use
news_sentimentinstead.- Parameters:
- Returns:
scores (list[float]) – Sentiment score for each text, in the range [-1.0, 1.0].
mean_score (float) – Mean sentiment across all texts.
engine (str) – Name of the engine used.
- Return type:
Example
>>> result = sentiment_score("Stock rallied on strong earnings") >>> print(f"Score: {result['scores'][0]:.3f}") >>> print(f"Engine: {result['engine']}")
See also
news_sentiment: Full news sentiment pipeline with data fetching. sentiment_signal: Discrete signal from sentiment.
- news_impact(returns, event_dates, window=5)[source]¶
Measure the impact of news events on returns using event study.
Delegates to
wraquant.causal.treatment.event_studyto compute cumulative abnormal returns (CARs) around each event date.- When to use:
Use news impact analysis to quantify whether specific news events (earnings releases, FDA approvals, geopolitical shocks) have a statistically significant effect on returns.
- Parameters:
returns (
Series) – Return series with a DatetimeIndex.event_dates (
list|DatetimeIndex) – List of event dates to study.window (
int, default:5) – Number of periods before and after each event to include in the analysis window.
- Returns:
car (float) – Mean cumulative abnormal return across all events.
event_results – Detailed event study output from
wraquant.causal.treatment.event_study.
- Return type:
Example
>>> import pandas as pd, numpy as np >>> rng = np.random.default_rng(42) >>> dates = pd.bdate_range("2023-01-01", periods=252) >>> rets = pd.Series(rng.normal(0.0005, 0.01, 252), index=dates) >>> events = [dates[50], dates[150]] >>> result = news_impact(rets, events, window=5)
See also
wraquant.causal.treatment.event_study: Underlying event study. earnings_surprise: Earnings-specific impact metric.
- earnings_surprise(actual, estimate)[source]¶
Compute the standardized earnings surprise.
Earnings surprise is one of the most widely used signals in fundamental-driven quant strategies. A positive surprise (actual exceeds estimate) typically triggers positive abnormal returns in the short term (post-earnings announcement drift, or PEAD).
- Mathematical formulation:
surprise = (actual - estimate) / |estimate|
- When to use:
Use earnings surprise as an input to event-driven strategies. Combine with
news_impactto quantify the return effect.
- Parameters:
- Return type:
- Returns:
Standardized earnings surprise as a float. Positive values indicate a beat; negative values indicate a miss.
Example
>>> earnings_surprise(actual=2.50, estimate=2.30) 0.08695652173913043 >>> earnings_surprise(actual=1.80, estimate=2.00) -0.1
See also
news_impact: Measure the return impact of events. sentiment_score: Score textual sentiment.
- sentiment_aggregate(scores, method='mean')[source]¶
Aggregate multiple sentiment scores into a single composite.
- When to use:
Use after collecting sentiment scores from multiple sources (multiple news articles, analyst reports, social media posts) to produce a single consensus sentiment for a given asset or time period.
- Parameters:
- Return type:
- Returns:
Aggregated sentiment score as a float.
- Raises:
ValueError – If method is not
"mean"or"median".
Example
>>> sentiment_aggregate([0.5, 0.3, -0.1, 0.7]) 0.35 >>> sentiment_aggregate([0.5, 0.3, -0.1, 0.7], method="median") 0.4
See also
sentiment_score: Generate individual scores. news_sentiment: Full sentiment pipeline.
- news_signal(sentiment_series, threshold=0.5)[source]¶
Convert a continuous sentiment series into discrete trading signals.
Applies threshold-based classification to convert continuous sentiment scores into actionable trading signals: +1 (bullish), -1 (bearish), or 0 (neutral).
- When to use:
Use as the final step in a sentiment pipeline, after scoring and aggregation, to generate position signals for a trading strategy.
- Parameters:
- Return type:
- Returns:
pd.Series of integer signals (-1, 0, or +1).
Example
>>> import pandas as pd >>> sent = pd.Series([0.8, 0.3, -0.6, 0.1, -0.9]) >>> news_signal(sent, threshold=0.5) 0 1 1 0 2 -1 3 0 4 -1 dtype: int64
See also
sentiment_score: Generate sentiment scores. sentiment_aggregate: Combine multiple scores.
Events¶
Event-driven analysis for quantitative finance.
Provides functions for analyzing corporate events that drive short-term alpha: earnings announcements, dividend payments, insider transactions, and institutional ownership changes. All data is sourced from the FMP (Financial Modeling Prep) API.
Event-driven strategies exploit predictable market reactions to corporate announcements. The most well-documented anomaly is post-earnings announcement drift (PEAD): stocks that beat estimates tend to continue drifting upward for 60+ trading days, and vice versa for misses.
This module covers:
Earnings calendar & surprises – Upcoming and historical earnings with beat/miss classification and surprise magnitudes.
PEAD analysis – Quantifies the post-earnings drift signal.
Dividend history – Yield, growth, and payout ratio trends.
Insider activity – Net buy/sell ratios and notable transactions.
Institutional ownership – Top holders and quarterly changes.
References
Ball & Brown (1968), “An Empirical Evaluation of Accounting Income Numbers”
Bernard & Thomas (1989), “Post-Earnings-Announcement Drift”
Lakonishok & Lee (2001), “Are Insider Trades Informative?”
- earnings_calendar(from_date=None, to_date=None)[source]¶
Fetch the earnings calendar for a date range.
Returns a DataFrame of upcoming and recent earnings announcements across all symbols. Useful for screening the market for event-driven opportunities and avoiding earnings risk in existing positions.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
date (str) – Earnings date.
eps_estimated (float) – Consensus EPS estimate.
eps_actual (float) – Actual EPS (NaN if not yet reported).
revenue_estimated (float) – Consensus revenue estimate.
revenue_actual (float) – Actual revenue (NaN if not yet reported).
time (str) –
"bmo"(before market open),"amc"(after market close), or"--".
- Return type:
Example
>>> from wraquant.news.events import earnings_calendar >>> cal = earnings_calendar("2024-01-15", "2024-01-19") >>> print(cal[["symbol", "date", "eps_estimated"]].head())
See also
earnings_surprises: Historical beat/miss data for a single stock. upcoming_earnings: Next earnings date for a specific symbol.
- earnings_surprises(symbol, limit=20)[source]¶
Fetch historical earnings surprises for a stock.
Returns actual vs. estimated EPS for each earnings report, with the standardized surprise computed as
(actual - estimate) / |estimate|. This is the raw data behind the PEAD (post-earnings announcement drift) anomaly.- Mathematical formulation:
SUE_t = (EPS_actual - EPS_estimate) / |EPS_estimate|
- Parameters:
- Returns:
date (str) – Earnings announcement date.
actual (float) – Actual reported EPS.
estimate (float) – Consensus analyst estimate.
surprise (float) – Standardized surprise.
surprise_pct (float) – Surprise as a percentage.
beat (bool) – True if actual exceeded estimate.
- Return type:
Example
>>> from wraquant.news.events import earnings_surprises >>> df = earnings_surprises("MSFT", limit=8) >>> print(df[["date", "actual", "estimate", "surprise_pct", "beat"]])
Notes
Reference: Bernard & Thomas (1989). “Post-Earnings-Announcement Drift: Delayed Price Response or Risk Premium?” Journal of Accounting Research, 27, 1-36.
See also
earnings_history: Extended analysis including PEAD metrics. upcoming_earnings: Next expected earnings date.
- upcoming_earnings(symbol)[source]¶
Get the next expected earnings date and consensus estimate.
Combines earnings calendar lookup with analyst estimates to provide a quick snapshot of the upcoming earnings event for a symbol.
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"AMZN").- Returns:
symbol (str) – Ticker symbol.
next_date (str | None) – Next expected earnings date, or None if not scheduled.
eps_estimate (float | None) – Consensus EPS estimate.
revenue_estimate (float | None) – Consensus revenue estimate.
days_until (int | None) – Calendar days until earnings.
time (str | None) –
"bmo"or"amc"if known.
- Return type:
Example
>>> from wraquant.news.events import upcoming_earnings >>> info = upcoming_earnings("GOOG") >>> if info["next_date"]: ... print(f"Earnings on {info['next_date']} " ... f"({info['days_until']} days away)")
See also
earnings_calendar: Full market-wide calendar. earnings_surprises: Historical beat/miss data.
- earnings_history(symbol, limit=20)[source]¶
Comprehensive earnings history with beat/miss analysis and PEAD.
Builds on
earnings_surprisesto provide aggregate statistics about a company’s earnings track record, including beat rate, average surprise magnitude, consistency, and post-earnings announcement drift (PEAD) metrics.The PEAD analysis measures whether the stock price continues to drift in the direction of the surprise after the announcement, which is one of the most robust and well-documented anomalies in finance.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
quarters_analyzed (int) – Number of quarters in the analysis.
surprises (pd.DataFrame) – Raw earnings surprise data (same format as
earnings_surprises).beat_rate (float) – Fraction of quarters where actual exceeded estimate.
miss_rate (float) – Fraction of quarters where actual was below estimate.
avg_surprise (float) – Mean standardized surprise.
avg_beat_magnitude (float) – Mean surprise when beating.
avg_miss_magnitude (float) – Mean surprise when missing.
surprise_std (float) – Standard deviation of surprises (measures consistency).
streak (dict) – Current streak info: - type (str) –
"beat"or"miss". - length (int) – Number of consecutive beats/misses.pead_signal (str) –
"strong_beat","moderate_beat","neutral","moderate_miss", or"strong_miss"based on the most recent surprise.
- Return type:
Example
>>> from wraquant.news.events import earnings_history >>> hist = earnings_history("AAPL", limit=12) >>> print(f"Beat rate: {hist['beat_rate']:.0%}") >>> print(f"Avg surprise: {hist['avg_surprise']:.2%}") >>> print(f"Current streak: {hist['streak']}")
Notes
Reference: Ball & Brown (1968). “An Empirical Evaluation of Accounting Income Numbers.” Journal of Accounting Research, 6(2), 159-178.
See also
earnings_surprises: Raw surprise data. upcoming_earnings: Next earnings date.
- dividend_history(symbol, limit=40)[source]¶
Analyze dividend history including yield, growth, and payout ratio.
Fetches historical dividend data and computes metrics relevant to dividend-focused strategies: yield trends, dividend growth rates, and consistency of payments. Dividend growth is a strong predictor of total return for income-oriented portfolios.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
dividends (pd.DataFrame) – Historical dividend data with columns:
date,dividend,yield_pct(if price available).total_dividends (int) – Number of dividend payments.
current_annual_dividend (float) – Estimated annual dividend based on most recent payment.
dividend_growth_rate (float) – Compound annual growth rate of dividends (if sufficient history).
consecutive_payments (int) – Count of consecutive periods with a dividend payment.
is_grower (bool) – True if the dividend has grown year-over-year in each of the last 3 periods.
- Return type:
Example
>>> from wraquant.news.events import dividend_history >>> div = dividend_history("KO", limit=20) >>> print(f"Annual dividend: ${div['current_annual_dividend']:.2f}") >>> print(f"Growth rate: {div['dividend_growth_rate']:.1%}")
See also
earnings_history: Earnings-based fundamental analysis.
- insider_activity(symbol, limit=100)[source]¶
Analyze insider buying and selling activity.
Insider transactions are among the most informative signals in equity markets. Insiders (officers, directors, 10%+ owners) must file SEC Form 4 within two business days of a transaction. Aggregate insider buying is a stronger signal than selling, because insiders may sell for many reasons (diversification, liquidity) but typically buy only when they expect appreciation.
- Parameters:
- Returns:
symbol (str) – Ticker symbol.
transactions (pd.DataFrame) – Raw transaction data with columns:
date,insider,transaction_type,shares,price,value.total_transactions (int) – Number of transactions.
buy_count (int) – Number of purchase transactions.
sell_count (int) – Number of sale transactions.
buy_sell_ratio (float) – Ratio of buys to sells (>1 is bullish). Returns
infif no sells.net_shares (int) – Net shares bought minus sold.
net_value (float) – Net dollar value of insider trades.
notable_trades (list[dict]) – Transactions above $1M.
signal (str) –
"bullish"if net buying is significant,"bearish"if net selling is significant,"neutral"otherwise.
- Return type:
Example
>>> from wraquant.news.events import insider_activity >>> insiders = insider_activity("AAPL") >>> print(f"Buy/sell ratio: {insiders['buy_sell_ratio']:.2f}") >>> print(f"Net value: ${insiders['net_value']:,.0f}") >>> print(f"Signal: {insiders['signal']}")
Notes
Reference: Lakonishok & Lee (2001). “Are Insider Trades Informative?” The Review of Financial Studies, 14(1), 79-111.
See also
institutional_ownership: Institutional holder analysis. earnings_history: Fundamental event analysis.
- institutional_ownership(symbol)[source]¶
Analyze institutional ownership and recent changes.
Institutional investors (mutual funds, hedge funds, pension funds) hold the majority of US equity market capitalization. Changes in institutional ownership can signal informed conviction: increasing ownership by smart-money managers is a moderately bullish signal.
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"TSLA").- Returns:
symbol (str) – Ticker symbol.
holders (pd.DataFrame) – Top institutional holders with columns:
holder,shares,date_reported,change,change_pct.total_institutional_holders (int) – Count of institutional holders.
total_shares_held (int) – Total shares held by institutions.
top_holder (str | None) – Name of the largest holder.
net_change (str) –
"increasing","decreasing", or"stable"based on aggregate position changes.concentration (float) – Herfindahl index of ownership concentration among top holders (higher = more concentrated).
- Return type:
Example
>>> from wraquant.news.events import institutional_ownership >>> inst = institutional_ownership("AAPL") >>> print(f"Top holder: {inst['top_holder']}") >>> print(f"Net change: {inst['net_change']}") >>> print(inst["holders"].head())
See also
insider_activity: Corporate insider transaction analysis.
Filings¶
SEC filings retrieval and analysis.
Provides functions for searching and retrieving SEC filings (10-K, 10-Q, 8-K, and others) from the FMP data provider. SEC filings are the authoritative source of corporate financial data and material event disclosures.
Filing types commonly used in quant strategies:
10-K (annual report) – Complete financial statements, risk factors, management discussion. The definitive source for fundamental analysis.
10-Q (quarterly report) – Interim financials, updated risk factors. Useful for tracking intra-year trends.
8-K (current report) – Material events: executive changes, M&A, contract awards, covenant violations. The most time-sensitive filing type for event-driven strategies.
4 (insider transactions) – Officer/director stock trades. Filed within 2 business days of the transaction.
13F (institutional holdings) – Quarterly disclosure of equity positions by institutional managers with >$100M AUM.
Example
>>> from wraquant.news.filings import recent_filings, annual_reports
>>> filings = recent_filings("AAPL", limit=10)
>>> print(filings[["date", "type", "title"]])
>>> reports = annual_reports("MSFT", limit=3)
>>> print(reports[["date", "title"]])
References
SEC EDGAR: https://www.sec.gov/edgar
Loughran & McDonald (2011), “When Is a Liability Not a Liability? Textual Analysis, Dictionaries, and 10-Ks”
- recent_filings(symbol, form_type=None, limit=20, *, fmp_client=None)[source]¶
Fetch recent SEC filings for a company.
Returns a DataFrame of SEC filings sorted by date (most recent first). Optionally filter by form type to focus on specific filing categories.
- When to use:
Use this as the primary entry point for SEC filing retrieval. For specific filing types, prefer the convenience wrappers
annual_reports(),quarterly_reports(), ormaterial_events(). Use this function directly when you need filings of a specific type not covered by the convenience functions (e.g., Form 4 insider transactions, 13F institutional holdings, S-1 registration statements).
- Parameters:
symbol (
str) – Ticker symbol (e.g.,"AAPL").form_type (
str|None, default:None) – SEC form type to filter by (e.g.,"10-K","10-Q","8-K","4","13F"). IfNone, returns all filing types.limit (
int, default:20) – Maximum number of filings to return.fmp_client (
Any|None, default:None) – Optional pre-configuredFMPClientinstance. IfNone, a default client is created.
- Returns:
date (str) – Filing date.
type (str) – SEC form type.
title (str) – Filing title/description.
url (str) – Link to the filing on SEC EDGAR.
cik (str) – SEC Central Index Key.
- Return type:
Example
>>> from wraquant.news.filings import recent_filings >>> filings = recent_filings("MSFT", form_type="10-K", limit=5) >>> print(filings[["date", "type", "title"]])
See also
annual_reports: Shortcut for 10-K filings. quarterly_reports: Shortcut for 10-Q filings. material_events: Shortcut for 8-K filings. filing_search: Text search across filings.
- annual_reports(symbol, limit=5, *, fmp_client=None)[source]¶
Fetch 10-K annual report filings for a company.
Convenience wrapper around
recent_filings()that filters for 10-K filings only. Annual reports are the most comprehensive disclosure and include audited financial statements, MD&A (management discussion and analysis), risk factors, and more.- When to use:
Use this to find annual report filing dates and links for fundamental analysis. Annual reports are required reading before making investment decisions – they contain the audited financials, risk disclosures, and management’s own assessment of the business.
- Parameters:
- Returns:
date,type,title,url,cik. Sorted by date descending.- Return type:
Example
>>> from wraquant.news.filings import annual_reports >>> reports = annual_reports("AMZN", limit=3) >>> print(reports[["date", "title"]])
See also
quarterly_reports: 10-Q filings. material_events: 8-K filings. recent_filings: All filing types.
- quarterly_reports(symbol, limit=10, *, fmp_client=None)[source]¶
Fetch 10-Q quarterly report filings for a company.
Convenience wrapper around
recent_filings()that filters for 10-Q filings only. Quarterly reports provide interim financial statements and updated risk disclosures between annual reports.- When to use:
Use this to track intra-year financial trends. Quarterly reports are especially important for companies undergoing rapid change (turnarounds, market share shifts, cost restructuring) where waiting for the annual report would miss critical inflection points.
- Parameters:
- Returns:
date,type,title,url,cik. Sorted by date descending.- Return type:
Example
>>> from wraquant.news.filings import quarterly_reports >>> reports = quarterly_reports("META", limit=4) >>> print(reports[["date", "title"]])
See also
annual_reports: 10-K filings. material_events: 8-K filings. recent_filings: All filing types.
- material_events(symbol, limit=20, *, fmp_client=None)[source]¶
Fetch 8-K current report filings for a company.
8-K filings disclose material events that shareholders should know about between regular SEC reporting periods. These include:
Entry into or termination of a material agreement
Bankruptcy or receivership
Departure or appointment of officers/directors
Changes in fiscal year
Amendments to articles of incorporation
Material impairments
Unregistered sales of equity securities
Changes in certifying accountant
- When to use:
For event-driven strategies, 8-K filings are the most actionable filing type because they signal discrete, potentially price-moving corporate actions. Monitor 8-K filings for activist targets, M&A candidates, and companies undergoing management transitions.
- Parameters:
- Returns:
date,type,title,url,cik. Sorted by date descending.- Return type:
Example
>>> from wraquant.news.filings import material_events >>> events = material_events("GM", limit=10) >>> print(events[["date", "title"]])
See also
annual_reports: 10-K filings. quarterly_reports: 10-Q filings. recent_filings: All filing types.
- filing_search(query=None, from_date=None, to_date=None, *, limit=50, fmp_client=None)[source]¶
Search SEC filings by keyword and/or date range.
Performs a text search over filing titles and descriptions to find filings related to a specific topic (e.g.,
"merger","restatement","executive departure").This performs client-side filtering on bulk filing data, so it works best with a focused symbol-level query. For market-wide filing searches, use the SEC EDGAR full-text search API directly.
- When to use:
Use this to find specific filings when you know what topic you are looking for but not the exact form type or date. For example, searching for “merger” filings to identify M&A activity, or “restatement” to flag accounting issues. The query supports a
SYMBOL:keywordsyntax for targeted searches.
- Parameters:
query (
str|None, default:None) – Search query string. Matched case-insensitively against filing titles. Supports a"SYMBOL:keyword"syntax (e.g.,"AAPL:merger"). If only a symbol is provided (no":"), returns all filings for that symbol.from_date (
str|date|None, default:None) – Start date filter (inclusive). Accepts"YYYY-MM-DD"string ordatetime.dateobject.to_date (
str|date|None, default:None) – End date filter (inclusive).limit (
int, default:50) – Maximum number of results to return.fmp_client (
Any|None, default:None) – Optional pre-configuredFMPClientinstance. IfNone, a default client is created.
- Returns:
date,type,title,url,cik,symbol.- Return type:
Example
>>> from wraquant.news.filings import filing_search >>> results = filing_search("TSLA:merger", limit=10) >>> print(results[["date", "type", "title"]].head()) >>> results = filing_search( ... "AAPL:executive", ... from_date="2023-01-01", ... to_date="2023-12-31", ... )
See also
recent_filings: Browse filings by symbol and type. material_events: 8-K filings for material corporate events.