Trading System

Parameter Insensitive Models

In my opinion there are two enemies to successful system development. One is the “exploitability” of the anomaly  you are trying to extract profit from. The other is the parameters that you choose to exploit the anomaly with. The “exploitability” aspect is something you can’t have much control over as the profitability of any anomaly is in constant flux. One example is the profitability of trend following in general. When markets are choppy, its tough for any trend followers to extract sizeable profits.

The other area that you have absolute control over is the parameters with which you choose to trade with. The more varied the parameter selection, the more robust you are as the diversification increase will reduce probability of loss if any parameters were to suffer lack of performance. Parameters here can literally be the days you choose to employ a MA crossover strategy or it can extend to similar models like breakouts.

In the following experiment, I will test the performance of 5 different models. They are all mean reversion in nature.

Model1 (rsi1): RSI(2) 50/50

Model2 (rsi2): RSI(2) Buy: <30 Short: >70

Model3 (rsi3): RSI(2) Buy: <30 Sell: >50 Short: >70 Cover: <50

Model4 (no.reb): no rebalance but equal weight

Model5 (reb): equal weight rebalance weekly

Parameter insensitive models rest on the idea that no one knows what the future holds and how each parameter will perform. Instead of just relying on past data to select something that “was” consistent, parameter insensitive models try to avoid putting all eggs in one basket. The following is the equity curve of the strategy.

The focus should be on the bold equity curve which rebalances weekly. From the graph, it is very much correlated with the other equity curves, but it is smoother than individual strategies equity curve. What I am trying to convey here is that return to any strategy is attributed to the underlying health of the anomaly (something you cannot control) plus the efficiency of the parameters that are used to extract profit (something you have control over). The next chart is the drawdown

If we unfortunately chose to trade rsi2 (blue), our drawdowns will be markedly different.  Next a stacked horizon plot of rolling 252 day return

The first three are the models rsi1, rsi2, rsi3 and the third and fourth are no rebalance and rebalance. As you can see the overall performance is reduced, but in times when certain individual models underperform, the aggregate rebalancing model is able to mitigate it quite successfully.  An finally, the numbers…

One little experiment cannot prove anything. I am still trying the idea out in many different ways and hope that through further research, I will arrive at some more concrete conclusions.

# RSI Parameter insensitive Model
# test out rebalancing equal wait verses holding constant weight
# correctly set working directory and import in your own equity curves
# for blending, I passed in three equity curves for blending

data<-read.csv("rsi.csv") #set your own input files

#conversion to zoo object
data$date<-as.Date(data$date,"%Y-%m-%d")
rsi2.50.50<-zoo(data$rsi2.50,data$date)
rsi2.extreme<-zoo(data$rsi2.extreme,data$date)
rsi2.semi<-zoo(data$rsi2.semi,data$date)
data<-merge(rsi2.50.50,rsi2.extreme)
data<-merge(data,rsi2.semi)

names(data)<-c("rsi1",'rsi2','rsi3')
ret<-ROC(data)
ret[is.na(ret)]<-0

#normalize equity curves
ret$rsi1.equity<-cumprod(1+ret$rsi1) #simulated equity
ret$rsi2.equity<-cumprod(1+ret$rsi2)
ret$rsi3.equity<-cumprod(1+ret$rsi3)
ret$equity<-ret$rsi1.equity+ret$rsi2.equity+ret$rsi3.equity #add them together

ret$equity<-ROC(ret$equity)
ret$equity[is.na(ret$equity)]<-0
ret$equity<-cumprod(1+ret$equity)

rsi.equity1<-ret[,-(1:3)] #same allocation through time
rsi.equity2<-as.xts(rsi.equity1[,-4])

###############################
#Rebalancing of equity
###############################
# Load Systematic Investor Toolbox (SIT)
setInternet2(TRUE)
con = gzcon(url('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', 'rb'))
source(con)
close(con)

#*****************************************************************
# prep input
#******************************************************************
data <- list(prices=rsi.equity2,
 rsi1=rsi.equity2$rsi1,
 rsi2=rsi.equity2$rsi2,
 rsi3=rsi.equity2$rsi3) #need to create new list to store stuff
