Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZachWolpe/071dd2c4d397df66d0952871d685c54c to your computer and use it in GitHub Desktop.
Save ZachWolpe/071dd2c4d397df66d0952871d685c54c to your computer and use it in GitHub Desktop.
library(tidyquant)
library(readxl)
library(lubridate)
library(tidyverse)
library(reshape2)
library(imputeTS)
library(scales)
# ---- equity data ----x
options("getSymbols.warning4.0"=FALSE)
options("getSymbols.yahoo.warning"=FALSE)
# --- date range ---x
from <- '2000-01-01'
to <- Sys.Date()
# all available EFTS
EFTs_on_JSE <- readxl::read_excel('./OptimAlpha/repo/data/EFTs_from_JSE.xlsx')
stx_idx <- unlist(lapply(unique(EFTs_on_JSE$Alpha), FUN=function(i){grepl('STX', i, fixed = TRUE)}))
# return satrix assets
stx_assets <- EFTs_on_JSE$Alpha[stx_idx]
# remove: Too new for data extraction
remove <- c('STXCHN', 'STXILB', 'STXMMT', 'STXGBD', 'STXWDM', 'STXESG', 'STXEME', 'STXGOV')
final <- c()
for (r in remove) {
for (s in stx_assets) {
if (r != s){
if (s %in% final == FALSE){
final <- c(final, s)
}}}}
# ---------- get data ------------x
all_data <- c()
for (s in final){
data <- tq_get(paste0(s, '.JO'), get = "stock.prices", from=from, to=to)
all_data <- rbind(all_data, data)
}
# --- additional data ---x
usd_zar <- tq_get('USDZAR=X', from=from, to=to)
gbp_zar <- tq_get('GBPZAR=X', from=from, to=to)
btc_usd <- tq_get('BTC-USD', from=from, to=to)
Tbills <- tq_get('INTGSTZAM193N', from=from, to=to, get = "economic.data")
inflation_SA <- tq_get('FPCPITOTLZGZAF', from=from, to=to, get = "economic.data")
inflation_US <- tq_get('FPCPITOTLZGUSA', from=from, to=to, get = "economic.data")
options(width = 80)
n <- 10000
compute_returns <- function(yrs, n=10000) {
results <- c()
for (i in 1:n){
#------- progress padding ------x
extra <- nchar('||100%')
width <- options()$width
step <- round(i / n * (width - extra))
text <- sprintf('|%s%s|% 3s%%', strrep('=', step),
strrep(' ', width - step - extra), round(i / n * 100))
cat(text)
Sys.sleep(0.05)
cat(if (i == n) '\n' else '\014')
#------- progress padding ------x
# start dates
dates <- seq.Date(as.Date(from), to - years(5), by='year')
assets <- sample(final, 3, replace=TRUE) # sample 3 assets
start_date <- sample(dates, 1) # sample starting date
end_date <- start_date + years(yrs)
# extract date range
data <- all_data %>% filter(date>start_date & date<end_date)
# compute ROI
ROI <- data %>% group_by(symbol) %>% summarise(
min = close[which.min(date)],
max = close[which.max(date)]
) %>% mutate(ROI = (max-min)/min, delta=max-min)
ROI$ROI[is.na(ROI$ROI)] <- 0
# concat data
d1 <- data.frame(start_date=start_date, end_date=end_date, assets=paste(assets,collapse=', '),
mean=mean(ROI$ROI, na.rm = TRUE), sd=sd(ROI$ROI))
results <- rbind(results, d1)
}
return(list(results=results, cash_yield=(1+0.025)^yrs-1, years=yrs, n=n))
}
# compute
res <- c()
for (y in 1:10) {
res[[y]] <- compute_returns(yrs=y, n=2000)
}
ROI_plots <- function(res_ind) {
results <- res[[res_ind]]$results
cash <- res[[res_ind]]$cash_yield
yr <- res[[res_ind]]$years
x <- results$mean
x <- x[!is.na(x)]
mean_return <- mean(x, na.rm=TRUE)
h <- hist(x, breaks=15, c='#7FC2DF', xlab='ROI', main=paste('Distribution of Yield - Years:', yr), font.main=1, border=F)
xfit<-seq(min(x),max(x),length=40)
yfit<-dnorm(xfit,mean=mean(x),sd=sd(x))
yfit <- yfit*diff(h$mids[1:2])*length(x)
lines(xfit, yfit, col='#0086bf', lwd=2)
abline(v = cash, lty=4, lwd=2, col='#d80078')
abline(v = mean_return, lty=5, lwd=2, col='#004c97')
legend('topright',
col=c('#0086bf', '#d80078', '#004c97'), border.lwd = 0,
lty=c(1,2,5), legend=c('ROI distribution',
paste0('cash: ', round(cash, 3)),
paste0('portfolio: ', round(mean_return, 3)))
)
return(list(cash=cash, mean_return=mean_return, delta=mean_return-cash))
}
delta <- c()
for (y in 1:10) {
delta <- rbind(delta, ROI_plots(y))
}
std_data <- c()
for (r in 1:length(res)) {
std <- res[[r]]$results$sd
std_data <- rbind(std_data, data.frame(year=r, roi=res[[r]]$results$mean, std=std))
}
df <- data.frame(yr=1:10)
df$yld <- apply(df['yr'], 1, FUN=function(i){(1+0.025)^i-1})
df$roi <- apply(df['yr'], 1, FUN=function(i){mean(res[[i]]$results$mean, na.rm = TRUE)})
ggplot(std_data, aes(x = `roi`, y = as.factor(std_data$year), fill = ..x..)) +
geom_density_ridges_gradient(scale = 3, rel_min_height = 0.01) +
scale_fill_viridis(direction = -1, name = "Temp. [F]", option = "C") +
labs(title = 'Portfolio Yield Distributions') + ylab('Portfolio Duration') + xlab('ROI') +
theme_ipsum() +
# geom_point(x=df$roi, y=df$yr)
theme(
legend.position="none",
panel.spacing = unit(0.1, "lines"),
strip.text.x = element_text(size = 8)
)
library(RColorBrewer)
boxplot(roi~year, data = std_data, varwidth = TRUE, las = 1, col=RColorBrewer::brewer.pal(10, 'RdBu'),
frame=F, ylab='Yield')
lines(df$yr, df$yld, col='#d80078', lwd=3, lty=4)
lines(df$yr, df$roi, col='steelblue', lwd=3, lty=2)
title(main='Distribution of Returns', font.main=1)
legend('topleft', border.lwd=0, col=c('#d80078', 'steelblue'), lwd=3, lty=c(4,2), legend=c('Cash Yield', 'Expected ROI'))
# --- bootstrap illustration ---x
boxplot(std~year, data = std_data, varwidth = TRUE, las = 1, col=RColorBrewer::brewer.pal(10, 'RdBu'),
frame=F)
title(main='Variation of Returns', font.main=1)
library(tidyverse)
df <- all_data %>% select(symbol, date, close)
# --- additional data ---x
df <- rbind(df, usd_zar %>% select(symbol, date, close))
df <- rbind(df, gbp_zar %>% select(symbol, date, close))
# df <- rbind(df, btc_usd %>% select(symbol, date, close))
names(Tbills) <- c('symbol', 'date', 'close'); Tbills$symbol <- 'Tbills'
names(inflation_SA) <- c('symbol', 'date', 'close'); inflation_SA$symbol <- 'inflation_SA'
names(inflation_US) <- c('symbol', 'date', 'close'); inflation_US$symbol <- 'inflation_US'
df <- rbind(df, Tbills)
df <- rbind(df, inflation_SA)
df <- rbind(df, inflation_US)
summary <- df %>% group_by(symbol) %>% summarise(
start_price=close[which.min(date)],
close_price=close[which.max((date))],
ROI_percent = (close_price-start_price)/start_price*100
)
summary %>% order_by(ROI_percent)
summary %>%
arrange(ROI_percent) %>%
mutate(name=factor(symbol, levels=symbol)) %>%
ggplot(aes(x=name, y=ROI_percent)) +
geom_segment( aes(xend=name, yend=0)) +
geom_point(size=3.5, color='#ed8b00') +
coord_flip() +
theme_light() +
xlab('') + ylab('ROI %') + ggtitle('Return on Assets')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment