Imaginary World
Why an imaginary world? the short answer is, because I studied economics and there I learnt to make assumptions whenever and wherever I desired :)). The long answer is that when I was backpacking through trans Siberia, I thought that in Tehran Stocks Exchange, short selling is not possible, as a result spread trading could not be exploited and hence spreads are high and mean revertible. Simply, if there is no competition, anomaly would preserve. So I thought if this is true, maybe one can detect with a plausible probability that which one of the pairs is undervalued, for example by utilizing a third or more series. And this could result in implementing nice strategies. Here I will see whether this assumption would result favorable results. Since it is an imaginary world I would use just simple methods. if it gonna work by using a third series, it need to be profitable in simple forms. For this purpose I tried to use QuantStrat package. Up until using it, I normally used functions written by myself for strategy implementation purposes. I used it, and it turned out to not be good idea, it was both slow and the code used different style than the packages I used. For example it used “match.names” function that used partial match names and it forced me to change all of my object naming method. Or some functions need to be modified to consider irregular dates format and NAs. I think that if I have had migrated to Julia for this matter it would have been better.
simple pair candidates
Pairs are selected based on correlations and not by common factor models. And the results where tested by Phillips Ouliaris test for cointegration. In of sample period from “2010-01-01” to “2015-01-01” has been used for computing correlations. I used whole sample data also, the results was profitable but I have not included them here. I mean, If I had the whole sample data, life would have not been a martingale :). The results are somehow strange and some pairs seems not to be related at all. Further, stocks are reduced to ones that have on average at least 5*10^5 volume per day. By my experience having this amount of volume, slippage could be neglected while trading 10^8 Rials value of stocks (it would be on average around 2-5 Rials per round trip trade on a normal day by my experience, a detailed an accurate quantity needs to be computed by tick data. In cases like the ones I explained in Markov Chain post, it would be substantially more. Here I have not seen that it is necessary to include such details). another reason is that I saw that less liquid assets have some lag before adjusting to news.
colnames(WDATA)<- c("DATE","sym","FIRST", "HIGH", "LOW", "LCLOSE",
"VOL", "CLOSE" )
vol.sym.mean<- ddply(WDATA, "sym", .fun = function(x) {
denom<- as.numeric(x$DATE[dim(x)[1]] - x$DATE[1])
denom<- floor(denom*(202/364))
mean.vol<- sum(as.numeric(x$VOL), na.rm = TRUE) / denom
return(mean.vol)
})
sym.min.vol<- droplevels(vol.sym.mean[,1][which(vol.sym.mean[2] > 5*10^5)])
WDATA<-subset(WDATA, WDATA$sym %in% sym.min.vol)
WDATA<- droplevels(WDATA)
WDATA_last<- subset(WDATA_last, WDATA_last$DATE >= as.Date("2010-01-01") & WDATA_last$DATE <= as.Date("2015-01-01"))
retDATA<- WDATA_last[,c("DATE","sym","retCL_t")]
retDATAw<- dcast(retDATA, DATE ~ sym, value.var = "retCL_t")
J <- (retDATAw[, 1])
retDATAw <- retDATAw[,-1]
rownames(retDATAw)<- J
rm(J)
retDATAw<- apply(retDATAw,2, function(x) as.numeric(x))
#scale_retDATAw<- apply(retDATAw,2, scale)
abs_cor<- abs(cor(retDATAw, use = "pairwise.complete.obs"))
diag(abs_cor)<-0
cor.high.10<- sort(abs_cor, decreasing = TRUE)[1:50]
cor.ranked.sym<- list()
for( i in seq(2,50, by = 2)){
cor.ranked.sym[[( i / 2)]]<-rownames(which(abs_cor == cor.high.10[i], arr.ind = TRUE))
}
for( i in 1 : length(cor.ranked.sym) ){
ret.sym.1<- cor.ranked.sym[[i]][1]
ret.sym.2<- cor.ranked.sym[[i]][2]
ret.m<- cbind( retDATAw [ ,ret.sym.1 ],
retDATAw [ ,ret.sym.2])
temp<- po.test(ret.m)$p.value
print(temp)
}
transaction costs
transaction costs is about 0.005 for buying the stock and 0.01 for selling the stocks. It also includes tax on selling stocks that is about 0.005 of stocks value. And a good point about Tehran Stock Exchange is that there is no other tax than this and capital gain tax is zero :)
txnFUN <- function(TxnQty, TxnPrice, Symbol, rate = 0.015) {
comission <- abs(TxnQty) * TxnPrice * rate
if (comission > 0) comission <- -comission
return(comission)
}
Computing Spread
Total least square, Dynamic OLS, Integrated Modified OLS, and OLS with changing the dependent variable is used for getting the betas and constructing spread.
beta.fun<- function( ret.all = ret.m){
end_date<- index(ret.all)[ length(ret.all[,1])]
po.pvalue<- suppressWarnings( po.test(ret.all)$p.value)
pca.ret<- prcomp( ~ as.numeric(ret.all[,1]) + as.numeric( ret.all[,2]))
beta.pca<- pca.ret$rotation[2, 1] / pca.ret$rotation[1, 1]
spread.pca<- ret.all[,2 ] - beta.pca * ret.all[,1 ]
level.pca<- mean (spread.pca, na.rm = TRUE)
beta.12<- lm(as.numeric(ret.all[,1])~as.numeric( ret.all[,2]) - 1)$coeff
beta.21<- lm(as.numeric(ret.all[,2])~as.numeric( ret.all[,1]) - 1)$coeff
spread.12<- ret.all[,1 ] - beta.12 * ret.all[,2 ]
level.12<- mean (spread.12, na.rm = TRUE)
spread.21<- ret.all[,2 ] - beta.21 * ret.all[,1 ]
level.21<- mean (spread.21, na.rm = TRUE)
beta.DOLS<- cointRegD(as.numeric( ret.all[,1]), as.numeric( ret.all[,2]))$beta
spread.DOLS<- ret.all[,1 ] - beta.DOLS * ret.all[,2 ]
level.DOLS<- mean (spread.DOLS, na.rm = TRUE)
beta.IMOLS<- cointRegIM(as.numeric( ret.all[,1]), as.numeric( ret.all[,2]))$gamma
spread.IMOLS<- ret.all[,1 ] - beta.IMOLS * ret.all[,2 ]
level.IMOLS<- mean (spread.IMOLS, na.rm = TRUE)
out<- cbind.data.frame(#DATE = end_date,
po.pvalue = po.pvalue,
beta.pca = beta.pca,
spread.pca = spread.pca[length(spread.pca)],
level.pca = level.pca,
beta.12 = beta.12,
spread.12 = spread.12[length(spread.12)],
level.12 = level.12,
beta.21 = beta.21,
spread.21 = spread.21[length(spread.21)],
level.21 = level.21,
beta.DOLS = beta.DOLS,
spread.DOLS = spread.DOLS[length(spread.DOLS)],
level.DOLS = level.DOLS,
beta.IMOLS = beta.IMOLS,
spread.IMOLS = spread.IMOLS[length(spread.IMOLS)],
level.IMOLS = level.IMOLS
# po.test, if needed for furthure work
)
out<- as.numeric(out)
return(out)
}
thresold_level<- function(data = data ,level.m = "mlevel_pca", sd.m = "sd_spread_pca", multi = 1) {
sym.name<- strsplit(colnames(data)[1], split="[.]")[[1]][1]
out<- cbind( data[, level.m] + (multi * data[, sd.m]),
data[, level.m] - (multi * data[, sd.m]))
method.name<- strsplit(level.m, split="[_]")[[1]][2]
names.out<- c( paste("upper", method.name, sep = "_"),
paste("lower", method.name, sep = "_"))
colnames(out)<- names.out
return(out)
}
The threshold is computed based on standard deviation of spread.
Function for placing orders
This function is a modification to demo function in the package that I modified for replacing pairs order, NAs in data and considering end equity on trade size. I use level one for trade sizing, tests with level two resulted on much better results.
osSpreadMaxPos <- function (data, timestamp, orderqty, ordertype, orderside, beta.method, lvls,
portfolio.st, account.st,
portfolio, symbol, ruletype, reverse, cor.pair, orderprice, ...) {
portf <- getPortfolio(portfolio)
#check to make sure pair slot has the things needed for this function
x<- get(symbol)$RHS[1]
if (x == 1) legside <- "long"
if (x == 0) legside <- "short"
if (reverse == TRUE & x == 1) legside <- "short"
if (reverse == TRUE & x == 0) legside <- "long"
updatePortf(portfolio.st)
updateAcct( account.st, paste(t.out0, timestamp, sep="::"))
updateEndEq( account.st, paste(t.out0, timestamp, sep="::"))
endEq<- floor( getEndEq( account.st, Date = timestamp))
x1 <- get(cor.pair[1])
x2 <- get(cor.pair[2])
spread.price <- (1 * Cl(x1)) + (abs(x1[,beta.method]) * Cl(x2))
if (reverse == TRUE){
spread.price <- (abs(x1[,beta.method]) * Cl(x1)) + ( 1 * Cl(x2))
}
colnames(spread.price) <- 'spread.price'
spread.num<- endEq / spread.price
long.size<- (spread.num / (1 + abs(x1[,beta.method]))) / (lvls )
short.size<- (long.size * abs(x1[,beta.method])) / (lvls)
long.size[ is.na(long.size)]<- 0
short.size[ is.na(short.size)]<- 0
long.size[ is.null(long.size)]<- 0
short.size[ is.null(short.size)]<- 0
if( length(x1[as.POSIXct(timestamp)]) != 0 &
length(long.size[as.POSIXct(timestamp)]) != 0 &
length(short.size[as.POSIXct(timestamp)]) != 0) {
#ratio <- getHedgeRatio(portfolio, timestamp)
pos <- getPosQty(portfolio, symbol, timestamp)
try(addPosLimit(portfolio=portfolio, timestamp=timestamp, symbol=symbol,
maxpos=round(long.size[as.POSIXct(timestamp)],0), longlevels=lvls,
minpos=round(-long.size[as.POSIXct(timestamp)],0), shortlevels=lvls))
qty <- long.size[as.POSIXct(timestamp)]
if (legside == "short") {#symbol is 2nd leg
## Comment out next line to use equal ordersizes for each stock.
try(addPosLimit(portfolio=portfolio, timestamp=timestamp, symbol=symbol,
maxpos=round(short.size[as.POSIXct(timestamp)],0), longlevels=lvls,
minpos=round(-short.size[as.POSIXct(timestamp)],0), shortlevels=lvls))
##
qty <- -short.size[as.POSIXct(timestamp)] #switch orderqty for Stock B
}
if (qty > 0) orderside = 'long'
if (qty < 0) orderside = 'short'
orderqty <- osMaxPos(data=data,timestamp=timestamp, orderqty=qty,
ordertype=ordertype, orderside=orderside,
portfolio=portfolio, symbol=symbol, ruletype=ruletype,
...)
} else {
qty <- 0
orderside <- 'long'
orderqty <- 0
}
if (!is.null(orderqty) & !orderqty == 0 & !is.null(orderprice)) {
addOrder(portfolio=portfolio, symbol=symbol,
timestamp=timestamp, qty=orderqty, price=as.numeric(orderprice),
ordertype=ordertype, side=orderside, replace=FALSE,
status="open", ...=...)
}
return(0)
}
Loop or Function
First I tried to write a function for computing the results but some of packages functions failed to work inside functions, I think it was because of environment they were defined to create. Instead of making changes in global environment with functions, I see that it is more reasonable to use for loops. Here I do not write replication for different kind of calculated spread and corresponding rules and signals- it became too lengthy. Betas, Spread level and sd are computed by 30 days backward rolling window.
results<- list()
temp<- NULL
for ( i in 6 : length(cor.ranked.sym)){
cor.pair = cor.ranked.sym [[i]]
beta.fun. = beta.fun;
osSpreadMaxPos. = osSpreadMaxPos # index = VLGI
txnFUN. = txnFUN
rm(list = ls(.blotter), envir = .blotter)
rm(list = ls(.strategy), envir = .blotter)
if (!exists('.blotter')) .blotter <- new.env()
if(!exists('.strategy')) .strategy <- new.env()
if(!exists('.instrument')) .instrument <- new.env()
symbols <- cor.pair
stock(symbols, currency = "IRR", multiplier = 1)
ret.1<- diff.xts( x = log( get( cor.pair[1 ])[,6 ]))
ret.2<- diff( log( get( cor.pair[2 ])[,6 ]))
ret.m<- cbind( ret.1, ret.2)
ret.m<- ret.m[complete.cases(ret.m[,1]),]
ret.m<- ret.m[complete.cases(ret.m[,2]),]
ret.m<- ret.m[paste(t.out0,"::", sep = "")]
# roll apply
betas<- rollapply(ret.m, width = 30,
FUN = function(x) beta.fun.(x), by.column = FALSE, align = "right")
sd_spread<- rollapply(betas[,c(3,6,9,12,15)],
width = 30, FUN = function(x) apply(x, 2 , sd, na.rm = TRUE),
by.column = FALSE, align = "right")
mean_level<- rollapply(betas[,c(4,7,10,13,16)],
width = 30, FUN = function(x) apply(x, 2 , sd, na.rm = TRUE),
by.column = FALSE, align = "right")
betas<- cbind(betas, sd_spread)
betas<- cbind( betas, mean_level)
names_beta<- c("po_pvalue", "beta_pca", "spread_pca",
"level_pca", "beta_12", "spread_12",
"level_12", "beta_21", "spread_21",
"level_21", "beta_DOLS", "spread_DOLS",
"level_DOLS", "beta_IMOLS", "spread_IMOLS",
"level_IMOLS",
"sdD_pca", "sdD_12", "sdD_21",
"sdD_DOLS", "sdD_IMOLS",
"mlevel_pca", "mlevel_12", "mlevel_21",
"mlevel_DOLS", "mlevel_IMOLS")
colnames(betas)<- names_beta
#zero crossing
zerocross.pca<- length( rle( as.numeric(betas$spread_pca) >=
as.numeric(betas$mlevel_pca))$lengths) -1
zerocross.12<- length( rle( as.numeric(betas$spread_12) >=
as.numeric(betas$mlevel_12))$lengths) -1
zerocross.21<- length( rle( as.numeric(betas$spread_21) >=
as.numeric(betas$mlevel_21))$lengths) -1
zerocross.DOLS<- length( rle( as.numeric(betas$spread_DOLS) >=
as.numeric(betas$mlevel_DOLS))$lengths) -1
zerocross.IMOLS<- length( rle( as.numeric(betas$spread_IMOLS) >=
as.numeric(betas$mlevel_IMOLS))$lengths) -1
zerocross<- c( zerocross.pca = zerocross.pca, zerocross.12 = zerocross.12,
zerocross.21 = zerocross.21, zerocross.DOLS = zerocross.DOLS,
zerocross.IMOLS = zerocross.IMOLS)
sd.pca<- thresold_level( data = betas,
level.m = "mlevel_pca", sd.m = "sdD_pca", multi = 1)
betas<- cbind( betas, sd.pca)
### doing same for other methods
temp<- get( cor.pair[1 ])
temp<- cbind( temp, betas)
temp<- cbind( temp, 1)
colnames( temp)[ length( colnames( temp))]<- "RHS"
assign( cor.pair[1 ], temp)
rm( temp)
temp<- get( cor.pair[2 ])
temp<- cbind( temp, betas)
temp<- cbind( temp, 0)
colnames( temp)[ length( colnames( temp))]<- "RHS"
assign( cor.pair[2 ], temp)
rm( temp)
# buy sell signal
strategy.pca <- paste("strategy", "pca", cor.pair[1 ], cor.pair[2 ], sep = "_")
portfolio.pca <- paste("portfolio", "pca", cor.pair[1 ], cor.pair[2 ], sep = "_")
account.pca<- paste("account", "pca", cor.pair[1 ], cor.pair[2 ], sep = "_")
rm.strat(portfolio.pca)
rm.strat(strategy.pca)
rm.strat(account.pca)
initPortf( portfolio.pca, symbols = symbols, initDate = initDate, currency = "IRR")
initAcct( account.pca, portfolios = portfolio.pca, initDate = initDate, currency = "IRR", initEq = initEq)
initOrders(portfolio = portfolio.pca, initDate = initDate)
#test<- tryCatch(getPortfolio(portfolio.pca), error=function(e){NA})
strategy(strategy.pca, store = TRUE)
# same for other methods
add.signal(strategy = strategy.pca, data = quote(mktdata), name = "sigCrossover",
arguments = list( columns = c( "spread_pca", "upper_pca"), relationship= "gt"),
label = "shortOrsell")
add.signal(strategy = strategy.pca, data = quote(mktdata), name = "sigCrossover",
arguments = list( columns = c( "spread_pca", "lower_pca"), relationship= "lt"),
label = "buyOrcover")
# same for other methods
#### pca
add.rule(strategy=strategy.pca, name='ruleSignal',
arguments=list(sigcol="shortOrsell", sigval=TRUE,
orderqty=1e7, ordertype='market', cor.pair = cor.pair,
orderside=NULL, osFUN='osSpreadMaxPos.', reverse = FALSE,
replace = FALSE, beta.method = "beta_pca",lvls = 1,
portfolio.st = portfolio.pca,
account.st = account.pca,
TxnFees = "txnFUN.", rate = 0.01,
prefer = "Open"),
type='enter')
add.rule(strategy=strategy.pca, name='ruleSignal',
arguments=list(sigcol="buyOrcover", sigval=TRUE,
orderqty=-1e7, ordertype='market', cor.pair= cor.pair,
orderside=NULL, osFUN='osSpreadMaxPos.', reverse = FALSE,
replace = FALSE, beta.method = "beta_pca",lvls = 1,
portfolio.st = portfolio.pca,
account.st = account.pca,
TxnFees = "txnFUN.", rate = 0.005,
prefer = "Open"),
type='enter')
add.rule(strategy=strategy.pca, name='ruleSignal',
arguments=list(sigcol="buyOrcover", sigval=TRUE,
orderqty='all', ordertype='market',
orderside=NULL,
replace = FALSE,
TxnFees = "txnFUN.", rate = 0.005,
prefer = "Open"),
type='exit')
add.rule(strategy=strategy.pca, name='ruleSignal',
arguments=list(sigcol="shortOrsell", sigval=TRUE,
orderqty='all', ordertype='market',
orderside=NULL,
replace = FALSE,
TxnFees = "txnFUN.", rate = 0.01,
prefer = "Open"),
type='exit')
# same for other methods
######
###############
applyStrategy(strategy.pca, portfolio.pca, debug = TRUE)
updatePortf(portfolio.pca)
updateAcct( account.pca,paste(t.out0, t.out1, sep="::"))
updateEndEq(account.pca, paste(t.out0, t.out1, sep="::"))
# same for other methods
###########
ret1 <- PortfReturns(account.pca,
Dates = paste(t.out0, t.out1, sep="::"))[paste(t.out0, t.out1, sep="::")]
PortRets.pca <- xts(rowSums(ret1) , order.by = index(ret1))
# same for other methods
mDraw.pca<- maxDrawdown( PortRets.pca)
an.ret.pca<- as.numeric( Return.annualized( PortRets.pca, geometric = TRUE))
an.sharp.pca<- as.numeric( SharpeRatio.annualized(PortRets.pca))
UPR.pca<- as.numeric( UpsidePotentialRatio( PortRets.pca))
#InformationRatio(Ra, VLGI, scale = NA)
#UpDownRatios
# same for other methods
out<- list( ret = list( PortRets.pca = PortRets.pca,
PortRets.12 = PortRets.12,
PortRets.21 = PortRets.21,
PortRets.DOLS = PortRets.DOLS,
PortRets.IMOLS = PortRets.IMOLS),
zerocross = zerocross,
mDraw = c( mDraw.pca, mDraw.12,
mDraw.21, mDraw.DOLS,
mDraw.IMOLS),
an.ret = c( an.ret.pca, an.ret.12,
an.ret.21, an.ret.DOLS,
an.ret.IMOLS),
an.sharp = c( an.sharp.pca, an.sharp.12,
an.sharp.21, an.sharp.DOLS,
an.sharp.IMOLS),
UPR = c( UPR.pca, UPR.12,
UPR.21, UPR.DOLS,
UPR.IMOLS))
results[[i]]<- out
print(i)
}
Results
for comparing strategies I usually use annualized returns, max drawdown and Sharp ratio. The first one tells me whether it is better than GDP deflator and VLGI, the second tells me whether I can take the pain, and third one compares it with risk defined as variance. Usually other measures for risk adjusted returns are used, but before I was thinking that if stop losses are not existed in strategy, then if we take out the drift term, whatever could happen upward could happen downward also. I mean, one cannot simply neglect upward movements of a martingale, just because it is plausible for them or compare a Brownian motion with another and their comovement, and consider it highly informative; the information has already been shown through correlation and Beta, plus drift. After I read this I just dropped the assumption that absence of stop loss is necessary, since it says that it is the case even for truncated elliptical distributions.
path = "C:/Users/msdeb/Documents/Stock and trades/"
setwd(path)
load(".Rdata")
library(pander)
an.ret<- NULL
temp<- NULL
an.sharp<- NULL
mDraw<- NULL
UPR<- NULL
zerocross<- NULL
for ( i in 1 : length( results)){
temp <- results[[i]]$an.ret
an.ret <- rbind( an.ret, temp)
temp <- results[[i]]$an.sharp
an.sharp <- rbind( an.sharp, temp)
temp <- results[[i]]$mDraw
mDraw <- rbind( mDraw, temp)
temp <- results[[i]]$UPR
UPR <- rbind( UPR, temp)
temp <- results[[i]]$zerocross
zerocross <- rbind( zerocross, temp)
name<- paste(cor.ranked.sym [[i]][1 ], cor.ranked.sym [[i]][2 ], sep = "_")
rownames(an.ret)[i]<- name
rownames(an.sharp)[i]<- name
rownames(mDraw)[i]<- name
rownames(UPR)[i]<- name
rownames(zerocross)[i]<- name
}
name<- c( "pca", "12", "21", "DOLS", "IMOLS")
colnames(an.ret)<- name
colnames(an.sharp)<- name
colnames(mDraw)<- name
colnames(UPR)<- name
colnames(zerocross)<- name
pander(an.ret)
pca | 12 | 21 | DOLS | IMOLS | |
---|---|---|---|---|---|
MSKN_DADE | -0.1191 | -0.1576 | -0.0954 | -0.1847 | -0.175 |
PETR_KAVR | -0.03679 | -0.132 | -0.2176 | -0.136 | -0.08305 |
SPDZ_SAHD | -0.2066 | -0.1332 | -0.1305 | -0.1787 | -0.1033 |
TOKA_SPDZ | -0.0907 | -0.1271 | -0.1402 | -0.1833 | -0.1811 |
TOKA_SAHD | -0.1233 | -0.1074 | -0.1647 | -0.1271 | -0.1415 |
TRIR_DADE | -0.1022 | -0.09237 | -0.06199 | -0.1722 | -0.1815 |
SPDZ_MADN | -0.1492 | -0.1821 | -0.1497 | -0.2017 | -0.09106 |
CHML_BMDZ | -0.02405 | -0.02676 | -0.1791 | -0.105 | -0.05954 |
SAHD_PLKK | -0.1315 | -0.1382 | -0.1497 | -0.1236 | -0.104 |
TRIR_MSKN | -0.03885 | -0.1406 | -0.1162 | -0.1159 | -0.2215 |
KRAF_BHKZ | -0.01496 | 0.01845 | -0.2321 | -0.1935 | -0.09654 |
SPDZ_BIME | -0.1993 | -0.1532 | 0.01241 | -0.2255 | -0.1326 |
TOKA_PLKK | -0.1344 | -0.1602 | -0.1382 | -0.157 | -0.1386 |
CHML_BSTE | -0.04435 | -0.03258 | -0.1499 | -0.1137 | -0.1293 |
SPDZ_PLKK | -0.1933 | -0.1769 | -0.1514 | -0.1932 | -0.1228 |
TRIR_BHKZ | -0.0053 | -0.1206 | -0.197 | 0.0105 | -0.03681 |
TOKA_MADN | -0.03911 | -0.1897 | -0.107 | -0.1403 | -0.126 |
SSHR_AZIN | -0.05137 | -0.2715 | -0.1157 | -0.1752 | -0.196 |
SPDZ_BANK | -0.2575 | -0.1372 | -0.09012 | -0.2419 | -0.2177 |
SPDZ_COMB | -0.1907 | -0.03624 | -0.1892 | -0.1657 | -0.1745 |
HPKP_BHKZ | -0.0542 | -0.1469 | -0.2615 | -0.1798 | -0.1569 |
TORZ_BGHZ | -0.1574 | -0.09773 | -0.2016 | -0.1101 | -0.1561 |
TRIR_KRAF | -0.06131 | -0.2012 | -0.06416 | -0.1071 | -0.1113 |
MSKN_BHKZ | -0.03129 | -0.05945 | -0.2585 | -0.06324 | -0.09587 |
TOKA_COMB | -0.1278 | -0.1374 | -0.2291 | -0.06743 | -0.1591 |
pander(colMeans(an.ret))
pca | 12 | 21 | DOLS | IMOLS |
---|---|---|---|---|
-0.1034 | -0.1256 | -0.1511 | -0.1461 | -0.1357 |
pander(an.sharp)
pca | 12 | 21 | DOLS | IMOLS | |
---|---|---|---|---|---|
MSKN_DADE | -1.493 | -2.378 | -0.4827 | -2.623 | -2.483 |
PETR_KAVR | -0.5154 | -0.8825 | -1.779 | -0.9855 | -0.7885 |
SPDZ_SAHD | -2.074 | -1.124 | -1.04 | -1.16 | -0.5504 |
TOKA_SPDZ | -1.468 | -0.4212 | -1.675 | -0.8586 | -1.018 |
TOKA_SAHD | -2.399 | -0.7916 | -1.576 | -1.16 | -1.245 |
TRIR_DADE | -0.8033 | -0.8603 | -0.3515 | -1.137 | -1.746 |
SPDZ_MADN | -1.235 | -1.505 | -1.154 | -1.254 | -0.4263 |
CHML_BMDZ | -0.5748 | -0.1282 | -1.4 | -0.6869 | -0.5226 |
SAHD_PLKK | -2.337 | -2.007 | -0.65 | -2.506 | -2.542 |
TRIR_MSKN | -0.297 | -1.146 | -0.9144 | -0.6997 | -2.294 |
KRAF_BHKZ | -0.6621 | 0.08135 | -2.243 | -1.457 | -1.028 |
SPDZ_BIME | -1.808 | -1.329 | 0.06908 | -1.677 | -0.7211 |
TOKA_PLKK | -2.451 | -1.272 | -1.108 | -1.279 | -1.156 |
CHML_BSTE | -0.9839 | -0.16 | -0.9741 | -0.9615 | -1.804 |
SPDZ_PLKK | -1.772 | -1.493 | -1.118 | -1.376 | -0.6714 |
TRIR_BHKZ | -0.03859 | -0.9577 | -2.046 | 0.05516 | -0.3142 |
TOKA_MADN | -0.6652 | -1.449 | -0.9134 | -1.182 | -1.082 |
SSHR_AZIN | -1.074 | -1.6 | -0.3651 | -1.088 | -1.265 |
SPDZ_BANK | -2.784 | -1.095 | -0.8336 | -2.157 | -1.156 |
SPDZ_COMB | -1.751 | -0.2111 | -1.692 | -1.013 | -0.7581 |
HPKP_BHKZ | -0.1895 | -1.231 | -2.473 | -1.049 | -0.7433 |
TORZ_BGHZ | -2.146 | -0.7947 | -1.823 | -0.8831 | -1.237 |
TRIR_KRAF | -0.2067 | -1.124 | -1.665 | -0.3986 | -0.3801 |
MSKN_BHKZ | -0.5748 | -1.141 | -1.844 | -1.25 | -1.753 |
TOKA_COMB | -2.584 | -1.031 | -2.292 | -0.4901 | -1.595 |
pander(colMeans(an.sharp))
pca | 12 | 21 | DOLS | IMOLS |
---|---|---|---|---|
-1.315 | -1.042 | -1.294 | -1.171 | -1.171 |
pander(mDraw)
pca | 12 | 21 | DOLS | IMOLS | |
---|---|---|---|---|---|
MSKN_DADE | 0.2789 | 0.3671 | 0.4138 | 0.3967 | 0.3755 |
PETR_KAVR | 0.1793 | 0.3617 | 0.4567 | 0.4037 | 0.2511 |
SPDZ_SAHD | 0.4403 | 0.3156 | 0.3863 | 0.4205 | 0.3578 |
TOKA_SPDZ | 0.1986 | 0.5156 | 0.3159 | 0.4399 | 0.4006 |
TOKA_SAHD | 0.282 | 0.283 | 0.4208 | 0.3437 | 0.3221 |
TRIR_DADE | 0.2784 | 0.2638 | 0.3188 | 0.4852 | 0.3992 |
SPDZ_MADN | 0.3406 | 0.4062 | 0.3328 | 0.4447 | 0.4158 |
CHML_BMDZ | 0.07467 | 0.2817 | 0.3886 | 0.3145 | 0.2475 |
SAHD_PLKK | 0.2931 | 0.3197 | 0.4386 | 0.2892 | 0.2486 |
TRIR_MSKN | 0.1878 | 0.351 | 0.2876 | 0.4178 | 0.4631 |
KRAF_BHKZ | 0.04448 | 0.3062 | 0.4751 | 0.4103 | 0.241 |
SPDZ_BIME | 0.4283 | 0.378 | 0.4016 | 0.4799 | 0.3961 |
TOKA_PLKK | 0.3177 | 0.4282 | 0.3309 | 0.4117 | 0.3253 |
CHML_BSTE | 0.112 | 0.2647 | 0.3444 | 0.3167 | 0.3032 |
SPDZ_PLKK | 0.4161 | 0.5046 | 0.3598 | 0.4593 | 0.322 |
TRIR_BHKZ | 0.1818 | 0.3138 | 0.4168 | 0.2669 | 0.3103 |
TOKA_MADN | 0.1216 | 0.4248 | 0.2438 | 0.3445 | 0.3067 |
SSHR_AZIN | 0.1298 | 0.5659 | 0.3911 | 0.4373 | 0.4024 |
SPDZ_BANK | 0.5147 | 0.3888 | 0.3074 | 0.5018 | 0.4568 |
SPDZ_COMB | 0.4126 | 0.3378 | 0.4007 | 0.4031 | 0.4909 |
HPKP_BHKZ | 0.2917 | 0.3659 | 0.5302 | 0.4069 | 0.411 |
TORZ_BGHZ | 0.3651 | 0.3376 | 0.4483 | 0.3655 | 0.4021 |
TRIR_KRAF | 0.4259 | 0.4485 | 0.1548 | 0.4595 | 0.4244 |
MSKN_BHKZ | 0.07956 | 0.1547 | 0.5471 | 0.1523 | 0.2187 |
TOKA_COMB | 0.2974 | 0.3522 | 0.4789 | 0.2157 | 0.3648 |
pander(colMeans(mDraw))
pca | 12 | 21 | DOLS | IMOLS |
---|---|---|---|---|
0.2677 | 0.3615 | 0.3836 | 0.3835 | 0.3543 |
pander(UPR)
pca | 12 | 21 | DOLS | IMOLS | |
---|---|---|---|---|---|
MSKN_DADE | 0.5455 | 0.3821 | 0.9347 | 0.3742 | 0.4338 |
PETR_KAVR | 0.7307 | 0.7676 | 0.6951 | 0.8132 | 0.6747 |
SPDZ_SAHD | 0.4583 | 0.6584 | 0.8653 | 0.5329 | 0.6946 |
TOKA_SPDZ | 0.6109 | 0.7675 | 0.5703 | 0.7897 | 0.7353 |
TOKA_SAHD | 0.5242 | 0.8107 | 0.7898 | 0.8151 | 0.6241 |
TRIR_DADE | 0.6442 | 0.7448 | 0.838 | 0.7792 | 0.6542 |
SPDZ_MADN | 0.6146 | 0.4904 | 0.8401 | 0.5226 | 0.6238 |
CHML_BMDZ | 0.4323 | 0.8916 | 0.732 | 0.7125 | 0.7693 |
SAHD_PLKK | 0.5435 | 0.5619 | 0.8268 | 0.4784 | 0.4136 |
TRIR_MSKN | 0.5945 | 0.5636 | 0.7593 | 0.6129 | 0.4325 |
KRAF_BHKZ | 0.4044 | 0.7102 | 0.5377 | 0.55 | 0.437 |
SPDZ_BIME | 0.6229 | 0.7504 | 0.9058 | 0.6406 | 0.7573 |
TOKA_PLKK | 0.6079 | 0.687 | 0.8114 | 0.8254 | 0.6386 |
CHML_BSTE | 0.3633 | 0.6992 | 0.7413 | 0.6843 | 0.596 |
SPDZ_PLKK | 0.5079 | 0.6039 | 0.7131 | 0.5327 | 0.6544 |
TRIR_BHKZ | 0.665 | 0.568 | 0.5063 | 0.7001 | 0.6707 |
TOKA_MADN | 0.6713 | 0.6942 | 0.8158 | 0.6011 | 0.6285 |
SSHR_AZIN | 0.2865 | 0.4789 | 0.6822 | 0.7088 | 0.3111 |
SPDZ_BANK | 0.5062 | 0.5941 | 0.802 | 0.6959 | 0.557 |
SPDZ_COMB | 0.5231 | 0.5202 | 0.8103 | 0.6109 | 0.5333 |
HPKP_BHKZ | 0.7173 | 0.5855 | 0.4523 | 0.6834 | 0.6816 |
TORZ_BGHZ | 0.5695 | 0.8284 | 0.694 | 0.7353 | 0.7213 |
TRIR_KRAF | 0.7264 | 0.6139 | 0.4446 | 0.7623 | 0.7992 |
MSKN_BHKZ | 0.549 | 0.4921 | 0.825 | 0.5087 | 0.4751 |
TOKA_COMB | 0.4789 | 0.7741 | 0.705 | 0.8321 | 0.7183 |
pander(colMeans(UPR))
pca | 12 | 21 | DOLS | IMOLS |
---|---|---|---|---|
0.5559 | 0.6496 | 0.7319 | 0.6601 | 0.6094 |
#pander(zerocross)
pander(colMeans(zerocross))
pca | 12 | 21 | DOLS | IMOLS |
---|---|---|---|---|
214.6 | 220.9 | 230 | 225.2 | 217.4 |
Conclusion
The results shows that the strategies are not profitable, so I leave this idea and I would not proceed for improving it. It it was supposed to be good it should have shown that in simplest form.
Further total least square and after that IM OLS showed better results than others. The case that IM OLS works better than simple OLS was not a straightforward conclusion for me, because it uses hyper parameters and by my experience this would usually make things worse, which was not the case here.