An Easy Way to Compute Portfolio Performance in R for Stocks and Crypto

Portfolio Performance in R for Stocks

### Install missing packages
list_of_used_packages <- c("quantmod", "tidyverse", "PerformanceAnalytics")
packages_to_install   <- list_of_used_packages[!(list_of_used_packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(packages_to_install)

### Include used packages
library(quantmod)              # Geting data from Yahoo Finance 
library(tidyverse)             # General data crunching 
library(PerformanceAnalytics)  # Portfolio calculations

### Defining Plot Size
options(repr.plot.width=6, repr.plot.height=3)

### Define a list of used stocks
stocks = c("AAPL", "MSFT", "BA", "V", "F", "FB", "AMZN", "NVDA", "GOOG")

### Get data for all stocks
stocks_data <- lapply(
  stocks, 
  function(s){
    
    # Get Data from yahoo as a data.frame
    data <- getSymbols(s, auto.assign = F, return.class='data.frame')
    
    # Keep only date and close
    data <- data.frame(
      date  = row.names(data), 
      close = Cl(data),
      stringsAsFactors = F
    )  
    
    # Calculate P&L
    data <- data %>%
      arrange(date) %>%
      mutate(
        pnl = replace_na(close / lag(close) - 1, 0)
      ) %>% 
      select(date, pnl)
    
    # Name pnl with a symbol
    names(data) <- c("date", s)
    
    data
  }
)

str(stocks_data)

# Join list of df together in 1 df
stocks_df <- stocks_data %>% 
  reduce(inner_join, by = "date")

row.names(stocks_df) <- stocks_df$date

stocks_df <- stocks_df %>%
  select(-date)

head(stocks_df)

### Calculate Portfolio Returns
portf <- Return.portfolio(stocks_df)
str(portf)

### Chart Cummulative Returns
chart.CumReturns(portf)

### Chart Drawdown
chart.Drawdown(portf)

### Annualized Returns
table.AnnualizedReturns(portf)

### Basic Portfolio Stats
table.Stats(portf)

### Monthly Returns Table
portf_monthly <- apply.monthly(portf, Return.cumulative)
table.CalendarReturns(portf_monthly)

### Portfolio With Custom Weigth
portf <- Return.portfolio(stocks_df, weights = c(0.1, 0.2, 0.15, 0.1, 0.15, 0.1, 0.05, 0.05, 0.05))
table.AnnualizedReturns(portf)

### Portfolio With Rebalancing
portf <- Return.portfolio(stocks_df, rebalance_on = "months")
table.AnnualizedReturns(portf)

### Output Wealth Index
portf <- Return.portfolio(stocks_df, wealth.index = TRUE)
head(portf)
tail(portf)

### Output Contributions
portf <- Return.portfolio(stocks_df, contribution = TRUE)
head(portf)

Portfolio Performance in R for Crypto

### Install missing packages
list_of_used_packages <- c("quantmod", "tidyverse", "PerformanceAnalytics", "jsonlite", "httr")
packages_to_install   <- list_of_used_packages[!(list_of_used_packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(packages_to_install)

### Include used packages
library(quantmod)              # Geting data from Yahoo Finance 
library(tidyverse)             # General data crunching 
library(PerformanceAnalytics)  # Portfolio calculations
library(jsonlite)              # Parsing JSON
library(httr)                  # Http requests

### Defining Plot Size
options(repr.plot.width=6, repr.plot.height=3)

### Define a list of used crypto
crypos = c("BTCUSDT", "ETHUSDT", "LTCUSDT", "BNBUSDT", "EOSUSDT", "XRPUSDT", "TRXUSDT")

### Get data for all stocks
crypos_data <- lapply(
  crypos, 
  function(c){
    
    url <- "https://api.binance.com/api/v1/klines"
    
    params <- list(
      interval = "1d",
      symbol  = c, 
      limit   = 1000
    )
    
    data <- as.data.frame(fromJSON(content(GET(url, query = params), as = "text")), stringsAsFactors = F)
    
    names(data) <- c("date", "open", "high", "low", "close", "volume", 
                     "close_time", "quote_aseet_volume", "number_of_trades", 
                     "taker_buy_base_asset_volume", "taker_buy_quote_asset_volume", "ignore")
    
    
    # Fix data types
    data <- data %>%
      mutate(
        date  = as.Date(as.POSIXct(as.numeric(date)  / 1000, origin="1970-01-01", tz = "UTC")),
        close = as.numeric(close), 
      )
    
    data <- data %>%
      arrange(date) %>%
      mutate(
        pnl = replace_na(close / lag(close) - 1, 0)
      ) %>%
      select(date, pnl)
    
    names(data) <- c("date", c)
    
    data
  }
)

str(crypos_data)

# Join list of df together in 1 df
crypos_df <- crypos_data %>% 
  reduce(inner_join, by = "date")

row.names(crypos_df) <- crypos_df$date

crypos_df <- crypos_df %>%
  select(-date)

head(crypos_df)

### Calculate Portfolio Returns
portf <- Return.portfolio(crypos_df)
str(portf)

### Chart Cummulative Returns
chart.CumReturns(portf)

### Chart Drawdown
chart.Drawdown(portf)

### Annualized Returns
table.AnnualizedReturns(portf)

### Basic Portfolio Stats
table.Stats(portf)

### Monthly Returns Table
portf_monthly <- apply.monthly(portf, Return.cumulative)
table.CalendarReturns(portf_monthly)

### Portfolio With Custom Weigth
portf <- Return.portfolio(crypos_df, weights = c(0.15, 0.2, 0.15, 0.1, 0.15, 0.1, 0.15))
table.AnnualizedReturns(portf)

### Portfolio With Rebalancing
portf <- Return.portfolio(crypos_df, rebalance_on = "months")
table.AnnualizedReturns(portf)

### Output Wealth Index
portf <- Return.portfolio(crypos_df, wealth.index = TRUE)
head(portf)
tail(portf)

### Output Contributions
portf <- Return.portfolio(crypos_df, contribution = TRUE)
head(portf)

Leave a Reply

Your email address will not be published. Required fields are marked *