Building a Real-Time Financial News Sentiment Analyzer with Python, Redis, and OpenAI
Introduction
In the fast-paced world of stock trading, having real-time access to financial news and the ability to analyze its sentiment can give traders a significant edge. In this blog post, we will walk you through the development of a system that read the live financial news, analyzes its sentiment, and publishes the results to a Redis channel. This setup can then be used to trigger automated trading decisions based on news sentiment.
Step 1: Setting Up the Environment
Before diving into the code, ensure you have the following components installed and configured:
- Interactive Brokers API (IB API): For fetching live financial news.
- Redis: For publishing and subscribing to processed news data.
- OpenAI API: For sentiment analysis of the news articles.
Step 2: Fetching Financial News Using IB API
The IB API provides access to live market data, including news headlines and full articles. We start by creating a client that connects to the Interactive Brokers Trader Workstation (TWS) or IB Gateway.
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
class IBApi(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.processed_news_ids = set()
def tickNews(self, tickerId, timeStamp, providerCode, articleId, headline, extraData):
print(f"News: {headline} (Provider: {providerCode}, ID: {articleId})")
if articleId in self.processed_news_ids:
print(f"Skipping duplicate news article ID: {articleId}")
return
self.processed_news_ids.add(articleId)
self.reqNewsArticle(tickerId, providerCode, articleId, [])
def newsArticle(self, reqId, articleType, articleText):
print(f"Full Article (Type {articleType}): {articleText}")
sentiment, symbol = self.analyze_sentiment(articleText)
print(f"Sentiment: {sentiment}, Symbol: {symbol}")
self.publish_article_with_sentiment(articleText, sentiment, symbol)
Step 3: Analyzing Sentiment with OpenAI API
The next step is to analyze the sentiment of the news articles using OpenAI’s GPT-3.5-turbo model. This will help us understand whether the news is positive, neutral, or negative, and how it might impact stock prices.
from openai import OpenAI
import json
from util import openai_pass
client = OpenAI(api_key=openai_pass)
class IBApi(EWrapper, EClient):
# Other methods...
def analyze_sentiment(self, text):
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a financial news analyst."},
{"role": "user", "content": (
f"Analyze the sentiment of the following news article and return a sentiment score from 1 to 5 "
f"(1 = Strong Sell, 2 = Sell, 3 = Neutral, 4 = Buy, 5 = Strong Buy) and identify the stock symbol affected:\n\n"
f"{text}\n\n"
"Return the result in the format: {\"sentiment\": <score>, \"symbol\": \"<stock_symbol>\"}"
)}
],
max_tokens=100
)
result = response.choices[0].message.content.strip()
try:
result = result.replace("'", '"')
result_json = json.loads(result)
sentiment = result_json.get('sentiment', 3)
symbol = result_json.get('symbol', 'Unknown')
except json.JSONDecodeError as e:
print(f"JSON decode error: {e}")
print(f"Response text: {result}")
sentiment = 3
symbol = 'Unknown'
return sentiment, symbol
Step 4: Publishing Data to Redis
To make the analyzed data accessible to other systems or services, we publish the news article and its sentiment score to a Redis channel.
import redis
class IBApi(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.redis_client = redis.StrictRedis(host='192.168.50.245', port=6379, db=1)
self.processed_news_ids = set()
# Other methods...
def publish_article_with_sentiment(self, text, sentiment, symbol):
news_data = {
"article": text,
"sentiment": sentiment,
"symbol": symbol
}
self.redis_client.publish('news_channel', json.dumps(news_data))
Step 5: Subscribing to Redis Channel
Finally, create a subscriber that listens to the news_channel
and processes the incoming data. This can be used to trigger automated trading decisions.
import redis
import json
def redis_subscribe():
client = redis.StrictRedis(host='192.168.50.245', port=6379, db=1)
pubsub = client.pubsub()
pubsub.subscribe('news_channel')
print("Subscribed to 'news_channel'. Waiting for messages...")
try:
for message in pubsub.listen():
if message['type'] == 'message':
news_data = json.loads(message['data'].decode('utf-8'))
print(f"Received news update: {news_data}")
except KeyboardInterrupt:
print("Unsubscribing and exiting...")
pubsub.unsubscribe()
print("Unsubscribed.")
if __name__ == "__main__":
redis_subscribe()
Conclusion
By combining the power of Interactive Brokers API, OpenAI, and Redis, we’ve created a real-time system that processes financial news, analyzes its sentiment, and publishes the results to a Redis channel. This setup can be extended to automate trading decisions, providing a robust tool for traders to stay ahead of market movements.
This tutorial demonstrates the seamless integration of various technologies to build a practical and valuable financial tool. We hope this inspires you to explore further enhancements and applications in your trading strategies.
Feel free to ask any questions or share your thoughts in the comments below! Happy trading!