summaryrefslogtreecommitdiffstats
path: root/bandit.R
blob: 4ce86bff776d7247b938a6c8718103ee11771523 (plain)
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 )
}