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.
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
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.
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
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.
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()