1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
source('utils.R')
sp500<- read.table("sp500 tickers 10-17.csv",sep="\t",header=T,quote="",colClasses="character",strip.white=T)
colnames(sp500) <- c("name","ticker")
#replace / by -
sp500$ticker <- sub('/', '-', sp500$ticker)
load("sp500-bloomberg.RData")
#first don't take care about survivor bias
tickerlist <- list()
for(i in 1:length(sp500$ticker)){
ticker <- sp500[i,"ticker"]
tickerlist[[ticker]] <- getYahooData(ticker,"20000101")
cat("ticker",i,ticker,"\n")
}
price2return <- function(x){
diff(log(abs(x)))
}
#compute list of returns
tickerlist <- names(stock.data)
returns <- price2return(stock.data[[tickerlist[1]]]$Close)
for(i in 2:length(tickerlist)){
ticker <- tickerlist[i]
returns <- merge(returns,price2return(stock.data[[ticker]]$Close),all=T)
}
colnames(returns) <- tickerlist
returns <- returns[-1,]
#constant weight rebalancing
N <- 1000000
W <- N
for(day in 1:NROW(returns)){
date <- time(returns)[day]
subset <- memb(sp500$ticker,add,date)
r <- as.vector(exp(returns[day,subset])-1)
r[is.na(r)] <- 0 #NA means we don't have quotes that day, but next return
#will catch up
w <- rep(1/length(r),length(r))
dN <- N*crossprod(w,r)
N <- N+dN
W <- c(W,N)
}
#bandit strategy
current.wealth <- 1
V <- 0
pnl <- 0
members <- memb(sp500$ticker,add,as.Date("2000-01-01"))
w <- rep(1/499,499)
L <- rep(0,NCOL(returns))
for(day in 1:NROW(returns)){
#browser()
date <- time(returns)[day]
r <- exp(coredata(returns[day,]))-1
r[is.na(r)] <- 0
V <- V+drop(crossprod(w,r[,members]^2))
#L <- exp(-colSums(returns[1:day,],na.rm=T))-1
L <- L-r
pnl <- c(pnl, current.wealth*crossprod(w,r[,members]))
current.wealth <- 1 + sum(pnl)
members <- memb(sp500$ticker,add,date)
#eta <- 2/3*sqrt(log(500)/V)
eta <- 0.15
w <- exp(-eta*L[,members])
w <- w/sum(w)
}
#number of shares implementations
tc <- 0.005+0.02
days <- nrow(data.bus)
init.capital <- 1000000
tickers <- memb(sp500.tickers,add,as.Date(time(data.bus)[1]))
tickers.index <- which(sp500.tickers.extended%in%tickers)
n.stocks <- length(tickers)
w <- rep(0,length(sp500.tickers.extended))
w[tickers.index] <- rep(1/n.stocks,n.stocks)
N <- round((capital*w)/as.numeric(data.bus[1,tickers.index]))
dP <- apply(data.bus,2,diff)
L <- rep(0,n.stocks)
V <- 0
W <- w
pnl <- 0
tcvec <- sum(N)*tc
for(i in 1:days){
tickers <- memb(sp500.tickers,add,as.Date(time(data.bus)[1]))
tickers.index <- which(sp500.tickers.extended%in%tickers)
r <- dP[i,]/as.numeric(data.bus[i,])
pnl <- cbind(pnl,crossprod(N,dP[i,]))
capital <- init.capital+sum(pnl)-sum(tcvec)
L <- rbind(L,-r)
V <- V+crossprod(w,r^2)
T <- 2/3*sqrt(log(days)/V)
#w <- exp(-T*(apply(1+L,2,prod)-1))
w <- exp(-T*colSums(L))
w <- w/sum(w)
newN <- round((capital*w)/as.numeric(data.bus[(i+1),tickers.index]))
tcvec <- c(tcvec,sum(abs(newN-N)*tc))
N <- newN
if(i%%10==0){
cat(capital,sep="\n")
}
}
fixed.rebal <- function(P,delta){
init.capital <- 1
dP <- apply(P,2,diff)
capital <- init.capital
pnl <- c()
for(i in 1:(nrow(P)-1)){
r <- dP[i,]/P[i,]
pnl <- c(pnl,capital*crossprod(delta,r))
capital <- init.capital+sum(pnl)
}
return( pnl )
}
|