http://www.scottsinvestments.com/all-season-etf/
Anyone can give me tips to change it to quarterly/yearly rebalancing?
http://www.scottsinvestments.com/all-season-etf/
Anyone can give me tips to change it to quarterly/yearly rebalancing?
For periodic rebalancing you can use something along the lines of
def rebalance(data,context,target_weight,sid):
if pd.datetools.isBMonthEnd(date):
Your rebalance code
This will give you monthly rebalance, of course you need to either set a global date variable in handle data or pass an additional arg to rebalance, which is stored in the bar data
Hi Bernd,
A simple way to rebalance monthly would be to rebalance the first of the month when
context.month != get_datetime().month
I've attached a backtest that shows you it in action, I've also put all the weights into a Python dictionary to make it a bit easier to call the rebalance() function
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.
Thanks Seong, your ideas helped me very much. They helped me setting up the closed form minimum correlation variant. Will have to take a look into the scipy optimizers to form one using weight constraints so I can get a long only variant as well.
Heres how you use Scipy to optimize:
import scipy.optimize as opt
def cost_func(weights):
your function to minimize here (example)
return -1 * (mu/ sigma)
syms = [list of your trading universe]
bounds = [(0, 1) for x in syms] #0 to 1 bounds to prevent leverage or shorts
constraint = ({'type':'eq', 'fun': lambda weights: weights.sum() - 1}) #constrain weights such that they sum to 1.00
fmin = opt.minimize(cost_func, weights, method = 'SLSQP', bounds=bounds, constraints = c) #You have to use SLSQP for bound-constrained optimization
w = Series(fmin.x, index= syms) #create series with percentage weights indexed by sym
for sym in w.dropna().index: #iterate through and buy positions
target_percent(data[sym].sid, w[sym]) #Not sure if this function carries over from zipline, however this orders the percentage given by fmin
Clearly, you will need to modify this to suit your needs but this is the general workflow. Just be careful in designing your cost function such that there exists a solution. Also more stringent constraints will make it harder to find a solution. You should also raise a Value Error if the optimization doesn't work, as the above simply ignores it and will continue on.
Thanks, I will play around with that. When I tried to use it yesterday I had some problems with passing on the covariance matrix as extra args because it interpreted every row/colums (not sure which one) as a single argument.
Yes, tried something like this:
def solve_weights(C):
def fitness(W, C):
return (dot(dot(W,C),W)
n = len(C)
W = ones([n])/n
b_ = [(0.,1.) for i in range(n)]
c_ = ({'type':'eq', 'fun': lambda W: sum(W)-1. })
optimized = scipy.optimize.minimize(fitness, W, args = (C), method='SLSQP', constraints=c_, bounds=b_)
if not optimized.success:
raise BaseException(optimized.message)
return optimized.x
But the fitness function wouldn't accept my covariance matrix (C). Still kinda new to numpy/scipy. Usually use matlab for that kinda stuff.
Well for the global minimum variance portfolio there is a numerical solution, that will be far faster and therefore Scipy isn't necessary. However should you choose otherwise, there really is no need to pass covariance, as it isn't changing between calls to fitness. if your fitness function is inside handle_data, your covariance matrix will still be in the scope.
your solve weights function really isn't necessary;
def fitness(W):
return (dot(dot(W,C),W)
n = len(C)
W = ones([n])/n
b_ = [(0.,1.) for i in range(n)]
c_ = ({'type':'eq', 'fun': lambda W: sum(W)-1. })
optimized = scipy.optimize.minimize(fitness, W, method='SLSQP', constraints=c_, bounds=b_)
if not optimized.success:
raise ValueError(optimized.message)
return optimized.x
The numerical solution is
in pseudo code
inv(cov).dot(1) / 1T.dot(inv(cov).dot(1))
I know, I already used that. But the closed from solution doesn't allow for weight constraints which it what I want to accomplish using the optimizer.