Tracking NVDA's share price

Nvidia’s stock price compared to it’s competitors.

I had been tracking the performance of Nvidia for a while since they were reporting impressive earnings and share price growth over recent years. I conducted a study (DCF analysis) to see if Nvidia was fairly priced at this time. I had it marked down as a $141 fair value per share based on the DCF I constructed, however it was trading between a high of $280 to a low of $130 from September and to December of 2018.

Let’s download some fundamental data for Nvida and compare it’s performance to it’s industry peers.

# A function to collect fundamental data from Yahoo finance (Income Statement, Balance Sheet and Cash Flow statements, just skip past this part.)

getFin <- function(stock){
  if ("rvest" %in% installed.packages()) {
    library(rvest)
    }else{
      install.packages("rvest")
      library(rvest)
      }
  for (i in 1:length(stock)) {
    tryCatch(
      {
        # Collect the Income Statement data
        link <- "https://finance.yahoo.com/quote/"
        link <- paste0(link, stock[i], "/financials?p=", stock[i])
        wahis.session <- html_session(link)
        p <- wahis.session %>%
          html_nodes(xpath = '//*[@id="Col1-1-Financials-Proxy"]/section/div[3]/table')%>%
          html_table(fill = TRUE)
        IncomeStatement <- p[[1]]
        colnames(IncomeStatement) <- paste(IncomeStatement[1,])
        IncomeStatement <- IncomeStatement[-c(1,5,12,20,25),]
        names_row <- paste(IncomeStatement[,1])
        IncomeStatement <- IncomeStatement[,-1]
        IncomeStatement <- apply(IncomeStatement, 2, function(x){gsub(",","",x)})
        IncomeStatement <- as.data.frame(apply(IncomeStatement, 2, as.numeric))
        rownames(IncomeStatement) <- paste(names_row)
        temp1 <- IncomeStatement
        
        # Collect the Balance Sheet data
        link <- "https://finance.yahoo.com/quote/"
        link <- paste0(link, stock[i],"/balance-sheet?p=", stock[i])
        wahis.session <- html_session(link)
        p <- wahis.session %>%
          html_nodes(xpath = '//*[@id="Col1-1-Financials-Proxy"]/section/div[3]/table')%>%
          html_table(fill = TRUE)
        BalanceSheet <- p[[1]]
        colnames(BalanceSheet) <- BalanceSheet[1,]
        BalanceSheet <- BalanceSheet[-c(1,2,17,28),]
        names_row <- BalanceSheet[,1]
        BalanceSheet <- BalanceSheet[,-1]
        BalanceSheet <- apply(BalanceSheet, 2, function(x){gsub(",","",x)})
        BalanceSheet <- as.data.frame(apply(BalanceSheet, 2, as.numeric))
        rownames(BalanceSheet) <- paste(names_row)
        temp2 <- BalanceSheet
        
        # Collect the Cash Flow data
        link <- "https://finance.yahoo.com/quote/"
        link <- paste0(link, stock[i], "/cash-flow?p=", stock[i])
        wahis.session <- html_session(link)
        p <- wahis.session %>%
          html_nodes(xpath = '//*[@id="Col1-1-Financials-Proxy"]/section/div[3]/table')%>%
          html_table(fill = TRUE)
        CashFlow <- p[[1]]
        colnames(CashFlow) <- CashFlow[1,]
        CashFlow <- CashFlow[-c(1,3,11,16),]
        names_row <- CashFlow[,1]
        CashFlow <- CashFlow[,-1]
        CashFlow <- apply(CashFlow, 2, function(x){gsub(",","",x)})
        CashFlow <- as.data.frame(apply(CashFlow, 2, as.numeric))
        rownames(CashFlow) <- paste(names_row)
        temp3 <- CashFlow
        
        assign(paste0(stock[i],'.f'),value = list(IncomeStatement = temp1, BalanceSheet = temp2, CashFlow = temp3), envir = parent.frame())
        },
      error = function(cond){
        message(stock[i], "Give error ",cond)
        }
      )
  }
}

We can inspect Nvidia’s recent performance by scraping Yahoo finance. The original getFinancials option from the package quantmod became defunct a little while ago, however I have been using this function without problems ever since. You can just add tickers to the symbols object to download more company financial accounts.

symbols <- c("NVDA")
getFin(symbols)
symbols.f <- sapply(symbols, function(x) { paste0(x, ".f") })
tickers <- list2env(mget(symbols.f))

IS <- lapply(tickers, "[[", "IncomeStatement")
BS <- lapply(tickers, "[[", "BalanceSheet")
CF <- lapply(tickers, "[[", "CashFlow")

IS <- as.data.frame(IS)
BS <- as.data.frame(BS)
CF <- as.data.frame(CF)

Nvidia’s Income Statement data.

IS %>%
  kable() %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
