3 weak days in a row

Recently, Trading the odds posted one of many flavors of mean reverting strategies and I decided to get my hands dirty by writing R code and testing it.

You can find full description of the strategy by following latter link above. Long story short – if SPY shows lower open, high and close 3 days in a row, then buy on the close of third day and sell it 1 days later.
Let’s do simple test:

?View Code RSPLUS
require('xts')
require('quantmod')
getSymbols('SPY',from='1995-01-01',index.class=c("POSIXt","POSIXct"))
dividends=getDividends('SPY',from='1995-01-01',index.class=c("POSIXt","POSIXct"))
 
temp=cbind(dividends,SPY)
temp[,1][is.na(temp[,1])]=0
 
SPY=cbind(temp[,2],temp[,3],temp[,4],temp[,1]+temp[,5])
colnames(SPY)=c("Open","High","Low","Close")
 
#one day before
lag1=lag((SPY),1)
 
#two days defore
lag2=lag((SPY),2)
 
signal=ifelse( (Cl(lag2)>Cl(lag1) & Cl(lag1)>Cl(SPY))&
			(Hi(lag2)>Hi(lag1) & Hi(lag1)>Hi(SPY)) &
			(Op(lag2)>Op(lag1) & Op(lag1)>Op(SPY)),
			1,0
)
#one day later
lag3=lag(Cl(SPY),-1)
 
profit=(lag3/Cl(SPY)-1)*signal
profit[is.na(profit)]=0
png(file='first.png',width=500)
plot(cumprod(profit+1),main='Profit 1995-2010')
dev.off()

The code above supposed to produce something similar:

Photobucket

Nice curve, isn’t it? But neither commissions nor slippage were taken into account. So, let’s run more complicated test. For that purpose I utilized blotter package. Here’s the code:

?View Code RSPLUS
require('xts')
require('quantmod')
require('blotter')
require('PerformanceAnalytics')
require('FinancialInstrument')
getSymbols('SPY',from='1995-01-01',index.class=c("POSIXt","POSIXct"))
dividends=getDividends('SPY',from='1995-01-01',index.class=c("POSIXt","POSIXct"))
 
temp=cbind(dividends,SPY)
temp[,1][is.na(temp[,1])]=0
 
SPY=cbind(temp[,2],temp[,3],temp[,4],temp[,1]+temp[,5])
colnames(SPY)=c('Open','High','Low','Close')
 
#one day before
lag1=lag((SPY),1)
 
#two days defore
lag2=lag((SPY),2)
 
signal=ifelse( (Cl(lag2)>Cl(lag1) & Cl(lag1)>Cl(SPY))&
			(Hi(lag2)>Hi(lag1) & Hi(lag1)>Hi(SPY)) &
			(Op(lag2)>Op(lag1) & Op(lag1)>Op(SPY)),
			1,0
)
#one day later
lag3=lag(Cl(SPY),-1)
 
symbols=c('SPY')
 
initDate=index(get(symbols)[1])
initEq=10000
rm(list=ls(envir=.blotter),envir=.blotter)
ltportfolio='3days'
ltaccount='3days'
initPortf(ltportfolio,symbols, initDate=initDate)
initAcct(ltaccount,portfolios=c(ltportfolio), initDate=initDate,initEq=initEq)
currency("USD")
stock("SPY",currency="USD",multiplier=1)
 
signal[is.na(signal)]=0
 
counter<-0
 
