library(quantr) library(dplyr) library(ggplot2) library(lubridate)
The goal of this notebook is to demonstrate stock screening using the following eight criteria:
Let's do this for Best Buy, ticker BBY
.
ticker <- "WBA" fin <- yahoo_financials(ticker) fin_web <- yahoo_financials_web(ticker) fin_web
For the trailing PE ratio, use current price and the EPS history from yahoo_financials_web()
:
price <- yahoo_history(ticker, interval = "1d", days = 1, end_date = Sys.time()) %>% arrange(desc(date)) %>% head(1) price
pe_ratio <- price$open / mean(fin_web$dilutedEps, na.rm = TRUE)
This gives us a mean PE ratio of r round(mean(pe_ratio), 2)
.
ggplot() + geom_bar(aes(x = fin$endDate, y = fin_web$dilutedEps), stat = "identity", fill = "#33658A", width = as.numeric(days(100))) + xlab("date") + ylab("Earnings per share")
Return on invested capital will be calculated here as cash flow divided by equity + debt. Needs to be checked r emo::ji("warning")
.
roic <- fin$freeCashflow / (fin$longTermDebt + fin$totalStockholderEquity) ggplot() + geom_bar(aes(x = fin$endDate, y = roic), stat = "identity", fill = "#33658A", width = as.numeric(days(100))) + xlab("date") + ylab("ROIC")
This gives us a mean ROIC of r round(mean(roic), 2)
.
Revenue should be going up, so let's try a linear regression model.
mod <- lm(fin$totalRevenue ~ fin$endDate) summary(mod)
ggplot(fin) + geom_point(aes(x = endDate, y = totalRevenue)) + geom_abline(slope = coef(mod)[["fin$endDate"]], intercept = coef(mod)[["(Intercept)"]]) + scale_y_continuous(expand = c(0.1, 0), limits = c(0, NA))
This gives us an annual growth rate of r round(coef(mod)[["fin$endDate"]] / mean(fin$totalRevenue) * as.numeric(days(365)), 2)
.
Same procedure as before:
mod <- lm(fin$netIncome ~ fin$endDate) summary(mod)
ggplot(fin) + geom_point(aes(x = endDate, y = netIncome)) + geom_abline(slope = coef(mod)[["fin$endDate"]], intercept = coef(mod)[["(Intercept)"]]) + scale_y_continuous(expand = c(0.1, 0), limits = c(0, NA))
This gives us an annual growth rate of r round(coef(mod)[["fin$endDate"]] / mean(fin$netIncome) * as.numeric(days(365)), 2)
.
Shares outstanding should be decreasing or staying the same.
mod <- lm(fin_web$dilutedAverageShares ~ fin_web$endDate) summary(mod)
ggplot(fin_web) + geom_point(aes(x = endDate, y = dilutedAverageShares)) + geom_abline(slope = coef(mod)[["fin_web$endDate"]], intercept = coef(mod)[["(Intercept)"]]) + scale_y_continuous(expand = c(0.1, 0), limits = c(0, NA))
This gives us an annual growth rate of r round(coef(mod)[["fin_web$endDate"]] / mean(fin_web$dilutedAverageShares) * as.numeric(days(365)), 2)
.
To do.
mod <- lm(fin$freeCashflow ~ fin$endDate) summary(mod)
ggplot(fin) + geom_point(aes(x = endDate, y = freeCashflow)) + geom_abline(slope = coef(mod)[["fin$endDate"]], intercept = coef(mod)[["(Intercept)"]]) + scale_y_continuous(expand = c(0.1, 0), limits = c(0, NA))
This gives us an annual growth rate of r round(coef(mod)[["fin$endDate"]] / mean(fin$freeCashflow) * as.numeric(days(365)), 2)
.
pfcf <- price$open / mean(fin$freeCashflow / fin_web$dilutedAverageShares, na.rm = TRUE)
This gives us a price to free cash flow of r round(mean(pfcf), 2)
.
ggplot() + geom_bar(aes(x = fin$endDate, y = fin$freeCashflow / fin_web$dilutedAverageShares), stat = "identity", fill = "#33658A", width = as.numeric(days(100))) + xlab("date") + ylab("Free cash flow per share")
bind_rows( eight_pillars("BBY"), eight_pillars("MSFT") )
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.