Skip to main content

Example: Creating an OpenAI GPT that Measures the Impact of News Sentiment on Stock Prices

This example illustrates the construction of a custom OpenAI GPT, which a user can interact with to understand news and their impact on stock prices.

This is accomplished by creating multiple APIs in RAW and then creating a GPT in OpenAI to consume them. These RAW APIs combine data from multiple sources: IEX Cloud for stock ticker prices, Twinword for sentiment analysis and newsdata.io for news information.

This example illustrates the potential of GPTs, and specifically, combining sentiment analysis with financial data to offer a more holistic view of market trends, enabling users to make more informed and strategic investment decisions.

info

If you are not familiar with GPTs, please read our introductory section

Overview

To create a GPT, we need to do the following steps.

First off, we need to create RAW APIs. These include APIs search and retrieve stock prices, search for the latest news, analyze their sentiment, and then APIs that do the correlation between prices and news sentiment.

Finally, we need to create a GPT in the OpenAPI interface, and have it consume these APIs.

Let's get started!

Create RAW Endpoints

The first step is to create the necessary endpoints using RAW. We will create the following endpoints:

  • search for stock market ticker, given a company name;
  • retrieve previous and current stock market price for a given ticker;
  • retrieve latest news about a company and compute aveage sentiment;
  • correlate stocker market price change with latest news sentiment.

In the following sections you can see the details for each individual endpoint.

Searching for stock market tickers

URL

/stockprice/ticker

Purpose

Retrieves the ticker symbol for a given company name using the IEX Cloud API. E.g. "Apple Inc" -> "AAPL"

External services

You need to create an IEX API Token and register it as RAW Secret with the name iex_cloud_api_token, as seen in the source code below.

Source code

main(name: string): string =
let
iex_api_token = Environment.Secret("iex_cloud_api_token"),
escaped_name = Http.UrlEncode(name),
search_result = Json.Read("https://cloud.iexapis.com/stable/search/"+escaped_name+"?token="+iex_api_token, type collection(
record(
symbol: string,
exchange: string,
exchangeSuffix: string,
exchangeName: string,
name: string,
`type`: string,
iexId: string,
region: string,
currency: string,
figi: string,
cik: string,
lei: string,
securityName: string,
securityType: string,
sector: string
)
)),
output = Collection.Transform(
Collection.GroupBy(search_result, s -> s.name),
s ->
{
name:s.key,
symbol: Collection.Distinct(
Collection.Transform(
Collection.Filter(s.group, s->s.exchange=="XNAS"), o->o.symbol)
)
}
)
in
if(Collection.Count(output)==1) then
if(Collection.Count(Collection.First(output).symbol) == 1) then Collection.First(Collection.First(output).symbol)
else Error.Build("Too many ticker symbols")
else Error.Build("Too many ticker matches")

main("Apple Inc")

Retrieving for stock market price

URL

/stockprice/price

Purpose

Retrieves the previous and current price of a stock using the IEX Cloud API.

External services

Since, you have already registered RAW Secret with the name iex_cloud_api_token, you do not have to repeat it.

Source code

main(ticker: string) =
let
iex_api_token = Environment.Secret("iex_cloud_api_token"),
response=Json.Read(Http.Get("https://api.iex.cloud/v1/data/core/quote/"+ticker, args=[{"token", iex_api_token}]), type collection(
record(
avgTotalVolume: int,
calculationPrice: string,
change: double,
changePercent: double,
close: double,
closeSource: string,
closeTime: long,
companyName: string,
currency: string,
delayedPrice: double,
delayedPriceTime: long,
extendedChange: double,
extendedChangePercent: double,
extendedPrice: double,
extendedPriceTime: long,
high: double,
highSource: string,
highTime: long,
iexAskPrice: int,
iexAskSize: int,
iexBidPrice: int,
iexBidSize: int,
iexClose: double,
iexCloseTime: long,
iexLastUpdated: long,
iexMarketPercent: double,
iexOpen: double,
iexOpenTime: long,
iexRealtimePrice: double,
iexRealtimeSize: int,
iexVolume: int,
lastTradeTime: long,
latestPrice: double,
latestSource: string,
latestTime: string,
latestUpdate: long,
latestVolume: int,
low: double,
lowSource: string,
lowTime: long,
marketCap: long,
oddLotDelayedPrice: double,
oddLotDelayedPriceTime: long,
open: double,
openTime: long,
openSource: string,
peRatio: double,
previousClose: double,
previousVolume: int,
primaryExchange: string,
symbol: string,
volume: int,
week52High: double,
week52Low: double,
ytdChange: double,
isUSMarketOpen: bool
)
))
in
{previousPrice: Collection.First(response).previousClose, currentPrice: Collection.First(response).latestPrice}

main("MSFT")

Searching for latest news and extracting sentiment

URL

/news_feed_sentiment

Purpose

Calculates the average sentiment score of news articles related to a company using the NewsData API and the Twinword Sentiment Analysis API.

External services