for(i in 2:length(signal))
{
	currentDate= time(signal)[i]
	equity = 10000 #getEndEq(ltaccount, currentDate)
	#print(paste("equity ",equity))
	position = getPosQty(ltportfolio, Symbol=symbols[1], Date=currentDate)	
	print(currentDate)
	if(position==0)
	{		
		#open a new position if signal is >0
		if(signal[i]>0 &counter ==0)
		{
			print('open position')
			closePrice<-as.double(Cl(SPY[currentDate]))
			unitSize = as.numeric(trunc((equity/closePrice)))
			commssions=-unitSize*closePrice*0.0003
			addTxn(ltportfolio, Symbol=symbols[1],  TxnDate=currentDate, TxnPrice=closePrice, TxnQty = unitSize , TxnFees=commssions, verbose=T)
			counter<-1
		}
 
	}
	else
	{
		#position is open. If signal is 0 - close it.
		if(position>0 &counter>=1)
		{
			print('close position>>>>')
			position = getPosQty(ltportfolio, Symbol=symbols[1], Date=currentDate)
			closePrice<-as.double((Cl(SPY[currentDate])))#as.double(get(symbols[1])[i+100])
			commssions=-position*closePrice*0.0003
			addTxn(ltportfolio, Symbol=symbols[1],  TxnDate=currentDate, TxnPrice=closePrice, TxnQty = -position , TxnFees=commssions, verbose=T)
			counter<-0
		}
		else
			counter<-counter+1
	}	
	#print(equity)
	updatePortf(ltportfolio, Dates = currentDate)
	updateAcct(ltaccount, Dates = currentDate)
	updateEndEq(ltaccount, Dates = currentDate)
 
	#equity = getEndEq(ltaccount, currentDate)
	#print(paste("equity ",equity))
}
result=rez1$symbols$SPY$txn[,7]
result=result[result!=0]
 
png(file='second.png',width=500)
#fix commission rate 2*3
plot(cumsum(result-6))
#next line will allow you to compare the performace with and without commissions
#chart.CumReturns(cbind((result)/10000,(result-6)/10000))
dev.off()

Photobucket

Nice curve, but let’s look beyond that. First of all, here’s nice function in PerformanceAnalytics package, AnnulizedReturns:
table.AnnualizedReturns((result-6)/10000)
Gross.Txn.Realized.PL
Annualized Return 0.0265
Annualized Std Dev 0.0494
Annualized Sharpe (Rf=0%) 0.5366

Well, Sharpe ratio is not impressive. The profit percentage of this strategy is 57% and mean of profitable return is 111$ against 98$ loss. Profit factor is ~1.55.

I think, this strategy can be as one of the parameter or vote in another system, but alone it is weak.

6 Comments »

  1. kafka said,

    December 6, 2010 @ 23:04

    Plugin for R code doesn’t work properly and I will work on that tomorrow, meantime you can check the code here: https://github.com/kafka399/Rproject/blob/master/3lowDays.R

  2. kafka said,

    December 7, 2010 @ 8:45

    The code is fixed – let me know if you have some difficulties to run it.

  3. A Few Posts - Quantitative Finance - said,

    December 8, 2010 @ 19:00

    [...] testing the performance of 3 days in a row trading strategy with & without commission in R, http://www.investuotojas.eu/?p=409;2, writing nicer R codes with Notepad++ and NppToR, http://robjhyndman.com/researchtips/npptor/;3, [...]

  4. John said,

    January 21, 2011 @ 4:34

    Hi,

    I’m trying to find out what the “>” and “&” in the ifelse code mean. I keep getting an error at that point of the script.

    From my Rgui:
    > signal=ifelse( (Cl(lag2)>Cl(lag1) & Cl(lag1)>Cl(SPY))&
    Error: unexpected ‘;’ in “signal=ifelse( (Cl(lag2)>”
    > (Hi(lag2)>Hi(lag1) & Hi(lag1)>Hi(SPY)) &
    Error: unexpected ‘;’ in ” (Hi(lag2)>”
    > (Op(lag2)>Op(lag1) & Op(lag1)>Op(SPY)),
    Error: unexpected ‘;’ in ” (Op(lag2)>”
    > 1,0
    Error: unexpected ‘,’ in ” 1,”
    > )
    Error: unexpected ‘)’ in “)”

    I tried Rseek for answer but came up with nothing useful.

    John

  5. Dzidorius Martinaitis said,

    January 21, 2011 @ 11:38

    John,
    I suspect, that when you copied the code you took html interpretation of > and &. Click on View code and make a copy of source code from there.

  6. jim green said,

    May 23, 2012 @ 16:39

    52c52
    stock(symbols,currency=”USD”,multiplier=1)
    there seems to be a little bug.

RSS feed for comments on this post · TrackBack URI

Leave a Comment