Related-Symbol Recommendations and Technical Insights

Overview

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.)

Required Packages

# Install required packages if not already installed:
# install.packages(c("yahoofinancer", "dplyr", "tidyr", "purrr", "ggplot2", "scales"))

library(yahoofinancer)
library(dplyr)
library(tidyr)
library(purrr)
library(ggplot2)
library(scales)

2. The Technical Insights Snapshot

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 Evidence

The valuation block summarizes where price sits relative to fair value:

ins$instrumentInfo$valuation$description
#> [1] "Near Fair Value"

ins$instrumentInfo$valuation$discount
#> [1] "8%"

3. Company Scorecard vs. Sector

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 rows
ggplot(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"
  )

4. Research Rating and Target Price

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             620

Recent 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"
#> ...

6. Minimal Reproducible Example

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_tbl

7. Summary

In this guide, you learned how to:

  1. Rank market associations: Pull related-symbol scores with Ticker$recommendations and visualize them as ranked bars.
  2. Unpack research snapshots: Flatten technical_insights into tidy tables of key levels, directional outlooks, and valuation posture.
  3. Compare against the sector: Chart the six-dimension company scorecard next to its sector median.
  4. Log the research call: Capture provider, rating, and target price as structured fields.
  5. Scale to a watchlist: Fan out across multiple symbols with Tickers and rank within groups using .by_group = TRUE.

8. Going Further

  • Combine with prices: Overlay keyTechnicals support/resistance on a yf_download_prices() chart—see vignette("first-stock-analysis", package = "yahoofinancer").
  • Dashboard integration: These surfaces slot directly into the reactive layer built in vignette("shiny-dashboard", package = "yahoofinancer").
  • Failure semantics: Like every network call in the package, both bindings warn and return invisible(NULL) when Yahoo is unreachable—guard with is.null() before extracting fields.
  • More recipes: For drawdown analysis, technical indicators (EMA, RSI, MACD), and portfolio modeling, see vignette("cookbook", package = "yahoofinancer").