Daily News Sentiment by Ticker
Daily sentiment for one ticker across every source combined. Mentions of the company in news articles and in finance discussion forums are scored with a finance-tuned language model, then counted and averaged into one row per ticker per day. Scored from a rolling news window rather than the full historical corpus.
news_sentiment - the dataset name to pass to the Obscura API.
What one row means
One day's aggregated FinBERT sentiment for one ticker across ALL sources (news + Reddit combined) - a read-only `news_sentiment` MATERIALIZED VIEW (`GROUP BY ticker, available_date` over `news_sentiment_by_source`). The per-source breakdown lives in `news_sentiment_by_source`; the raw per-story facts in `news_sentiment_events`.
One row per One row per (ticker, available_date) - unique index (ticker, available_date). All sources summed/averaged into one row..
Point-in-time availability
Every Obscura dataset carries available_date: the calendar day the publisher made the row
available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the
same thing on every dataset in the catalog.
For news_sentiment: published: available_date = the day the underlying stories became publicly observable (WARC-Date for CC-NEWS, post-creation date for Reddit), grouped through from news_sentiment_events. UTC calendar day.
Refresh cadence
Obscura refreshes news_sentiment daily - the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.
Schema - 10 columns
The full public column list for news_sentiment, with the meaning of every field. The same
schema is served unauthenticated at https://api.obscura.trade/v1/catalog/news_sentiment.
| Column | Type | Description |
|---|---|---|
| ticker | text · not null | Equity ticker the story/post mentioned (bare symbol, no exchange qualifier). |
| available_date | date · not null | PUBLIC-availability day the underlying stories became public (WARC-Date for CC-NEWS, Reddit post date). This view IS the per-day rollup, so this is both the grain key and the point-in-time availability column. UTC day. |
| article_count | integer | Novel-story count summed across sources: distinct stories whose most recent prior mention (if any) was >91 days earlier. Re-syndication within 91 days is not re-counted (undercounts raw press volume by design; see raw_mentions). |
| raw_mentions | integer | Un-deduplicated count of every scored ticker mention that day, including re-syndication/reposts (summed across sources). |
| avg_sentiment | double precision | AVG across sources of each source's mean FinBERT story score (positive minus negative softmax), over novel stories only. NULL when no novel story existed. |
| pos_count | integer | Count of novel stories that day labeled positive by FinBERT (summed across sources). |
| neg_count | integer | Count of novel stories that day labeled negative by FinBERT (summed across sources). |
| neu_count | integer | Count of novel stories that day labeled neutral by FinBERT (summed across sources). |
| buzz | numeric | AVG across sources of each source's buzz ratio: that day's novel-story count over its trailing 30-day average - an attention-spike multiple. NULL/0 when there is no trailing baseline yet. |
| sentiment_index | double precision | AVG across sources of each source's exponentially-decayed sentiment carry-forward (30-day half-life): the last novel-day sentiment decayed on quiet days, so a smooth day-over-day series without NULL gaps. |
Access news_sentiment
Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.
import obscura
client = obscura.Client("obs_live_…")
df = client.query(
dataset="news_sentiment",
symbols=["NVDA", "AAPL"],
start="2024-01-01",
)
Create a free account Browse all 122 datasets
Frequently asked questions
What is in the news_sentiment dataset?
Daily sentiment for one ticker across every source combined. Mentions of the company in news articles and in finance discussion forums are scored with a finance-tuned language model, then counted and averaged into one row per ticker per day. Scored from a rolling news window rather than the full historical corpus. One day's aggregated FinBERT sentiment for one ticker across ALL sources (news + Reddit combined) - a read-only `news_sentiment` MATERIALIZED VIEW (`GROUP BY ticker, available_date` over `news_sentiment_by_source`). The per-source breakdown lives in `news_sentiment_by_source`; the raw per-story facts in `news_sentiment_events`.
How do I avoid look-ahead bias with news_sentiment?
Filter on news_sentiment.available_date, the day the publisher made the row public. For this dataset that date is derived as follows - published: available_date = the day the underlying stories became publicly observable (WARC-Date for CC-NEWS, post-creation date for Reddit), grouped through from news_sentiment_events. UTC calendar day. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.
In what formats can I get news_sentiment?
As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="news_sentiment". The column schema is public at https://api.obscura.trade/v1/catalog/news_sentiment.
Can I filter news_sentiment by company or symbol?
Yes. news_sentiment carries ticker, the column the API's symbols filter resolves against.
How often is news_sentiment updated?
Obscura refreshes news_sentiment on a daily schedule - that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.