# Load required libraries
library(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
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
# Define the ETFs
tickers <- c("0050.TW", "0056.TW", "006205.TW", "00646.TW")
# Set start and end dates
start_date <- "2015-12-14"
end_date <- "2018-12-28"
# Get historical data
getSymbols(tickers, from = start_date, to = end_date)
## Warning: 006205.TW contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## Warning: 00646.TW contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## [1] "0050.TW" "0056.TW" "006205.TW" "00646.TW"
# Combine adjusted closing prices into a single data frame
prices <- merge(Ad(`0050.TW`), Ad(`0056.TW`), Ad(`006205.TW`), Ad(`00646.TW`))
# Display the first few rows of the combined data
head(prices)
## X0050.TW.Adjusted X0056.TW.Adjusted X006205.TW.Adjusted
## 2015-12-14 45.62283 12.93674 31.06
## 2015-12-15 45.66124 13.02854 31.59
## 2015-12-16 46.35249 13.15705 31.60
## 2015-12-17 46.89013 13.33452 32.23
## 2015-12-18 46.65971 13.43243 32.18
## 2015-12-21 46.58291 13.48138 33.00
## X00646.TW.Adjusted
## 2015-12-14 19.61
## 2015-12-15 19.63
## 2015-12-16 19.89
## 2015-12-17 20.05
## 2015-12-18 19.85
## 2015-12-21 19.64
# Load required libraries
library(quantmod)
# Define the ETFs
tickers <- c("0050.TW", "0056.TW", "006205.TW", "00646.TW")
# Set start and end dates
start_date <- "2015-12-14"
end_date <- "2018-12-28"
# Get historical data
getSymbols(tickers, from = start_date, to = end_date)
## Warning: 006205.TW contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## Warning: 00646.TW contains missing values. Some functions will not work if
## objects contain missing values in the middle of the series. Consider using
## na.omit(), na.approx(), na.fill(), etc to remove or replace them.
## [1] "0050.TW" "0056.TW" "006205.TW" "00646.TW"
# Extract adjusted closing prices
adjusted_prices <- lapply(tickers, function(ticker) Ad(get(ticker)))
# Combine adjusted closing prices into a single data frame
prices <- do.call(merge, adjusted_prices)
# Convert prices to monthly returns
monthly_returns <- monthlyReturn(prices)
## Warning in to_period(xx, period = on.opts[[period]], ...): missing values
## removed from data
# View the first few rows of monthly returns
head(monthly_returns)
## monthly.returns
## 2015-12-31 0.022727313
## 2016-01-29 -0.054835514
## 2016-02-26 0.013185655
## 2016-03-31 0.026028112
## 2016-04-29 0.009639804
## 2016-05-31 0.022110580
# Calculate mean returns for each ETF
mean_returns <- colMeans(monthly_returns, na.rm = TRUE)
mean_returns
## monthly.returns
## 0.004846972
# Calculate standard deviation of returns for each ETF
sd_returns <- apply(monthly_returns, 2, sd, na.rm = TRUE)
sd_returns
## monthly.returns
## 0.03047291
# Calculate correlation matrix
correlation_matrix <- cor(monthly_returns, use = "pairwise.complete.obs")
correlation_matrix
## monthly.returns
## monthly.returns 1
# Calculate covariance matrix
covariance_matrix <- cov(monthly_returns, use = "pairwise.complete.obs")
covariance_matrix
## monthly.returns
## monthly.returns 0.0009285982
# Load required libraries
library(PortfolioAnalytics)
## Loading required package: foreach
## Loading required package: PerformanceAnalytics
##
## Attaching package: 'PerformanceAnalytics'
## The following object is masked _by_ '.GlobalEnv':
##
## prices
## The following object is masked from 'package:graphics':
##
## legend
library(magrittr) # Load magrittr explicitly
# Convert monthly returns to matrix form
returns_matrix <- as.matrix(monthly_returns)
# Create a portfolio specification object
portfolio_spec <- portfolio.spec(assets = colnames(returns_matrix))
# Add portfolio constraints (optional)
# For example, you can add constraints on weights, such as minimum and maximum weights
# Create an optimization objective to maximize the Sharpe ratio
opt_objective <- "Sharpe"
objective_name <- "Maximize_Sharpe"
# Create an optimization algorithm
opt_algorithm <- "ROI"
# Specify the risk-free rate
rf_rate <- 0
# Find the tangency portfolio
tangency_portfolio <- add.objective(portfolio_spec, type = opt_objective, name = objective_name)