A Quick Guide To Sentiment-Powered Stock Predictions With Benzinga’s News And Bars Endpoints

Introduction

Context is as critical as data. Relying solely on price movements is like evaluating a novel by its cover—you risk overlooking the deeper narrative behind market shifts. Benzinga’s Newsfeed & Bars APIs bridge this gap by combining market-moving headlines with detailed historical price data, which gives a better view of market behavior.

In this guide, we will walk you through integrating these robust data sources into your trading strategy. You’ll learn how to extract full-length articles using Benzinga’s Why Is It Moving v2 endpoint and obtain precise price bars from the Bars endpoint. By merging these insights into a sentiment-based model, you can uncover actionable intelligence that enhances your market predictions. This straightforward yet powerful approach showcases how real-time news sentiment can elevate your decision-making in a dynamic market environment.

1. The APIs at a Glance

Newsfeed (Why Is It Moving v2)

  • Endpoint: GET /news
  • Purpose: Pulls news items by ticker, date, and other filters.
  • Notable Parameters:
    • token (your API key)
    • tickers (comma-separated list of symbols)
    • displayOutput (e.g., full to see the entire article body)
    • dateFrom, dateTo or page and pageSize to organize how many articles you get.
  • Why Use It?
    Up-to-date headlines and deeper stories are essential for gauging sentiment and discovering why a stock is in the spotlight.

Bars Endpoint

  • Endpoint: GET /bars
  • Purpose: Returns historical candlestick (bar) data to measure how a stock’s price changes over time.
  • Key Parameters:
    • symbols (one or more comma-separated tickers)
    • from, to (date range)
    • interval (1D, 5M, 1W, etc.)
  • Why Use It?
    Comparing sentiment against price movements can help uncover patterns in how news influences stock returns.

2. Let’s Build a Sentiment-Fueled Predictor

Below, we’ll walk through the code in manageable parts to show how we fetch data, analyze it, and make a simple prediction about tomorrow’s price movement.

2.1 Import Libraries & Set Up Endpoints

First, we need our usual suspects for making requests, handling data, performing sentiment analysis, and running a model.

import requests
import pandas as pd
from textblob import TextBlob
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import datetime, sys

API_KEY = "YOUR_API_KEY"
NEWS_ENDPOINT = "https://api.benzinga.com/api/v2/news"
BARS_ENDPOINT = "https://api.benzinga.com/api/v2/bars"
  • requests helps us call the Benzinga APIs.
  • pandas structures our data in easy-to-use data frames.
  • TextBlob quickly calculates text sentiment.
  • sklearn libraries let us build and evaluate a simple Logistic Regression model.

2.2 Fetching News Data

Next, we define a helper function to retrieve articles from the Newsfeed endpoint. We pass parameters like tickers, dateFrom, dateTo, and—most importantly—our API key.

def fetch_news_data(ticker="AAPL", date_from="2023-01-01", date_to="2023-12-01"):
    params = {
        "token": API_KEY,
        "tickers": ticker,
        "displayOutput": "full",
        "dateFrom": date_from,
        "dateTo": date_to,
        "pageSize": 20
    }
    headers = {"accept": "application/json"}
    
    resp = requests.get(NEWS_ENDPOINT, params=params, headers=headers)
    if resp.status_code != 200:
        print("Error:", resp.text)

  • displayOutput=full ensures we get the article’s full text.
  • pageSize=20 controls how many articles come back in a single query.

2.3 Fetching Price Bars

Similarly, our fetch_bar_data function grabs daily candlestick data. We can adjust the interval to 1D, 5M, or other increments.

def fetch_bar_data(ticker="AAPL", from_date="2023-01-01", to_date="2023-12-01"):
    params = {
        "token": API_KEY,
        "symbols": ticker,
        "interval": "1D",
        "from": from_date,
        "to": to_date
    }
    headers = {"accept": "application/json"}
   
    resp = requests.get(BARS_ENDPOINT, params=params, headers=headers)
    if resp.status_code != 200:
        print("Error:", resp.text)
        sys.exit(1)
    return resp.json()
  • symbols can be multiple tickers, comma-separated.
  • interval=1D suits our plan to look at daily moves.

2.4 Combining News & Bars

Now it’s time to call our functions, parse the returned data, and build a pandas DataFrame. Notice how we handle the date in articles, then merge everything by date.

# 1. Fetch news
news_data = fetch_news_data("AAPL", "2023-01-01", "2023-12-01")
news_records = []
for article in news_data:
    raw_date = article.get("created", "")
    try:
        date_parsed = datetime.datetime.strptime(raw_date[:25], "%a, %d %b %Y %H:%M:%S")
    except:
        date_parsed = None
   
    combined_text = (article.get("title", "") + " " + article.get("body", "")).strip()
    if date_parsed:
        news_records.append({"date": date_parsed.date(), "text": combined_text})

