# Load necessary libraries
require("httr")
## Loading required package: httr
require("highcharter")
## Loading required package: highcharter
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
require("quantmod")
## Loading required package: quantmod
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: TTR
require("scales")
## Loading required package: scales
require("DT")
## Loading required package: DT
# Set options for highcharter
hcoptslang <- getOption("highcharter.lang")
hcoptslang$thousandsSep <- ","
options(highcharter.lang = hcoptslang)

# *****************************************************************************************************************************
#                   Get Financials : Income Statement, Cash Flow Statement, & Balance Sheet
# *****************************************************************************************************************************
#'@param symbol = ticker symbol
#'@param AQ = Annual (A) or Quarterly (Q) 
#'@param FS = Financial Statement (FS): Income Statement (I), Balance Sheet (B), Cash Flow (C) 
getFins = function(symbol, AQ, FS){
  URL = paste0('https://finviz.com/api/statement.ashx?t=',symbol,'&so=F&s=',FS,AQ)
  
  headers = c(
    'Host'= 'finviz.com',
    'User-Agent'= 'Mozilla/5.0',
    'Accept'= '*/*',
    'Referer'= paste0('https://finviz.com/quote.ashx?t=', symbol),
    'Connection'= 'keep-alive'
  )

  pg = httr::GET(url = URL, add_headers(headers))
  res = httr::content(pg)
  
  if (is.null(res$data)) {
    stop("No financial data found for ", symbol)
  }
  
  tbl = unlist(res$data)
  
  if (length(tbl) == 0) {
    stop("Financial data is empty for ", symbol)
  }
  
  rName = gsub("1","",unique(names(tbl)[seq(1,length(tbl),8)]))
  df = matrix(tbl, ncol = 8, byrow = TRUE)
  df = data.frame(df, row.names = rName)
  
  colnames(df) = df[1,]
  df = df[-1,]
  
  dfn = data.frame(apply(df, 2, function(x) as.numeric(gsub("\\,", "", x))), row.names = rownames(df))
  colnames(dfn) = colnames(df)
  
  dfn = dfn[rowSums(is.na(dfn)) != ncol(dfn),]
  return(dfn)
}

# *****************************************************************************************************************************
#                             Plot Financial Trends
# *****************************************************************************************************************************

#'@param ticker = ticker symbol
#'@param WHAT = Metric to plot ('Total Revenue', 'Net Income', 'Total Liabilities')
#'@param FROM = Data source
plotTrends = function(ticker, WHAT, FROM){
  dta <- subset(FROM, row.names(FROM) == WHAT)
  
  if (nrow(dta) == 0) {
    stop("No data found for ", WHAT)
  }
  
  dta <- rev(dta)
  dta = as.data.frame(t(dta))
  dta$date = row.names(dta)
  
  dta = data.frame(date=format(as.Date(dta$date,"%m/%d/%Y"), "%b %d '%y"), value = dta[,1])
  dta$pct_change = c(NA, diff(dta$value) / head(dta$value, -1))
  dta$yoy_change = c(rep(NA, 4), diff(dta$value, lag = 4) / head(dta$value, -4))
  
  dta %>% 
    hchart('column', hcaes(x = 'date', y = 'value'), name="Value") %>%
    hc_title(text=paste0(ticker, ": ", WHAT), align="center") %>%
    hc_yAxis_multiples(list(title = list(text = "Value"), opposite = FALSE),
                       list(showLastLabel = FALSE, opposite = TRUE, title = list(text = "% Change"), min=-100, max=100)) %>%
    hc_add_series(round(dta$yoy_change * 100, 2), yAxis=1, name="YoY % Change") %>%
    hc_add_series(round(dta$pct_change * 100, 2), yAxis=1, name="QoQ % Change")
}

# *****************************************************************************************************************************
#                       Convert Balance Sheet to Percentages
# *****************************************************************************************************************************
pctBS = function(BS){
  rownames(BS)[is.na(rownames(BS))] <- paste0("Row_", seq_len(sum(is.na(rownames(BS)))))  
  BS <- BS[rowSums(is.na(BS)) != ncol(BS), ]
  
  i = which(rownames(BS) == "Total Assets")      
  j = which(rownames(BS) == "Total Liabilities") 
  k = which(rownames(BS) == "Total Equity") 

  if (length(i) == 0 | length(j) == 0 | length(k) == 0) {
    stop("Missing key financial values (Assets, Liabilities, Equity).")
  }

  BS_numeric <- data.frame(lapply(BS, function(x) as.numeric(gsub(",", "", x))), row.names = rownames(BS))

  total_assets_divisor <- as.numeric(BS_numeric[i, ])
  total_liab_divisor <- as.numeric(BS_numeric[j, ])
  total_eqt_divisor <- as.numeric(BS_numeric[k, ])

  total_assets_divisor[total_assets_divisor == 0] <- NA
  total_liab_divisor[total_liab_divisor == 0] <- NA
  total_eqt_divisor[total_eqt_divisor == 0] <- NA

  total_assets <- sweep(BS_numeric[1:i, ], 2, total_assets_divisor, "/")
  total_liab <- sweep(BS_numeric[(i+1):j, ], 2, total_liab_divisor, "/")
  total_eqt <- sweep(BS_numeric[(j+1):k, ], 2, total_eqt_divisor, "/")

  total_assets <- apply(total_assets, 2, scales::percent, accuracy = 0.01, na.rm = TRUE)
  total_liab <- apply(total_liab, 2, scales::percent, accuracy = 0.01, na.rm = TRUE)
  total_eqt <- apply(total_eqt, 2, scales::percent, accuracy = 0.01, na.rm = TRUE)

  BS_pct <- rbind(data.frame(total_assets), data.frame(total_liab), data.frame(total_eqt))
  rownames(BS_pct) <- c(rownames(BS)[1:i], rownames(BS)[(i+1):j], rownames(BS)[(j+1):k])

  return(BS_pct)
}

# *****************************************************************************************************************************
#                     Get Netflix Financials and Plot Trends
# *****************************************************************************************************************************

ticker <- "NFLX"

# Get financials
NFLX_IS <- getFins(ticker, "A", "I")  # Income Statement
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
## Warning in FUN(newX[, i], ...): NAs introduced by coercion
NFLX_BS <- getFins(ticker, "A", "B")  # Balance Sheet

# Plot trends
plotTrends(ticker, "Total Revenue", NFLX_IS)
plotTrends(ticker, "Net Income", NFLX_IS)
plotTrends(ticker, "Total Liabilities", NFLX_BS)
# Convert balance sheet to percentages
NFLX_BS_pct <- pctBS(NFLX_BS)

# Display Data Table
datatable(NFLX_BS_pct, options = list(pageLength = 10, autoWidth = TRUE))