Updating to latest version of labs

This commit is contained in:
John Lam 2017-05-09 09:30:39 -07:00
Родитель 925369cce1
Коммит bce5c59aad
6 изменённых файлов: 430 добавлений и 120 удалений

Двоичный файл не отображается.

Просмотреть файл

@ -6,11 +6,13 @@ library(rhandsontable)
starting.investment = 100000
start.date = "2017-01-01"
compute.portfolio.daily.book.value <- function(portfolio, dollars) {
portfolio <- cbind(portfolio, dollars = portfolio$percentage * dollars)
compute.portfolio.daily.market.value <- function(portfolio, dollars) {
portfolio <- cbind(
portfolio,
dollars = portfolio$percentage * dollars)
df <- NULL
compute.daily.book.value <- function(symbol, dollars) {
compute.daily.market.value <- function(symbol, dollars) {
symbol.data <- getSymbols(
symbol,
@ -18,28 +20,25 @@ compute.portfolio.daily.book.value <- function(portfolio, dollars) {
from = start.date)
shares <- dollars / as.numeric(first(Op(symbol.data)))
book.value <- Ad(symbol.data) * shares
market.value <- Ad(symbol.data) * shares
if (is.null(df)) {
df <<- data.frame(book.value)
df <<- data.frame(market.value)
}
else {
df <<- cbind(df, data.frame(book.value))
df <<- cbind(df, data.frame(market.value))
}
}
mapply(compute.daily.book.value, portfolio$symbols, portfolio$dollars)
# Compute totals for each day
mapply(
compute.daily.market.value,
portfolio$symbols,
portfolio$dollars)
return(cbind(df, data.frame(Total = rowSums(df))))
}
convert.totals.dataframe.to.xts <- function(df) {
return(xts(df$Total, as.POSIXct(rownames(df))))
}
function(input, output) {
shinyServer(function(input, output) {
v <- reactiveValues(portfolio = NULL, index = NULL)
@ -52,8 +51,10 @@ function(input, output) {
portfolio = hot_to_r(input$hot)
v$portfolio <- compute.portfolio.daily.book.value(portfolio, starting.investment)
v$index <- compute.portfolio.daily.book.value(
v$portfolio <- compute.portfolio.daily.market.value(
portfolio,
starting.investment)
v$index <- compute.portfolio.daily.market.value(
data.frame(
symbols = c("QQQ"),
percentage = c(1.0),
@ -61,14 +62,21 @@ function(input, output) {
),
starting.investment
)
print(v$index)
})
convert.totals.dataframe.to.xts <- function(df) {
return(xts(df$Total, as.POSIXct(rownames(df))))
}
output$chart <- renderHighchart({
if (is.null(v$portfolio) || is.null(v$index)) return()
highchart(type = "stock") %>%
hc_add_series(convert.totals.dataframe.to.xts(v$portfolio), name = "Portfolio") %>%
hc_add_series(convert.totals.dataframe.to.xts(v$index), name = "QQQ") %>%
hc_add_series(
data = convert.totals.dataframe.to.xts(v$portfolio),
name = "Portfolio") %>%
hc_add_series(
data = convert.totals.dataframe.to.xts(v$index),
name = "QQQ") %>%
hc_add_theme(hc_theme_538())
})
@ -85,4 +93,4 @@ function(input, output) {
rhandsontable(portfolio) %>%
hot_table(highlightCol = TRUE, highlightRow = TRUE)
})
}
})

Просмотреть файл

@ -4,103 +4,205 @@
library(quantmod)
# We are comparing our performance against QQQ
# which tracks the Nasdaq 100
# which tracks the Nasdaq 100 index. Run the lines of code
# below to get all the data from the beginning of the year.
start.date <- "2017-01-01"
QQQ <- getSymbols("QQQ", auto.assign = FALSE, from = start.date)
# View this in variable explorer
# Open table viewer
# Export to Excel
# View the contents of the data frame in variable explorer. Try:
#
# 1. Clicking on the chevron to the left of the QQQ variable to
# drill down into its internal structure.
#
# 2. Clicking on the hourglass icon to the right of the QQQ
# variable to open up the data in the Data Table viewer.
#
# 3. Clicking on the Excel icon to the right of the QQQ variable
# to open the data frame in Excel.
# Now lets plot QQQ for the YTD using the HighCharter package
# You should see a chart open up in the default browser, showing
# a plot of the Open, High, Low, and Close prices for each date.
# Note that the highcharter package is simply a wrapper around
# the HighChart commercial library. See more at
# https://highcharts.com.
library(highcharter)
# Notice the %>% operator. It's also known as the "pipe" operator
# which lets you chain together multiple function calls into a
# single statement. It's provided by the magrittr library.
highchart(type = "stock") %>%
hc_add_series(QQQ, type = "ohlc")
# Let's get another stock MSFT and plot that in a comparison chart
# Next, let's grab data for another stock, MSFT, and create a chart
# that compares the performance of MSFT vs. the QQQ S&P100 index.
MSFT <- getSymbols("MSFT", auto.assign = FALSE, from = start.date)
# Here, we generate a chart, showing both stocks head-to-head.
# However, because the stock prices are at different scales, it's
# hard to see a clear analysis of their performance. Also
# notice how we've added the 538 (from 538.com) theme to the plot.
highchart(type = "stock") %>%
hc_add_series(QQQ, type = "ohlc") %>%
hc_add_series(MSFT) %>%
hc_add_theme(hc_theme_538())
# So we need to transform our data so that we look at the increase
# in value of a portfolio invested equally between the two
# series that we want to visualize. Before we can perform
# calculations, we first need to take a look at the data structures.
# Let's examine the data again in QQQ. You can see that it contains
# open, high, low, close, volume, and adjusted prices.
# open, high, low, close, volume, and adjusted prices. The command
# below first converts QQQ to a data frame so that we can visualize
# it using our built in data grid viewer. Experiment with the grid
# to play with the different features that it offers!
View(as.data.frame(QQQ))
# We really are only interested in the adjusted prices at close
# for the purposes of computing daily returns, which we can
# extract using the Ad() function
# for the purposes of computing daily returns. We can extract the
# adjusted prices column from the time series using the Ad()
# function. Note that in R, the "." is just part of the variable
# name; it has no semantic meaning.
QQQ.adjusted <- Ad(QQQ)
# Let's view the first few rows of the xts result set. We can see
# that it contains both dates and the adjusted price for QQQ.
# that it contains both dates and the adjusted price for QQQ. The
# dates are part of the row labels (each row can have a label)
# associated with it, and it's not a separate column. You can
# extract the row labels using the rownames() function, which
# we will see later in this lab.
View(as.data.frame(QQQ.adjusted))
# Now let's compute returns by buying a certain number of shares of the stock
# Now let's compute returns by buying a certain number of shares
# of the stock
starting.investment = 100000
# Compute the number of shares we can buy by dividing starting investment by opening price
# Compute the number of shares we can buy by dividing starting
# investment by opening price in the time period
MSFT.starting.shares = starting.investment / as.numeric(first(Op(MSFT)))
QQQ.starting.shares = starting.investment / as.numeric(first(Op(QQQ)))
# Now compute the daily adjusted book value of our shares
# This is a vector * scalar which yields another vector
# Now compute the daily adjusted market value of our shares
# This is a vector * scalar which yields another vector. Put
# another way, we are multiplying each row in the adjusted closing
# price by the # shares that we hold.
MSFT.daily.book.value = Ad(MSFT) * MSFT.starting.shares
QQQ.daily.book.value = Ad(QQQ) * QQQ.starting.shares
MSFT.daily.market.value = Ad(MSFT) * MSFT.starting.shares
QQQ.daily.market.value = Ad(QQQ) * QQQ.starting.shares
# Now let's plot the value of our investments in QQQ vs. MSFT
# on a single chart to see which one wins.
highchart(type = "stock") %>%
hc_add_series(QQQ.daily.book.value, name = "QQQ") %>%
hc_add_series(MSFT.daily.book.value, name = "MSFT") %>%
hc_add_series(QQQ.daily.market.value, name = "QQQ") %>%
hc_add_series(MSFT.daily.market.value, name = "MSFT") %>%
hc_add_theme(hc_theme_538())
# Now let's compute the book value based on the amount invested in a stock
# Now let's compute the market value based on the amount invested
# in an arbitrary stock. We'll define a new function,
# compute.daily.market.value(), which takes a symbol, the amount
# invested in it and returns a list that contains the market
# value for each day in the investment range.
compute.daily.book.value <- function(symbol, dollars) {
symbol.data <- getSymbols(symbol, auto.assign = FALSE, from = start.date)
# There are some new notable R features in this example:
# 1. Functions are defined as values
# 2. The return statement returns the result of an expression. If
# you don't use return, then the value of the last evaluated
# expression will be returned from your function.
# When you run the function, you can either:
# 1. Select all the code in the editor and press CTRL+ENTER to
# send it in one chunk to the REPL.
# 2. Send one line at a time by repeatedly pressing CTRL+ENTER
# to see our multi-line support in the REPL. You'll see this
# in the "+" characters running down the left margin to
# indicate that you're continuing the current block of code
# in the REPL.
compute.daily.market.value <- function(symbol, dollars) {
symbol.data <- getSymbols(
symbol,
auto.assign = FALSE,
from = start.date)
shares <- dollars / first(Op(symbol.data))
return(Ad(symbol.data) * shares)
}
# Now, let's get the daily returns, expressed as a percentage
# gain or loss, based on the adjusted prices
# gain or loss, based on the adjusted prices. All we have to
# do now is call the compute.daily.market.value() with the
# name of the symbol, and the starting investment.
QQQ.daily.book.value <- compute.daily.book.value("QQQ", starting.investment)
View(as.data.frame(QQQ.daily.book.value))
QQQ.daily.market.value <- compute.daily.market.value(
"QQQ",
starting.investment)
# Let's test it on TSLA
View(as.data.frame(QQQ.daily.market.value))
TSLA.daily.book.value <- compute.daily.book.value("TSLA", starting.investment)
View(TSLA.daily.book.value)
# Now let's do the same thing for an equal weight portfolio
# of FANG (Facebook, Amazon, Netflix, Google). Let's define
# a data frame that contains two columns: symbols and percentage
# that represent the stock symbol names and their percentage
# weight in the portfolio (these ideally add up to 1.0 -
# enforcing that is an exercise left to the reader).
TSLA.cumulative.returns <- cumsum(TSLA.daily.returns * starting.investment)
head(TSLA.cumulative.returns)
# Now let's do the same thing for an equal weight portfolio of FANG
# You will notice that there is a peculiar named parameter in
# the call to the data.frame() function to define the data frame.
# stringsAsFactors is something you'll run into often in R -
# by default, R interprets character strings as Factors. These
# are roughly analogous to enumeration values in other languages.
# You get better performance, but these values are not treated
# as strings. This parameter forces the data.frame() function to
# treat the list of strings assigned to the symbols column as
# strings and not factors.
portfolio <- data.frame(
symbols = c("FB", "AMZN", "NFLX", "GOOG"),
percentage = c(0.25, 0.25, 0.25, 0.25),
stringsAsFactors = FALSE)
# We need to adjust our daily book value function to compute against portfolio of stocks
# Now we need to change our daily market value function to compute
# against portfolio of stocks rather than a single stock.
compute.portfolio.daily.market.value <- function(portfolio, dollars) {
# The cbind() function binds two dataframes together by column.
# In this case, we're appending a new column, dollars, to
# the portfolio dataframe. That column contains the result
# of muliplying each row in the percentage column against the
# dollars scalar value.
# Note that there are no explicit loops here. In general, if
# you find yourself writing a loop in R, you're probably
# doing it wrong :)
portfolio <- cbind(
portfolio,
dollars = portfolio$percentage * dollars)
# We define a variable here in the middle of the body of
# the compute.portfolio.daily.market.value() function. Because
# R supports lexical scoping, this variable can be manipulated
# from within the compute.daily.market.value() function that
# is defined immediately below it.
compute.portfolio.daily.book.value <- function(portfolio, dollars) {
portfolio <- cbind(portfolio, dollars = portfolio$percentage * dollars)
df <- NULL
compute.daily.book.value <- function(symbol, dollars) {
# This is a nested function. It can access variables in
# the enclosing scope by using the <<- operator.
compute.daily.market.value <- function(symbol, dollars) {
symbol.data <- getSymbols(
symbol,
@ -108,46 +210,93 @@ compute.portfolio.daily.book.value <- function(portfolio, dollars) {
from = start.date)
shares <- dollars / as.numeric(first(Op(symbol.data)))
book.value <- Ad(symbol.data) * shares
market.value <- Ad(symbol.data) * shares
# Here, we use the <<- operator to either:
# 1. Assign a new data frame if one didn't exist already
# 2. Append a new column to the existing data frame.
if (is.null(df)) {
df <<- data.frame(book.value)
df <<- data.frame(market.value)
}
else {
df <<- cbind(df, data.frame(book.value))
df <<- cbind(df, data.frame(market.value))
}
}
mapply(compute.daily.book.value, portfolio$symbols, portfolio$dollars)
# This is how we iterate over all of the rows in the
# portfolio data frame. We pass the symbols column to
# the compute.daily.market.value() function by dereferencing
# it using the $ operator. Similarly, we pass the dollars
# column as well. When this function returns, the df
# variable will now hold a new data frame containing the
# daily market values of all of the stocks in the portfolio.
# Compute totals for each day
mapply(
compute.daily.market.value,
portfolio$symbols,
portfolio$dollars)
# Compute totals for each day using the rowSums function.
# Here we create a new data frame that contains a column
# called Total, which contains the sum of the daily
# market values of each of the stock symbols.
df <- cbind(
df,
data.frame(Total = rowSums(df)))
df <- cbind(df, data.frame(Total = rowSums(df)))
return(df)
}
portfolio.daily.book.value <- compute.portfolio.daily.book.value(portfolio, starting.investment)
# Here's a single function call that computes the daily market
# value of our portfolio.
portfolio.daily.market.value <- compute.portfolio.daily.market.value(
portfolio,
starting.investment)
# Let's define another "portfolio", but this time it contains only
# a single stock - QQQ which represents the NASDAQ 100 index.
index <- data.frame(
symbols = c("QQQ"),
percentage = c(1.0),
stringsAsFactors = FALSE)
index.daily.book.value <- compute.portfolio.daily.book.value(index, starting.investment)
index.daily.market.value <- compute.portfolio.daily.market.value(
index,
starting.investment)
# Now let's plot the two curves against each other
# This loses the date labels - better to remove columns?
# Our daily market value results are in a data frame.
# We need to convert them to an xts object (time series object)
# so that the dates display correctly in the plots. We didn't
# need to do this in our previous single-stock calculations
# because we modified an existing xts object in-place. In our
# new portfolio base calculation, we are computing a new data
# frame from scratch, hence the need to convert it to
# an xts object using the labels from the data frame that
# contain the identity of each trading day.
convert.totals.dataframe.to.xts <- function(df) {
return(xts(df$Total, as.POSIXct(rownames(df))))
return(
xts(
df$Total,
as.POSIXct(rownames(df))))
}
# Plot the comparison chart between our portfolio and QQQ.
highchart(type = "stock") %>%
hc_add_series(convert.totals.dataframe.to.xts(index.daily.book.value), name = "QQQ") %>%
hc_add_series(convert.totals.dataframe.to.xts(portfolio.daily.book.value), name = "Portfolio") %>%
hc_add_series(
convert.totals.dataframe.to.xts(index.daily.market.value),
name = "QQQ") %>%
hc_add_series(
convert.totals.dataframe.to.xts(portfolio.daily.market.value),
name = "Portfolio") %>%
hc_add_theme(hc_theme_538())
# Now the next step in this is to turn this analysis into an applicatoin
# where you can pick the stocks to add to your asset allocation and their
# proportions. The constraint is that they must add up to 100% in your allocation.
# Hit the compute button to generate the results.
# Now the next step in this is to turn this analysis into an
# application where you can pick the stocks to add to your
# asset allocation and their percentages. See the next
# section in the lab manual for how to complete this part of the lab.

Просмотреть файл

@ -0,0 +1,10 @@
library(shiny)
library(quantmod)
library(highcharter)
library(rhandsontable)
shinyServer(function(input, output) {
observeEvent(input$go, {
print("Hello, World!")
})
})

Просмотреть файл

@ -0,0 +1,14 @@
library(shiny)
library(highcharter)
library(rhandsontable)
shinyUI(
fluidPage(
tags$link(rel = "stylesheet", type = "text/css", href = "https://bootswatch.com/paper/bootstrap.css"),
fluidRow(
column(width = 3, class = "panel",
actionButton("go", label = "Say Hello")
)
)
)
)

Просмотреть файл

@ -21,16 +21,18 @@ QQQ <- getSymbols("QQQ", auto.assign = FALSE, from = start.date)
# 3. Clicking on the Excel icon to the right of the QQQ variable
# to open the data frame in Excel.
# Now lets plot QQQ for the YTD using the HighCharter package
# You should see a chart open up in the default browser, showing
# a plot of the Open, High, Low, and Close prices for each date.
# Note that the highcharter package is simply a wrapper around
# the HighChart commercial library. See more at
# https://highcharts.com.
library(highcharter)
# Notice the %>% operator. It's also known as the "pipe" operator
# which lets you chain together multiple function calls into a
# single statement.
# single statement. It's provided by the magrittr library.
highchart(type = "stock") %>%
hc_add_series(QQQ, type = "ohlc")
@ -42,85 +44,165 @@ MSFT <- getSymbols("MSFT", auto.assign = FALSE, from = start.date)
# Here, we generate a chart, showing both stocks head-to-head.
# However, because the stock prices are at different scales, it's
# hard to see a clear analysis of their performance.
# hard to see a clear analysis of their performance. Also
# notice how we've added the 538 (from 538.com) theme to the plot.
highchart(type = "stock") %>%
hc_add_series(QQQ, type = "ohlc") %>%
hc_add_series(MSFT) %>%
hc_add_theme(hc_theme_538())
# So we need to transform our data so that we look at the increase
# in value of a portfolio invested equally between the two
# series that we want to visualize. Before we can perform
# calculations, we first need to take a look at the data structures.
# Let's examine the data again in QQQ. You can see that it contains
# open, high, low, close, volume, and adjusted prices.
# open, high, low, close, volume, and adjusted prices. The command
# below first converts QQQ to a data frame so that we can visualize
# it using our built in data grid viewer. Experiment with the grid
# to play with the different features that it offers!
View(as.data.frame(QQQ))
# We really are only interested in the adjusted prices at close
# for the purposes of computing daily returns, which we can
# extract using the Ad() function
# for the purposes of computing daily returns. We can extract the
# adjusted prices column from the time series using the Ad()
# function. Note that in R, the "." is just part of the variable
# name; it has no semantic meaning.
QQQ.adjusted <- Ad(QQQ)
# Let's view the first few rows of the xts result set. We can see
# that it contains both dates and the adjusted price for QQQ.
# that it contains both dates and the adjusted price for QQQ. The
# dates are part of the row labels (each row can have a label)
# associated with it, and it's not a separate column. You can
# extract the row labels using the rownames() function, which
# we will see later in this lab.
View(as.data.frame(QQQ.adjusted))
# Now let's compute returns by buying a certain number of shares of the stock
# Now let's compute returns by buying a certain number of shares
# of the stock
starting.investment = 100000
# Compute the number of shares we can buy by dividing starting investment by opening price
# Compute the number of shares we can buy by dividing starting
# investment by opening price in the time period
MSFT.starting.shares = starting.investment / as.numeric(first(Op(MSFT)))
QQQ.starting.shares = starting.investment / as.numeric(first(Op(QQQ)))
# Now compute the daily adjusted book value of our shares
# This is a vector * scalar which yields another vector
# Now compute the daily adjusted market value of our shares
# This is a vector * scalar which yields another vector. Put
# another way, we are multiplying each row in the adjusted closing
# price by the # shares that we hold.
MSFT.daily.book.value = Ad(MSFT) * MSFT.starting.shares
QQQ.daily.book.value = Ad(QQQ) * QQQ.starting.shares
MSFT.daily.market.value = Ad(MSFT) * MSFT.starting.shares
QQQ.daily.market.value = Ad(QQQ) * QQQ.starting.shares
# Now let's plot the value of our investments in QQQ vs. MSFT
# on a single chart to see which one wins.
highchart(type = "stock") %>%
hc_add_series(QQQ.daily.book.value, name = "QQQ") %>%
hc_add_series(MSFT.daily.book.value, name = "MSFT") %>%
hc_add_series(QQQ.daily.market.value, name = "QQQ") %>%
hc_add_series(MSFT.daily.market.value, name = "MSFT") %>%
hc_add_theme(hc_theme_538())
# Now let's compute the book value based on the amount invested in a stock
# Now let's compute the market value based on the amount invested
# in an arbitrary stock. We'll define a new function,
# compute.daily.market.value(), which takes a symbol, the amount
# invested in it and returns a list that contains the market
# value for each day in the investment range.
compute.daily.book.value <- function(symbol, dollars) {
symbol.data <- getSymbols(symbol, auto.assign = FALSE, from = start.date)
# There are some new notable R features in this example:
# 1. Functions are defined as values
# 2. The return statement returns the result of an expression. If
# you don't use return, then the value of the last evaluated
# expression will be returned from your function.
# When you run the function, you can either:
# 1. Select all the code in the editor and press CTRL+ENTER to
# send it in one chunk to the REPL.
# 2. Send one line at a time by repeatedly pressing CTRL+ENTER
# to see our multi-line support in the REPL. You'll see this
# in the "+" characters running down the left margin to
# indicate that you're continuing the current block of code
# in the REPL.
compute.daily.market.value <- function(symbol, dollars) {
symbol.data <- getSymbols(
symbol,
auto.assign = FALSE,
from = start.date)
shares <- dollars / first(Op(symbol.data))
return(Ad(symbol.data) * shares)
}
# Now, let's get the daily returns, expressed as a percentage
# gain or loss, based on the adjusted prices
# gain or loss, based on the adjusted prices. All we have to
# do now is call the compute.daily.market.value() with the
# name of the symbol, and the starting investment.
QQQ.daily.book.value <- compute.daily.book.value("QQQ", starting.investment)
View(as.data.frame(QQQ.daily.book.value))
QQQ.daily.market.value <- compute.daily.market.value(
"QQQ",
starting.investment)
# Let's test it on TSLA
View(as.data.frame(QQQ.daily.market.value))
TSLA.daily.book.value <- compute.daily.book.value("TSLA", starting.investment)
View(TSLA.daily.book.value)
# Now let's do the same thing for an equal weight portfolio
# of FANG (Facebook, Amazon, Netflix, Google). Let's define
# a data frame that contains two columns: symbols and percentage
# that represent the stock symbol names and their percentage
# weight in the portfolio (these ideally add up to 1.0 -
# enforcing that is an exercise left to the reader).
TSLA.cumulative.returns <- cumsum(TSLA.daily.returns * starting.investment)
head(TSLA.cumulative.returns)
# Now let's do the same thing for an equal weight portfolio of FANG
# You will notice that there is a peculiar named parameter in
# the call to the data.frame() function to define the data frame.
# stringsAsFactors is something you'll run into often in R -
# by default, R interprets character strings as Factors. These
# are roughly analogous to enumeration values in other languages.
# You get better performance, but these values are not treated
# as strings. This parameter forces the data.frame() function to
# treat the list of strings assigned to the symbols column as
# strings and not factors.
portfolio <- data.frame(
symbols = c("FB", "AMZN", "NFLX", "GOOG"),
percentage = c(0.25, 0.25, 0.25, 0.25),
stringsAsFactors = FALSE)
# We need to adjust our daily book value function to compute against portfolio of stocks
# Now we need to change our daily market value function to compute
# against portfolio of stocks rather than a single stock.
compute.portfolio.daily.market.value <- function(portfolio, dollars) {
# The cbind() function binds two dataframes together by column.
# In this case, we're appending a new column, dollars, to
# the portfolio dataframe. That column contains the result
# of muliplying each row in the percentage column against the
# dollars scalar value.
# Note that there are no explicit loops here. In general, if
# you find yourself writing a loop in R, you're probably
# doing it wrong :)
portfolio <- cbind(
portfolio,
dollars = portfolio$percentage * dollars)
# We define a variable here in the middle of the body of
# the compute.portfolio.daily.market.value() function. Because
# R supports lexical scoping, this variable can be manipulated
# from within the compute.daily.market.value() function that
# is defined immediately below it.
compute.portfolio.daily.book.value <- function(portfolio, dollars) {
portfolio <- cbind(portfolio, dollars = portfolio$percentage * dollars)
df <- NULL
compute.daily.book.value <- function(symbol, dollars) {
# This is a nested function. It can access variables in
# the enclosing scope by using the <<- operator.
compute.daily.market.value <- function(symbol, dollars) {
symbol.data <- getSymbols(
symbol,
@ -128,46 +210,93 @@ compute.portfolio.daily.book.value <- function(portfolio, dollars) {
from = start.date)
shares <- dollars / as.numeric(first(Op(symbol.data)))
book.value <- Ad(symbol.data) * shares
market.value <- Ad(symbol.data) * shares
# Here, we use the <<- operator to either:
# 1. Assign a new data frame if one didn't exist already
# 2. Append a new column to the existing data frame.
if (is.null(df)) {
df <<- data.frame(book.value)
df <<- data.frame(market.value)
}
else {
df <<- cbind(df, data.frame(book.value))
df <<- cbind(df, data.frame(market.value))
}
}
mapply(compute.daily.book.value, portfolio$symbols, portfolio$dollars)
# This is how we iterate over all of the rows in the
# portfolio data frame. We pass the symbols column to
# the compute.daily.market.value() function by dereferencing
# it using the $ operator. Similarly, we pass the dollars
# column as well. When this function returns, the df
# variable will now hold a new data frame containing the
# daily market values of all of the stocks in the portfolio.
# Compute totals for each day
mapply(
compute.daily.market.value,
portfolio$symbols,
portfolio$dollars)
# Compute totals for each day using the rowSums function.
# Here we create a new data frame that contains a column
# called Total, which contains the sum of the daily
# market values of each of the stock symbols.
df <- cbind(
df,
data.frame(Total = rowSums(df)))
df <- cbind(df, data.frame(Total = rowSums(df)))
return(df)
}
portfolio.daily.book.value <- compute.portfolio.daily.book.value(portfolio, starting.investment)
# Here's a single function call that computes the daily market
# value of our portfolio.
portfolio.daily.market.value <- compute.portfolio.daily.market.value(
portfolio,
starting.investment)
# Let's define another "portfolio", but this time it contains only
# a single stock - QQQ which represents the NASDAQ 100 index.
index <- data.frame(
symbols = c("QQQ"),
percentage = c(1.0),
stringsAsFactors = FALSE)
index.daily.book.value <- compute.portfolio.daily.book.value(index, starting.investment)
index.daily.market.value <- compute.portfolio.daily.market.value(
index,
starting.investment)
# Now let's plot the two curves against each other
# This loses the date labels - better to remove columns?
# Our daily market value results are in a data frame.
# We need to convert them to an xts object (time series object)
# so that the dates display correctly in the plots. We didn't
# need to do this in our previous single-stock calculations
# because we modified an existing xts object in-place. In our
# new portfolio base calculation, we are computing a new data
# frame from scratch, hence the need to convert it to
# an xts object using the labels from the data frame that
# contain the identity of each trading day.
convert.totals.dataframe.to.xts <- function(df) {
return(xts(df$Total, as.POSIXct(rownames(df))))
return(
xts(
df$Total,
as.POSIXct(rownames(df))))
}
# Plot the comparison chart between our portfolio and QQQ.
highchart(type = "stock") %>%
hc_add_series(convert.totals.dataframe.to.xts(index.daily.book.value), name = "QQQ") %>%
hc_add_series(convert.totals.dataframe.to.xts(portfolio.daily.book.value), name = "Portfolio") %>%
hc_add_series(
convert.totals.dataframe.to.xts(index.daily.market.value),
name = "QQQ") %>%
hc_add_series(
convert.totals.dataframe.to.xts(portfolio.daily.market.value),
name = "Portfolio") %>%
hc_add_theme(hc_theme_538())
# Now the next step in this is to turn this analysis into an applicatoin
# where you can pick the stocks to add to your asset allocation and their
# proportions. The constraint is that they must add up to 100% in your allocation.
# Hit the compute button to generate the results.
# Now the next step in this is to turn this analysis into an
# application where you can pick the stocks to add to your
# asset allocation and their percentages. See the next
# section in the lab manual for how to complete this part of the lab.