NVDA.f.1.27.2019 NVDA.f.1.28.2018 NVDA.f.1.29.2017 NVDA.f.1.31.2016
Total Revenue 11716000 9714000 6910000 5010000
Cost of Revenue 4545000 3892000 2847000 2199000
Gross Profit 7171000 5822000 4063000 2811000
Research Development 2376000 1797000 1463000 1331000
Selling General and Administrative 991000 815000 663000 602000
Non Recurring NA NA NA NA
Others NA NA NA NA
Total Operating Expenses 7912000 6504000 4973000 4132000
Operating Income or Loss 3804000 3210000 1937000 878000
Total Other Income/Expenses Net 92000 -14000 -32000 -135000
Earnings Before Interest and Taxes 3804000 3210000 1937000 878000
Interest Expense -58000 -61000 -58000 -47000
Income Before Tax 3896000 3196000 1905000 743000
Income Tax Expense -245000 149000 239000 129000
Minority Interest NA NA NA NA
Net Income From Continuing Ops 4141000 3047000 1666000 614000
Discontinued Operations NA NA NA NA
Extraordinary Items NA NA NA NA
Effect Of Accounting Changes NA NA NA NA
Other Items NA NA NA NA
Net Income 4141000 3047000 1666000 614000
Preferred Stock And Other Adjustments NA NA NA NA
Net Income Applicable To Common Shares 4141000 3047000 1666000 614000

Nvidia’s Balance Sheet Information.

BS %>%
  kable() %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
NVDA.f.1.27.2019 NVDA.f.1.28.2018 NVDA.f.1.29.2017 NVDA.f.1.31.2016
Cash And Cash Equivalents 782000 4002000 1766000 596000
Short Term Investments 6640000 3106000 5032000 4441000
Net Receivables 1424000 1265000 826000 505000
Inventory 1575000 796000 794000 418000
Other Current Assets NA NA NA NA
Total Current Assets 10557000 9255000 8536000 6053000
Long Term Investments NA NA NA NA
Property, plant and equipment 1404000 997000 521000 466000
Goodwill 618000 618000 618000 618000
Intangible Assets 45000 52000 104000 166000
Accumulated Amortization NA NA NA NA
Other Assets 668000 319000 62000 67000
Deferred Long Term Asset Charges 560000 245000 NA NA
Total Assets 13292000 11241000 9841000 7370000
Accounts Payable 511000 596000 485000 296000
Short/Current Long Term Debt NA 15000 796000 1413000
Other Current Liabilities 588000 318000 325000 532000
Total Current Liabilities 1329000 1153000 1788000 2351000
Long Term Debt 1988000 1985000 1983000 7000
Other Liabilities 633000 632000 308000 533000
Deferred Long Term Liability Charges NA NA NA NA
Minority Interest NA NA NA NA
Negative Goodwill NA NA NA NA
Total Liabilities 3950000 3770000 4079000 2901000
Misc. Stocks Options Warrants NA NA NA NA
Redeemable Preferred Stock NA NA NA NA
Preferred Stock NA NA NA NA
Common Stock 1000 1000 1000 1000
Retained Earnings 12565000 8787000 6108000 4350000
Treasury Stock -9275000 -6668000 -5055000 -4052000
Capital Surplus 6051000 5351000 4708000 4170000
Other Stockholder Equity -12000 -18000 -16000 -4000
Total stockholders’ equity 9342000 7471000 5762000 4469000
Net Tangible Assets 8679000 6801000 5040000 3685000

Nvidia’s Cash Flow Statements

CF %>%
  kable() %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
NVDA.f.1.27.2019 NVDA.f.1.28.2018 NVDA.f.1.29.2017 NVDA.f.1.31.2016
Net Income 4141000 3047000 1666000 614000
Depreciation 262000 199000 187000 197000
Adjustments To Net Income 197000 71000 498000 386000
Changes In Accounts Receivables -149000 -440000 -321000 -32000
Changes In Liabilities -135000 90000 184000 -11000
Changes In Inventories -776000 -776000 -375000 66000
Changes In Other Operating Activities 203000 535000 -167000 -74000
Total Cash Flow From Operating Activities 3743000 3502000 1672000 1175000
Capital Expenditure -600000 -593000 -176000 -86000
Investments -3497000 1869000 -624000 -345000
Other Cash flows from Investing Activities NA NA -5000 24000
Total Cash Flows From Investing Activities -4097000 1278000 -793000 -400000
Dividends Paid -371000 -341000 -261000 -213000
Sale Purchase of Stock NA NA NA NA
Net Borrowings -16000 -812000 1315000 1315000
Other Cash Flows from Financing Activities -5000 -9000 -15000 4000
Total Cash Flows From Financing Activities -2866000 -2544000 291000 -676000
Effect Of Exchange Rate Changes NA NA NA NA
Change In Cash and Cash Equivalents -3220000 2236000 1170000 99000

Nvidia’s fundamentals looked solid after some analysis, but taking into account per share ratios, I changed my opinion. Their share price seemed overvalued compared to their business performance.

