Fahrial Hisyam 110021133 Homework 4 ETF Backtesting Exercisr
R.version
## _
## platform x86_64-w64-mingw32
## arch x86_64
## os mingw32
## crt ucrt
## system x86_64, mingw32
## status
## major 4
## minor 4.0
## year 2024
## month 04
## day 24
## svn rev 86474
## language R
## version.string R version 4.4.0 (2024-04-24 ucrt)
## nickname Puppy Cup
#Clear the workspace and load required libraries
rm(list = ls())
library(devtools)
## Loading required package: usethis
library(pacman)
library(reshape2)
library(xts)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(quantmod)
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(SIT)
library(curl)
## Using libcurl 8.3.0 with Schannel
# Read data from CSV file
etf6 <- read.table('C:/Users/user/Downloads/ETF6_20080101-20200430.csv', sep = ',', header = TRUE)
# Manipulate data
etf6 <- etf6[, -2]
colnames(etf6) <- c('id', 'date', 'price')
# Reshape data
etf6.l <- dcast(etf6, date ~ id)
## Using price as value column: use value.var to override.
# Convert to xts object
etf6.xts <- xts(etf6.l[, -1], order.by = as.Date(as.character(etf6.l$date), format = '%Y%m%d'))
# Define trading strategies
data <- new.env()
model <- list()
etf3 <- etf6.xts[, 1:3]
head(etf3)
## 0050 0052 0056
## 2008-01-02 39.6472 27.0983 14.5739
## 2008-01-03 38.9876 26.0676 14.3758
## 2008-01-04 38.9876 25.9346 14.4041
## 2008-01-07 37.2064 24.1391 14.1777
## 2008-01-08 37.5692 24.1391 14.3531
## 2008-01-09 38.2619 24.2721 14.4663
names(etf3)
## [1] "0050 " "0052 " "0056 "
colnames(etf3) <- c('e50', 'e52', 'e56')
names(etf3)
## [1] "e50" "e52" "e56"
p_load(reshape2, xts, quantmod)
etf6.l <- dcast(etf6, date~id)
## Using price as value column: use value.var to override.
head(etf6.l)
## date 0050 0052 0056 0061 006206 00638R
## 1 20080102 39.6472 27.0983 14.5739 NA NA NA
## 2 20080103 38.9876 26.0676 14.3758 NA NA NA
## 3 20080104 38.9876 25.9346 14.4041 NA NA NA
## 4 20080107 37.2064 24.1391 14.1777 NA NA NA
## 5 20080108 37.5692 24.1391 14.3531 NA NA NA
## 6 20080109 38.2619 24.2721 14.4663 NA NA NA
# Convert to xts object
etf6.xts <- xts(etf6.l[, -1], order.by = as.Date(as.character(etf6.l$date), format = '%Y%m%d'))
class(etf6.xts)
## [1] "xts" "zoo"
etf3 <- etf6.xts[, 1:3]
head(etf3)
## 0050 0052 0056
## 2008-01-02 39.6472 27.0983 14.5739
## 2008-01-03 38.9876 26.0676 14.3758
## 2008-01-04 38.9876 25.9346 14.4041
## 2008-01-07 37.2064 24.1391 14.1777
## 2008-01-08 37.5692 24.1391 14.3531
## 2008-01-09 38.2619 24.2721 14.4663
colnames(etf3) <- c('e50', 'e52', 'e56')
names(etf3)
## [1] "e50" "e52" "e56"
tail(etf3)
## e50 e52 e56
## 2020-04-23 80.90 62.65 26.34
## 2020-04-24 80.90 62.55 26.33
## 2020-04-27 82.55 63.75 26.79
## 2020-04-28 82.55 63.10 26.91
## 2020-04-29 83.70 63.80 27.07
## 2020-04-30 85.50 64.75 27.46
md = 50
i = 'e50'
# Assuming 'etf3' is your final data to plot which consists of 3 ETFs: 'e50', 'e52', 'e56'
library(ggplot2)
# Calculate moving averages and create signals
etf3$e50.sma <- SMA(etf3$e50, n=md) # Modify 'md' as per required moving average days
etf3$e52.sma <- SMA(etf3$e52, n=md)
etf3$e56.sma <- SMA(etf3$e56, n=md)
# Create plots
etf_plot <- ggplot() +
geom_line(data = etf3, aes(x = index(etf3), y = e50, colour = "e50")) +
geom_line(data = etf3, aes(x = index(etf3), y = e50.sma, colour = "e50.sma.cross")) +
geom_line(data = etf3, aes(x = index(etf3), y = e52, colour = "e52")) +
geom_line(data = etf3, aes(x = index(etf3), y = e52.sma, colour = "e52.sma.cross")) +
geom_line(data = etf3, aes(x = index(etf3), y = e56, colour = "e56")) +
geom_line(data = etf3, aes(x = index(etf3), y = e56.sma, colour = "e56.sma.cross")) +
scale_colour_manual(values = c("e50" = "black", "e50.sma.cross" = "red",
"e52" = "green", "e52.sma.cross" = "blue",
"e56" = "cyan", "e56.sma.cross" = "magenta")) +
labs(title = "ETF Cumulative Performance with SMA Cross", x = "Date", y = "Cumulative Performance") +
theme_minimal()
print(etf_plot)
## Warning: Removed 49 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Removed 49 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Removed 49 rows containing missing values or values outside the scale range
## (`geom_line()`).