Let’s get Petronet LNG’s stock data; Petronet LNG’s ticker symbol at BSE is ‘PETRONET.BO’. We use the quantmod function getSymbols, and pass a string as a first argument to identify the desired ticker symbol, pass ‘yahoo’ to src for Yahoo!Finance, and from and to specify date ranges.

The default behavior for getSymbols is to load data directly into the global environment, with the object being named after the loaded ticker symbol. This feature may become deprecated in the future, but we exploit it now.

library(quantmod)
start <- as.POSIXct("2016-01-01")
end <- as.POSIXct("2017-03-29")
getSymbols(Symbols = "PETRONET.BO",src = "yahoo", from = start, to = end)
## [1] "PETRONET.BO"
class(PETRONET.BO)
## [1] "xts" "zoo"
head(PETRONET.BO)
##            PETRONET.BO.Open PETRONET.BO.High PETRONET.BO.Low
## 2015-12-31           248.10           257.40          247.00
## 2016-01-01           257.70           262.00          256.50
## 2016-01-04           258.95           258.95          249.00
## 2016-01-05           255.50           261.80          252.65
## 2016-01-06           261.00           272.00          261.00
## 2016-01-07           266.00           272.10          258.00
##            PETRONET.BO.Close PETRONET.BO.Volume PETRONET.BO.Adjusted
## 2015-12-31            254.85             391400               253.03
## 2016-01-01            259.00             212500               257.15
## 2016-01-04            249.60              85200               247.82
## 2016-01-05            260.05             177200               258.19
## 2016-01-06            266.75             272300               264.85
## 2016-01-07            262.95             369700               261.07
colnames(PETRONET.BO)
## [1] "PETRONET.BO.Open"     "PETRONET.BO.High"     "PETRONET.BO.Low"     
## [4] "PETRONET.BO.Close"    "PETRONET.BO.Volume"   "PETRONET.BO.Adjusted"

Yahoo! Finance provides six series with each security. Open is the price of the stock at the beginning of the trading day (it need not be the closing price of the previous trading day), high is the highest price of the stock on that trading day, low the lowest price of the stock on that trading day, and close the price of the stock at closing time. Volume indicates how many stocks were traded. Adjusted close (abreviated as “adjusted” by getSymbols()) is the closing price of the stock that adjusts the price of the stock for corporate actions. While stock prices are considered to be set mostly by traders, stock splits (when the company makes each extant stock worth two and halves the price) and dividends (payout of company profits per share) also affect the price of a stock and should be accounted for.

Visualizing Stock Data

plot(PETRONET.BO$"PETRONET.BO.Close", main = "Closing Prices of Petronet LNG")

hist(PETRONET.BO$"PETRONET.BO.High", breaks = 60, col = "orange")

A linechart is fine, but there are at least four variables involved for each date (open, high, low, and close), and we would like to have some visual way to see all four variables that does not require plotting four separate lines. Financial data is often plotted with a Japanese candlestick plot, so named because it was first created by 18th century Japanese rice traders. Use the function candleChart() from quantmod to create such a chart.

We may wish to plot multiple financial instruments together; we may want to compare stocks, compare them to the market, or look at other securities such as exchange-traded funds (ETFs). Later, we will also want to see how to plot a financial instrument against some indicator, like a moving average. For this you would rather use a line chart than a candlestick chart. (How would you plot multiple candlestick charts on top of one another without cluttering the chart?)

Let’s get the data for Hindalco & Dish TV

getSymbols(c("HINDALCO.BO", "DISHTV.BO"), src = "yahoo", from = start, to = end)
## [1] "HINDALCO.BO" "DISHTV.BO"
### Create an xts object (xts is loaded with quantmod) that contains closing prices for all the stocks.

stocks <- as.xts(data.frame(Petronet = PETRONET.BO$"PETRONET.BO.Close", Hindalco = HINDALCO.BO$"HINDALCO.BO.Close",Dishtv = DISHTV.BO$"DISHTV.BO.Close"))
head(stocks)
##            PETRONET.BO.Close HINDALCO.BO.Close DISHTV.BO.Close
## 2015-12-31            254.85             84.75          101.50
## 2016-01-01            259.00             84.85          102.30
## 2016-01-04            249.60             80.85          100.30
## 2016-01-05            260.05             82.80          100.20
## 2016-01-06            266.75             80.50          103.70
## 2016-01-07            262.95             76.70           98.05

