Home > Backtesting, R, Strategy, Trading Strategies > Transaction Cost and Execution Price functionality in the Backtesting library in the Systematic Investor Toolbox

Transaction Cost and Execution Price functionality in the Backtesting library in the Systematic Investor Toolbox

I want to introduce the Transaction Cost and Execution Price functionality in the Backtesting library in the Systematic Investor Toolbox.

The Transaction Cost is implemented by a commission parameter in the bt.run() function. You may specify the commissions in $ per share for “share” type backtest and as a percentage of total trade for “weight” type backtest.

Following is a simple example of 50 / 200 day moving average cross over strategy with 10c per share commission:

###############################################################################
# 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$execution.price[] = NA
		data$weight[] = 1
	models$buy.hold = bt.run.share(data, clean.signal=T)

	#*****************************************************************
	# MA cross-over strategy
	#****************************************************************** 
	sma.fast = SMA(prices, 50)
	sma.slow = SMA(prices, 200)
		signal = iif(sma.fast >= sma.slow, 1, -1)
	
	data$weight[] = NA
		data$weight[] = signal
	models$ma.crossover = bt.run.share(data, clean.signal=T, trade.summary = TRUE)

	#*****************************************************************
	# MA cross-over strategy, add 10c per share commission
	#*****************************************************************	
	data$weight[] = NA
		data$weight[] = signal
	models$ma.crossover.com = bt.run.share(data, commission = 0.10, clean.signal=T)

The transaction costs reduced the total strategy performance from 5.13 to 4.83

The Backtesting library in the Systematic Investor Toolbox was designed with an assumption that there is only one price at which securities are traded each day, by default I used Close prices. The Execution.Price field allows to override this default functionality. In the following example, I modified the 50 / 200 day moving average cross over strategy to Enter trades at the open the next day after the signal.

	#*****************************************************************
	# MA cross-over strategy:
	# Exit trades at the close on the day of the signal
	# Enter trades at the open the next day after the signal	
	#****************************************************************** 
	popen = bt.apply(data, Op)		
	signal.new = signal
		trade.start	 = which(signal != mlag(signal) & signal != 0)
		signal.new[trade.start] = 0
		trade.start = trade.start + 1
		
	data$weight[] = NA
		data$execution.price[] = NA
		data$execution.price[trade.start,] = popen[trade.start,]
		data$weight[] = signal.new
	models$ma.crossover.enter.next.open = bt.run.share(data, clean.signal=T, trade.summary = TRUE)			
	
	#*****************************************************************
	# Create Report
	#****************************************************************** 	
	# Plot perfromance
	plotbt(models, plotX = T, log = 'y', LeftMargin = 3)	    	
		mtext('Cumulative Performance', side = 2, line = 1)
		
	# Plot trades
	plotbt.custom.report.part3(models$ma.crossover, trade.summary = TRUE)		
	plotbt.custom.report.part3(models$ma.crossover.enter.next.open, trade.summary = TRUE)		

This modification reduced the total strategy performance from 5.13 to 5.09 and we can double check the logic by comparing trades for each strategy below:

To view the complete source code for this example, please have a look at the bt.execution.price.test() function in bt.test.r at github.

About these ads
  1. John
    April 17, 2012 at 8:42 am

    Thank you for this explanation. Am I understanding correctly that using Systematic Investor Toolbox we can not replicate http://ibankcoin.com/woodshedderblog/2010/09/27/the-overnight-edge-drilling-deeper/ or http://marketsci.wordpress.com/2010/09/30/overnight-vs-daytime-markets-two-very-different-animals/ ?

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 252 other followers

%d bloggers like this: