In this guide, you will explore the two sentiment-adjacent surfaces
that Yahoo Finance exposes through yahoofinancer:
related-symbol recommendations (which securities the
market associates most strongly with a ticker, scored by relevance) and
technical insights (a research snapshot combining
Trading Central outlooks, key price levels, a Morningstar-style company
scorecard, and an Argus Research rating with target price).
(A note on scope: classic sell-side consensus ratings—the
strong-buy/hold/sell vote distribution—are served by Yahoo’s
quoteSummary modules, which yahoofinancer does
not currently wrap. Everything shown here comes from endpoints the
package already supports.)
technical_insights returns a nested list aggregating
several research providers. It helps to pull the fields you care about
into small tibbles before analyzing them. First, key technical levels
from Trading Central:
ins <- aapl_obj$technical_insights
levels_tbl <- tibble::tibble(
level = c("Support", "Resistance", "Stop loss"),
price = c(
ins$instrumentInfo$keyTechnicals$support,
ins$instrumentInfo$keyTechnicals$resistance,
ins$instrumentInfo$keyTechnicals$stopLoss
)
)
levels_tbl
#> # A tibble: 3 × 2
#> level price
#> <chr> <dbl>
#> 1 Support 417.
#> 2 Resistance 507.
#> 3 Stop loss 397.Next, the short-, intermediate-, and long-term outlooks, each scored on Trading Central’s evidence scale:
te <- ins$instrumentInfo$technicalEvents
outlooks_tbl <- tibble::tibble(
horizon = c("Short term", "Intermediate term", "Long term"),
direction = c(
te$shortTermOutlook$direction,
te$intermediateTermOutlook$direction,
te$longTermOutlook$direction
),
score = c(
te$shortTermOutlook$score,
te$intermediateTermOutlook$score,
te$longTermOutlook$score
),
description = c(
te$shortTermOutlook$scoreDescription,
te$intermediateTermOutlook$scoreDescription,
te$longTermOutlook$scoreDescription
)
)
outlooks_tbl
#> # A tibble: 3 × 4
#> horizon direction score description
#> <chr> <chr> <dbl> <chr>
#> 1 Short term Bullish 3 Strong Bullish Evidence
#> 2 Intermediate term Bullish 3 Strong Bullish Evidence
#> 3 Long term Bearish 1 Weak Bearish EvidenceThe valuation block summarizes where price sits relative to fair value:
ins$instrumentInfo$valuation$description
#> [1] "Near Fair Value"
ins$instrumentInfo$valuation$discount
#> [1] "8%"The companySnapshot block rates the firm on six
dimensions (0–1), alongside the sector median for comparison. Pivot to
long form and chart both scopes side by side:
snap <- ins$companySnapshot
snapshot_tbl <- tibble::tibble(
dimension = names(snap$company),
Company = unlist(snap$company),
Sector = unlist(snap$sector)
)
snapshot_long <- snapshot_tbl |>
pivot_longer(
cols = c(Company, Sector),
names_to = "scope",
values_to = "score"
)
snapshot_long
#> # A tibble: 12 × 3
#> dimension scope score
#> <chr> <chr> <dbl>
#> 1 innovativeness Company 0.977
#> 2 innovativeness Sector 0.5
#> 3 hiring Company 0.966
#> 4 hiring Sector 0.5
#> # i 8 more rowsggplot(snapshot_long, aes(x = score, y = reorder(dimension, score))) +
geom_point(aes(color = scope, size = scope), position = position_dodge(width = 0.5)) +
scale_color_manual(values = c("Company" = "#1f77b4", "Sector" = "#9aa5ad")) +
scale_size_manual(values = c("Company" = 3.4, "Sector" = 2.4), guide = "none") +
scale_x_continuous(labels = percent_format(accuracy = 1), limits = c(0, 1)) +
labs(
title = "Company Scorecard vs. Sector Median",
subtitle = paste("Sector:", snap$sectorInfo),
x = "Score",
y = NULL,
color = NULL,
caption = "Source: Yahoo Finance insights via yahoofinancer"
) +
theme_minimal(base_size = 12) +
theme(
panel.grid.major.y = element_blank(),
legend.position = "top"
)The recommendation block carries a provider, categorical
rating, and 12-month target price—a compact sentiment triple worth
logging alongside your own models:
call_tbl <- tibble::tibble(
provider = ins$recommendation$provider,
rating = ins$recommendation$rating,
target_price = ins$recommendation$targetPrice
)
call_tbl
#> # A tibble: 1 × 3
#> provider rating target_price
#> <chr> <chr> <dbl>
#> 1 Argus Research BUY 620Recent research report headlines are also embedded under
reports, useful for quick qualitative context:
head(map_chr(ins$reports, "title"), n = 3)
#> [1] "Last week featured another monumental run for the stock market, as the major indices recaptured ..."
#> [2] "Daily - Vickers Top Buyers & Sellers for 03/10/2026"
#> ...Below is the complete, self-contained workflow in a single copy-pasteable script:
library(yahoofinancer)
library(dplyr)
library(ggplot2)
library(scales)
# 1. Fetch and plot related-symbol recommendations
aapl_obj <- Ticker$new("AAPL")
top_related <- aapl_obj$recommendations |>
arrange(desc(score))
ggplot(top_related, aes(x = score, y = reorder(symbol, score))) +
geom_col(fill = "#1f77b4", width = 0.65) +
scale_x_continuous(labels = percent_format(accuracy = 1)) +
labs(
title = "Securities Most Associated with AAPL",
subtitle = "Yahoo Finance related-symbol relevance scores",
x = "Relevance score",
y = NULL,
caption = "Source: Yahoo Finance via yahoofinancer"
) +
theme_minimal(base_size = 12) +
theme(panel.grid.major.y = element_blank())
# 2. Extract technical insights and key support/resistance levels
ins <- aapl_obj$technical_insights
levels_tbl <- tibble::tibble(
level = c("Support", "Resistance", "Stop loss"),
price = c(
ins$instrumentInfo$keyTechnicals$support,
ins$instrumentInfo$keyTechnicals$resistance,
ins$instrumentInfo$keyTechnicals$stopLoss
)
)
levels_tbl
# 3. Extract research recommendation and price target
call_tbl <- tibble::tibble(
provider = ins$recommendation$provider,
rating = ins$recommendation$rating,
target_price = ins$recommendation$targetPrice
)
call_tblIn this guide, you learned how to:
Ticker$recommendations and visualize them as
ranked bars.technical_insights into tidy tables of key levels,
directional outlooks, and valuation posture.Tickers and rank within groups using
.by_group = TRUE.keyTechnicals support/resistance on a
yf_download_prices() chart—see
vignette("first-stock-analysis", package = "yahoofinancer").vignette("shiny-dashboard", package = "yahoofinancer").invisible(NULL) when
Yahoo is unreachable—guard with is.null() before extracting
fields.vignette("cookbook", package = "yahoofinancer").