#weight with n column as input data
data$weight<-rsi.equity2
data$weight[!is.na(data$weight)]<- NA
#execution price
data$execution.price<-rsi.equity2
data$execution.price[!is.na(data$execution.price)]<-NA
#dates
data$dates<-index(rsi.equity2)

#*****************************************************************
# Rebalancing Algo
#******************************************************************
prices = data$prices
nperiods = nrow(prices)
target.allocation = matrix(c(0.33,0.33,0.33), nrow=1)

# Rebalance periodically
models = list()

period<-'weeks' #change to whatever rebalancing preiod you want
data$weight[] = NA
data$weight[1,] = target.allocation

period.ends = endpoints(prices, period)
period.ends = period.ends[period.ends > 0]
data$weight[period.ends,] = repmat(target.allocation, len(period.ends), 1)

capital = 100000
data$weight[] = (capital / prices) * data$weight

#this works oly when your input prices are object XTS rather than zoo
models[[period]] = bt.run(data, type='share', capital=capital)

#*****************************************************************
# Create Report
#******************************************************************
#all 5 equity curves
equity1<-merge(rsi.equity1,models$weeks$equity)
names(equity1)<-c('rsi1','rsi2','rsi3','no.reb','reb')
equity1<-as.xts(equity1)

#print out all the strategies return
for(i in 1:ncol(equity1)
{
 ret<-ROC(equity1[,i])
 ret[is.na(ret)]<-0
 ret<-as.xts(ret)
 dd<-Drawdowns(ret,geometric=T) #
 print(compute.cagr(equity1[,i]))
 print(maxDrawdown(as.xts(ret)))
 print((compute.cagr(equity1[,1]))/(maxDrawdown(as.xts(ret))))
 print(compute.sharpe(ret))
}

ret<-ROC(equity1,252)
horizonplot(ret,origin=0,scales = list(y = list(relation = "same")),colorkey=T)

df<-equity1
df <- data.frame( time=index(df),rsi1=df$rsi1,rsi2=df$rsi2,rsi3=df$rsi3,no.reb=df$no.reb,reb=df$reb)
#plot Equity

ggplot(df,aes(df$time)) +
 geom_line(aes(y=rsi1,colour="rsi1")) +
 geom_line(aes(y=rsi2,colour="rsi2")) +
 geom_line(aes(y=rsi3,colour="rsi3")) +
 geom_line(aes(y=no.reb,colour="no.reb")) +
 geom_line(aes(y=reb,colour="reb"),size=1.2)
#plot drawdown
df1<-merge(dd1,dd2,dd3,dd4,dd5)
df1<-data.frame( time=index(df1),rsi1=df1$rsi1,rsi2=df1$rsi2,rsi3=df1$rsi3,no.reb=df1$no.reb,reb=df1$reb)

ggplot(df1,aes(df$time)) +
 geom_line(aes(y=rsi1,colour="rsi1")) +
 geom_line(aes(y=rsi2,colour="rsi2")) +
 geom_line(aes(y=rsi3,colour="rsi3")) +
 geom_line(aes(y=no.reb,colour="no.reb")) +
 geom_line(aes(y=reb,colour="reb"),size=1.2)
Advertisements

Systematic Edge Backtest Engine: plotting features

Here are some new additions to the plotting functions of the backtester. They are a great way of visualizing the performance of a trading strategy. As I wanted ease and simplicity, all of the following plots can be done in one line of code. Each image is followed by the code that  generated it.

plot.equity(equity,bench,testParameters)

 

plot.drawdown(perf,bench)

plot.horizon(equity,bench,testParameters,250)

plot.calendarHeatMap(equity)

The first two plots are very self-explanatory. The third plot is called horizon plot. It is a compact way of visualizing time series data. The intuition behind the way I use it is to chart rolling n (250 in my case) period performance of a strategy relative to its benchmark. The darker the red, the more underperformance, while the darker the blue, the more outperformance. If you refer to the plot and look at the 2008 crisis, you can see that in general, the colour of the strategy is lighter in red compared to the benchmark, showing hedging at its best.

The last chart is a calendar heat-map. It plots the n-period log return for the entire test period and shows you how it has performed in different periods of time. This plot is great for detailed consistency checking as it is a great way peeling in to the strategies performance as it cycles through time; a true time machine in my opinion.

A creative performance measure derived from the calendar heat map is the percent of daily return above a user defined return threshold. The threshold by definition should be the risk free rate. When doing strategy comparison, the higher the percent of days of out performance, the better.

Much more to come. Enjoy!

 

 

On the Theory of Asset Allocation Part 2

In this post, I would like to show some research I have done on the front of utilizing portfolio theory to efficiently and optimally allocate capital to a pair of systems.

Traditional theory applied outright can be problematic. As I mentioned in the previous post, the assumptions that go in are not consistent in the long run, ie expected return, therefore the optimized portfolio performance will deviate significantly from backtest results. This is similar to developing a system on data that no longer reflect the current market state which will ultimately bankrupt you.

In my opinion, there are ideas within the traditional framework that are useful. Expected return of individual assets may not be reliable, but expected return of a well designed system should be, in a probabilistic sense.

For the past year, I started to view everything as a return streams. By this I mean rather than differentiating between assets and trading systems applied on assets, one should look at them equally. Although this may sound obvious, I will come back to this subject later and expand on it. But this way of thinking has helped me go against traditional methods of system design to built more robust systems that are model free and parameter insensitive.

In portfolio theory, the lower the correlation between instruments the better. In this experiments, I will be referring to two trading systems that are different in nature; Mean Reversion and Trend Following. Both of these trading systems will be applied to the same asset, SPY. System details:

Their daily return correlation is 0.04. The following is their equity curve.

Both of them are profitable and aren’t optimized as all. Test date is 1995-2012. Daily data are used from yahoo finance and no commissions or slippage was taken in to account. Next is their risk reward chart as popularized by traditional theory.

MR = Mean reversion, TF = Trend following, SPY = etf. From an asset allocation point of view, MR seems to be the most desirable of the three. Up next I show the efficient frontier of the two systems from 2000-2004 and then based on the minimum variance (MV) allocation in that period, I will forward test it. More concretely, I will compare the portfolio level equity curve from trading the two systems together.

The MV allocation is the left most point on the curve. It’s the allocation that minimizes portfolio variance. The following is the equity curves from 2005-2012 with different allocations.

Apologies for not plotting the legend! The red curve is the buy and hold of the SPY, the blue is a equal weight allocation between the two systems, and the orange curve is the MV allocation (~19% TF and ~81% MR). From a pure return perspective, trading the MV allocation produced the most return but from a risk reward standpoint, the equal weight allocation is better. In my optimization process, I found that the allocation that maximizes sharpe ratio would be allocation 100% to MR system. Now the numbers…

If I were to choose, I would go with the equal weight allocation as it has in my opinion the features that I will be able to sleep at night. I am not going to discuss the results in more depth as its well passed midnight, maybe another time I will come back and do something different.

Note: the portfolio level testing was simulated using tradingblox while the optimization and plotting were done in R. If you have any questions or comments, please leave a comment below! Email me if you want the TB system files.

Combining Edges

It was early on when I started out in research that I found the academic space provides a lot of ideas and inspirational data. On such popped up this morning when I was over at CXO Advisory. They do such a great job in gathering and filtering out relevant research; I highly recommend them.

In the paper, The Supraview of Return Predictors, they combined a total of 333 stock return predictors varying from accounting based ratios all the way to priced based predictors like momentum. I though a picture would explain a thousand words…

Above graph’s Y-Axis is the gross Sharpe ratio while the X-Axis is the number of predictors. The different lines are varying correlations amounts predictors in portfolio. As the number of predictors included increases (equal-weighted), so would the Sharpe ratio.

The above image shows Sharpe Ratio (Y-Axis) versus the correlations (X-Axis) amongst predictor. The concept here has reinforced my own philosophy about combining uncorrelated strategies to achieve exceptional return.

Images source from paper.