df_news = pd.DataFrame(news_records)

Key Points

  • We parse out the “created” field, trimming the string to avoid time-zone quirks.
  • We combine the title and body to get the entire text for sentiment analysis.

2.5 Calculating Sentiment

Here’s where TextBlob comes in. We average the polarity (sentiment) of all articles that appear on the same day. Values range from -1 (very negative) to 1 (very positive).

df_news["sentiment"] = df_news["text"].apply(lambda x: TextBlob(x).sentiment.polarity)
df_daily_sent = df_news.groupby("date")["sentiment"].mean().reset_index()
df_daily_sent.columns = ["date", "avg_sentiment"]

2.6 Merging with Bar Data

Let’s grab the bar data, convert it to a DataFrame, and then merge the sentiment we just computed. We fill missing sentiment data with 0.

bars_data = fetch_bar_data("AAPL", "2023-01-01", "2023-12-01")
if isinstance(bars_data, list) and len(bars_data) > 0 and "candles" in bars_data[0]:
    candle_list = bars_data[0]["candles"]
    df_bars = pd.DataFrame(candle_list)
    df_bars["time"] = pd.to_numeric(df_bars["time"], errors="coerce")
    df_bars["date"] = pd.to_datetime(df_bars["time"], unit='ms').dt.date
    df_bars = df_bars[["date", "open", "high", "low", "close"]]
else:
    df_bars = pd.DataFrame(columns=["date", "open", "high", "low", "close"])

df_merged = pd.merge(df_bars, df_daily_sent, on="date", how="left").fillna(0)

2.7 Creating a Label and Training the Model

Finally, we shift the closing price by one day to see if tomorrow’s close is higher than today’s.

df_merged["next_close"] = df_merged["close"].shift(-1)
df_merged.dropna(inplace=True)
df_merged["label"] = (df_merged["next_close"] > df_merged["close"]).astype(int)

X = df_merged[["close", "avg_sentiment"]]
y = df_merged["label"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

model = LogisticRegression()
model.fit(X_train, y_train)
  • label is 1 if the stock price goes up, 0 otherwise.
  • We’re using an 80/20 split for training and testing.

2.8 Evaluating & Making a Prediction

We check accuracy on the test set, then predict tomorrow’s movement.

y_pred = model.predict(X_test)
acc = accuracy_score(y_test, y_pred)
print(f"Validation Accuracy: {acc:.2f}")

latest_row = df_merged.iloc[-1][["close", "avg_sentiment"]]
prediction = model.predict([latest_row])
signal = "UP" if prediction[0] == 1 else "DOWN"
print(f"Tomorrow's predicted movement: {signal}")

3. The Output

Below is a sample output you might see when running the script:

nikhil05@Nikhil:~/Algo-AI/client/python $ python3 bezinga.py
News endpoint status: 200
News articles retrieved: 20
Bars endpoint status: 200
Bars retrieved: 231
Validation Accuracy: 0.59
Tomorrow's predicted movement: DOWN
  • Validation Accuracy: This numeric score (e.g., 0.59) tells you how often the model guesses the next day’s movement correctly during back-testing.
  • Tomorrow’s Predicted Movement: Printed as either “UP” or “DOWN.” This uses the last known data point’s sentiment and closing price to guess where the market might head tomorrow.

4. Why This Matters

Market headlines can trigger sudden spikes or drops, so ignoring news is like driving with one eye closed. By pairing Benzinga’s robust news feed (including article titles, teasers, and full bodies) with bar data, you can catch subtle shifts in investor sentiment. Even a simple logistic regression reveals how bullish or bearish signals in the news might align with a stock’s next-day performance.

Final Thoughts

That’s all it takes to build a basic sentiment-based stock predictor—and you can level it up in countless ways. Try analyzing multiple tickers at once, applying advanced natural language processing, or adding technical indicators on top of price bars. 

With Benzinga’s APIs, you have the raw ingredients for your own unique “recipe” in market analysis. The beauty is in experimenting, refining, and seeing how each new insight helps you navigate the market more confidently.

OTHER ARTICLES

See what's happening at Benzinga

As new accounts stabilize, the intermediate trader will come into the limelight.  Here are Benzinga’s 2022 Data Market Predictions: 1.) Advanced Analytics will take Priority

Read More

As we close out Q1 of the new year, our attention is caught by the fact that the industry has exploded with a record number

Read More

In a fast paced world, empower users to make quick and subconscious decisions with a distinctive and easily recognizable company logo. Whether you use an

Read More