I wanted to track their performance and compare it to Nvidia’s competitors. I downloaded price data using the tidyquant package.

############### Collect the stock price and benchmark data #############

nvda <- "NVDA" %>%
  tq_get(get = "stock.prices",
         from =  "2017-01-01",
         to = Sys.Date())

amd <- "AMD" %>%
  tq_get(get = "stock.prices",
         from =  "2017-01-01",
         to = Sys.Date())

txn <- "TXN" %>%
  tq_get(get = "stock.prices",
         from =  "2017-01-01",
         to = Sys.Date())

intc <- "INTC" %>%
  tq_get(get = "stock.prices",
         from =  "2017-01-01",
         to = Sys.Date())

nasdaq <- "^IXIC" %>%
  tq_get(get = "stock.prices",
         from = "2017-01-01",
         to = Sys.Date())

Joining all the stock price data together along with a benchmark NASDAQ:

Stock Price Data

########## Join the data together ###########
# Ra is the asset price
# Rb is the benchmark price (NASDAQ)
RaRb <- nvda %>%
  full_join(., amd, by = "date") %>%
  full_join(., intc, by = "date") %>%
  full_join(., nasdaq, by = "date") %>%
  select(date, adjusted.x, adjusted.y, adjusted.x.x, adjusted.y.y) %>%
  setNames(c("date", "NVDA", "AMD", "INTC", "NASDAQ"))

RaRb %>%
  head(6) %>%
  kable() %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
date NVDA AMD INTC NASDAQ
2017-01-03 101.0116 11.43 34.06019 5429.08
2017-01-04 103.3683 11.43 33.88338 5477.00
2017-01-05 100.7443 11.24 33.82755 5487.94
2017-01-06 102.0910 11.32 33.94852 5521.06
2017-01-09 106.2301 11.49 34.06950 5531.82
2017-01-10 105.4280 11.44 34.00436 5551.82

It’s still quite difficult to compare Nvidia’s performance based on the raw stock price data, so I normalise the data.

############# Normalise the data ################## 
normalise_series <- function(xdat) xdat / coredata(xdat)[1]

normalised_RaRb <- RaRb %>%
  mutate(NVDA = normalise_series(NVDA),
         AMD = normalise_series(AMD),
         INTC = normalise_series(INTC),
         NASDAQ = normalise_series(NASDAQ))

The first few observations normalised

normalised_RaRb %>%
  head() %>%
  kable() %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
date NVDA AMD INTC NASDAQ
2017-01-03 1.0000000 1.0000000 1.0000000 1.000000
2017-01-04 1.0233309 1.0000000 0.9948089 1.008827
2017-01-05 0.9973533 0.9833771 0.9931697 1.010842
2017-01-06 1.0106853 0.9903762 0.9967214 1.016942
2017-01-09 1.0516616 1.0052493 1.0002734 1.018924
2017-01-10 1.0437212 1.0008749 0.9983608 1.022608

The last few observations normalised

normalised_RaRb %>%
  tail() %>%
  kable() %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
date NVDA AMD INTC NASDAQ
2019-09-18 1.781775 2.661417 1.519076 1.506220
2019-09-19 1.751679 2.650044 1.514084 1.507231
2019-09-20 1.709605 2.629046 1.489129 1.495220
2019-09-23 1.730890 2.680665 1.494413 1.494260
2019-09-24 1.708021 2.582677 1.462705 1.472373
2019-09-25 1.764450 2.584427 1.497936 1.487800

The data looks a lot more comparable. I plot the results in ggplot2

normalised_RaRb %>%
  melt(id = "date") %>%
  ggplot(aes(x = date, y = value, color = variable)) +
  geom_line(aes(linetype = variable)) +
  #scale_color_manual(values=c("red", "black", "darkblue", "yellow", "green")) +
  labs(title = "Normalised NVDA, AMD, INTC and NASDAQ Benchmark",
       x = "", subtitle = "From January 2017 - to Sys.Date()", y = "Normalised Price US$", color = "") +
  scale_y_continuous(labels = scales::dollar) +
  theme_tq(base_size = 8) +
  geom_dl(aes(label = variable), method = list(dl.combine("last.points"), cex = 1)) +
  scale_color_manual(values = c(NASDAQ = 'black',
                                NVDA = 'darkgreen',
                                AMD = 'red',
                                INTC = 'blue')) +
  theme(legend.position = "none")

So $1 invested in Nvidia back in Jan 2017 would have given you aprox $2.75 return if you sold at the back end of 2018, however the price today would be around $1.60. Compare that with AMD you would have got the same return of $2.75 if you sold at the same time as Nvidia but today your return would be more or less the same at aprox $2.75 despite a drop in AMD’s share price at the same time as NVDA.

Avatar
Matthew Smith
Researcher in Dept Finance

I am a researcher with a focus on Machine Learning methods applied to economics and finance.

Related

comments powered by Disqus