Create a plot showing all series as lines; must use as.zoo to use the zoo method for plot, which allows for multiple series to be plotted on same plot

plot(as.zoo(stocks),screens = 1,lty = c(1,3,5),col = c("red","blue","green") ,xlab = "Date",ylab = "Price")
legend("top",c("Petronet","Hindalco","Dishtv"),lty = c(1,3,5),col = c("red","blue","green"),cex = 0.5)

What’s wrong with this chart? While absolute price is important (pricey stocks are difficult to purchase, which affects not only their volatility but your ability to trade that stock), when trading, we are more concerned about the relative change of an asset rather than its absolute price. Petronet’s stocks are much more expensive than Hindalco’s or Dishtv’s, and this difference makes Hindalco’s and Dishtv’s stocks appear much less volatile than they truly are (that is, their price appears to not deviate much).

One solution would be to use two different scales when plotting the data; one scale will be used by Hindalco and Dishtv stocks, and the other by Petronet.

plot(as.zoo(stocks[,c("HINDALCO.BO.Close","DISHTV.BO.Close")]),screens = 1,lty = c(1,3), col = c("blue","green"),xlab = "Date",ylab = "Price")
par(new =TRUE)
plot(as.zoo(stocks$"PETRONET.BO.Close"),screens = 1,lty = 5, col = "red",xlab = "",ylab = "", xaxt = "n", yaxt = "n")
axis(4)
mtext("Price", side = 4, line = 3)
legend("topleft",c("Hindalco(left)","Dishtv(left)","Petronet(right)"),lty = c(1,3,5),cex = 0.5)

Not only is this solution difficult to implement well, it is seen as a bad visualization method; it can lead to confusion and misinterpretation, and cannot be read easily.

A “better” solution, though, would be to plot the information we actually want: the stock’s returns. This involves transforming the data into something more useful for our purposes. There are multiple transformations we could apply.

One transformation would be to consider the stock’s return since the beginning of the period of interest. In other words, we plot:

return(t,o) = Price(t)/ Price(o)

Scaling the Getting of Financial Data

library(tidyquant)
stock_list <- tibble(stock = c("PETRONET.BO","HINDALCO.BO","DISHTV.BO"))
stockinfo <- stock_list %>%
    tq_get(get = "stock.prices", from = start, to = end)
order.by=as.POSIXct(stockinfo$date)

Calculating Yearly Returns

stk <- as.tbl(stockinfo)
stk$date <- as.Date(stk$date)
stockinfo_returns_yearly <- stk %>% group_by(stock) %>% tq_transmute(ohlc_fun=Ad, mutate_fun = periodReturn, period = "yearly", col_rename = "AnnualReturns")
stockinfo_returns_yearly
## Source: local data frame [9 x 3]
## Groups: stock [3]
## 
##         stock       date AnnualReturns
##         <chr>     <date>         <dbl>
## 1 PETRONET.BO 2015-12-31     0.0000000
## 2 PETRONET.BO 2016-12-30     0.4531874
## 3 PETRONET.BO 2017-03-28     0.1165352
## 4 HINDALCO.BO 2015-12-31     0.0000000
## 5 HINDALCO.BO 2016-12-30     0.8411996
## 6 HINDALCO.BO 2017-03-28     0.2228313
## 7   DISHTV.BO 2015-12-31     0.0000000
## 8   DISHTV.BO 2016-12-30    -0.1655172
## 9   DISHTV.BO 2017-03-28     0.2827627

We can visualize the Annual Returns

stockinfo_returns_yearly %>%
    ggplot(aes(x = year(date), y = AnnualReturns, fill = stock)) +
    geom_bar(position = "dodge", stat = "identity") +
    labs(title = "Stock: Annual Returns \n Mutating at scale is quick and easy!",
         y = "Returns", x = "", color = "") +
    scale_y_continuous(labels = scales::percent) +
    theme_tq() +
    scale_fill_tq()+theme(plot.title = element_text(hjust = 0.5))