# Mean reversion Spread Trading with Linear Regression # # Deniz Turan, (denizstij AT gmail DOT com), 19-Jan-2014 import numpy as np from scipy.stats import linregress R_P = 1 # refresh period in days W_L = 30 # window length in days def initialize(context): context.y=sid(14517) # EWC context.x=sid(14516) # EWA # for long and shorting context.max_notional = 1000000 context.min_notional = -1000000.0 # set a fixed slippage set_slippage(slippage.FixedSlippage(spread=0.01)) context.long=False; context.short=False; def handle_data(context, data): xpx=data[context.x].price ypx=data[context.y].price retVal=linearRegression(data,context) # lets dont do anything if we dont have enough data yet if retVal is None: return None hedgeRatio,intercept=retVal; spread=ypx-hedgeRatio*xpx data[context.y]['spread'] = spread record(ypx=ypx,spread=spread,xpx=xpx) # find moving average rVal=getMeanStd(data, context) # lets dont do anything if we dont have enough data yet if rVal is None: return meanSpread,stdSpread = rVal # zScore is the number of unit zScore=(spread-meanSpread)/stdSpread; QTY=1000 qtyX=-hedgeRatio*QTY*xpx; qtyY=QTY*ypx; entryZscore=1; exitZscore=0; if zScore < -entryZscore and canEnterLong(context): # enter long the spread order(context.y, qtyY) order(context.x, qtyX) context.long=True context.short=False if zScore > entryZscore and canEnterShort(context): # enter short the spread order(context.y, -qtyY) order(context.x, -qtyX) context.short=True context.long=False record(cash=context.portfolio.cash, stock=context.portfolio.positions_value) @batch_transform(window_length=W_L, refresh_period=R_P) def linearRegression(datapanel, context): xpx = datapanel['price'][context.x] ypx = datapanel['price'][context.y] beta, intercept, r, p, stderr = linregress(ypx, xpx) # record(beta=beta, intercept=intercept) return (beta, intercept) @batch_transform(window_length=W_L, refresh_period=R_P) def getMeanStd(datapanel, context): spread = datapanel['spread'][context.y] meanSpread=spread.mean() stdSpread=spread.std() if meanSpread is not None and stdSpread is not None : return (meanSpread, stdSpread) else: return None def canEnterLong(context): notional=context.portfolio.positions_value if notional < context.max_notional and not context.long: # and not context.short: return True else: return False def canEnterShort(context): notional=context.portfolio.positions_value if notional > context.max_notional and not context.short: #and not context.short: return True else: return False
Sunday, January 19, 2014
Mean reversion with Linear Regression and Bollinger Band for Spread Trading within Python
Following code demonstrates how to utilize to linear regression to estimate hedge ratio and Bollinger band for spread trading. The code can be back tested at Quantopian.com
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment