Today I want to show how to use Volatility Position Sizing to improve strategy’s Risk Adjusted Performance. I will use the Average True Range (ATR) as a measure of Volatility and will increase allocation during low Volatility periods and will decrease allocation during high Volatility periods. Following are two good references that explain these strategy in detail:
First, let’s load prices for SPY and compute Buy & Hold performance using the Systematic Investor Toolbox:
###############################################################################
# Load Systematic Investor Toolbox (SIT)
# http://systematicinvestor.wordpress.com/systematic-investor-toolbox/
###############################################################################
con = gzcon(url('http://www.systematicportfolio.com/sit.gz', 'rb'))
source(con)
close(con)
#*****************************************************************
# Load historical data
#******************************************************************
load.packages('quantmod')
tickers = spl('SPY')
data <- new.env()
getSymbols(tickers, src = 'yahoo', from = '1970-01-01', env = data, auto.assign = T)
for(i in ls(data)) data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)
bt.prep(data, align='keep.all', dates='1970::')
#*****************************************************************
# Code Strategies
#******************************************************************
prices = data$prices
nperiods = nrow(prices)
models = list()
#*****************************************************************
# Buy & Hold
#******************************************************************
data$weight[] = 0
data$weight[] = 1
models$buy.hold = bt.run.share(data, clean.signal=T)
Next, let’s modify Buy & Hold strategy to vary it’s allocation according to the Average True Range (ATR).
#***************************************************************** # Volatility Position Sizing - ATR #****************************************************************** atr = bt.apply(data, function(x) ATR(HLC(x),20)[,'atr']) # position size in units = ((porfolio size * % of capital to risk)/(ATR*2)) data$weight[] = NA capital = 100000 # risk 2% of capital data$weight[] = (capital * 2/100) / (2 * atr) # make sure you are not committing more than 100% max.allocation = capital / prices data$weight[] = iif(data$weight > max.allocation, max.allocation,data$weight) models$buy.hold.2atr = bt.run(data, type='share', capital=capital) #***************************************************************** # Create Report #****************************************************************** models = rev(models) plotbt.custom.report.part1(models) plotbt.custom.report.part2(models)
The Sharpe and DVR are both higher for new strategy and draw-downs are lower.
To view the complete source code for this example, please have a look at the bt.position.sizing.test() function in factor.model.test.r at github.
R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series,ecdf, trading) and more...



Zero Inflated Models and Generalized Linear Mixed Models with R.
Zuur, Saveliev, Ieno (2012).