Simple Mean-Reverting Model with and without Transaction Costs


In [1]:
import numpy as np

In [2]:
import pandas as pd

In [3]:
startDate=20060101

In [4]:
endDate=20061231

In [5]:
df=pd.read_table('SPX_20071123.txt')

In [6]:
df['Date']=df['Date'].astype('int')

In [7]:
df.set_index('Date', inplace=True)

In [8]:
df.sort_index(inplace=True)

In [9]:
dailyret=df.pct_change()

In [10]:
marketDailyret=dailyret.mean(axis=1)

In [11]:
weights=-(np.array(dailyret)-np.array(marketDailyret).reshape((dailyret.shape[0], 1)))

In [12]:
wtsum=np.nansum(abs(weights), axis=1)

In [13]:
weights[wtsum==0,]=0

In [14]:
wtsum[wtsum==0]=1

In [15]:
weights=weights/wtsum.reshape((dailyret.shape[0],1))

In [16]:
dailypnl=np.nansum(np.array(pd.DataFrame(weights).shift())*np.array(dailyret), axis=1)

In [17]:
dailypnl=dailypnl[np.logical_and(df.index >= startDate, df.index <= endDate)]

In [18]:
sharpeRatio=np.sqrt(252)*np.mean(dailypnl)/np.std(dailypnl)

In [19]:
sharpeRatio


Out[19]:
0.957785681010386

With transaction costs


In [20]:
onewaytcost=0.0005

In [21]:
weights=weights[np.logical_and(df.index >= startDate, df.index <= endDate)]

In [22]:
dailypnlminustcost=dailypnl - (np.nansum(abs(weights-np.array(pd.DataFrame(weights).shift())), axis=1)*onewaytcost)

In [23]:
sharpeRatioMinusTcost=np.sqrt(252)*np.mean(dailypnlminustcost)/np.std(dailypnlminustcost)

In [24]:
sharpeRatioMinusTcost


Out[24]:
-2.1617433718962276