You need to register two API keys, as RAW Secrets, rapid_api_key and newsdata_api_key respectively. The first one refers to Twinword sentiment API which is hosted in RapidAPI. newsdata_api_key corresponds to the API Key of your Newsdata.io account.

Source code

get_document_sentiment(content:string): double =
let
payload = Json.Read(
Http.Post("https://twinword-sentiment-analysis.p.rapidapi.com/analyze/",
headers=[
{"X-RapidAPI-Host", "twinword-sentiment-analysis.p.rapidapi.com"},
{"X-RapidAPI-Key", Environment.Secret("rapid_api_key")},
{"content-type", "application/x-www-form-urlencoded"}
],
bodyString="text="+content
), type record(
`type`: string,
score: double,
ratio: int,
keywords: collection(record(word: string, score: double)),
version: string,
author: string,
email: string,
result_code: string,
result_msg: string
)
)
in
payload.score

main(company: string) =
let

rec get_page_sentiments(search_term: string, apikey: string, page: string, max_results: int): collection(double) =
let

ret_type = type record(
status: string,
totalResults: int,
results: collection(
record(
article_id: string,
title: string,
link: string,
keywords: collection(string),
creator: collection(string),
video_url: undefined,
description: string,
content: string,
pubDate: timestamp,
image_url: string,
source_id: string,
source_priority: int,
country: collection(string),
category: collection(string),
language: string,
ai_tag: string,
sentiment: string,
sentiment_stats: string
)
),
nextPage: string),
news_feed =
if(Nullable.IsNull(page)) then
Json.Read(
Http.Get("https://newsdata.io/api/1/news",
args = [{ "q", search_term}, {"language", "en"}, {"apikey", apikey}]
), ret_type)
else Json.Read(
Http.Get("https://newsdata.io/api/1/news",
args = [{ "q", search_term}, {"language", "en"}, {"apikey", apikey}, {"page", page}]
), ret_type),
sentiment =
Collection.Union(
Collection.Transform(Collection.Take(news_feed.results, max_results), s->get_document_sentiment(s.content)),
if(Nullable.IsNull(news_feed.nextPage) or Collection.Count(news_feed.results)>=max_results)
then Collection.Empty(type double)
else get_page_sentiments(search_term, apikey, news_feed.nextPage, max_results-Int.From(Collection.Count(news_feed.results)))
)
in
sentiment,

newsdata_api_key = Environment.Secret("newsdata_api_key"),
max_results = 13
in
Collection.Avg(get_page_sentiments(company, newsdata_api_key, null, max_results))


main("Apple Inc")

Computing correlation

URL

/correlation

Purpose

Calculates the correlation between news feed sentiment and stock price change, and provides an outcome message.

External services

None

Source code

main(previousPrice: double, currentPrice: double, news_feed_sentiment: double, company_name: string): record(correlation: double, outcome: string) =
let
c = 1,
d = 1 + news_feed_sentiment,
slope = (d - c) / (currentPrice - previousPrice),
correlation_str=(if(slope<-0.25) then "negative"
else if(slope<-0.05) then "slightly negative"
else if(slope<0.05) then "neutral"
else if(slope<0.05) then "slightly positive"
else "positive" ),
output = {
correlation:slope,
outcome: "We computed a "+correlation_str + " correlation between the sentiment of readers based on the latest news feed and the change in stock price for "+company_name+"."+
" Sentiment is " + String.From(news_feed_sentiment) + " and stock price change is " +String.From(currentPrice-previousPrice)
}
in
output

main(181.20, 183.5, 0.5, "mycompany")

Putting It All Together in StockStream GPT

After setting up RAW endpoints, we proceed with implementing our integration logic in the form of a new GPT called StockStream

note

Further information regarding creating GPTs can be found in our detailed guide

Here are the GPT setup details:

Setup GPT

Name
StockStream
Description
A financial assistant for stock market analysis and news sentiment correlation.
Instructions
As StockStream, your primary function is to assist users in understanding the relationship between stock market movements and news sentiment for specific companies. You are equipped with the ability to fetch and analyze financial data and news articles, focusing particularly on correlating stock price changes with the sentiment of news stories about a specific company.

Your responses should be factual, data-driven, and clear, providing users with insights into how news sentiment may be affecting stock prices.

Always verify that a company exists on Nasdaq before providing analysis. In case of data retrieval issues, politely inform the user and suggest retrying. Respond only to queries about stock price and news sentiment correlation, maintaining a professional tone.

Conversation starters
1. What's the sentiment correlation for Tesla's stock?
2. Analyze Apple's stock with recent news sentiment.
3. Is there a link between Amazon's stock price and news sentiment?
4. How does Microsoft's news sentiment affect its stock?
Schema
https://stockstream.api.raw-labs.com/raw/1/api/admin/endpoints/open-api?file_format=json&include_private=false
Privacy policy
https://raw-labs.com/privacy-policy/

Test GPT

GPT testing

Use StockStream GPT

StockStream initial screen

GPT Run Homepage

Allow RAW Host

GPT Run Confirm

Final Result / Insight

GPT Run Result

Ready to try it out?Register for free and start building today!

Otherwise, if you have questions/comments, join us on Discord!