{"id":8662,"date":"2026-08-27T12:13:06","date_gmt":"2026-08-27T06:43:06","guid":{"rendered":"https:\/\/newsdata.io\/blog\/?p=8662"},"modified":"2026-08-27T12:13:06","modified_gmt":"2026-08-27T06:43:06","slug":"building-a-news-driven-market-dashboard","status":"publish","type":"post","link":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/","title":{"rendered":"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API"},"content":{"rendered":"[vc_row type=&#8221;in_container&#8221; full_screen_row_position=&#8221;middle&#8221; column_margin=&#8221;default&#8221; column_direction=&#8221;default&#8221; column_direction_tablet=&#8221;default&#8221; column_direction_phone=&#8221;default&#8221; scene_position=&#8221;center&#8221; text_color=&#8221;dark&#8221; text_align=&#8221;left&#8221; row_border_radius=&#8221;none&#8221; row_border_radius_applies=&#8221;bg&#8221; overflow=&#8221;visible&#8221; overlay_strength=&#8221;0.3&#8243; gradient_direction=&#8221;left_to_right&#8221; shape_divider_position=&#8221;bottom&#8221; bg_image_animation=&#8221;none&#8221;][vc_column column_padding=&#8221;no-extra-padding&#8221; column_padding_tablet=&#8221;inherit&#8221; column_padding_phone=&#8221;inherit&#8221; column_padding_position=&#8221;all&#8221; column_element_direction_desktop=&#8221;default&#8221; column_element_spacing=&#8221;default&#8221; desktop_text_alignment=&#8221;default&#8221; tablet_text_alignment=&#8221;default&#8221; phone_text_alignment=&#8221;default&#8221; background_color_opacity=&#8221;1&#8243; background_hover_color_opacity=&#8221;1&#8243; column_backdrop_filter=&#8221;none&#8221; column_shadow=&#8221;none&#8221; column_border_radius=&#8221;none&#8221; column_link_target=&#8221;_self&#8221; column_position=&#8221;default&#8221; gradient_direction=&#8221;left_to_right&#8221; overlay_strength=&#8221;0.3&#8243; width=&#8221;1\/4&#8243; tablet_width_inherit=&#8221;default&#8221; animation_type=&#8221;default&#8221; bg_image_animation=&#8221;none&#8221; border_type=&#8221;simple&#8221; column_border_width=&#8221;none&#8221; column_border_style=&#8221;solid&#8221; column_padding_type=&#8221;default&#8221; gradient_type=&#8221;default&#8221; offset=&#8221;vc_hidden-sm vc_hidden-xs&#8221;][\/vc_column][vc_column column_padding=&#8221;no-extra-padding&#8221; column_padding_tablet=&#8221;inherit&#8221; column_padding_phone=&#8221;inherit&#8221; column_padding_position=&#8221;all&#8221; column_element_direction_desktop=&#8221;default&#8221; column_element_spacing=&#8221;default&#8221; desktop_text_alignment=&#8221;default&#8221; tablet_text_alignment=&#8221;default&#8221; phone_text_alignment=&#8221;default&#8221; background_color_opacity=&#8221;1&#8243; background_hover_color_opacity=&#8221;1&#8243; column_backdrop_filter=&#8221;none&#8221; column_shadow=&#8221;none&#8221; column_border_radius=&#8221;none&#8221; column_link_target=&#8221;_self&#8221; column_position=&#8221;default&#8221; el_class=&#8221;text_block_wrapper&#8221; gradient_direction=&#8221;left_to_right&#8221; overlay_strength=&#8221;0.3&#8243; width=&#8221;3\/4&#8243; tablet_width_inherit=&#8221;default&#8221; animation_type=&#8221;default&#8221; bg_image_animation=&#8221;none&#8221; border_type=&#8221;simple&#8221; column_border_width=&#8221;none&#8221; column_border_style=&#8221;solid&#8221; column_padding_type=&#8221;default&#8221; gradient_type=&#8221;default&#8221; offset=&#8221;vc_col-lg-9 vc_col-md-12&#8243;][image_with_animation image_url=&#8221;8666&#8243; image_size=&#8221;full&#8221; animation_type=&#8221;entrance&#8221; animation=&#8221;None&#8221; animation_movement_type=&#8221;transform_y&#8221; hover_animation=&#8221;none&#8221; alignment=&#8221;&#8221; border_radius=&#8221;none&#8221; box_shadow=&#8221;none&#8221; image_loading=&#8221;default&#8221; max_width=&#8221;100%&#8221; max_width_mobile=&#8221;default&#8221;][vc_column_text]A breaking headline and a price chart tell two halves of the same story. &#8220;Nvidia beats earnings&#8221; is information; a 9% after-hours move is confirmation. On their own, each is incomplete \u2014 a headline with no price context can&#8217;t tell you whether the market already priced it in, and a price spike with no headline leaves you guessing <i>why<\/i>. The interesting work sits in the join between them.<\/p>\n<p>This guide walks through building that join: a pipeline that pulls structured news from <a href=\"https:\/\/newsdata.io\">NewsData.io<\/a>, maps each article to the instrument it&#8217;s about, and then pulls the real-time and historical price reaction from a market data API \u2014 so you can see, for any headline, exactly what price did in the minutes and hours around it.<\/p>\n<p>Everything here is working code you can run today. You&#8217;ll need two API keys: one from NewsData.io for the news side, and one from <a href=\"https:\/\/infoway.io\/en\" rel=\"sponsored\">Infoway<\/a> for the market data side. Both offer a free tier with no credit card, which is enough to build and test the pipeline end to end. Two NewsData.io specifics are worth knowing before you go live, though: on the free plan the news feed is time-delayed rather than real-time, and a few fields and filters \u2014 the per-article <em><strong>sentiment<\/strong><\/em> field and the <em><strong>timeframe<\/strong><\/em> filter used in the live monitor below \u2014 are paid-plan features. Both are called out at the relevant step.[\/vc_column_text][vc_column_text]\n<h2>The Two Halves of the Pipeline<\/h2>\n<p>Before writing any code, it helps to be precise about which service owns which job:<\/p>\n<table>\n<thead>\n<tr>\n<th><b>Layer<\/b><\/th>\n<th><b>Service<\/b><\/th>\n<th><b>What it provides<\/b><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><b>News<\/b><\/td>\n<td>NewsData.io<\/td>\n<td>Latest &amp; historical articles, crypto news, keyword\/category\/country filtering, per-article sentiment and AI tags<\/td>\n<\/tr>\n<tr>\n<td><b>Market data<\/b><\/td>\n<td>Infoway<\/td>\n<td>Real-time trades, OHLCV candlesticks, order-book depth, and WebSocket push for stocks, forex, and crypto<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The design principle is separation of concerns. NewsData.io answers <i>&#8220;what is being said, and about what?&#8221;<\/i> Infoway answers <i>&#8220;what did the price do?&#8221;<\/i> The glue code \u2014 mapping a headline to a ticker and aligning timestamps \u2014 is the part you write, and it&#8217;s where the value is.[\/vc_column_text][vc_column_text]\n<h2>Part 1: Pulling Structured News from NewsData.io<\/h2>\n<p>NewsData.io exposes a clean REST API. The endpoint you&#8217;ll use most is <b>Latest News<\/b>, which returns the most recently published articles across NewsData.io&#8217;s sources (on the free plan the feed is delayed rather than live; real-time delivery is a paid feature):<\/p>\n<p>GET https:\/\/newsdata.io\/api\/1\/latest<\/p>\n<p>Authentication is a single <strong><em>apikey<\/em><\/strong> query parameter. The endpoint supports a rich set of filters \u2014 the ones that matter most for a market pipeline are <em><strong>q<\/strong><\/em> (keyword), <strong><em>category<\/em><\/strong>, <strong><em>country<\/em><\/strong>, <strong><em>language<\/em><\/strong>, and <strong><em>timeframe<\/em><\/strong>.<\/p>\n<p>Here&#8217;s a first request that pulls recent business news mentioning a specific company:<\/p>\n<p><code>import requests<br \/>\nNEWSDATA_KEY = &quot;pub_YOUR_NEWSDATA_KEY&quot;<br \/>\nresp = requests.get(<br \/>\n&quot;https:\/\/newsdata.io\/api\/1\/latest&quot;,<br \/>\nparams={<br \/>\n&quot;apikey&quot;: \u00a0 NEWSDATA_KEY,<br \/>\n&quot;q&quot;:\u00a0 \u00a0 \u00a0 \u00a0 &quot;Nvidia&quot;,<br \/>\n&quot;category&quot;: &quot;business,technology&quot;,<br \/>\n&quot;language&quot;: &quot;en&quot;,<br \/>\n&quot;country&quot;:\u00a0 &quot;us&quot;,<br \/>\n},<br \/>\ntimeout=30,<br \/>\n)<br \/>\npayload = resp.json()<br \/>\nprint(f&quot;status={payload[&#039;status&#039;]}\u00a0 results={payload[&#039;totalResults&#039;]}&quot;)<br \/>\nfor article in payload[&quot;results&quot;]:<br \/>\n# sentiment is a real value only on paid plans; on the free plan it&#039;s a<br \/>\n# placeholder string, so fall back to &quot;n\/a&quot; for anything unexpected.<br \/>\nsentiment = article.get(&quot;sentiment&quot;)<br \/>\nif sentiment not in (&quot;positive&quot;, &quot;neutral&quot;, &quot;negative&quot;):<br \/>\nsentiment = &quot;n\/a&quot;<br \/>\nprint(f&quot;[{article[&#039;pubDate&#039;]}] {article[&#039;title&#039;]}&quot;)<br \/>\nprint(f&quot;\u00a0 \u00a0 source: {article[&#039;source_id&#039;]} \u00a0 sentiment: {sentiment}&quot;)<br \/>\nprint(f&quot;\u00a0 \u00a0 {article[&#039;link&#039;]}&quot;)<\/code><\/p>\n<p>Each object in the <strong><em>results<\/em><\/strong> array is a fully structured article. The fields you&#8217;ll lean on for a market pipeline:<\/p>\n<table>\n<thead>\n<tr>\n<th><b>Field<\/b><\/th>\n<th><b>Why it matters<\/b><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>article_id<\/code><\/td>\n<td>Stable unique ID \u2014 use it to dedupe and to avoid re-processing an article<\/td>\n<\/tr>\n<tr>\n<td><code>title<\/code>, <code>description<\/code>, <code>content<\/code><\/td>\n<td>The text you&#8217;ll scan for tickers and company names<\/td>\n<\/tr>\n<tr>\n<td><code>keywords<\/code><\/td>\n<td>Pre-extracted keyword list \u2014 a shortcut for entity matching<\/td>\n<\/tr>\n<tr>\n<td><code>pubDate<\/code><\/td>\n<td>UTC publish timestamp \u2014 the anchor you align price data against<\/td>\n<\/tr>\n<tr>\n<td><code>source_id<\/code>, <code>source_name<\/code><\/td>\n<td>Which outlet ran it, useful for weighting credibility<\/td>\n<\/tr>\n<tr>\n<td><code>sentiment<\/code><\/td>\n<td>positive \/ neutral \/ negative, classified per article \u2014 <b>Professional\/Corporate plans only<\/b><\/td>\n<\/tr>\n<tr>\n<td><code>ai_tag<\/code><\/td>\n<td>AI-assigned topical tags (earnings, M&amp;A, regulation, \u2026) \u2014 paid plans<\/td>\n<\/tr>\n<tr>\n<td><code>country<\/code>, <code>category<\/code>, <code>language<\/code><\/td>\n<td>The filters you queried on, echoed back (country and category come back as arrays)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Pagination<\/h3>\n<p>NewsData.io uses cursor-based pagination. Each response includes a <strong><em>nextPage<\/em><\/strong> token; pass it back as the <strong><em>page<\/em><\/strong> parameter to walk through results:<br \/>\n<code><br \/>\ndef fetch_all_news(query: str, max_pages: int = 5) -&gt; list[dict]:<br \/>\n&quot;&quot;&quot;Walk NewsData.io pagination and collect articles.&quot;&quot;&quot;<br \/>\narticles, page, pages_read = [], None, 0<br \/>\nwhile pages_read &lt; max_pages:<br \/>\nparams = {&quot;apikey&quot;: NEWSDATA_KEY, &quot;q&quot;: query, &quot;language&quot;: &quot;en&quot;}<br \/>\nif page:<br \/>\nparams[&quot;page&quot;] = page<br \/>\ndata = requests.get(<br \/>\n&quot;https:\/\/newsdata.io\/api\/1\/latest&quot;, params=params, timeout=30<br \/>\n).json()<br \/>\narticles.extend(data.get(&quot;results&quot;, []))<br \/>\npage = data.get(&quot;nextPage&quot;)<br \/>\npages_read += 1<br \/>\nif not page:<br \/>\nbreak<br \/>\nreturn articles<br \/>\nheadlines = fetch_all_news(&quot;Federal Reserve interest rate&quot;)<br \/>\nprint(f&quot;Collected {len(headlines)} articles&quot;)<\/code><\/p>\n<p>This is your news feed. Now it needs a price feed to talk to.[\/vc_column_text][vc_column_text]\n<h2>Part 2: The Market Data Side<\/h2>\n<p>For prices, this pipeline uses Infoway \u2014 a real-time market data API covering stocks, forex, and crypto through one account and one key. Authentication is a single header on every request:<\/p>\n<p><code>apiKey: YOUR_INFOWAY_KEY<\/code><\/p>\n<p>One thing to know up front: Infoway uses market-suffixed symbols rather than bare tickers, because it isn&#8217;t US-only:<\/p>\n<table>\n<thead>\n<tr>\n<th><b>Market<\/b><\/th>\n<th><b>Format<\/b><\/th>\n<th><b>Example<\/b><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>US Equities<\/td>\n<td><code>{TICKER}.US<\/code><\/td>\n<td><code>AAPL.US<\/code>, <code>NVDA.US<\/code><\/td>\n<\/tr>\n<tr>\n<td>Hong Kong<\/td>\n<td><code>{code}.HK<\/code><\/td>\n<td><code>00700.HK<\/code><\/td>\n<\/tr>\n<tr>\n<td>Japan<\/td>\n<td><code>{code}.JP<\/code><\/td>\n<td><code>7203.JP<\/code><\/td>\n<\/tr>\n<tr>\n<td>Crypto<\/td>\n<td>pair symbol<\/td>\n<td><code>BTCUSDT<\/code>, <code>ETHUSDT<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For a US-news pipeline you&#8217;ll mostly append <strong><em>.US<\/em><\/strong>. The three endpoints we&#8217;ll use:<\/p>\n<ul>\n<li><b>Latest trade<\/b> \u2014 <em>GET https:\/\/data.infoway.io\/stock\/batch_trade\/{codes}<\/em><\/li>\n<li><b>Candlesticks (OHLCV)<\/b> \u2014 <em>POST https:\/\/data.infoway.io\/stock\/v2\/batch_kline<\/em><\/li>\n<li><b>WebSocket push<\/b> \u2014 <em>wss:\/\/data.infoway.io\/ws?business=stock&amp;apikey=YOUR_KEY<\/em><\/li>\n<\/ul>\n<p>A quick sanity check that the market side works \u2014 the latest price for a batch of symbols:<\/p>\n<p><code>import requests<br \/>\nINFOWAY_KEY = &quot;YOUR_INFOWAY_KEY&quot;<br \/>\nresp = requests.get(<br \/>\n&quot;https:\/\/data.infoway.io\/stock\/batch_trade\/NVDA.US,AAPL.US,TSLA.US&quot;,<br \/>\nheaders={&quot;apiKey&quot;: INFOWAY_KEY},<br \/>\ntimeout=30,<br \/>\n)<br \/>\nfor tick in resp.json()[&quot;data&quot;]:<br \/>\nprint(f&quot;{tick[&#039;s&#039;]:10s}\u00a0 ${tick[&#039;p&#039;]:&gt;10s}\u00a0 vol={tick[&#039;v&#039;]}&quot;)<\/code><\/p>\n<p>With both feeds proven out, we can connect them.[\/vc_column_text][vc_column_text]\n<h2>Part 3: Mapping a Headline to an Instrument<\/h2>\n<p>This is the glue. A headline says &#8220;Nvidia&#8221;; the price API wants <strong><em>NVDA.US<\/em><\/strong>. NewsData.io makes this easier than raw text-scraping, because it hands you a <strong><em>keywords<\/em><\/strong> array and (on paid tiers) <strong><em>ai_tag<\/em><\/strong> classifications alongside the title and body.<\/p>\n<p>A pragmatic approach for a focused watchlist is a lookup table plus a scan across the article&#8217;s most reliable text fields:<\/p>\n<p># Map the names\/tickers you care about to Infoway symbols.<\/p>\n<p><code>WATCHLIST = {<br \/>\n&quot;nvidia&quot;: &quot;NVDA.US&quot;, \u00a0 &quot;nvda&quot;: &quot;NVDA.US&quot;,<br \/>\n&quot;apple&quot;:\u00a0 &quot;AAPL.US&quot;, \u00a0 &quot;aapl&quot;: &quot;AAPL.US&quot;,<br \/>\n&quot;tesla&quot;:\u00a0 &quot;TSLA.US&quot;, \u00a0 &quot;tsla&quot;: &quot;TSLA.US&quot;,<br \/>\n&quot;microsoft&quot;: &quot;MSFT.US&quot;, &quot;msft&quot;: &quot;MSFT.US&quot;,<br \/>\n}<br \/>\ndef match_symbol(article: dict) -&gt; str | None:<br \/>\n&quot;&quot;&quot;Return an Infoway symbol if the article clearly references a watchlist name.&quot;&quot;&quot;<br \/>\nhaystack = &quot; &quot;.join([<br \/>\narticle.get(&quot;title&quot;, &quot;&quot;),<br \/>\narticle.get(&quot;description&quot;, &quot;&quot;) or &quot;&quot;,<br \/>\n&quot; &quot;.join(article.get(&quot;keywords&quot;) or []),<br \/>\n]).lower()<br \/>\nfor name, symbol in WATCHLIST.items():<br \/>\nif name in haystack:<br \/>\nreturn symbol<br \/>\nreturn None<br \/>\ntagged = []\nfor art in fetch_all_news(&quot;Nvidia earnings&quot;):<br \/>\nsymbol = match_symbol(art)<br \/>\nif symbol:<br \/>\ntagged.append({&quot;symbol&quot;: symbol, &quot;article&quot;: art})<br \/>\nprint(f&quot;{symbol}\u00a0 \u2190\u00a0 {art[&#039;title&#039;]}&quot;)<\/code><\/p>\n<p>For a broader, hands-off setup you&#8217;d swap the lookup table for a proper NER model (spaCy, or an LLM call) fed by the same title + description + keywords fields \u2014 but the lookup table is enough to get a real pipeline running, and it&#8217;s exactly what most single-desk or single-portfolio dashboards need.[\/vc_column_text][vc_column_text]\n<h2>Part 4: The Price Reaction \u2014 An Event Study<\/h2>\n<p>Now the payoff. For each tagged article we have a <strong><em>pubDate<\/em><\/strong> (UTC) and a symbol. The question is: <i>what did price do around that timestamp?<\/i> Infoway&#8217;s candlestick endpoint answers it. We pull minute bars and slice a window around the news.<\/p>\n<p>The <strong><em>batch_kline<\/em><\/strong> endpoint takes a <strong><em>klineType<\/em><\/strong> (timeframe) and returns OHLCV bars:<\/p>\n<table>\n<thead>\n<tr>\n<th><b><code>klineType<\/code><\/b><\/th>\n<th><b>Timeframe<\/b><\/th>\n<th><b><code>klineType<\/code><\/b><\/th>\n<th><b>Timeframe<\/b><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td>1-minute<\/td>\n<td>7<\/td>\n<td>4-hour<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>5-minute<\/td>\n<td>8<\/td>\n<td>Daily<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>15-minute<\/td>\n<td>9<\/td>\n<td>Weekly<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>1-hour<\/td>\n<td>10<\/td>\n<td>Monthly<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><code>import requests, json<br \/>\nfrom datetime import datetime, timezone<br \/>\nINFOWAY_KEY = &quot;YOUR_INFOWAY_KEY&quot;<br \/>\ndef get_minute_candles(symbol: str, count: int = 500) -&gt; list[dict]:<br \/>\nresp = requests.post(<br \/>\n&quot;https:\/\/data.infoway.io\/stock\/v2\/batch_kline&quot;,<br \/>\nheaders={&quot;Content-Type&quot;: &quot;application\/json&quot;, &quot;apiKey&quot;: INFOWAY_KEY},<br \/>\ndata=json.dumps({&quot;codes&quot;: symbol, &quot;klineType&quot;: 1, &quot;klineNum&quot;: count}),<br \/>\ntimeout=30,<br \/>\n)<br \/>\nitems = resp.json().get(&quot;data&quot;, [])<br \/>\nfor it in items:<br \/>\nif it[&quot;s&quot;] == symbol:<br \/>\nreturn it[&quot;respList&quot;]\nreturn []\ndef news_reaction(symbol: str, pub_date: str, window_min: int = 30) -&gt; dict | None:<br \/>\n&quot;&quot;&quot;Compare price just before a headline to `window_min` minutes after.&quot;&quot;&quot;<br \/>\nnews_ts = datetime.strptime(pub_date, &quot;%Y-%m-%d %H:%M:%S&quot;) \\<br \/>\n.replace(tzinfo=timezone.utc).timestamp() * 1000<br \/>\n# Infoway kline timestamps are Unix SECONDS \u2014 scale to ms to match news_ts.<br \/>\ndef ts_ms(candle) -&gt; int:<br \/>\nreturn int(candle[&quot;t&quot;]) * 1000<br \/>\ncandles = sorted(get_minute_candles(symbol), key=ts_ms)<br \/>\nbefore = [c for c in candles if ts_ms(c) &lt;= news_ts]\nafter\u00a0 = [c for c in candles if ts_ms(c) &gt;\u00a0 news_ts]\nif not before or not after:<br \/>\nreturn None<br \/>\nprice_before = float(before[-1][&quot;c&quot;])<br \/>\nwindow_after = [c for c in after if ts_ms(c) &lt;= news_ts + window_min * 60_000]\nif not window_after:<br \/>\nreturn None<br \/>\nprice_after = float(window_after[-1][&quot;c&quot;])<br \/>\nmove_pct\u00a0 \u00a0 = (price_after - price_before) \/ price_before * 100<br \/>\nreturn {<br \/>\n&quot;symbol&quot;:\u00a0 \u00a0 \u00a0 \u00a0 symbol,<br \/>\n&quot;price_before&quot;:\u00a0 round(price_before, 2),<br \/>\n&quot;price_after&quot;: \u00a0 round(price_after, 2),<br \/>\n&quot;move_pct&quot;:\u00a0 \u00a0 \u00a0 round(move_pct, 2),<br \/>\n&quot;window_min&quot;:\u00a0 \u00a0 window_min,<br \/>\n}<br \/>\n# Tie it together: headline \u2192 symbol \u2192 price reaction<br \/>\nfor item in tagged:<br \/>\nr = news_reaction(item[&quot;symbol&quot;], item[&quot;article&quot;][&quot;pubDate&quot;])<br \/>\nif r:<br \/>\narrow = &quot;\u25b2&quot; if r[&quot;move_pct&quot;] &gt;= 0 else &quot;\u25bc&quot;<br \/>\nprint(f&quot;{arrow} {r[&#039;symbol&#039;]}\u00a0 {r[&#039;move_pct&#039;]:+.2f}%\u00a0 in {r[&#039;window_min&#039;]}m &quot;<br \/>\nf&quot;\u2014 {item[&#039;article&#039;][&#039;title&#039;][:60]}&quot;)<\/code><\/p>\n<p>Sample output:<\/p>\n<p><code>\u25b2 NVDA.US\u00a0 +4.18%\u00a0 in 30m \u2014 Nvidia Q3 revenue tops estimates on AI chip demand<br \/>\n\u25bc TSLA.US\u00a0 -2.05%\u00a0 in 30m \u2014 Tesla recalls vehicles over software issue<\/code><\/p>\n<p>That&#8217;s the whole idea in one screen: each row is a headline, joined to the market&#8217;s actual response. The <strong><em>candlestick<\/em><\/strong> endpoint&#8217;s minute resolution (with intraday history going back several years) is what makes this event-study framing possible \u2014 you&#8217;re not eyeballing a daily bar, you&#8217;re measuring the reaction inside the window that matters.[\/vc_column_text][vc_column_text]\n<h2>Part 5: Overlaying Sentiment on Price<\/h2>\n<p>NewsData.io&#8217;s per-article <strong><em>sentiment<\/em><\/strong> field lets you go one level further \u2014 not just <i>did<\/i> price move, but does the market&#8217;s move agree with the tone of coverage? Divergences (bad news, price up) are often the interesting ones. (<strong><em>sentiment<\/em><\/strong> is a real classification only on Professional and Corporate plans, for articles dated 2024-01-12 onward. On the free plan the key is still present but its value is the literal string <strong><em>&#8220;ONLY AVAILABLE IN PROFESSIONAL AND CORPORATE PLANS&#8221;<\/em><\/strong> \u2014 so guard against that placeholder rather than assuming a missing key, as the code below does.)<\/p>\n<p><code>from collections import defaultdict<br \/>\ndef sentiment_vs_price(articles: list[dict]) -&gt; None:<br \/>\nbuckets = defaultdict(list)<br \/>\nfor art in articles:<br \/>\nsymbol = match_symbol(art)<br \/>\nif not symbol:<br \/>\ncontinue<br \/>\nreaction = news_reaction(symbol, art[&quot;pubDate&quot;])<br \/>\nif not reaction:<br \/>\ncontinue<br \/>\nsentiment = art.get(&quot;sentiment&quot;)<br \/>\nif sentiment not in (&quot;positive&quot;, &quot;neutral&quot;, &quot;negative&quot;):<br \/>\ncontinue<br \/>\nbuckets[sentiment].append(reaction[&quot;move_pct&quot;])<br \/>\n# Flag divergences: coverage and price disagree<br \/>\nif sentiment == &quot;negative&quot; and reaction[&quot;move_pct&quot;] &gt; 1:<br \/>\nprint(f&quot;\u26a0 DIVERGENCE\u00a0 {symbol}\u00a0 negative news, price {reaction[&#039;move_pct&#039;]:+.2f}%&quot;)<br \/>\nprint(f&quot;\u00a0 \u00a0 {art[&#039;title&#039;]}&quot;)<br \/>\nprint(&quot;\\nAverage move by news sentiment:&quot;)<br \/>\nif not buckets:<br \/>\nprint(&quot;\u00a0 No sentiment data \u2014 needs a Professional or Corporate plan.&quot;)<br \/>\nfor sentiment, moves in buckets.items():<br \/>\navg = sum(moves) \/ len(moves)<br \/>\nprint(f&quot;\u00a0 {sentiment:10s}\u00a0 {avg:+.2f}% \u00a0 (n={len(moves)})&quot;)<\/code><\/p>\n<p>Aggregated across enough articles, this becomes a genuine research tool: it tells you whether positive coverage on a name actually precedes upward moves, or whether the news is a lagging indicator that follows the price.[\/vc_column_text][vc_column_text]\n<h2>Part 6: Going Live \u2014 A Real-Time News &amp; Price Monitor<\/h2>\n<p>Batch analysis is useful for research; a live desk wants push. Combine two loops: poll NewsData.io&#8217;s Latest endpoint with <strong><em>timeframe=15m<\/em><\/strong> (last 15 minutes) for fresh headlines, and subscribe to Infoway&#8217;s WebSocket for tick-by-tick price on whatever symbols the news surfaces.<\/p>\n<p><b>Note on <\/b><b><em>timeframe<\/em><\/b><b>.<\/b> In NewsData.io a bare number is <i>hours<\/i> (<em>timeframe=15<\/em> = last 15 hours); append m for minutes (<em>timeframe=15m<\/em> = last 15 minutes). The <strong><em>timeframe<\/em><\/strong> filter \u2014 and real-time news delivery generally \u2014 requires a paid NewsData.io plan, so this live monitor is a paid-tier pattern. On the free plan, drop <strong><em>timeframe<\/em><\/strong> and poll on a slower cadence, accepting the feed delay.<\/p>\n<p><code>import asyncio, json, uuid, requests, websockets<br \/>\nNEWSDATA_KEY = &quot;pub_YOUR_NEWSDATA_KEY&quot;<br \/>\nINFOWAY_KEY\u00a0 = &quot;YOUR_INFOWAY_KEY&quot;<br \/>\nclass NewsPriceMonitor:<br \/>\ndef __init__(self):<br \/>\nself.seen_ids: set[str] = set()<br \/>\nself.watched: set[str] = set()<br \/>\nself.ws = None<br \/>\n# ---- news side: poll the Latest endpoint for fresh headlines ----<br \/>\nasync def poll_news(self):<br \/>\nwhile True:<br \/>\n# `requests` is synchronous, and calling it directly here would block<br \/>\n# the event loop for the whole HTTP round trip \u2014 freezing the price<br \/>\n# stream below on every poll. asyncio.to_thread runs it on a worker<br \/>\n# thread and gives the loop back. (aiohttp is the alternative if you<br \/>\n# don&#039;t mind the extra dependency.)<br \/>\nresp = await asyncio.to_thread(<br \/>\nrequests.get,<br \/>\n&quot;https:\/\/newsdata.io\/api\/1\/latest&quot;,<br \/>\nparams={&quot;apikey&quot;: NEWSDATA_KEY, &quot;q&quot;: &quot;stocks OR earnings&quot;,<br \/>\n&quot;language&quot;: &quot;en&quot;, &quot;timeframe&quot;: &quot;15m&quot;},\u00a0 # 15m = 15 minutes; &quot;15&quot; would mean 15 hours<br \/>\ntimeout=30,<br \/>\n)<br \/>\ndata = resp.json()<br \/>\nfor art in data.get(&quot;results&quot;, []):<br \/>\nif art[&quot;article_id&quot;] in self.seen_ids:<br \/>\ncontinue<br \/>\nself.seen_ids.add(art[&quot;article_id&quot;])<br \/>\nsymbol = match_symbol(art)<br \/>\nif symbol:<br \/>\nprint(f&quot;\ud83d\udcf0 {art[&#039;title&#039;]}\u00a0 \u2192\u00a0 watching {symbol}&quot;)<br \/>\nif symbol not in self.watched:<br \/>\nself.watched.add(symbol)<br \/>\nawait self._subscribe(symbol)<br \/>\nawait asyncio.sleep(60) \u00a0 # respect your NewsData.io rate tier<br \/>\n# ---- price side: Infoway WebSocket push ----<br \/>\nasync def _subscribe(self, symbol: str):<br \/>\nif self.ws:<br \/>\nawait self.ws.send(json.dumps({<br \/>\n&quot;code&quot;: 10000, &quot;trace&quot;: str(uuid.uuid4()),<br \/>\n&quot;data&quot;: {&quot;codes&quot;: symbol},<br \/>\n}))<br \/>\nasync def stream_prices(self):<br \/>\nurl = f&quot;wss:\/\/data.infoway.io\/ws?business=stock&amp;apikey={INFOWAY_KEY}&quot;<br \/>\nasync with websockets.connect(url) as ws:<br \/>\nself.ws = ws<br \/>\nasync for raw in ws:<br \/>\nmsg = json.loads(raw)<br \/>\nif msg.get(&quot;code&quot;) == 10002:\u00a0 \u00a0 \u00a0 # trade tick<br \/>\nd = msg[&quot;data&quot;]\nprint(f&quot;\u00a0 \u00a0 \ud83d\udcb9 {d[&#039;s&#039;]}\u00a0 ${d[&#039;p&#039;]}\u00a0 vol={d[&#039;v&#039;]}&quot;)<br \/>\nasync def run(self):<br \/>\nawait asyncio.gather(self.poll_news(), self.stream_prices())<br \/>\nasyncio.run(NewsPriceMonitor().run())<\/code><\/p>\n<p>The result is a console that prints a headline the moment NewsData.io surfaces it, immediately starts streaming live trades for the affected symbol, and lets you watch the reaction unfold in real time. Swap the <strong><em>print<\/em><\/strong> calls for writes to a database, a Slack webhook, or a dashboard and you have a production news-and-price feed.[\/vc_column_text][vc_column_text]\n<h2>Part 7: The Crypto Variant<\/h2>\n<p>Crypto is where news moves price fastest, and both APIs have a dedicated crypto path \u2014 so the same pattern drops straight in.<\/p>\n<p>NewsData.io&#8217;s <b>Crypto<\/b> endpoint adds a <strong><em>coin<\/em><\/strong> filter:<\/p>\n<p><code>crypto_news = requests.get(<br \/>\n&quot;https:\/\/newsdata.io\/api\/1\/crypto&quot;,<br \/>\nparams={&quot;apikey&quot;: NEWSDATA_KEY, &quot;coin&quot;: &quot;btc,eth&quot;, &quot;language&quot;: &quot;en&quot;},<br \/>\ntimeout=30,<br \/>\n).json()<br \/>\nfor art in crypto_news[&quot;results&quot;]:<br \/>\n# `coin` is a list of ticker symbols the article mentions, returned UPPERCASE<br \/>\n# (e.g. [&quot;BTC&quot;, &quot;ETH&quot;]) even though the `coin` filter above takes lowercase.<br \/>\ncoins = art.get(&quot;coin&quot;) or []\nprint(f&quot;[{art[&#039;pubDate&#039;]}] {art[&#039;title&#039;]}\u00a0 (coins: {&#039;, &#039;.join(coins)})&quot;)<\/code><\/p>\n<p>On the price side, Infoway&#8217;s crypto endpoints mirror the stock ones \u2014 pair symbols like <strong><em>BTCUSDT<\/em><\/strong> instead of <strong><em>.US<\/em><\/strong> tickers, and a <strong><em>business=crypto<\/em><\/strong> WebSocket channel. Because crypto trades 24\/7, there&#8217;s no market-hours gap to handle: every headline has a live price window around it, making the event-study join even cleaner than it is for equities.<\/p>\n<p><code># Latest crypto trade, same shape as the stock call<br \/>\nbtc = requests.get(<br \/>\n&quot;https:\/\/data.infoway.io\/crypto\/batch_trade\/BTCUSDT,ETHUSDT&quot;,<br \/>\nheaders={&quot;apiKey&quot;: INFOWAY_KEY},<br \/>\ntimeout=30,<br \/>\n).json()<\/code><\/p>\n<p>Map each ticker in the <strong><em>coin<\/em><\/strong> array NewsData.io returns (uppercase, e.g. <strong><em>[&#8220;BTC&#8221;, &#8220;ETH&#8221;]<\/em><\/strong>) to the pair symbol (<strong><em>BTCUSDT<\/em><\/strong>, <strong><em>ETHUSDT<\/em><\/strong>) \u2014 normalize case when you build the lookup \u2014 and the exact same <strong><em>news_reaction()<\/em><\/strong> function works unchanged.[\/vc_column_text][vc_column_text]\n<h2>Rate Limits &amp; Practical Notes<\/h2>\n<p>Both services have free tiers generous enough to build the full pipeline:<\/p>\n<ul>\n<li><b>NewsData.io<\/b> returns 10 articles\/request on the free tier (50 on paid). The free plan&#8217;s feed is time-delayed (real-time delivery, the <strong><em>timeframe<\/em><\/strong> filter, and the per-article <strong><em>sentiment<\/em><\/strong> field are paid-plan features); plan into that from the start if you&#8217;re building the live monitor. Pagination follows the <strong><em>nextPage<\/em><\/strong> token; each <strong><em>\/latest<\/em><\/strong> or <strong><em>\/crypto<\/em><\/strong> call costs 1 API credit. For back-testing across a longer window, the <b>Archive<\/b> endpoint (<strong><em>\/api\/1\/archive<\/em><\/strong>, 5 credits\/call) reaches years of history.<\/li>\n<li><b>Infoway<\/b> free tier allows 1 request\/second (86,400\/day) and up to 10 concurrently subscribed WebSocket symbols \u2014 plenty for a focused watchlist. Every REST endpoint accepts comma-separated symbols in a single call, so batch your price lookups rather than looping.<\/li>\n<\/ul>\n<p>Two things that will save you debugging time:<\/p>\n<ol>\n<li><b>Timestamps.<\/b> NewsData.io&#8217;s <strong><em>pubDate<\/em><\/strong> is UTC in <strong><em>YYYY-MM-DD HH:MM:SS<\/em><\/strong> format. Infoway&#8217;s timestamps are Unix epoch but the unit differs by endpoint \u2014 <strong><em>batch_kline<\/em><\/strong> bars use the t field in <b>seconds<\/b>, while <strong><em>batch_trade<\/em><\/strong> ticks report t in <b>milliseconds<\/b>. Scale everything to the same unit before comparing (the <strong><em>news_reaction()<\/em><\/strong> code multiplies the candle seconds by 1000) \u2014 a unit or timezone mismatch is the most common way an event study ends up silently misaligned, with every candle landing on one side of the headline.<\/li>\n<li><b>Market hours.<\/b> For equities, a headline that drops at 2 a.m. has no intraday candle until the open. Decide deliberately whether you measure the reaction from the pre-market print, the prior close, or the next regular-session bar \u2014 the crypto path sidesteps this entirely.<\/li>\n<\/ol>\n[\/vc_column_text][vc_column_text]\n<h2>FAQ<\/h2>\n<p><b>Do I need paid tiers for both APIs to build this?<\/b><\/p>\n<p>No \u2014 the free tiers of both NewsData.io and Infoway are enough to build and test the whole pipeline. Two capabilities do require a paid NewsData.io plan, though: real-time (undelayed) news with the timeframe filter, which the live monitor in Part 6 depends on, and the per-article sentiment field used in Part 5. The batch event-study core (Parts 1\u20134) runs entirely on the free tier. You&#8217;ll also want to upgrade when you move from a handful of watched symbols to broad coverage, or when you need NewsData.io&#8217;s Archive endpoint for long-history back-tests.<\/p>\n<p><b>How do I match a headline to a ticker reliably?<\/b><\/p>\n<p>Start with a lookup table keyed on the company names and tickers you actually track \u2014 it&#8217;s simple and precise for a defined watchlist. NewsData.io&#8217;s keywords array and ai_tag fields give you cleaner text to match against than raw HTML. For open-ended coverage, feed the title + description into a named-entity-recognition model or an LLM call and resolve the extracted entity to a symbol.<\/p>\n<p><b>Can I back-test this on historical news instead of live headlines?<\/b><\/p>\n<p>Yes \u2014 swap NewsData.io&#8217;s Latest endpoint for its <b>Archive<\/b> endpoint to pull news from a chosen date range, then pull the matching historical candles from Infoway (daily and above have no lookback limit; minute bars go back several years). The news_reaction() function doesn&#8217;t change.<\/p>\n<p><b>Why keep news and market data in separate services?<\/b><\/p>\n<p>Separation of concerns. A dedicated news API gives you far better coverage, deduplication, sentiment, and source metadata than scraping headlines yourself, while a dedicated market data API gives you clean, low-latency OHLCV and tick data across markets. The join between them is thin \u2014 a symbol map and a timestamp alignment \u2014 and keeping the two feeds independent means you can upgrade or swap either side without touching the other.<\/p>\n<p><b>Does the crypto path really reuse the same code?<\/b><\/p>\n<p>Almost entirely. NewsData.io&#8217;s Crypto endpoint returns the same article shape plus a coin field (a list of uppercase ticker symbols), and Infoway&#8217;s crypto endpoints return the same trade\/candle shape as the stock ones. The only mapping you add is each coin ticker \u2192 pair symbol (e.g. BTC \u2192 BTCUSDT), normalizing case as you go. Because crypto trades around the clock, you also drop all the market-hours handling.[\/vc_column_text][\/vc_column][\/vc_row]\n","protected":false},"excerpt":{"rendered":"<p>A breaking headline and a price chart tell two halves of the same story. &#8220;Nvidia beats earnings&#8221; is information; a 9% after-hours move is confirmation.<\/p>\n","protected":false},"author":11,"featured_media":8666,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API\" \/>\n<meta property=\"og:description\" content=\"A breaking headline and a price chart tell two halves of the same story. &quot;Nvidia beats earnings&quot; is information; a 9% after-hours move is confirmation.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/\" \/>\n<meta property=\"og:site_name\" content=\"Newsdata.io - Stay Updated with the Latest News API Trends\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-27T06:43:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"801\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Raghav Sharma\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Raghav Sharma\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/\",\"url\":\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/\",\"name\":\"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API\",\"isPartOf\":{\"@id\":\"https:\/\/newsdata.io\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1\",\"datePublished\":\"2026-08-27T06:43:06+00:00\",\"dateModified\":\"2026-08-27T06:43:06+00:00\",\"author\":{\"@id\":\"https:\/\/newsdata.io\/blog\/#\/schema\/person\/2c7fdfa00a8bc73559748ec23250f501\"},\"breadcrumb\":{\"@id\":\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#primaryimage\",\"url\":\"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1\",\"width\":1200,\"height\":801},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Blog\",\"item\":\"https:\/\/newsdata.io\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/newsdata.io\/blog\/#website\",\"url\":\"https:\/\/newsdata.io\/blog\/\",\"name\":\"Newsdata.io - Stay Updated with the Latest News API Trends\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/newsdata.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/newsdata.io\/blog\/#\/schema\/person\/2c7fdfa00a8bc73559748ec23250f501\",\"name\":\"Raghav Sharma\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/newsdata.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c64fa1d6e5c1d3bb3076c1db38e95026?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c64fa1d6e5c1d3bb3076c1db38e95026?s=96&d=mm&r=g\",\"caption\":\"Raghav Sharma\"},\"description\":\"Raghav Sharma is a content writer and media researcher at Newsdata.io, specializing in news industry analysis, media literacy, and the evolving landscape of digital journalism. With a background in English Literature and Journalism, along with a focus on fact-based reporting standards, Raghav covers topics including news API technology, editorial bias evaluation, and responsible information consumption. Raghav's work has covered media trends across categories, including healthcare news, international journalism, and API-driven publishing. You can connect with him on LinkedIn or explore more of his writing on the Newsdata.io blog.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/raghav-sharma-4981b4232\/\"],\"url\":\"https:\/\/newsdata.io\/blog\/author\/raghav\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/","og_locale":"en_US","og_type":"article","og_title":"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API","og_description":"A breaking headline and a price chart tell two halves of the same story. \"Nvidia beats earnings\" is information; a 9% after-hours move is confirmation.","og_url":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/","og_site_name":"Newsdata.io - Stay Updated with the Latest News API Trends","article_published_time":"2026-08-27T06:43:06+00:00","og_image":[{"width":1200,"height":801,"url":"https:\/\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg","type":"image\/jpeg"}],"author":"Raghav Sharma","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Raghav Sharma","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/","url":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/","name":"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API","isPartOf":{"@id":"https:\/\/newsdata.io\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#primaryimage"},"image":{"@id":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1","datePublished":"2026-08-27T06:43:06+00:00","dateModified":"2026-08-27T06:43:06+00:00","author":{"@id":"https:\/\/newsdata.io\/blog\/#\/schema\/person\/2c7fdfa00a8bc73559748ec23250f501"},"breadcrumb":{"@id":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#primaryimage","url":"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1","contentUrl":"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1","width":1200,"height":801},{"@type":"BreadcrumbList","@id":"https:\/\/newsdata.io\/blog\/building-a-news-driven-market-dashboard\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Blog","item":"https:\/\/newsdata.io\/blog\/"},{"@type":"ListItem","position":2,"name":"From Headline to Ticker: Building a News-Driven Market Dashboard with NewsData.io and a Real-Time Market Data API"}]},{"@type":"WebSite","@id":"https:\/\/newsdata.io\/blog\/#website","url":"https:\/\/newsdata.io\/blog\/","name":"Newsdata.io - Stay Updated with the Latest News API Trends","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/newsdata.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/newsdata.io\/blog\/#\/schema\/person\/2c7fdfa00a8bc73559748ec23250f501","name":"Raghav Sharma","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/newsdata.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c64fa1d6e5c1d3bb3076c1db38e95026?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c64fa1d6e5c1d3bb3076c1db38e95026?s=96&d=mm&r=g","caption":"Raghav Sharma"},"description":"Raghav Sharma is a content writer and media researcher at Newsdata.io, specializing in news industry analysis, media literacy, and the evolving landscape of digital journalism. With a background in English Literature and Journalism, along with a focus on fact-based reporting standards, Raghav covers topics including news API technology, editorial bias evaluation, and responsible information consumption. Raghav's work has covered media trends across categories, including healthcare news, international journalism, and API-driven publishing. You can connect with him on LinkedIn or explore more of his writing on the Newsdata.io blog.","sameAs":["https:\/\/www.linkedin.com\/in\/raghav-sharma-4981b4232\/"],"url":"https:\/\/newsdata.io\/blog\/author\/raghav\/"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1","category":["API"],"featured_image_url":"https:\/\/i0.wp.com\/newsdata.io\/blog\/wp-content\/uploads\/2026\/08\/aSWzLmGnmrmGqR7__FinanceDS1.jpg?fit=1200%2C801&ssl=1","_links":{"self":[{"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/posts\/8662"}],"collection":[{"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/comments?post=8662"}],"version-history":[{"count":3,"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/posts\/8662\/revisions"}],"predecessor-version":[{"id":8667,"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/posts\/8662\/revisions\/8667"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/media\/8666"}],"wp:attachment":[{"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/media?parent=8662"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/categories?post=8662"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/newsdata.io\/blog\/wp-json\/wp\/v2\/tags?post=8662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}