Sometimes looking at stocks, they look trend stationary. Do people do stuff like this? Maybe take into account the residuals? It's kind of lame, but I'd be interested in what the optimal hyperparameters look like.

Hello Taylor,

Did you post an algorithm? I'm getting a never-ending "Loading..." message. Please post it again. I want to have a peak at how you did the linear regression.

Grant

Let me just paste the code. Weird stuff has been happening to my computer lately

```
import statsmodels.api as sm
@batch_transform(window_length=10, refresh_period=1)
def get_LR(data, sid):
ts = data.price[sid]
time = sm.add_constant(range(0,len(ts)))
slope , intercept = sm.OLS(ts, time).fit().params
return slope, intercept
def initialize(context):
context.spy = sid(8554)
#each to be optimized
#also optimize window length
context.buyThresh = 2
context.sellThresh = -2.5
context.invested = 0
# Will be called on every trade event for the securities you specify.
def handle_data(context, data):
myStock = context.spy
params = get_LR(data, myStock)
if params is None:
return
if(params[1] > context.buyThresh and not context.invested):
order(myStock, 10000)
if(params[1] < context.sellThresh and not context.invested):
order(myStock, -10000)
else:
order(myStock, -context.portfolio.positions[myStock].amount)
```

Hi Taylor and Grant, sorry for the trouble loading the backtest in the thread. We're sorting through an issue on our end and hopefully will have it fixed soon.

thanks,

Jean

Hey all, that issue should be fixed now. Taylor, when you can, please run the backtest again and share that. Hopefully we'll see more than "Loading..." on that one.

-Rich

Quantopian

Taylor,

Here's a version of your algorithm that I tweaked a bit. It seems to be able to profit off of dramatic down-turns in the market...not so sure about the up-swings...might require additional "tuning" or different logic.

Jean & Rich - thanks for the fix!

Grant

bug maybe...doesn't sm.ols() return params in the order of intercept, slope instead of slope intercept?

edit: your logic is right. you're trading on the fitted slope. kind of stupid though because I've never in my life seen a model matrix with a ones column at the end. i'm gonna add a prepend = True to my sm.OLS call.

also your reversing of my idea makes more sense... it's like fading all the dudes that figure trend stationary will persist for a while longer.

just looked at thomas wiecki's slides on the internet that are floating around. could try running grid search on the thing below. might be messed up since it comes out with different results

```
import matplotlib.pyplot as plt
import statsmodels.api as sm
import datetime as dt
from zipline.algorithm import TradingAlgorithm
from zipline.transforms import batch_transform
from zipline.utils.factory import load_from_yahoo
@batch_transform
def get_LR(data, sid):
ts = data.price[sid]
time = sm.add_constant(range(0,len(ts)), prepend = True)
intercept, slope = sm.OLS(ts, time).fit().params
return intercept, slope
class slidingLR(TradingAlgorithm):
def initialize(self, window_length=10, buy_thresh = -1, sell_thresh = 1):
self.window_length = window_length
self.buyThresh = buy_thresh
self.sellThresh = sell_thresh
self.invested = False
self.getRegression = get_LR(refresh_period = 1, window_length = self.window_length)
def handle_data(self, data):
params = self.getRegression.handle_data(data, globalTicker)
if params is None:
return
slope = params[1]
#place orders
if(slope < self.buyThresh and not self.invested):
self.order(globalTicker, 10000)
self.invested = True
elif(slope > self.sellThresh and not self.invested):
self.order(globalTicker, -10000)
self.invested = True
elif(abs(self.portfolio.positions[globalTicker].amount) > 0):
self.order(globalTicker, -self.portfolio.positions[globalTicker].amount)
self.invested = False
globalTicker = "SPY"
start = dt.datetime(2002,1,3)
end = dt.datetime(2013,4,5)
data = load_from_yahoo(stocks=[globalTicker], start = start, end = end, indexes={})
def run_slidingLR(window_length = 10, buy_thresh = -1, sell_thresh = 1):
algoObj = slidingLR(window_length, buy_thresh, sell_thresh)
results = algoObj.run(data)
#return results.portfolio_value[len(results)-1]
return results.portfolio_value
results = run_slidingLR(window_length = 10, buy_thresh = -1, sell_thresh = 1)
results.plot()
plt.show()
```

Hello Taylor,

My hunch is that the algorithm I posted above (the modification of yours) works because it is sensitive to over-reaction to a down-turn. Market participants get scared, etc. so the market tanks and then bounces back--a buying opportunity.

Grant